mirror of
https://github.com/acid-info/lsd.git
synced 2025-01-11 17:44:14 +00:00
chore: update storybook docs
This commit is contained in:
parent
efa4792a2a
commit
ade4af1856
@ -1,7 +1,9 @@
|
||||
import { dirname, join } from 'path'
|
||||
|
||||
module.exports = {
|
||||
stories: [
|
||||
'../src/components/**/*.stories.mdx',
|
||||
'../src/docs/**/*.mdx',
|
||||
'../src/components/**/*.mdx',
|
||||
'../src/components/**/*.stories.@(js|jsx|ts|tsx)',
|
||||
],
|
||||
|
||||
|
@ -1,6 +1,15 @@
|
||||
import {
|
||||
Canvas,
|
||||
Controls,
|
||||
Description,
|
||||
Subtitle,
|
||||
Title,
|
||||
useOf,
|
||||
} from '@storybook/blocks'
|
||||
import type { Preview } from '@storybook/react'
|
||||
import React from 'react'
|
||||
import { THEME_TYPOGRAPHY_FONT_CATEGORIES } from '../src/components/Theme/constants'
|
||||
import { storybookThemes } from './themes'
|
||||
import { docTheme, storybookThemes } from './themes'
|
||||
import { withTheme } from './withTheme.decorator'
|
||||
|
||||
const preview: Preview = {
|
||||
@ -32,6 +41,27 @@ const preview: Preview = {
|
||||
),
|
||||
},
|
||||
},
|
||||
docs: {
|
||||
theme: docTheme,
|
||||
page: () => {
|
||||
const resolvedOf = useOf('meta', ['meta'])
|
||||
const { stories, meta, moduleExports } = resolvedOf.csfFile
|
||||
|
||||
const controls =
|
||||
typeof meta?.parameters?.docs?.controls === 'undefined' ||
|
||||
meta?.parameters?.docs?.controls === true
|
||||
|
||||
return (
|
||||
<>
|
||||
<Title />
|
||||
<Subtitle />
|
||||
<Description />
|
||||
<Canvas sourceState="shown" />
|
||||
{controls && <Controls />}
|
||||
</>
|
||||
)
|
||||
},
|
||||
},
|
||||
},
|
||||
decorators: [withTheme],
|
||||
argTypes: {
|
||||
|
@ -118,13 +118,13 @@ export const extractMetadata = async (dir: string) => {
|
||||
})
|
||||
|
||||
const components = await fromStories(stories.default, assetsDir)
|
||||
const globalTypes = await extractGlobalTypes(assetsDir)
|
||||
// const globalTypes = await extractGlobalTypes(assetsDir)
|
||||
|
||||
fs.unlinkSync(path.join(assetsDir, 'package.json'))
|
||||
|
||||
return {
|
||||
components,
|
||||
globalTypes,
|
||||
// globalTypes,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { Parameters, StoryContext } from '@storybook/react'
|
||||
import { create } from '@storybook/theming/create'
|
||||
import { GlobalTypes } from '@storybook/types'
|
||||
import { CreateThemeProps, createTheme, defaultThemes } from '../src'
|
||||
import { THEME_TYPOGRAPHY_FONT_CATEGORIES } from '../src/components/Theme/constants'
|
||||
@ -104,3 +105,30 @@ const createThemes = () => {
|
||||
}
|
||||
|
||||
export const storybookThemes = createThemes()
|
||||
|
||||
const darkTheme = defaultThemes.dark
|
||||
export const docTheme = create({
|
||||
base: 'dark',
|
||||
fontBase: darkTheme.typographyGlobal.genericFontFamily,
|
||||
fontCode: darkTheme.typographyGlobal.genericFontFamily,
|
||||
colorPrimary: `rgb(${darkTheme.palette.primary})`,
|
||||
colorSecondary: `rgb(${darkTheme.palette.secondary})`,
|
||||
appBg: `rgb(${darkTheme.palette.surface.primary})`,
|
||||
appContentBg: `rgb(${darkTheme.palette.surface.primary})`,
|
||||
appBorderColor: `rgb(${darkTheme.palette.border.primary})`,
|
||||
appBorderRadius: 0,
|
||||
textColor: `rgb(${darkTheme.palette.text.primary})`,
|
||||
textInverseColor: `rgb(${darkTheme.palette.text.secondary})`,
|
||||
barTextColor: `rgb(${darkTheme.palette.text.primary})`,
|
||||
barSelectedColor: `rgb(${darkTheme.palette.text.primary})`,
|
||||
barBg: `rgb(${darkTheme.palette.surface.primary})`,
|
||||
inputBg: `rgb(${darkTheme.palette.surface.secondary})`,
|
||||
inputBorder: `rgb(${darkTheme.palette.border.primary})`,
|
||||
inputTextColor: `rgb(${darkTheme.palette.text.secondary})`,
|
||||
inputBorderRadius: 0,
|
||||
booleanBg: `rgb(${darkTheme.palette.surface.primary})`,
|
||||
booleanSelectedBg: `rgb(${darkTheme.palette.surface.primary})`,
|
||||
buttonBorder: `rgb(${darkTheme.palette.border.primary})`,
|
||||
buttonBg: `rgb(${darkTheme.palette.surface.secondary})`,
|
||||
textMutedColor: `rgb(${darkTheme.palette.text.primary})`,
|
||||
})
|
||||
|
@ -1,3 +1,4 @@
|
||||
import { Global, css } from '@emotion/react'
|
||||
import { useGlobals } from '@storybook/preview-api'
|
||||
import { Decorator } from '@storybook/react'
|
||||
import React, { useEffect } from 'react'
|
||||
@ -6,9 +7,9 @@ import { storybookThemes } from './themes'
|
||||
|
||||
export const withTheme: Decorator = (Story, context) => {
|
||||
const StoryComponent = Story as any as React.ComponentType
|
||||
const isDoc = context.viewMode === 'docs'
|
||||
|
||||
const theme = storybookThemes.getTheme(context)
|
||||
|
||||
const [globals, setGlobals] = useGlobals()
|
||||
|
||||
useEffect(() => {
|
||||
@ -28,8 +29,19 @@ export const withTheme: Decorator = (Story, context) => {
|
||||
|
||||
return (
|
||||
<div>
|
||||
<ThemeProvider theme={theme}>
|
||||
<ThemeProvider theme={theme} injectCssVars={true}>
|
||||
<StoryComponent />
|
||||
{isDoc && (
|
||||
<Global
|
||||
styles={css`
|
||||
.docs-story {
|
||||
${theme.cssVars}
|
||||
|
||||
background: rgb(var(--lsd-surface-primary));
|
||||
}
|
||||
`}
|
||||
/>
|
||||
)}
|
||||
</ThemeProvider>
|
||||
</div>
|
||||
)
|
||||
|
@ -1,12 +1,26 @@
|
||||
import { StoryObj, Meta, StoryFn } from '@storybook/react'
|
||||
import { Meta, StoryObj } from '@storybook/react'
|
||||
import shuffle from 'lodash/shuffle'
|
||||
import { Autocomplete, AutocompleteProps } from './Autocomplete'
|
||||
|
||||
const list = JSON.parse(
|
||||
'["BitTorrent","VANIG","BenjiRolls","Status Network Token","GigTricks","Vechain","Insureum","Instant Sponsor Token","IslaCoin","Kcash","Litecoin","BoutsPro","Valorem","Artcoin","Insureum","Zen Protocol","CryptoPennies","MediBond","WishFinance","BlockNet","Big Data Block","Loom Network","Gamedex","Universal Recognition Token","Soarcoin","IZX","aelf","Bitcoin Private","TerraCoin","Coinnec","Revolution VR","SecureCoin","Swarm Fund","Fan360","LakeBanker","16BitCoin","CyberTrust","Actinium","ZestCoin","Monero 0","DACash","Bitswift","Bethereum","Hedge Token","Megastake","HeelCoin","RealChain","LiteBitcoin","SexCoin","Suretly","Internet of People","Rate3","Invictus","WorldPay","iOlite","Cashaa","NovaCoin","U Network","Gimli","Chynge.net","BMChain","Ethereum Premium","BlackShadowCoin","Javvy","Befund","Bancor Network Token","BOONSCoin","Pantos","IDEX Membership","BitStation","Lynx","Encrybit","HighVibe.Network","Credo","HiCoin","RiptideCoin","BitBoss","NXTTY","Presale Ventures","Urbit Data","Xeonbit","Newbium","Mint","Crypto Wine Exchange","HARA","Pioneer Coin","Ethereum Dark","FazzCoin","Fitrova","The EFFECT Network","CargoX","PolicyPal Network","Vechain","President Clinton","GenesysCoin","Trivver","Bitdeal","ShareMeAll","Primas","RoboAdvisorCoin","Liquid","Napoleon X","NOKU Master token","Liqnet","ZeroState","0chain","DarkCash","Sudan Gold Coin","PokerSports","Bankera","Think And Get Rich Coin","ELTCOIN","USOAMIC","XDNA","Autoria","Cosmo","Bigbom","EagsCoin","Stakinglab","SaffronCoin","BnrtxCoin","FoodCoin","PutinCoin","SID Token","Quartz","IOU1","Spend","NEO Gold","High Voltage Coin","Unobtanium","Sandcoin","FrazCoin","Sudan Gold Coin","VeriCoin","Aurora","NANJCOIN","Muse","DuckDuckCoin","Saifu","CryCash","Rustbits","BitFlip","Cpollo","Monkey Project","Coin Analyst","Scanetchain Token","Aditus","LendConnect","FOREXCOIN","Crypto Improvement Fund","Electra","Psilocybin","GameLeagueCoin","Switcheo","BitQuark","BinaryCoin","CyberVein","KATZcoin","BtcEX","ByteCoin","Shping Coin","Liquid","Stacktical","Tezos","ParkByte","Imbrex","Pinmo","Sigil","LePenCoin","OmiseGO Classic","Digix DAO","ShareRing","CryptoCarbon","CDX Network","SONM","PhoenixCoin","Incent","Tokyo Coin","Premium","Unattanium","Biotron","WETH","Rublebit","KRCoin","Aegis","Legends Cryptocurrency","VARcrypt","Witcoin","GlowShares","HOQU","VARcrypt","Linx","BlackholeCoin","NumbersCoin","ZayedCoin","CarVertical","Securosys","ElliotCoin","Zelcash","AcesCoin","EtherInc"]',
|
||||
)
|
||||
const list = shuffle(
|
||||
JSON.parse(
|
||||
'["BitTorrent","VANIG","BenjiRolls","Status Network Token","GigTricks","Vechain","Insureum","Instant Sponsor Token","IslaCoin","Kcash","Litecoin","BoutsPro","Valorem","Artcoin","Insureum","Zen Protocol","CryptoPennies","MediBond","WishFinance","BlockNet","Big Data Block","Loom Network","Gamedex","Universal Recognition Token","Soarcoin","IZX","aelf","Bitcoin Private","TerraCoin","Coinnec","Revolution VR","SecureCoin","Swarm Fund","Fan360","LakeBanker","16BitCoin","CyberTrust","Actinium","ZestCoin","Monero 0","DACash","Bitswift","Bethereum","Hedge Token","Megastake","HeelCoin","RealChain","LiteBitcoin","SexCoin","Suretly","Internet of People","Rate3","Invictus","WorldPay","iOlite","Cashaa","NovaCoin","U Network","Gimli","Chynge.net","BMChain","Ethereum Premium","BlackShadowCoin","Javvy","Befund","Bancor Network Token","BOONSCoin","Pantos","IDEX Membership","BitStation","Lynx","Encrybit","HighVibe.Network","Credo","HiCoin","RiptideCoin","BitBoss","NXTTY","Presale Ventures","Urbit Data","Xeonbit","Newbium","Mint","Crypto Wine Exchange","HARA","Pioneer Coin","Ethereum Dark","FazzCoin","Fitrova","The EFFECT Network","CargoX","PolicyPal Network","Vechain","President Clinton","GenesysCoin","Trivver","Bitdeal","ShareMeAll","Primas","RoboAdvisorCoin","Liquid","Napoleon X","NOKU Master token","Liqnet","ZeroState","0chain","DarkCash","Sudan Gold Coin","PokerSports","Bankera","Think And Get Rich Coin","ELTCOIN","USOAMIC","XDNA","Autoria","Cosmo","Bigbom","EagsCoin","Stakinglab","SaffronCoin","BnrtxCoin","FoodCoin","PutinCoin","SID Token","Quartz","IOU1","Spend","NEO Gold","High Voltage Coin","Unobtanium","Sandcoin","FrazCoin","Sudan Gold Coin","VeriCoin","Aurora","NANJCOIN","Muse","DuckDuckCoin","Saifu","CryCash","Rustbits","BitFlip","Cpollo","Monkey Project","Coin Analyst","Scanetchain Token","Aditus","LendConnect","FOREXCOIN","Crypto Improvement Fund","Electra","Psilocybin","GameLeagueCoin","Switcheo","BitQuark","BinaryCoin","CyberVein","KATZcoin","BtcEX","ByteCoin","Shping Coin","Liquid","Stacktical","Tezos","ParkByte","Imbrex","Pinmo","Sigil","LePenCoin","OmiseGO Classic","Digix DAO","ShareRing","CryptoCarbon","CDX Network","SONM","PhoenixCoin","Incent","Tokyo Coin","Premium","Unattanium","Biotron","WETH","Rublebit","KRCoin","Aegis","Legends Cryptocurrency","VARcrypt","Witcoin","GlowShares","HOQU","VARcrypt","Linx","BlackholeCoin","NumbersCoin","ZayedCoin","CarVertical","Securosys","ElliotCoin","Zelcash","AcesCoin","EtherInc"]',
|
||||
),
|
||||
).slice(0, 20)
|
||||
|
||||
const subtitle = `Input`
|
||||
const description = `Autocomplete is an enhanced version of a TextField component, that displays suggested options as users type, allowing them to make a selection from the list.`
|
||||
|
||||
export default {
|
||||
title: 'Autocomplete',
|
||||
parameters: {
|
||||
componentSubtitle: subtitle,
|
||||
docs: {
|
||||
description: {
|
||||
component: description,
|
||||
},
|
||||
},
|
||||
},
|
||||
component: Autocomplete,
|
||||
argTypes: {
|
||||
size: {
|
||||
|
@ -1,10 +1,21 @@
|
||||
import { StoryObj, Meta, StoryFn } from '@storybook/react'
|
||||
import { Badge, BadgeProps } from './Badge'
|
||||
import { Meta, StoryObj } from '@storybook/react'
|
||||
import { useStorybookIconComponent } from '../../utils/storybook.utils'
|
||||
import { Badge, BadgeProps } from './Badge'
|
||||
|
||||
const subtitle = `Data Display`
|
||||
const description = `Badge component is used to display concise pieces of information, such as notifications, counts, statuses, and more. Typically, it is positioned near other UI elements to convey information associated with them.`
|
||||
|
||||
export default {
|
||||
title: 'Badge',
|
||||
component: Badge,
|
||||
parameters: {
|
||||
componentSubtitle: subtitle,
|
||||
docs: {
|
||||
description: {
|
||||
component: description,
|
||||
},
|
||||
},
|
||||
},
|
||||
argTypes: {
|
||||
variant: {
|
||||
type: {
|
||||
|
@ -1,8 +1,19 @@
|
||||
import { StoryObj, Meta, StoryFn } from '@storybook/react'
|
||||
import { Meta, StoryObj } from '@storybook/react'
|
||||
import { Breadcrumb, BreadcrumbProps } from './Breadcrumb'
|
||||
|
||||
const subtitle = `Navigation`
|
||||
const description = `Breadcrumbs show users their current location on the website or app and allow them to quickly navigate back to a parent level or a previous step.`
|
||||
|
||||
export default {
|
||||
title: 'Breadcrumb',
|
||||
parameters: {
|
||||
componentSubtitle: subtitle,
|
||||
docs: {
|
||||
description: {
|
||||
component: description,
|
||||
},
|
||||
},
|
||||
},
|
||||
component: Breadcrumb,
|
||||
argTypes: {
|
||||
size: {
|
||||
|
@ -1,10 +1,21 @@
|
||||
import { StoryObj, Meta, StoryFn } from '@storybook/react'
|
||||
import { Meta, StoryObj } from '@storybook/react'
|
||||
import { useStorybookIconComponent } from '../../utils/storybook.utils'
|
||||
import { Button, ButtonProps } from './Button'
|
||||
|
||||
const subtitle = `Input`
|
||||
const description = `Button component is used to trigger an action or event, it is labeled to convey what will happen upon interaction.`
|
||||
|
||||
export default {
|
||||
title: 'Button',
|
||||
component: Button,
|
||||
parameters: {
|
||||
componentSubtitle: subtitle,
|
||||
docs: {
|
||||
description: {
|
||||
component: description,
|
||||
},
|
||||
},
|
||||
},
|
||||
argTypes: {
|
||||
size: {
|
||||
type: {
|
||||
|
@ -1,11 +1,22 @@
|
||||
import { StoryObj, Meta, StoryFn } from '@storybook/react'
|
||||
import { Meta, StoryObj } from '@storybook/react'
|
||||
import { CardBody } from '../CardBody'
|
||||
import { CardHeader } from '../CardHeader'
|
||||
import { Card, CardProps } from './Card'
|
||||
|
||||
const subtitle = `Surface`
|
||||
const description = `Card is a flexible component designed to group and present content about a single subject in a clear and concise format, often including associated actions.`
|
||||
|
||||
export default {
|
||||
title: 'Card',
|
||||
component: Card,
|
||||
parameters: {
|
||||
componentSubtitle: subtitle,
|
||||
docs: {
|
||||
description: {
|
||||
component: description,
|
||||
},
|
||||
},
|
||||
},
|
||||
argTypes: {
|
||||
size: {
|
||||
type: {
|
||||
|
@ -1,9 +1,20 @@
|
||||
import { StoryObj, Meta, StoryFn } from '@storybook/react'
|
||||
import { Meta, StoryObj } from '@storybook/react'
|
||||
import { CardBody, CardBodyProps } from './CardBody'
|
||||
|
||||
const subtitle = ``
|
||||
const description = ``
|
||||
|
||||
export default {
|
||||
title: 'CardBody',
|
||||
component: CardBody,
|
||||
parameters: {
|
||||
componentSubtitle: subtitle,
|
||||
docs: {
|
||||
description: {
|
||||
component: description,
|
||||
},
|
||||
},
|
||||
},
|
||||
argTypes: {
|
||||
size: {
|
||||
type: {
|
||||
|
@ -1,9 +1,20 @@
|
||||
import { StoryObj, Meta, StoryFn } from '@storybook/react'
|
||||
import { Meta, StoryObj } from '@storybook/react'
|
||||
import { CardHeader, CardHeaderProps } from './CardHeader'
|
||||
|
||||
const subtitle = ``
|
||||
const description = ``
|
||||
|
||||
export default {
|
||||
title: 'CardHeader',
|
||||
component: CardHeader,
|
||||
parameters: {
|
||||
componentSubtitle: subtitle,
|
||||
docs: {
|
||||
description: {
|
||||
component: description,
|
||||
},
|
||||
},
|
||||
},
|
||||
argTypes: {
|
||||
size: {
|
||||
type: {
|
||||
|
@ -1,9 +1,20 @@
|
||||
import { StoryObj, Meta, StoryFn } from '@storybook/react'
|
||||
import { Meta, StoryObj } from '@storybook/react'
|
||||
import { Checkbox, CheckboxProps } from './Checkbox'
|
||||
|
||||
const subtitle = `Input`
|
||||
const description = `Checkbox component allows users to select one or multiple items from a list. It is ideal for cases where multiple selections are required from a range of options.`
|
||||
|
||||
export default {
|
||||
title: 'Checkbox',
|
||||
component: Checkbox,
|
||||
parameters: {
|
||||
componentSubtitle: subtitle,
|
||||
docs: {
|
||||
description: {
|
||||
component: description,
|
||||
},
|
||||
},
|
||||
},
|
||||
argTypes: {
|
||||
size: {
|
||||
type: {
|
||||
|
@ -1,9 +1,20 @@
|
||||
import { StoryObj, Meta, StoryFn } from '@storybook/react'
|
||||
import { Meta, StoryObj } from '@storybook/react'
|
||||
import { Checkbox } from '../Checkbox'
|
||||
import { CheckboxGroup, CheckboxGroupProps } from './CheckboxGroup'
|
||||
|
||||
const subtitle = `Input`
|
||||
const description = `CheckboxGroup component groups multiple Checkbox components, inheriting all their available styles.`
|
||||
|
||||
export default {
|
||||
title: 'CheckboxGroup',
|
||||
parameters: {
|
||||
componentSubtitle: subtitle,
|
||||
docs: {
|
||||
description: {
|
||||
component: description,
|
||||
},
|
||||
},
|
||||
},
|
||||
component: CheckboxGroup,
|
||||
argTypes: {
|
||||
size: {
|
||||
|
@ -1,10 +1,21 @@
|
||||
import { StoryObj, Meta, StoryFn } from '@storybook/react'
|
||||
import { Meta, StoryObj } from '@storybook/react'
|
||||
import { Typography } from '../Typography'
|
||||
import { Collapse, CollapseProps } from './Collapse'
|
||||
|
||||
const subtitle = `Surface`
|
||||
const description = `A collapsible and expandable content section that can be used to group or hide content.`
|
||||
|
||||
export default {
|
||||
title: 'Collapse',
|
||||
component: Collapse,
|
||||
parameters: {
|
||||
componentSubtitle: subtitle,
|
||||
docs: {
|
||||
description: {
|
||||
component: description,
|
||||
},
|
||||
},
|
||||
},
|
||||
argTypes: {
|
||||
size: {
|
||||
type: {
|
||||
|
@ -1,9 +1,20 @@
|
||||
import { StoryObj, Meta, StoryFn } from '@storybook/react'
|
||||
import { Meta, StoryObj } from '@storybook/react'
|
||||
import { CollapseHeader, CollapseHeaderProps } from './CollapseHeader'
|
||||
|
||||
const subtitle = ``
|
||||
const description = ``
|
||||
|
||||
export default {
|
||||
title: 'CollapseHeader',
|
||||
component: CollapseHeader,
|
||||
parameters: {
|
||||
componentSubtitle: subtitle,
|
||||
docs: {
|
||||
description: {
|
||||
component: description,
|
||||
},
|
||||
},
|
||||
},
|
||||
argTypes: {
|
||||
size: {
|
||||
type: {
|
||||
|
@ -1,9 +1,20 @@
|
||||
import { StoryObj, Meta, StoryFn } from '@storybook/react'
|
||||
import { Meta, StoryObj } from '@storybook/react'
|
||||
import { DateField, DateFieldProps } from './DateField'
|
||||
|
||||
const subtitle = `Input`
|
||||
const description = `DateField component allows users to manually enter a specific date.`
|
||||
|
||||
export default {
|
||||
title: 'DateField',
|
||||
component: DateField,
|
||||
parameters: {
|
||||
componentSubtitle: subtitle,
|
||||
docs: {
|
||||
description: {
|
||||
component: description,
|
||||
},
|
||||
},
|
||||
},
|
||||
argTypes: {
|
||||
size: {
|
||||
type: {
|
||||
|
@ -1,9 +1,20 @@
|
||||
import { StoryObj, Meta, StoryFn } from '@storybook/react'
|
||||
import { Meta, StoryObj } from '@storybook/react'
|
||||
import { DatePicker, DatePickerProps } from './DatePicker'
|
||||
|
||||
const subtitle = `Input`
|
||||
const description = `DatePicker component allows users select a date.`
|
||||
|
||||
export default {
|
||||
title: 'DatePicker',
|
||||
component: DatePicker,
|
||||
parameters: {
|
||||
componentSubtitle: subtitle,
|
||||
docs: {
|
||||
description: {
|
||||
component: description,
|
||||
},
|
||||
},
|
||||
},
|
||||
argTypes: {
|
||||
size: {
|
||||
type: {
|
||||
|
@ -1,9 +1,20 @@
|
||||
import { StoryObj, Meta, StoryFn } from '@storybook/react'
|
||||
import { Meta, StoryObj } from '@storybook/react'
|
||||
import { Dropdown, DropdownProps } from './Dropdown'
|
||||
|
||||
const subtitle = `Input`
|
||||
const description = `Dropdown is a menu of hidden options that a user can reveal by clicking on the component. It allows users to select one or multiple options, which can represent values in forms or serve as actions to filter or sort existing content.`
|
||||
|
||||
export default {
|
||||
title: 'Dropdown',
|
||||
component: Dropdown,
|
||||
parameters: {
|
||||
componentSubtitle: subtitle,
|
||||
docs: {
|
||||
description: {
|
||||
component: description,
|
||||
},
|
||||
},
|
||||
},
|
||||
argTypes: {
|
||||
variant: {
|
||||
type: {
|
||||
|
@ -1,9 +1,20 @@
|
||||
import { StoryObj, Meta, StoryFn } from '@storybook/react'
|
||||
import { Meta, StoryObj } from '@storybook/react'
|
||||
import { DropdownItem, DropdownItemProps } from './DropdownItem'
|
||||
|
||||
const subtitle = ``
|
||||
const description = ``
|
||||
|
||||
export default {
|
||||
title: 'DropdownItem',
|
||||
component: DropdownItem,
|
||||
parameters: {
|
||||
componentSubtitle: subtitle,
|
||||
docs: {
|
||||
description: {
|
||||
component: description,
|
||||
},
|
||||
},
|
||||
},
|
||||
argTypes: {
|
||||
size: {
|
||||
type: {
|
||||
|
@ -1,10 +1,21 @@
|
||||
import { StoryObj, Meta, StoryFn } from '@storybook/react'
|
||||
import { Meta, StoryObj } from '@storybook/react'
|
||||
import { useStorybookIconComponent } from '../../utils/storybook.utils'
|
||||
import { IconButton, IconButtonProps } from './IconButton'
|
||||
|
||||
const subtitle = `Input`
|
||||
const description = `IconButton component is used to trigger an action or event, it is labeled with an icon.`
|
||||
|
||||
export default {
|
||||
title: 'IconButton',
|
||||
component: IconButton,
|
||||
parameters: {
|
||||
componentSubtitle: subtitle,
|
||||
docs: {
|
||||
description: {
|
||||
component: description,
|
||||
},
|
||||
},
|
||||
},
|
||||
argTypes: {
|
||||
size: {
|
||||
type: {
|
||||
|
@ -1,11 +1,22 @@
|
||||
import { StoryObj, Meta, StoryFn } from '@storybook/react'
|
||||
import { Meta, StoryObj } from '@storybook/react'
|
||||
import { useStorybookIconComponent } from '../../utils/storybook.utils'
|
||||
import { IconButton } from '../IconButton/IconButton'
|
||||
import { IconButtonGroup, IconButtonGroupProps } from './IconButtonGroup'
|
||||
|
||||
const subtitle = `Input`
|
||||
const description = `IconButtonGroup component groups multiple IconButton components, inheriting all their available styles.`
|
||||
|
||||
export default {
|
||||
title: 'IconButtonGroup',
|
||||
component: IconButtonGroup,
|
||||
parameters: {
|
||||
componentSubtitle: subtitle,
|
||||
docs: {
|
||||
description: {
|
||||
component: description,
|
||||
},
|
||||
},
|
||||
},
|
||||
argTypes: {
|
||||
size: {
|
||||
type: {
|
||||
|
@ -1,13 +1,24 @@
|
||||
import { Meta, StoryObj } from '@storybook/react'
|
||||
import { useState } from 'react'
|
||||
import { StoryObj, Meta, StoryFn } from '@storybook/react'
|
||||
import { Modal, ModalProps } from './Modal'
|
||||
import { Button } from '../Button'
|
||||
import { ModalBody } from '../ModalBody'
|
||||
import { ModalFooter } from '../ModalFooter'
|
||||
import { Modal, ModalProps } from './Modal'
|
||||
|
||||
const subtitle = `Feedback`
|
||||
const description = `A modal is a window positioned above the page content to direct the user's attention solely toward a single task or piece of information.`
|
||||
|
||||
export default {
|
||||
title: 'Modal',
|
||||
component: Modal,
|
||||
parameters: {
|
||||
componentSubtitle: subtitle,
|
||||
docs: {
|
||||
description: {
|
||||
component: description,
|
||||
},
|
||||
},
|
||||
},
|
||||
argTypes: {
|
||||
size: {
|
||||
type: {
|
||||
|
@ -1,9 +1,20 @@
|
||||
import { StoryObj, Meta, StoryFn } from '@storybook/react'
|
||||
import { Meta, StoryObj } from '@storybook/react'
|
||||
import { ModalBody, ModalBodyProps } from './ModalBody'
|
||||
|
||||
const subtitle = ``
|
||||
const description = ``
|
||||
|
||||
export default {
|
||||
title: 'ModalBody',
|
||||
component: ModalBody,
|
||||
parameters: {
|
||||
componentSubtitle: subtitle,
|
||||
docs: {
|
||||
description: {
|
||||
component: description,
|
||||
},
|
||||
},
|
||||
},
|
||||
argTypes: {
|
||||
size: {
|
||||
table: {
|
||||
|
@ -1,10 +1,21 @@
|
||||
import { StoryObj, Meta, StoryFn } from '@storybook/react'
|
||||
import { ModalFooter, ModalFooterProps } from './ModalFooter'
|
||||
import { Meta, StoryObj } from '@storybook/react'
|
||||
import { Button } from '../Button'
|
||||
import { ModalFooter, ModalFooterProps } from './ModalFooter'
|
||||
|
||||
const subtitle = ``
|
||||
const description = ``
|
||||
|
||||
export default {
|
||||
title: 'ModalFooter',
|
||||
component: ModalFooter,
|
||||
parameters: {
|
||||
componentSubtitle: subtitle,
|
||||
docs: {
|
||||
description: {
|
||||
component: description,
|
||||
},
|
||||
},
|
||||
},
|
||||
argTypes: {
|
||||
size: {
|
||||
type: {
|
||||
|
@ -1,9 +1,20 @@
|
||||
import { StoryObj, Meta, StoryFn } from '@storybook/react'
|
||||
import { Meta, StoryObj } from '@storybook/react'
|
||||
import { NumberInput, NumberInputProps } from './NumberInput'
|
||||
|
||||
const subtitle = `Input`
|
||||
const description = `NumberInput allows users to input a numeric value and adjust the value incrementally using a two-segment control.`
|
||||
|
||||
export default {
|
||||
title: 'NumberInput',
|
||||
component: NumberInput,
|
||||
parameters: {
|
||||
componentSubtitle: subtitle,
|
||||
docs: {
|
||||
description: {
|
||||
component: description,
|
||||
},
|
||||
},
|
||||
},
|
||||
argTypes: {
|
||||
size: {
|
||||
type: {
|
||||
|
@ -1,9 +1,20 @@
|
||||
import { StoryObj, Meta, StoryFn } from '@storybook/react'
|
||||
import { Meta, StoryObj } from '@storybook/react'
|
||||
import { Quote, QuoteProps } from './Quote'
|
||||
|
||||
const subtitle = `Surface`
|
||||
const description = `Quote component is used to display a quotation.`
|
||||
|
||||
export default {
|
||||
title: 'Quote',
|
||||
component: Quote,
|
||||
parameters: {
|
||||
componentSubtitle: subtitle,
|
||||
docs: {
|
||||
description: {
|
||||
component: description,
|
||||
},
|
||||
},
|
||||
},
|
||||
argTypes: {
|
||||
mode: {
|
||||
type: {
|
||||
|
@ -1,9 +1,20 @@
|
||||
import { StoryObj, Meta, StoryFn } from '@storybook/react'
|
||||
import { Meta, StoryObj } from '@storybook/react'
|
||||
import { RadioButton, RadioButtonProps } from './RadioButton'
|
||||
|
||||
const subtitle = `Input`
|
||||
const description = `Radio buttons enable users to make a single selection from a list of options, particularly suitable for scenarios where you have a set of mutually exclusive choices.`
|
||||
|
||||
export default {
|
||||
title: 'RadioButton',
|
||||
component: RadioButton,
|
||||
parameters: {
|
||||
componentSubtitle: subtitle,
|
||||
docs: {
|
||||
description: {
|
||||
component: description,
|
||||
},
|
||||
},
|
||||
},
|
||||
argTypes: {
|
||||
size: {
|
||||
type: {
|
||||
|
@ -1,10 +1,21 @@
|
||||
import { StoryObj, Meta, StoryFn } from '@storybook/react'
|
||||
import { Meta, StoryObj } from '@storybook/react'
|
||||
import { RadioButton } from '../RadioButton'
|
||||
import { RadioButtonGroup, RadioButtonGroupProps } from './RadioButtonGroup'
|
||||
|
||||
const subtitle = `Input`
|
||||
const description = `RadioButtonGroup component groups multiple RadioButton components, inheriting all their available styles.`
|
||||
|
||||
export default {
|
||||
title: 'RadioButtonGroup',
|
||||
component: RadioButtonGroup,
|
||||
parameters: {
|
||||
componentSubtitle: subtitle,
|
||||
docs: {
|
||||
description: {
|
||||
component: description,
|
||||
},
|
||||
},
|
||||
},
|
||||
argTypes: {
|
||||
size: {
|
||||
type: {
|
||||
|
@ -1,10 +1,21 @@
|
||||
import { StoryObj, Meta, StoryFn } from '@storybook/react'
|
||||
import { Meta, StoryObj } from '@storybook/react'
|
||||
import { useStorybookIconComponent } from '../../utils/storybook.utils'
|
||||
import { TabItem, TabItemProps } from './TabItem'
|
||||
|
||||
const subtitle = ``
|
||||
const description = ``
|
||||
|
||||
export default {
|
||||
title: 'TabItem',
|
||||
component: TabItem,
|
||||
parameters: {
|
||||
componentSubtitle: subtitle,
|
||||
docs: {
|
||||
description: {
|
||||
component: description,
|
||||
},
|
||||
},
|
||||
},
|
||||
argTypes: {
|
||||
size: {
|
||||
type: {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { StoryObj, Meta, StoryFn } from '@storybook/react'
|
||||
import { Meta, StoryObj } from '@storybook/react'
|
||||
import { useState } from 'react'
|
||||
import { Button } from '../Button'
|
||||
import { Dropdown } from '../Dropdown'
|
||||
@ -8,9 +8,20 @@ import { TableItem } from '../TableItem'
|
||||
import { TableRow } from '../TableRow'
|
||||
import { Table, TableProps } from './Table'
|
||||
|
||||
const subtitle = `Data Display`
|
||||
const description = `Table component is used to efficiently organise and display sets of information in rows and columns, facilitating easy scanning for patterns and insights. Component allows for customisation with additional functionality.`
|
||||
|
||||
export default {
|
||||
title: 'Table',
|
||||
component: Table,
|
||||
parameters: {
|
||||
componentSubtitle: subtitle,
|
||||
docs: {
|
||||
description: {
|
||||
component: description,
|
||||
},
|
||||
},
|
||||
},
|
||||
argTypes: {
|
||||
size: {
|
||||
type: {
|
||||
|
@ -1,9 +1,20 @@
|
||||
import { StoryObj, Meta, StoryFn } from '@storybook/react'
|
||||
import { Meta, StoryObj } from '@storybook/react'
|
||||
import { TableBody, TableBodyProps } from './TableBody'
|
||||
|
||||
const subtitle = ``
|
||||
const description = ``
|
||||
|
||||
export default {
|
||||
title: 'TableBody',
|
||||
component: TableBody,
|
||||
parameters: {
|
||||
componentSubtitle: subtitle,
|
||||
docs: {
|
||||
description: {
|
||||
component: description,
|
||||
},
|
||||
},
|
||||
},
|
||||
argTypes: {
|
||||
size: {
|
||||
type: {
|
||||
|
@ -1,9 +1,20 @@
|
||||
import { StoryObj, Meta, StoryFn } from '@storybook/react'
|
||||
import { Meta, StoryObj } from '@storybook/react'
|
||||
import { TableHeader, TableHeaderProps } from './TableHeader'
|
||||
|
||||
const subtitle = ``
|
||||
const description = ``
|
||||
|
||||
export default {
|
||||
title: 'TableHeader',
|
||||
component: TableHeader,
|
||||
parameters: {
|
||||
componentSubtitle: subtitle,
|
||||
docs: {
|
||||
description: {
|
||||
component: description,
|
||||
},
|
||||
},
|
||||
},
|
||||
argTypes: {
|
||||
size: {
|
||||
type: {
|
||||
|
@ -1,9 +1,20 @@
|
||||
import { StoryObj, Meta, StoryFn } from '@storybook/react'
|
||||
import { Meta, StoryObj } from '@storybook/react'
|
||||
import { TableItem, TableItemProps } from './TableItem'
|
||||
|
||||
const subtitle = ``
|
||||
const description = ``
|
||||
|
||||
export default {
|
||||
title: 'TableItem',
|
||||
component: TableItem,
|
||||
parameters: {
|
||||
componentSubtitle: subtitle,
|
||||
docs: {
|
||||
description: {
|
||||
component: description,
|
||||
},
|
||||
},
|
||||
},
|
||||
argTypes: {
|
||||
size: {
|
||||
type: {
|
||||
|
@ -1,9 +1,20 @@
|
||||
import { StoryObj, Meta, StoryFn } from '@storybook/react'
|
||||
import { Meta, StoryObj } from '@storybook/react'
|
||||
import { TableRow, TableRowProps } from './TableRow'
|
||||
|
||||
const subtitle = ``
|
||||
const description = ``
|
||||
|
||||
export default {
|
||||
title: 'TableRow',
|
||||
component: TableRow,
|
||||
parameters: {
|
||||
componentSubtitle: subtitle,
|
||||
docs: {
|
||||
description: {
|
||||
component: description,
|
||||
},
|
||||
},
|
||||
},
|
||||
argTypes: {
|
||||
type: {
|
||||
type: {
|
||||
|
@ -1,11 +1,22 @@
|
||||
import { StoryObj, Meta, StoryFn } from '@storybook/react'
|
||||
import { Meta, StoryObj } from '@storybook/react'
|
||||
import { useStorybookIconComponent } from '../../utils/storybook.utils'
|
||||
import { TabItem } from '../TabItem'
|
||||
import { Tabs, TabsProps } from './Tabs'
|
||||
|
||||
const subtitle = `Navigation`
|
||||
const description = `Tabs are a navigational component that efficiently organizes related content, enabling users to switch between different groups of information within the same context.`
|
||||
|
||||
export default {
|
||||
title: 'Tabs',
|
||||
component: Tabs,
|
||||
parameters: {
|
||||
componentSubtitle: subtitle,
|
||||
docs: {
|
||||
description: {
|
||||
component: description,
|
||||
},
|
||||
},
|
||||
},
|
||||
argTypes: {
|
||||
size: {
|
||||
type: {
|
||||
@ -62,5 +73,6 @@ export const Root: StoryObj<
|
||||
fullWidth: false,
|
||||
scrollControls: true,
|
||||
onChange: undefined,
|
||||
tabs: 4,
|
||||
},
|
||||
}
|
||||
|
@ -1,10 +1,21 @@
|
||||
import { StoryObj, Meta, StoryFn } from '@storybook/react'
|
||||
import { Meta, StoryObj } from '@storybook/react'
|
||||
import { FolderIcon } from '../Icons'
|
||||
import { Tag, TagProps } from './Tag'
|
||||
|
||||
const subtitle = `Data Display`
|
||||
const description = `Tags are used to label, categorise and organise items with descriptive keywords.`
|
||||
|
||||
export default {
|
||||
title: 'Tag',
|
||||
component: Tag,
|
||||
parameters: {
|
||||
componentSubtitle: subtitle,
|
||||
docs: {
|
||||
description: {
|
||||
component: description,
|
||||
},
|
||||
},
|
||||
},
|
||||
argTypes: {
|
||||
variant: {
|
||||
type: {
|
||||
|
@ -1,10 +1,21 @@
|
||||
import { StoryObj, Meta, StoryFn } from '@storybook/react'
|
||||
import { Meta, StoryObj } from '@storybook/react'
|
||||
import { useStorybookIconComponent } from '../../utils/storybook.utils'
|
||||
import { TextField, TextFieldProps } from './TextField'
|
||||
|
||||
const subtitle = `Input`
|
||||
const description = `TextField component allows users to enter free-form text data, accommodating both long and short-form entries.`
|
||||
|
||||
export default {
|
||||
title: 'TextField',
|
||||
component: TextField,
|
||||
parameters: {
|
||||
componentSubtitle: subtitle,
|
||||
docs: {
|
||||
description: {
|
||||
component: description,
|
||||
},
|
||||
},
|
||||
},
|
||||
argTypes: {
|
||||
size: {
|
||||
type: {
|
||||
|
@ -0,0 +1,61 @@
|
||||
import styled from '@emotion/styled'
|
||||
import { Meta, StoryObj } from '@storybook/react'
|
||||
import { get } from 'lodash'
|
||||
import React from 'react'
|
||||
import { Typography } from '../Typography'
|
||||
import { ThemeProvider, ThemeProviderProps } from './ThemeProvider'
|
||||
import { Theme, TypographyVariants } from './types'
|
||||
import { useTheme } from './useTheme'
|
||||
import {
|
||||
ColorDesignTokens,
|
||||
TypographyDesignTokens,
|
||||
SpacingDesignTokens,
|
||||
} from '../../docs/components/DesignTokens'
|
||||
|
||||
const subtitle = ``
|
||||
const description = ``
|
||||
|
||||
export default {
|
||||
title: 'ThemeProvider',
|
||||
parameters: {
|
||||
componentSubtitle: subtitle,
|
||||
docs: {
|
||||
controls: false,
|
||||
description: {
|
||||
component: description,
|
||||
},
|
||||
},
|
||||
},
|
||||
component: ThemeProvider,
|
||||
} as Meta
|
||||
|
||||
export const Root: StoryObj<ThemeProviderProps> = {
|
||||
render: (args) => {
|
||||
return (
|
||||
<div>
|
||||
<Typography variant="h6" component="h2">
|
||||
Colour
|
||||
</Typography>
|
||||
<ColorDesignTokens />
|
||||
<Typography variant="h6" component="h2">
|
||||
Spacing
|
||||
</Typography>
|
||||
<SpacingDesignTokens />
|
||||
|
||||
<Typography variant="h6" component="h2">
|
||||
Typography
|
||||
</Typography>
|
||||
<TypographyDesignTokens />
|
||||
</div>
|
||||
)
|
||||
},
|
||||
parameters: {
|
||||
docs: {
|
||||
source: {
|
||||
code: null,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
args: {},
|
||||
}
|
@ -21,6 +21,9 @@ export const THEME_TYPOGRAPHY_VARIANTS = [
|
||||
'h6',
|
||||
'subtitle1',
|
||||
'subtitle2',
|
||||
'subtitle3',
|
||||
'subtitle4',
|
||||
'subtitle5',
|
||||
'body1',
|
||||
'body2',
|
||||
'body3',
|
||||
|
@ -1,10 +1,21 @@
|
||||
import { StoryObj, Meta, StoryFn } from '@storybook/react'
|
||||
import { Meta, StoryObj } from '@storybook/react'
|
||||
import { THEME_TYPOGRAPHY_VARIANTS } from '../Theme'
|
||||
import { Typography, TypographyProps } from './Typography'
|
||||
|
||||
const subtitle = `Data Display`
|
||||
const description = `Typography component lets you apply LSD typography styles of a specific variant to the elements in your app.`
|
||||
|
||||
export default {
|
||||
title: 'Typography',
|
||||
component: Typography,
|
||||
parameters: {
|
||||
componentSubtitle: subtitle,
|
||||
docs: {
|
||||
description: {
|
||||
component: description,
|
||||
},
|
||||
},
|
||||
},
|
||||
argTypes: {
|
||||
variant: {
|
||||
type: {
|
||||
@ -28,5 +39,6 @@ export const Root: StoryObj<TypographyProps> = {
|
||||
|
||||
args: {
|
||||
color: 'primary',
|
||||
variant: 'body1',
|
||||
},
|
||||
}
|
||||
|
@ -0,0 +1,382 @@
|
||||
import styled from '@emotion/styled'
|
||||
import { Meta, StoryObj } from '@storybook/react'
|
||||
import { get } from 'lodash'
|
||||
import React from 'react'
|
||||
import { Theme, TypographyVariants, useTheme } from '../../../components/Theme'
|
||||
import { Typography } from '../../../components/Typography'
|
||||
|
||||
type Token = (
|
||||
| {
|
||||
type: 'color'
|
||||
rgb: string
|
||||
hex: string
|
||||
}
|
||||
| {
|
||||
type: 'spacing'
|
||||
value: string
|
||||
}
|
||||
| {
|
||||
type: 'typography'
|
||||
value: string
|
||||
}
|
||||
) & {
|
||||
name: string
|
||||
varName: string
|
||||
}
|
||||
|
||||
type TokenGroup<T = Token> = {
|
||||
name: string
|
||||
tokens: T[]
|
||||
}
|
||||
|
||||
type Colors = TokenGroup<Extract<Token, { type: 'color' }>>[]
|
||||
type Spacing = TokenGroup<Extract<Token, { type: 'spacing' }>>[]
|
||||
type TypographyTokens = TokenGroup<Extract<Token, { type: 'typography' }>>[]
|
||||
|
||||
const getDesignTokens = (
|
||||
theme: Theme,
|
||||
): {
|
||||
colors: Colors
|
||||
spacing: Spacing
|
||||
typography: TypographyTokens
|
||||
} => {
|
||||
const rgbToHex = (r: number, g: number, b: number) =>
|
||||
'#' +
|
||||
[r, g, b]
|
||||
.map((val) => val.toString(16))
|
||||
.map((hex) => (hex.length === 1 ? `0${hex}` : hex))
|
||||
.join('')
|
||||
|
||||
const remToPx = (rem: string) => parseFloat(rem.replace('rem', '')) * 16
|
||||
|
||||
const keys = ['surface', 'border', 'text', 'icon']
|
||||
|
||||
const colors: Colors = [
|
||||
{
|
||||
name: 'primitives',
|
||||
tokens: [
|
||||
{
|
||||
type: 'color',
|
||||
name: 'primary',
|
||||
varName: `--lsd-theme-primary`,
|
||||
rgb: theme.palette.primary,
|
||||
hex: rgbToHex(
|
||||
...(theme.palette.primary
|
||||
.split(',')
|
||||
.map((x) => parseInt(x, 10)) as [number, number, number]),
|
||||
),
|
||||
},
|
||||
{
|
||||
type: 'color',
|
||||
name: 'secondary',
|
||||
varName: '--lsd-theme-secondary',
|
||||
rgb: theme.palette.secondary,
|
||||
hex: rgbToHex(
|
||||
...(theme.palette.secondary
|
||||
.split(',')
|
||||
.map((x) => parseInt(x, 10)) as [number, number, number]),
|
||||
),
|
||||
},
|
||||
],
|
||||
},
|
||||
...keys.map(
|
||||
(key) =>
|
||||
({
|
||||
name: key,
|
||||
tokens: ['primary', 'secondary'].map((ck) => ({
|
||||
name: ck,
|
||||
type: 'color',
|
||||
varName: `--lsd-${key}-${ck}`,
|
||||
rgb: get(theme.palette, key + '.' + ck),
|
||||
hex: rgbToHex(
|
||||
...(get(theme.palette, key + '.' + ck)
|
||||
.split(',')
|
||||
.map((x: string) => parseInt(x, 10)) as [
|
||||
number,
|
||||
number,
|
||||
number,
|
||||
]),
|
||||
),
|
||||
})),
|
||||
} as Colors[number]),
|
||||
),
|
||||
]
|
||||
|
||||
const spacing: Spacing = theme.spacing.map((spacing) => ({
|
||||
name: spacing.toString(),
|
||||
tokens: [
|
||||
{
|
||||
name: spacing.toString(),
|
||||
type: 'spacing',
|
||||
varName: `--lsd-spacing-${spacing}`,
|
||||
value: `${spacing}px`,
|
||||
},
|
||||
],
|
||||
}))
|
||||
|
||||
const typography: TypographyTokens = Object.entries(theme.typography).map(
|
||||
([name, settings]) => ({
|
||||
name: name,
|
||||
tokens: [
|
||||
{
|
||||
name: 'fontSize',
|
||||
type: 'typography',
|
||||
value: `${settings.fontSize} (${remToPx(
|
||||
(settings.fontSize as string) || '',
|
||||
)}px)`,
|
||||
varName: `--lsd-typography-${name}-fontSize`,
|
||||
},
|
||||
{
|
||||
name: 'lineHeight',
|
||||
type: 'typography',
|
||||
value: `${settings.lineHeight} (${remToPx(
|
||||
(settings.lineHeight as string) || '',
|
||||
)}px)`,
|
||||
varName: `--lsd-${name}-lineHeight`,
|
||||
},
|
||||
],
|
||||
}),
|
||||
)
|
||||
|
||||
return {
|
||||
colors,
|
||||
spacing,
|
||||
typography,
|
||||
}
|
||||
}
|
||||
|
||||
export const SpacingDesignTokens = () => {
|
||||
const theme = useTheme()
|
||||
const { spacing } = getDesignTokens(theme)
|
||||
|
||||
return <Spacing spacing={spacing}></Spacing>
|
||||
}
|
||||
|
||||
export const TypographyDesignTokens = () => {
|
||||
const theme = useTheme()
|
||||
const { typography } = getDesignTokens(theme)
|
||||
|
||||
return <TypographyTable typography={typography}></TypographyTable>
|
||||
}
|
||||
|
||||
export const ColorDesignTokens = () => {
|
||||
const theme = useTheme()
|
||||
const { colors } = getDesignTokens(theme)
|
||||
|
||||
return (
|
||||
<>
|
||||
{colors.map((group) => (
|
||||
<ColorGroup name={group.name} tokens={group.tokens} />
|
||||
))}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
const ColorGroup: React.FC<Colors[number]> = ({ name, tokens }) => {
|
||||
return (
|
||||
<ColorGroupRoot>
|
||||
<Typography className="color-group__name" component="div" variant="body1">
|
||||
{name}
|
||||
</Typography>
|
||||
<div className="color-group__tokens">
|
||||
{tokens.map((token) => (
|
||||
<ColorCard key={token.name} groupName={name} {...token} />
|
||||
))}
|
||||
</div>
|
||||
</ColorGroupRoot>
|
||||
)
|
||||
}
|
||||
|
||||
const ColorGroupRoot = styled.div`
|
||||
margin-bottom: var(--lsd-spacing-32);
|
||||
|
||||
.color-group__name {
|
||||
width: calc(50% - var(--lsd-spacing-16));
|
||||
padding: var(--lsd-spacing-16) 0;
|
||||
border-bottom: 1px solid rgba(var(--lsd-border-primary), 0.2);
|
||||
}
|
||||
|
||||
.color-group__tokens {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: var(--lsd-spacing-16);
|
||||
margin-top: var(--lsd-spacing-16);
|
||||
}
|
||||
`
|
||||
|
||||
const ColorCard: React.FC<
|
||||
Colors[number]['tokens'][number] & { groupName: string }
|
||||
> = ({ groupName, name, varName, rgb, hex }) => {
|
||||
return (
|
||||
<ColorCardRoot>
|
||||
<div
|
||||
className="color-card__color"
|
||||
style={{
|
||||
background: `rgb(var(${varName}))`,
|
||||
}}
|
||||
></div>
|
||||
<div className="color-card__details">
|
||||
<Typography
|
||||
genericFontFamily="monospace"
|
||||
variant="label2"
|
||||
className="color-card__var"
|
||||
component="div"
|
||||
>
|
||||
<p>
|
||||
{varName}: {rgb}
|
||||
</p>
|
||||
<p style={{ marginTop: 4 }}>
|
||||
theme.palette
|
||||
{groupName === 'primitives' ? `.${name}` : `.${groupName}.${name}`}
|
||||
</p>
|
||||
</Typography>
|
||||
<div className="color-card__value">
|
||||
<Typography variant="label2" className="color-card__rgb">
|
||||
{name}
|
||||
</Typography>
|
||||
<Typography variant="label2" className="color-card__hex">
|
||||
{hex}
|
||||
</Typography>
|
||||
</div>
|
||||
</div>
|
||||
</ColorCardRoot>
|
||||
)
|
||||
}
|
||||
|
||||
const ColorCardRoot = styled.div`
|
||||
width: 50%;
|
||||
border: 1px solid rgba(var(--lsd-border-primary), 0.2);
|
||||
|
||||
.color-card__color {
|
||||
width: 100%;
|
||||
height: 100px;
|
||||
border-bottom: 1px solid rgba(var(--lsd-border-primary), 0.2);
|
||||
}
|
||||
|
||||
.color-card__details {
|
||||
margin-top: var(--lsd-spacing-8);
|
||||
padding: var(--lsd-spacing-8);
|
||||
}
|
||||
|
||||
.color-card__value {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-top: var(--lsd-spacing-8);
|
||||
}
|
||||
`
|
||||
|
||||
export const Spacing: React.FC<{ spacing: Spacing }> = ({ spacing }) => {
|
||||
return (
|
||||
<Table>
|
||||
<thead>
|
||||
<th>Example</th>
|
||||
<th>CSS variable</th>
|
||||
<th>Value</th>
|
||||
</thead>
|
||||
<tbody>
|
||||
{spacing
|
||||
.flatMap((s) => s.tokens)
|
||||
.map((s, index) => (
|
||||
<tr key={s.name}>
|
||||
<td>
|
||||
<div
|
||||
style={{
|
||||
width: s.value,
|
||||
height: s.value,
|
||||
boxSizing: 'border-box',
|
||||
border: '1px solid rgb(var(--lsd-border-primary))',
|
||||
}}
|
||||
></div>
|
||||
</td>
|
||||
<td>
|
||||
<Typography variant="label1" genericFontFamily="monospace">
|
||||
{s.varName}
|
||||
</Typography>
|
||||
</td>
|
||||
<td>
|
||||
<Typography variant="label1" genericFontFamily="monospace">
|
||||
{s.value}
|
||||
</Typography>
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</Table>
|
||||
)
|
||||
}
|
||||
|
||||
export const TypographyTable: React.FC<{ typography: TypographyTokens }> = ({
|
||||
typography,
|
||||
}) => {
|
||||
return (
|
||||
<Table>
|
||||
<thead>
|
||||
<th>variant</th>
|
||||
<th>tokens</th>
|
||||
<th>Value</th>
|
||||
</thead>
|
||||
<tbody>
|
||||
{typography.map((t) => (
|
||||
<>
|
||||
<tr>
|
||||
<td rowSpan={t.tokens.length}>
|
||||
<Typography variant={t.name as TypographyVariants}>
|
||||
{t.name}
|
||||
</Typography>
|
||||
</td>
|
||||
{t.tokens.slice(0, 1).map((token) => (
|
||||
<>
|
||||
<td>
|
||||
<Typography variant="body2" genericFontFamily="monospace">
|
||||
{token.varName}
|
||||
</Typography>
|
||||
</td>
|
||||
<td>
|
||||
<Typography variant="body2" genericFontFamily="monospace">
|
||||
{token.value}
|
||||
</Typography>
|
||||
</td>
|
||||
</>
|
||||
))}
|
||||
</tr>
|
||||
{t.tokens.slice(1).map((token) => (
|
||||
<tr>
|
||||
<td>
|
||||
<Typography variant="body2" genericFontFamily="monospace">
|
||||
{token.varName}
|
||||
</Typography>
|
||||
</td>
|
||||
<td>
|
||||
<Typography variant="body2" genericFontFamily="monospace">
|
||||
{token.value}
|
||||
</Typography>
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</>
|
||||
))}
|
||||
</tbody>
|
||||
</Table>
|
||||
)
|
||||
}
|
||||
|
||||
const Table = styled.table`
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
margin-top: var(--lsd-spacing-32);
|
||||
margin-bottom: var(--lsd-spacing-32);
|
||||
|
||||
th {
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
th,
|
||||
td {
|
||||
border: 1px solid rgba(var(--lsd-border-primary), 0.2);
|
||||
padding: var(--lsd-spacing-8);
|
||||
text-align: left;
|
||||
color: rgb(var(--lsd-text-primary));
|
||||
}
|
||||
`
|
@ -0,0 +1 @@
|
||||
export * from './DesignTokens'
|
11
packages/lsd-react/src/docs/overview/design-tokens.mdx
Normal file
11
packages/lsd-react/src/docs/overview/design-tokens.mdx
Normal file
@ -0,0 +1,11 @@
|
||||
import { Meta, Story } from '@storybook/blocks'
|
||||
import { useTheme } from '../../'
|
||||
import { Root } from '../../components/Theme/ThemeProvider.stories'
|
||||
|
||||
<Meta title="Overview/Design Tokens" />
|
||||
|
||||
# Design tokens
|
||||
|
||||
Design tokens are variables that store values for the base layer of LSD, like colour and typography. They're used in components, so changes on this level will resonate throughout the whole system.
|
||||
|
||||
<Story of={Root} />
|
51
packages/lsd-react/src/docs/overview/quickstart.mdx
Normal file
51
packages/lsd-react/src/docs/overview/quickstart.mdx
Normal file
@ -0,0 +1,51 @@
|
||||
import { Meta } from '@storybook/blocks'
|
||||
|
||||
<Meta title="Overview/Quick Start" />
|
||||
|
||||
## 1. Installation
|
||||
|
||||
Install the latest version of `@acid-info/lsd-react`
|
||||
|
||||
```shell
|
||||
yarn add @acid-info/lsd-react @emotion/react @emotion/styled
|
||||
```
|
||||
|
||||
## 2. Setup
|
||||
|
||||
To use LSD theme and design tokens in your React app, wrap your app with the ThemeProvider component. This component:
|
||||
|
||||
- Creates a CSS baseline for the components using CSS-in-JS and inserts it into the DOM.
|
||||
- Injects the LSD CSS variables into the DOM for the theme prop.
|
||||
|
||||
The ThemeProvider component should be at the root of your app, as shown below:
|
||||
|
||||
```tsx
|
||||
import React from 'react'
|
||||
import ReactDOM from 'react-dom'
|
||||
import { ThemeProvider, defaultThemes } from '@acid-info/lsd-react'
|
||||
|
||||
import App from './App'
|
||||
|
||||
ReactDOM.render(
|
||||
<ThemeProvider theme={defaultThemes.dark}>
|
||||
<App />
|
||||
</ThemeProvider>,
|
||||
document.getElementById('root'),
|
||||
)
|
||||
```
|
||||
|
||||
## 3. Usage
|
||||
|
||||
Import LSD components from `@acid-info/lsd-react` and use them in your React app!
|
||||
|
||||
```tsx
|
||||
import { Button } from '@acid-info/lsd-react'
|
||||
|
||||
function App() {
|
||||
return (
|
||||
<div>
|
||||
<Button>Button</Button>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
```
|
@ -0,0 +1,7 @@
|
||||
import { Meta } from '@storybook/blocks'
|
||||
|
||||
<Meta title="Overview/Styling Components" />
|
||||
|
||||
# Styling Components
|
||||
|
||||
LSD components are styled with CSS-in-JS using the @emotion/react library, but we've made sure that you can still style them however you like.
|
Loading…
x
Reference in New Issue
Block a user