diff --git a/packages/bezier-react/.storybook/preview.js b/packages/bezier-react/.storybook/WithFoundationProvider.jsx similarity index 82% rename from packages/bezier-react/.storybook/preview.js rename to packages/bezier-react/.storybook/WithFoundationProvider.jsx index 4d467d8ad6..5785528c77 100644 --- a/packages/bezier-react/.storybook/preview.js +++ b/packages/bezier-react/.storybook/WithFoundationProvider.jsx @@ -17,35 +17,6 @@ const FoundationKeyword = { Dark: 'dark', } -export const parameters = { - layout: 'centered', - backgrounds: { - default: 'light', - values: [ - { - name: 'light', - value: 'white', - }, - { - name: 'dark', - value: '#2f3233', - }, - ], - } -} - -export const globalTypes = { - Foundation: { - name: 'Foundation', - description: 'Global Foundation for components', - defaultValue: 'light', - toolbar: { - icon: 'circlehollow', - items: [FoundationKeyword.Light, FoundationKeyword.Dark], - }, - }, -}; - function getFoundation(keyword) { const isDarkFoundation = keyword === FoundationKeyword.Dark return { @@ -87,7 +58,7 @@ const innerWrapperStyle = { borderRadius: 20, } -function withFoundationProvider(Story, context) { +export function WithFoundationProvider(Story, context) { const { isDarkFoundation, foundation, @@ -143,5 +114,3 @@ function withFoundationProvider(Story, context) { ) } - -export const decorators = [withFoundationProvider] diff --git a/packages/bezier-react/.storybook/main.js b/packages/bezier-react/.storybook/main.js deleted file mode 100644 index 9270930ba7..0000000000 --- a/packages/bezier-react/.storybook/main.js +++ /dev/null @@ -1,55 +0,0 @@ -const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin') - -module.exports = { - core: { - builder: 'webpack5', - }, - stories: [ - '../src/stories/Intro.stories.mdx', - '../src/**/*.stories.(tsx|mdx)', - ], - addons: [ - '@storybook/addon-controls', - '@storybook/addon-actions', - '@storybook/addon-a11y', - '@storybook/addon-toolbars', - '@storybook/addon-docs', - '@storybook/addon-backgrounds', - ], - features: { - postcss: false, - }, - typescript: { - /** - * @note - * - * `react-docgen-typescript-plugin` introduces significant overhead - * when HMR is enabled, so we enable it only in production. - */ - reactDocgen: process.env.NODE_ENV === 'production' && 'react-docgen-typescript', - reactDocgenTypescriptOptions: { - shouldRemoveUndefinedFromOptional: true, - shouldExtractLiteralValuesFromEnum: true, - propFilter: (prop) => (prop.parent ? !/node_modules/.test(prop.parent.fileName) : true), - }, - }, - webpackFinal: async (config) => { - // Apply tsconfig alias path - config.resolve.plugins = [ - ...(config.resolve.plugins || []), - new TsconfigPathsPlugin({}), - ] - - config.module.rules.push({ - test: /\.(ts|tsx)$/, - loader: require.resolve('babel-loader'), - options: { - presets: [['react-app', { flow: false, typescript: true }]], - }, - }) - - config.resolve.extensions.push('.ts', '.tsx') - - return config - } -} diff --git a/packages/bezier-react/.storybook/main.ts b/packages/bezier-react/.storybook/main.ts new file mode 100644 index 0000000000..f0b8dbfe65 --- /dev/null +++ b/packages/bezier-react/.storybook/main.ts @@ -0,0 +1,80 @@ +import { dirname, join } from "path" + +import TsconfigPathsPlugin from 'tsconfig-paths-webpack-plugin' +import { type StorybookConfig } from '@storybook/react-webpack5' + +function getAbsolutePath(value) { + return dirname(require.resolve(join(value, "package.json"))) +} + +const config: StorybookConfig = { + stories: [ + '../src/**/*.stories.(tsx|mdx)', + ], + + addons: [ + getAbsolutePath("@storybook/addon-controls"), + getAbsolutePath("@storybook/addon-actions"), + getAbsolutePath("@storybook/addon-a11y"), + getAbsolutePath("@storybook/addon-toolbars"), + getAbsolutePath("@storybook/addon-docs"), + getAbsolutePath("@storybook/addon-backgrounds"), + ], + + typescript: { + /** + * @note + * + * `react-docgen-typescript-plugin` introduces significant overhead + * when HMR is enabled, so we enable it only in production. + */ + reactDocgen: process.env.NODE_ENV === 'production' && 'react-docgen-typescript', + reactDocgenTypescriptOptions: { + shouldRemoveUndefinedFromOptional: true, + shouldExtractLiteralValuesFromEnum: true, + propFilter: (prop) => (prop.parent ? !/node_modules/.test(prop.parent.fileName) : true), + }, + }, + + webpackFinal: async (config) => { + config.resolve = { + ...config.resolve, + // Apply tsconfig alias path + plugins: [ + ...(config?.resolve?.plugins ?? []), + new TsconfigPathsPlugin({}), + ], + extensions: [ + ...(config.resolve?.extensions ?? []), + '.ts', + '.tsx', + ] + } + + config.module = { + ...config.module, + rules: [ + ...(config.module?.rules ?? []), { + test: /\.(ts|tsx)$/, + loader: require.resolve('babel-loader'), + options: { + presets: [['react-app', { flow: false, typescript: true }]], + } + } + ] + } + + return config + }, + + framework: { + name: '@storybook/react-webpack5', + options: {} + }, + + docs: { + autodocs: true + } +} + +export default config diff --git a/packages/bezier-react/.storybook/preview.ts b/packages/bezier-react/.storybook/preview.ts new file mode 100644 index 0000000000..e743b267de --- /dev/null +++ b/packages/bezier-react/.storybook/preview.ts @@ -0,0 +1,9 @@ +import type { Preview } from "@storybook/react" + +import { WithFoundationProvider } from './WithFoundationProvider' + +const preview: Preview = { + decorators: [WithFoundationProvider], +} + +export default preview diff --git a/packages/bezier-react/package.json b/packages/bezier-react/package.json index 2aa40fb97f..5a395f5caf 100644 --- a/packages/bezier-react/package.json +++ b/packages/bezier-react/package.json @@ -40,8 +40,8 @@ "clean:build": "rm -rf dist", "clean:cache": "rm -rf node_modules .turbo .eslintcache .stylelintcache tsconfig.tsbuildinfo coverage .jestcache", "prebuild": "yarn clean:build", - "storybook": "start-storybook -p 4101", - "build-storybook": "build-storybook", + "storybook": "storybook dev -p 4101", + "build-storybook": "storybook build", "chromatic": "chromatic --project-token=06157a6fbe6f" }, "keywords": [ @@ -70,15 +70,14 @@ "@rollup/plugin-node-resolve": "^15.2.1", "@rollup/plugin-typescript": "^11.1.3", "@rollup/plugin-url": "^8.0.1", - "@storybook/addon-a11y": "^6.5.16", - "@storybook/addon-actions": "^6.5.16", - "@storybook/addon-backgrounds": "^6.5.16", - "@storybook/addon-controls": "^6.5.16", - "@storybook/addon-docs": "^6.5.16", - "@storybook/addon-toolbars": "^6.5.16", - "@storybook/builder-webpack5": "^6.5.16", - "@storybook/manager-webpack5": "^6.5.16", - "@storybook/react": "^6.5.16", + "@storybook/addon-a11y": "^7.4.2", + "@storybook/addon-actions": "^7.4.2", + "@storybook/addon-backgrounds": "^7.4.2", + "@storybook/addon-controls": "^7.4.2", + "@storybook/addon-docs": "^7.4.2", + "@storybook/addon-toolbars": "^7.4.2", + "@storybook/react": "^7.4.2", + "@storybook/react-webpack5": "^7.4.2", "@storybook/storybook-deployer": "^2.8.16", "@testing-library/jest-dom": "^5.17.0", "@testing-library/react": "^14.0.0", @@ -103,6 +102,7 @@ "rollup": "^3.29.1", "rollup-plugin-node-externals": "^6.1.1", "rollup-plugin-visualizer": "^5.9.2", + "storybook": "^7.4.2", "styled-components": "^5.3.11", "ts-prune": "^0.10.3", "tsconfig": "workspace:*", diff --git a/packages/bezier-react/src/components/AlphaCenter/AlphaCenter.stories.tsx b/packages/bezier-react/src/components/AlphaCenter/AlphaCenter.stories.tsx index a8ea21c01c..2f0d9c2641 100644 --- a/packages/bezier-react/src/components/AlphaCenter/AlphaCenter.stories.tsx +++ b/packages/bezier-react/src/components/AlphaCenter/AlphaCenter.stories.tsx @@ -2,23 +2,20 @@ import React from 'react' import { type Meta, - type Story, + type StoryFn, } from '@storybook/react' -import base from 'paths.macro' - -import { getTitle } from '~/src/utils/storyUtils' import { Text } from '~/src/components/Text' import { AlphaCenter } from './AlphaCenter' import { type AlphaCenterProps } from './AlphaCenter.types' -export default { - title: getTitle(base), +const meta: Meta = { component: AlphaCenter, -} as Meta +} +export default meta -const Template: Story = ({ children, ...rest }) => ( +const Template: StoryFn = ({ children, ...rest }) => ( { children } @@ -26,12 +23,14 @@ const Template: Story = ({ children, ...rest }) => ( ) -export const Primary = Template.bind({}) +export const Primary = { + render: Template, -Primary.args = { - style: { - width: '200px', - height: '200px', + args: { + style: { + width: '200px', + height: '200px', + }, + children: 'Centered content', }, - children: 'Centered content', } diff --git a/packages/bezier-react/src/components/AlphaSmoothCornersBox/AlphaSmoothCornersBox.stories.tsx b/packages/bezier-react/src/components/AlphaSmoothCornersBox/AlphaSmoothCornersBox.stories.tsx index 9e70be1c3a..4f640f9b7d 100644 --- a/packages/bezier-react/src/components/AlphaSmoothCornersBox/AlphaSmoothCornersBox.stories.tsx +++ b/packages/bezier-react/src/components/AlphaSmoothCornersBox/AlphaSmoothCornersBox.stories.tsx @@ -2,21 +2,21 @@ import React from 'react' import { type Meta, - type Story, + type StoryFn, } from '@storybook/react' -import { base } from 'paths.macro' - -import { getTitle } from '~/src/utils/storyUtils' import { AlphaSmoothCornersBox } from './AlphaSmoothCornersBox' import { type AlphaSmoothCornersBoxProps } from './AlphaSmoothCornersBox.types' -export default { - title: getTitle(base), +const meta:Meta = { component: AlphaSmoothCornersBox, -} as Meta +} +export default meta -const Template: Story = ({ children, ...otherCheckboxProps }) => ( +const Template: StoryFn = ({ + children, + ...otherCheckboxProps +}) => ( = ({ children, ...otherCheckbo ) -export const Primary = Template.bind({}) -Primary.args = { - disabled: false, - borderRadius: '42%', - shadow: { - offsetX: 0, - offsetY: 0, - blurRadius: 10, - spreadRadius: 10, - color: 'bg-black-dark', +export const Primary = { + render: Template, + + args: { + disabled: false, + borderRadius: '42%', + shadow: { + offsetX: 0, + offsetY: 0, + blurRadius: 10, + spreadRadius: 10, + color: 'bg-black-dark', + }, + margin: 0, + backgroundColor: 'bgtxt-absolute-white-normal', + backgroundImage: '', }, - margin: 0, - backgroundColor: 'bgtxt-absolute-white-normal', - backgroundImage: '', } diff --git a/packages/bezier-react/src/components/AlphaStack/AlphaStack.stories.tsx b/packages/bezier-react/src/components/AlphaStack/AlphaStack.stories.tsx index 4276b39507..9d74930bad 100644 --- a/packages/bezier-react/src/components/AlphaStack/AlphaStack.stories.tsx +++ b/packages/bezier-react/src/components/AlphaStack/AlphaStack.stories.tsx @@ -2,22 +2,19 @@ import React from 'react' import { type Meta, - type Story, + type StoryFn, + type StoryObj, } from '@storybook/react' -import base from 'paths.macro' import { css } from '~/src/foundation/FoundationStyledComponent' import { range } from '~/src/utils/numberUtils' -import { getTitle } from '~/src/utils/storyUtils' import { AlphaStack } from './AlphaStack' -import { type AlphaStackProps } from './AlphaStack.types' const FLEX_PROPERTIES = ['start', 'center', 'end', 'stretch'] -export default { - title: getTitle(base), +const meta = { component: AlphaStack, argTypes: { spacing: { @@ -28,26 +25,30 @@ export default { direction: { control: { type: 'radio', - options: ['horizontal', 'vertical'], }, + options: ['horizontal', 'vertical'], }, justify: { control: { type: 'radio', - options: FLEX_PROPERTIES, }, + options: FLEX_PROPERTIES, }, align: { control: { type: 'radio', - options: FLEX_PROPERTIES, }, + options: FLEX_PROPERTIES, }, }, -} as Meta +} satisfies Meta -const Template: Story = ({ children, ...rest }) => ( - +export default meta + +type Story = StoryObj + +const Template: StoryFn = (args) => ( + <> { range(4).map((i) =>
{ i }
, @@ -56,12 +57,17 @@ const Template: Story = ({ children, ...rest }) => (
) -export const Primary = Template.bind({}) +export const Primary: Story = { + render: Template, -Primary.args = { - style: { - width: '200px', - height: '200px', + args: { + direction: 'vertical', + style: { + width: '200px', + height: '200px', + }, + interpolation: css` + background-color: blue; + `, }, - interpolation: css`background-color: blue;`, } diff --git a/packages/bezier-react/src/components/Avatars/Avatar/Avatar.stories.tsx b/packages/bezier-react/src/components/Avatars/Avatar/Avatar.stories.tsx index c0ec06254f..554982c57a 100644 --- a/packages/bezier-react/src/components/Avatars/Avatar/Avatar.stories.tsx +++ b/packages/bezier-react/src/components/Avatars/Avatar/Avatar.stories.tsx @@ -2,13 +2,12 @@ import React from 'react' import { type Meta, - type Story, + type StoryFn, + type StoryObj, } from '@storybook/react' -import { base } from 'paths.macro' import { styled } from '~/src/foundation' -import { getTitle } from '~/src/utils/storyUtils' import { isNaN } from '~/src/utils/typeUtils' import { StatusType } from '~/src/components/Status' @@ -26,24 +25,23 @@ const avatarSizeList = Object.keys(AvatarSize) const statusTypeList = Object.keys(StatusType) .map(key => StatusType[key]) -export default { - title: getTitle(base), +const meta:Meta = { component: Avatar, argTypes: { size: { control: { type: 'radio', - options: avatarSizeList, }, + options: avatarSizeList, }, status: { control: { type: 'radio', - options: [ - undefined, - ...statusTypeList, - ], }, + options: [ + undefined, + ...statusTypeList, + ], }, onClick: { action: 'clicked', @@ -55,7 +53,8 @@ export default { action: 'mouseLeave', }, }, -} as Meta +} +export default meta // NOTE: (@ed) border 색상을 명확하게 보여주기 위해 회색의 Wrapper를 추가했습니다 const Wrapper = styled.div` @@ -67,23 +66,26 @@ const Wrapper = styled.div` background-color: ${({ foundation }) => foundation?.theme?.['bg-grey-light']}; ` -const Template: Story = (args) => ( +const Template: StoryFn = (args) => ( ) -export const Primary: Story = Template.bind({}) -Primary.args = { - avatarUrl: MOCK_AVATAR_URL, - name: 'Channel', - size: AvatarSize.Size24, - showBorder: false, - disabled: false, - smoothCorners: true, +export const Primary: StoryObj = { + render: Template, + + args: { + avatarUrl: MOCK_AVATAR_URL, + name: 'Channel', + size: AvatarSize.Size24, + showBorder: false, + disabled: false, + smoothCorners: true, + }, } -const TemplateWithCustomStatus: Story = (args) => ( +const TemplateWithCustomStatus: StoryFn = (args) => ( = (args) => ( ) -export const WithCustomStatus: Story = TemplateWithCustomStatus.bind({}) -WithCustomStatus.args = { - avatarUrl: MOCK_AVATAR_URL, - name: 'Channel', - size: AvatarSize.Size48, - showBorder: false, - disabled: false, +export const WithCustomStatus: StoryObj = { + render: TemplateWithCustomStatus, + + args: { + avatarUrl: MOCK_AVATAR_URL, + name: 'Channel', + size: AvatarSize.Size48, + showBorder: false, + disabled: false, + }, } diff --git a/packages/bezier-react/src/components/Avatars/AvatarGroup/AvatarGroup.stories.tsx b/packages/bezier-react/src/components/Avatars/AvatarGroup/AvatarGroup.stories.tsx index e0767817af..2932e05641 100644 --- a/packages/bezier-react/src/components/Avatars/AvatarGroup/AvatarGroup.stories.tsx +++ b/packages/bezier-react/src/components/Avatars/AvatarGroup/AvatarGroup.stories.tsx @@ -2,11 +2,10 @@ import React from 'react' import { type Meta, - type Story, + type StoryFn, + type StoryObj, } from '@storybook/react' -import { base } from 'paths.macro' -import { getTitle } from '~/src/utils/storyUtils' import { isNaN } from '~/src/utils/typeUtils' import { @@ -25,21 +24,20 @@ const avatarSizeList = Object.keys(AvatarSize) .filter(value => isNaN(Number(value)) === true) .map(key => AvatarSize[key]) -export default { - title: getTitle(base), +const meta: Meta = { component: AvatarGroup, argTypes: { ellipsisType: { control: { type: 'radio', - options: AvatarGroupEllipsisType, }, + options: AvatarGroupEllipsisType, }, size: { control: { type: 'radio', - options: avatarSizeList, }, + options: avatarSizeList, }, max: { control: { @@ -64,24 +62,24 @@ export default { action: 'mouseLeave', }, }, -} as Meta +} +export default meta -const Template: Story = (args) => ( +const Template: StoryFn = (args) => ( { MOCK_AVATAR_LIST.map(({ id, avatarUrl, name }) => ( - + )) } ) -export const Primary: Story = Template.bind({}) -Primary.args = { - max: 5, - size: AvatarSize.Size30, - ellipsisType: AvatarGroupEllipsisType.Icon, - spacing: 4, +export const Primary: StoryObj = { + render: Template, + + args: { + max: 5, + size: AvatarSize.Size30, + ellipsisType: AvatarGroupEllipsisType.Icon, + spacing: 4, + }, } diff --git a/packages/bezier-react/src/components/Avatars/Avatars.stories.tsx b/packages/bezier-react/src/components/Avatars/Avatars.stories.tsx index 64d9f11ddd..c617879dff 100644 --- a/packages/bezier-react/src/components/Avatars/Avatars.stories.tsx +++ b/packages/bezier-react/src/components/Avatars/Avatars.stories.tsx @@ -2,14 +2,13 @@ import React from 'react' import { type Meta, - type Story, + type StoryFn, + type StoryObj, } from '@storybook/react' -import base from 'paths.macro' import { styled } from '~/src/foundation' import { range } from '~/src/utils/numberUtils' -import { getTitle } from '~/src/utils/storyUtils' import { Avatar, @@ -34,14 +33,15 @@ import { Text } from '~/src/components/Text' import mdx from './Avatars.mdx' -export default { - title: getTitle(base), +const meta: Meta = { + component: Avatar, parameters: { docs: { page: mdx, }, }, -} as Meta +} +export default meta const SAMPLE_AVATARS = [ { @@ -84,7 +84,7 @@ const NAVER_TALK_AVATAR = { avatarUrl: 'https://cf.channel.io/asset/plugin/images/app-messenger-naver-talk.png', } -export const Overview: Story<{}> = () => ( +export const Overview: StoryFn<{}> = () => ( @@ -148,33 +148,29 @@ export const Overview: Story<{}> = () => ( - { range(6).map(i => ( - + { range(6).map((i) => ( + )) } - { range(6).map(i => ( - + { range(6).map((i) => ( + )) } - - { range(6).map(i => ( - + + { range(6).map((i) => ( + )) } @@ -183,31 +179,30 @@ export const Overview: Story<{}> = () => ( ) -export const UsageBasic: Story<{}> = () => ( - - { SAMPLE_AVATARS.map(meta => ( - - - - )) } - -) +export const UsageBasic: StoryObj<{}> = { + render: () => ( + + { SAMPLE_AVATARS.map((avatar) => ( + + + + )) } + + ), -UsageBasic.storyName = 'Usage (basic)' - -export const UsagePresetStatus: Story<{}> = () => ( - - { [ - StatusType.Online, - StatusType.Offline, - StatusType.Lock, - StatusType.OnlineCrescent, - StatusType.OfflineCrescent, - ] - .map(status => ( + name: 'Usage (basic)', +} + +export const UsagePresetStatus: StoryObj<{}> = { + render: () => ( + + { [ + StatusType.Online, + StatusType.Offline, + StatusType.Lock, + StatusType.OnlineCrescent, + StatusType.OfflineCrescent, + ].map((status) => ( = () => ( /> )) } - -) + + ), -UsagePresetStatus.storyName = 'Usage (with preset status)' + name: 'Usage (with preset status)', +} -export const UsagePresetStatusWithSize: Story<{}> = () => ( - - { [AvatarSize.Size24, AvatarSize.Size36, AvatarSize.Size48] - .map(size => ( +export const UsagePresetStatusWithSize: StoryObj<{}> = { + render: () => ( + + { [AvatarSize.Size24, AvatarSize.Size36, AvatarSize.Size48].map((size) => ( = () => ( /> )) } - -) + + ), -UsagePresetStatusWithSize.storyName = 'Usage (with preset status and size)' + name: 'Usage (with preset status and size)', +} const EmojiStatusWrapper = styled.div` display: flex; @@ -248,206 +245,186 @@ const EmojiStatusWrapper = styled.div` border-radius: 42%; ` -export const UsageCustomStatus: Story<{}> = () => ( - - - - - - +export const UsageCustomStatus: StoryObj<{}> = { + render: () => ( + + + + + + - - - - - + + + + + - - - - - + + + + + - - - - - - - - -) + + + + + + + + + ), -UsageCustomStatus.storyName = 'Usage (with custom status)' - -export const UsageCustomStatusAvatar: Story<{}> = () => ( - - - -) + name: 'Usage (with custom status)', +} -UsageCustomStatusAvatar.storyName = 'Usage (avatar as custom status)' +export const UsageCustomStatusAvatar: StoryObj<{}> = { + render: () => ( + + + + ), -export const UsageDisabled: Story<{}> = () => ( - -) + name: 'Usage (avatar as custom status)', +} -UsageDisabled.storyName = 'Usage (disabled)' +export const UsageDisabled: StoryObj<{}> = { + render: () => ( + + ), -export const UsageCheckableAvatar: Story<{}> = () => ( - - - - - Checkable (checked=false) - + name: 'Usage (disabled)', +} - - - - - +export const UsageCheckableAvatar: StoryObj<{}> = { + render: () => ( + + + + + Checkable (checked=false) + - - - - Checkable (checked=false, disabled) - + + + + + - - - - - + + + + + Checkable (checked=false, disabled) + + - - - - Checkable (checked=true) - + + + + + - - - - - - -) + + + + Checkable (checked=true) + -UsageCheckableAvatar.storyName = 'Usage (checkable avatars)' + + + + + + + ), -export const UsageGroupEllipsis: Story<{}> = () => ( - - - - - Ellipsis type = Icon - + name: 'Usage (checkable avatars)', +} - - - { SAMPLE_AVATARS.map(meta => ) } - - - - +export const UsageGroupEllipsis: StoryObj<{}> = { + render: () => ( + + + + + Ellipsis type = Icon + - - - - Ellipsis type = Count - + + + { SAMPLE_AVATARS.map((avatar) => ( + + )) } + + + + - - - { SAMPLE_AVATARS.map(meta => ) } - - - - - -) + + + + Ellipsis type = Count + -UsageGroupEllipsis.storyName = 'Usage (avatar group with ellipsis)' + + + { SAMPLE_AVATARS.map(avatar => ) } + + + + + + ), -export const UsageGroupSpacing: Story<{}> = () => ( - - - - { SAMPLE_AVATARS.map(meta => ) } - - + name: 'Usage (avatar group with ellipsis)', +} - - - { SAMPLE_AVATARS.map(meta => ) } - - +export const UsageGroupSpacing: StoryObj<{}> = { + render: () => ( + + + + { SAMPLE_AVATARS.map((avatar) => ( + + )) } + + - - - { SAMPLE_AVATARS.map(meta => ) } - - - -) + + + { SAMPLE_AVATARS.map(avatar => ) } + + -UsageGroupSpacing.storyName = 'Usage (avatar group with spacing)' + + + { SAMPLE_AVATARS.map(avatar => ) } + + + + ), -export const VariantsSize: Story<{}> = () => ( - - { - [ + name: 'Usage (avatar group with spacing)', +} + +export const VariantsSize: StoryObj<{}> = { + render: () => ( + + { [ AvatarSize.Size20, AvatarSize.Size24, AvatarSize.Size30, @@ -472,9 +449,9 @@ export const VariantsSize: Story<{}> = () => ( - )) - } - -) + )) } + + ), -VariantsSize.storyName = 'Variants (size)' + name: 'Variants (size)', +} diff --git a/packages/bezier-react/src/components/Avatars/CheckableAvatar/CheckableAvatar.stories.tsx b/packages/bezier-react/src/components/Avatars/CheckableAvatar/CheckableAvatar.stories.tsx index a03357b70a..0981f25809 100644 --- a/packages/bezier-react/src/components/Avatars/CheckableAvatar/CheckableAvatar.stories.tsx +++ b/packages/bezier-react/src/components/Avatars/CheckableAvatar/CheckableAvatar.stories.tsx @@ -2,22 +2,18 @@ import React from 'react' import { type Meta, - type Story, + type StoryFn, + type StoryObj, } from '@storybook/react' -import { base } from 'paths.macro' -import { - getObjectFromEnum, - getTitle, -} from '~/src/utils/storyUtils' +import { getObjectFromEnum } from '~/src/utils/storyUtils' import { AvatarSize } from '~/src/components/Avatars/Avatar' import { CheckableAvatar } from './CheckableAvatar' import type { CheckableAvatarProps } from './CheckableAvatar.types' -export default { - title: getTitle(base), +const meta: Meta = { component: CheckableAvatar, argTypes: { checked: { @@ -28,25 +24,28 @@ export default { size: { control: { type: 'select', - options: getObjectFromEnum(AvatarSize), }, + options: getObjectFromEnum(AvatarSize), }, }, -} as Meta +} +export default meta -const Template: Story = ({ children, ...rest }) => ( - - { children } - +const Template: StoryFn = ({ children, ...rest }) => ( + { children } ) -export const Primary: Story = Template.bind({}) -Primary.args = { - avatarUrl: 'https://cf.channel.io/thumb/200x200/pub-file/1/606d87d059a6093594c0/ch-symbol-filled-smiley-bg.png', - name: 'Channel', - size: AvatarSize.Size24, - checked: undefined, - defaultChecked: false, - disabled: false, - showBorder: false, +export const Primary: StoryObj = { + render: Template, + + args: { + avatarUrl: + 'https://cf.channel.io/thumb/200x200/pub-file/1/606d87d059a6093594c0/ch-symbol-filled-smiley-bg.png', + name: 'Channel', + size: AvatarSize.Size24, + checked: undefined, + defaultChecked: false, + disabled: false, + showBorder: false, + }, } diff --git a/packages/bezier-react/src/components/Banner/Banner.stories.tsx b/packages/bezier-react/src/components/Banner/Banner.stories.tsx index 1c1278e8be..01a672bb90 100644 --- a/packages/bezier-react/src/components/Banner/Banner.stories.tsx +++ b/packages/bezier-react/src/components/Banner/Banner.stories.tsx @@ -13,15 +13,12 @@ import { } from '@channel.io/bezier-icons' import type { Meta, - Story, + StoryFn, + StoryObj, } from '@storybook/react' -import base from 'paths.macro' import { noop } from '~/src/utils/functionUtils' -import { - getObjectFromEnum, - getTitle, -} from '~/src/utils/storyUtils' +import { getObjectFromEnum } from '~/src/utils/storyUtils' import { StackItem, @@ -35,8 +32,7 @@ import { BannerVariant, } from './Banner.types' -export default { - title: getTitle(base), +const meta: Meta = { component: Banner, parameters: { docs: { @@ -47,13 +43,8 @@ export default { variant: { control: { type: 'radio', - options: getObjectFromEnum(BannerVariant), - }, - }, - dismissible: { - control: { - type: 'boolean', }, + options: getObjectFromEnum(BannerVariant), }, hasLink: { control: { @@ -71,19 +62,20 @@ export default { }, }, }, -} as Meta - -export const Playground: Story = props => +} +export default meta -Playground.args = { - variant: BannerVariant.Default, - icon: LightbulbIcon, - content: 'Information here.', - actionIcon: CancelSmallIcon, - onClickAction: noop, +export const Playground: StoryObj = { + args: { + variant: BannerVariant.Default, + icon: LightbulbIcon, + content: 'Information here.', + actionIcon: CancelSmallIcon, + onClickAction: noop, + }, } -export const Overview: Story<{}> = () => ( +export const Overview: StoryFn<{}> = () => ( = () => ( ) -export const UsageMinWidth: Story<{}> = () => ( - - - - - -) +export const UsageMinWidth: StoryObj<{}> = { + render: () => ( + + + + + + ), -UsageMinWidth.storyName = 'Usage (min width)' + name: 'Usage (min width)', +} -export const UsageFullWidth: Story<{}> = () => ( - - - - - - - - - - - -) +export const UsageFullWidth: StoryObj<{}> = { + render: () => ( + + + + + + + + + + + + ), -UsageFullWidth.storyName = 'Usage (full width)' + name: 'Usage (full width)', +} -export const UsageMaxWidth: Story<{}> = () => ( - - - - - -) +export const UsageMaxWidth: StoryObj<{}> = { + render: () => ( + + + + + + ), -UsageMaxWidth.storyName = 'Usage (max width)' + name: 'Usage (max width)', +} -export const UsageConsecutive: Story<{}> = () => ( - - - - - - - - - - - -) +export const UsageConsecutive: StoryObj<{}> = { + render: () => ( + + + + + + + + + + + + ), -UsageConsecutive.storyName = 'Usage (consecutive)' + name: 'Usage (consecutive)', +} -export const UsageNoIcon: Story<{}> = () => ( - -) +export const UsageNoIcon: StoryObj<{}> = { + render: () => ( + + ), -UsageNoIcon.storyName = 'Usage (no icon)' + name: 'Usage (no icon)', +} -export const UsageLink: Story<{}> = () => ( - -) +export const UsageLink: StoryObj<{}> = { + render: () => ( + + ), -UsageLink.storyName = 'Usage (link)' + name: 'Usage (link)', +} -export const UsageLinkTo: Story<{}> = () => ( - -) +export const UsageLinkTo: StoryObj<{}> = { + render: () => ( + + ), -UsageLinkTo.storyName = 'Usage (link to external location)' + name: 'Usage (link to external location)', +} diff --git a/packages/bezier-react/src/components/Button/Button.stories.tsx b/packages/bezier-react/src/components/Button/Button.stories.tsx index 01ef64dc95..99826b9adc 100644 --- a/packages/bezier-react/src/components/Button/Button.stories.tsx +++ b/packages/bezier-react/src/components/Button/Button.stories.tsx @@ -21,17 +21,14 @@ import { } from '@channel.io/bezier-icons' import { type Meta, - type Story, + type StoryObj, } from '@storybook/react' -import base from 'paths.macro' import { Typography, styled, } from '~/src/foundation' -import { getTitle } from '~/src/utils/storyUtils' - import { Avatar } from '~/src/components/Avatars/Avatar' import { ButtonGroup } from '~/src/components/ButtonGroup' import { ListItem } from '~/src/components/ListItem' @@ -57,8 +54,7 @@ import { ButtonStyleVariant, } from './Button.types' -export default { - title: getTitle(base), +const meta: Meta = { component: Button, parameters: { docs: { @@ -70,177 +66,182 @@ export default { size: { control: { type: 'radio', - options: [ - ...Object.values(ButtonSize), - ], }, + options: Object.values(ButtonSize), }, styleVariant: { control: { type: 'radio', - options: [ - ...Object.values(ButtonStyleVariant), - ], }, + options: Object.values(ButtonStyleVariant), }, colorVariant: { control: { type: 'radio', - options: [ - ...Object.values(ButtonColorVariant), - ], }, + options: Object.values(ButtonColorVariant), }, }, -} as Meta - -const Template: Story = (args) =>