From 0d9a4a656397f7a4f9c7b4f5b21bd911aec85cf4 Mon Sep 17 00:00:00 2001 From: storybook-bot <32066757+storybook-bot@users.noreply.github.com> Date: Thu, 28 Mar 2024 00:02:27 +0000 Subject: [PATCH 01/37] Update CHANGELOG.md for v8.0.5 [skip ci] --- CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c78e29fa62ae..2de9a1f7882f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +## 8.0.5 + +- Addon-docs: Fix `react-dom/server` imports breaking stories and docs - [#26557](https://github.com/storybookjs/storybook/pull/26557), thanks @JReinhold! +- Automigrations: Fix missing support for mts vite config - [#26441](https://github.com/storybookjs/storybook/pull/26441), thanks @drik98! +- CLI: Improve Yarn berry error parsing - [#26616](https://github.com/storybookjs/storybook/pull/26616), thanks @yannbf! +- React-Docgen: Make sure to be able to handle empty unions - [#26639](https://github.com/storybookjs/storybook/pull/26639), thanks @kasperpeulen! +- Viewport: Fix missing style - [#26530](https://github.com/storybookjs/storybook/pull/26530), thanks @jpzwarte! + ## 8.0.4 - Addon Docs: Support Stencil based display names in source snippets - [#26592](https://github.com/storybookjs/storybook/pull/26592), thanks @yannbf! From b2091f03ef695f3fc4a792ca872aff4cd8b0fd03 Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Thu, 28 Mar 2024 10:07:40 +0100 Subject: [PATCH 02/37] Fix sourcemap generation in webpack react-docgen-loader --- .../presets/react-webpack/src/loaders/react-docgen-loader.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/code/presets/react-webpack/src/loaders/react-docgen-loader.ts b/code/presets/react-webpack/src/loaders/react-docgen-loader.ts index 15b71f19bfd5..ac83e37982de 100644 --- a/code/presets/react-webpack/src/loaders/react-docgen-loader.ts +++ b/code/presets/react-webpack/src/loaders/react-docgen-loader.ts @@ -114,7 +114,10 @@ export default async function reactDocgenLoader( } }); - const map = magicString.generateMap({ hires: true }); + const map = magicString.generateMap({ + includeContent: true, + source: this.resourcePath, + }); callback(null, magicString.toString(), map); } catch (error: any) { if (error.code === ERROR_CODES.MISSING_DEFINITION) { From fdad84ebaf50e1ef0d590b93e14b0f9af40957c9 Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Thu, 28 Mar 2024 11:41:58 +0100 Subject: [PATCH 03/37] Fix parallelism for check and compile command on CI --- scripts/tasks/check.ts | 5 ++++- scripts/tasks/compile.ts | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/scripts/tasks/check.ts b/scripts/tasks/check.ts index 80065df999b4..1f5928c48147 100644 --- a/scripts/tasks/check.ts +++ b/scripts/tasks/check.ts @@ -2,7 +2,10 @@ import type { Task } from '../task'; import { exec } from '../utils/exec'; import { maxConcurrentTasks } from '../utils/maxConcurrentTasks'; -const parallel = `--parallel=${process.env.CI ? 8 : maxConcurrentTasks}`; +// The amount of VCPUs for the check task on CI is 8 (xlarge resource) +const amountOfVCPUs = 8; + +const parallel = `--parallel=${process.env.CI ? amountOfVCPUs - 1 : maxConcurrentTasks}`; const linkCommand = `nx affected -t check ${parallel}`; const nolinkCommand = `nx affected -t check -c production ${parallel}`; diff --git a/scripts/tasks/compile.ts b/scripts/tasks/compile.ts index 7f4beda5d609..af220b9f27a4 100644 --- a/scripts/tasks/compile.ts +++ b/scripts/tasks/compile.ts @@ -5,7 +5,10 @@ import { maxConcurrentTasks } from '../utils/maxConcurrentTasks'; import { exec } from '../utils/exec'; import type { Task } from '../task'; -const parallel = `--parallel=${process.env.CI ? 8 : maxConcurrentTasks}`; +// The amount of VCPUs for the check task on CI is 4 (large resource) +const amountOfVCPUs = 4; + +const parallel = `--parallel=${process.env.CI ? amountOfVCPUs - 1 : maxConcurrentTasks}`; const linkedContents = `export * from '../src/index';`; const linkCommand = `nx run-many -t build ${parallel}`; From 07728208244044272b8d45576cd0a33af69da2bc Mon Sep 17 00:00:00 2001 From: Gert Hengeveld Date: Sat, 30 Mar 2024 10:04:31 +0100 Subject: [PATCH 04/37] Ensure all matching notifications are cleared rather than just the first one, and use atomic state updates --- .../manager-api/src/modules/notifications.ts | 35 +++++++++---------- 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/code/lib/manager-api/src/modules/notifications.ts b/code/lib/manager-api/src/modules/notifications.ts index 3358dd67a241..0196fb1fcbc6 100644 --- a/code/lib/manager-api/src/modules/notifications.ts +++ b/code/lib/manager-api/src/modules/notifications.ts @@ -1,4 +1,5 @@ import type { API_Notification } from '@storybook/types'; +import partition from 'lodash/partition.js'; import type { ModuleFn } from '../lib/types'; export interface SubState { @@ -25,26 +26,24 @@ export interface SubAPI { export const init: ModuleFn = ({ store }) => { const api: SubAPI = { - addNotification: (notification) => { - // Get rid of it if already exists - api.clearNotification(notification.id); - - const { notifications } = store.getState(); - - store.setState({ notifications: [...notifications, notification] }); + addNotification: (newNotification) => { + store.setState(({ notifications }) => { + const [existing, others] = partition(notifications, (n) => n.id === newNotification.id); + existing.forEach((notification) => { + if (notification.onClear) notification.onClear({ dismissed: false }); + }); + return { notifications: [...others, newNotification] }; + }); }, - clearNotification: (id) => { - const { notifications } = store.getState(); - - const notification = notifications.find((n) => n.id === id); - - if (notification) { - store.setState({ notifications: notifications.filter((n) => n.id !== id) }); - if (notification.onClear) { - notification.onClear({ dismissed: false }); - } - } + clearNotification: (notificationId) => { + store.setState(({ notifications }) => { + const [matching, others] = partition(notifications, (n) => n.id === notificationId); + matching.forEach((notification) => { + if (notification.onClear) notification.onClear({ dismissed: false }); + }); + return { notifications: others }; + }); }, }; From 123774cab7c29f909fe922eaa31d91110d2696d5 Mon Sep 17 00:00:00 2001 From: Gert Hengeveld Date: Sat, 30 Mar 2024 10:37:18 +0100 Subject: [PATCH 05/37] Improve NotificationItem stories --- .../NotificationItem.stories.tsx | 27 ++++++++++--------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/code/ui/manager/src/components/notifications/NotificationItem.stories.tsx b/code/ui/manager/src/components/notifications/NotificationItem.stories.tsx index 5d58559b465b..dd9b351f222a 100644 --- a/code/ui/manager/src/components/notifications/NotificationItem.stories.tsx +++ b/code/ui/manager/src/components/notifications/NotificationItem.stories.tsx @@ -7,6 +7,7 @@ import { BookIcon as BookIconIcon, FaceHappyIcon, } from '@storybook/icons'; +import { fn } from '@storybook/test'; const meta = { component: NotificationItem, @@ -29,8 +30,8 @@ const meta = { export default meta; type Story = StoryObj; -const onClear = () => {}; -const onDismissNotification = () => {}; +const onClear = fn(); +const onDismissNotification = fn(); export const Simple: Story = { args: { @@ -40,7 +41,7 @@ export const Simple: Story = { content: { headline: 'Storybook cool!', }, - link: '/some/path', + link: undefined, }, onDismissNotification, }, @@ -55,7 +56,7 @@ export const LongHeadline: Story = { content: { headline: 'This is a long message that extends over two lines!', }, - link: '/some/path', + link: undefined, }, }, }; @@ -115,7 +116,7 @@ export const BookIcon: Story = { headline: 'Storybook has a book icon!', }, icon: , - link: '/some/path', + link: undefined, }, }, }; @@ -131,7 +132,7 @@ export const StrongSubHeadline: Story = { subHeadline: Strong subHeadline, }, icon: , - link: '/some/path', + link: undefined, }, }, }; @@ -151,7 +152,7 @@ export const StrongEmphasizedSubHeadline: Story = { ), }, icon: , - link: '/some/path', + link: undefined, }, }, }; @@ -167,7 +168,7 @@ export const BookIconSubHeadline: Story = { subHeadline: 'Find out more!', }, icon: , - link: '/some/path', + link: undefined, }, }, }; @@ -184,7 +185,7 @@ export const BookIconLongSubHeadline: Story = { 'Find out more! by clicking on on buttons and downloading some applications. Find out more! by clicking on buttons and downloading some applications', }, icon: , - link: '/some/path', + link: undefined, }, }, }; @@ -200,7 +201,7 @@ export const AccessibilityIcon: Story = { subHeadline: 'It is here!', }, icon: , - link: '/some/path', + link: undefined, }, }, }; @@ -216,7 +217,7 @@ export const AccessibilityGoldIcon: Story = { subHeadline: 'It is gold!', }, icon: , - link: '/some/path', + link: undefined, }, }, }; @@ -231,7 +232,7 @@ export const AccessibilityGoldIconLongHeadLineNoSubHeadline: Story = { headline: 'Storybook notifications has a accessibility icon it can be any color!', }, icon: , - link: '/some/path', + link: undefined, }, }, }; @@ -249,7 +250,7 @@ export const WithOldIconFormat: Story = { name: 'accessibility', color: 'gold', }, - link: '/some/path', + link: undefined, }, }, }; From e84cabef31b49a90e436be4b1c4edce73ff18dfe Mon Sep 17 00:00:00 2001 From: Gert Hengeveld Date: Sat, 30 Mar 2024 14:24:34 +0100 Subject: [PATCH 06/37] Add duration property to Notification API, and show countdown bar --- code/lib/types/src/modules/api.ts | 9 +- .../NotificationItem.stories.tsx | 15 +++- .../notifications/NotificationItem.tsx | 85 +++++++++++++------ 3 files changed, 82 insertions(+), 27 deletions(-) diff --git a/code/lib/types/src/modules/api.ts b/code/lib/types/src/modules/api.ts index 1ccc98cc9e24..4c6893d35ad4 100644 --- a/code/lib/types/src/modules/api.ts +++ b/code/lib/types/src/modules/api.ts @@ -115,9 +115,13 @@ export interface API_SidebarOptions { interface OnClearOptions { /** - * True when the user dismissed the notification. + * True when the user manually dismissed the notification. */ dismissed: boolean; + /** + * True when the notification timed out after the set duration. + */ + timeout: boolean; } /** @@ -130,11 +134,12 @@ interface DeprecatedIconType { } export interface API_Notification { id: string; - link: string; content: { headline: string; subHeadline?: string | any; }; + duration?: number; + link?: string; // TODO: Remove DeprecatedIconType in 9.0 icon?: React.ReactNode | DeprecatedIconType; onClear?: (options: OnClearOptions) => void; diff --git a/code/ui/manager/src/components/notifications/NotificationItem.stories.tsx b/code/ui/manager/src/components/notifications/NotificationItem.stories.tsx index dd9b351f222a..210623ee6c8c 100644 --- a/code/ui/manager/src/components/notifications/NotificationItem.stories.tsx +++ b/code/ui/manager/src/components/notifications/NotificationItem.stories.tsx @@ -41,7 +41,20 @@ export const Simple: Story = { content: { headline: 'Storybook cool!', }, - link: undefined, + }, + onDismissNotification, + }, +}; + +export const Timeout: Story = { + args: { + notification: { + id: '1', + onClear, + content: { + headline: 'Storybook cool!', + }, + duration: 5000, }, onDismissNotification, }, diff --git a/code/ui/manager/src/components/notifications/NotificationItem.tsx b/code/ui/manager/src/components/notifications/NotificationItem.tsx index 0028f87749cf..20d736bd32bb 100644 --- a/code/ui/manager/src/components/notifications/NotificationItem.tsx +++ b/code/ui/manager/src/components/notifications/NotificationItem.tsx @@ -1,26 +1,51 @@ import type { FC, SyntheticEvent } from 'react'; -import React from 'react'; +import React, { useCallback, useEffect, useRef } from 'react'; import { type State } from '@storybook/manager-api'; import { Link } from '@storybook/router'; -import { styled, useTheme } from '@storybook/theming'; +import { keyframes, styled, useTheme } from '@storybook/theming'; import type { IconsProps } from '@storybook/components'; import { IconButton, Icons } from '@storybook/components'; import { transparentize } from 'polished'; import { CloseAltIcon } from '@storybook/icons'; -const Notification = styled.div(({ theme }) => ({ - position: 'relative', - display: 'flex', - padding: 15, - width: 280, - borderRadius: 4, - alignItems: 'center', +const grow = keyframes({ + '0%': { + width: '0%', + }, + '100%': { + width: '100%', + }, +}); - background: theme.base === 'light' ? 'hsla(203, 50%, 20%, .97)' : 'hsla(203, 30%, 95%, .97)', - boxShadow: `0 2px 5px 0 rgba(0,0,0,0.05), 0 5px 15px 0 rgba(0,0,0,0.1)`, - color: theme.color.inverseText, - textDecoration: 'none', -})); +const Notification = styled.div<{ duration?: number }>( + ({ theme }) => ({ + position: 'relative', + display: 'flex', + padding: 15, + width: 280, + borderRadius: 4, + alignItems: 'center', + + background: theme.base === 'light' ? 'hsla(203, 50%, 20%, .97)' : 'hsla(203, 30%, 95%, .97)', + boxShadow: `0 2px 5px 0 rgba(0,0,0,0.05), 0 5px 15px 0 rgba(0,0,0,0.1)`, + color: theme.color.inverseText, + textDecoration: 'none', + overflow: 'hidden', + }), + ({ duration, theme }) => + duration && { + '&::after': { + content: '""', + display: 'block', + position: 'absolute', + bottom: 0, + left: 0, + height: 3, + background: theme.color.secondary, + animation: `${grow} ${duration}ms linear forwards reverse`, + }, + } +); const NotificationWithInteractiveStates = styled(Notification)(() => ({ transition: 'all 150ms ease-out', @@ -135,22 +160,34 @@ export const NotificationItemSpacer = styled.div({ const NotificationItem: FC<{ notification: State['notifications'][0]; onDismissNotification: (id: string) => void; -}> = ({ notification: { content, link, onClear, id, icon }, onDismissNotification }) => { - const dismissNotificationItem = () => { +}> = ({ notification: { content, duration, link, onClear, id, icon }, onDismissNotification }) => { + const onTimeout = useCallback(() => { onDismissNotification(id); - if (onClear) { - onClear({ dismissed: true }); - } - }; + if (onClear) onClear({ dismissed: false, timeout: true }); + }, [onDismissNotification, onClear]); + + const timer = useRef(null); + useEffect(() => { + if (!duration) return; + timer.current = setTimeout(onTimeout, duration); + return () => clearTimeout(timer.current); + }, [duration, onTimeout]); + + const onDismiss = useCallback(() => { + clearTimeout(timer.current); + onDismissNotification(id); + if (onClear) onClear({ dismissed: true, timeout: false }); + }, [onDismissNotification, onClear]); + return link ? ( - + - + ) : ( - + - + ); }; From b00d4ee29bae443158807f5794519d34a9104cc8 Mon Sep 17 00:00:00 2001 From: Gert Hengeveld Date: Sat, 30 Mar 2024 20:27:20 +0100 Subject: [PATCH 07/37] Add slide in animation to notifications --- .../components/notifications/NotificationItem.tsx | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/code/ui/manager/src/components/notifications/NotificationItem.tsx b/code/ui/manager/src/components/notifications/NotificationItem.tsx index 20d736bd32bb..ca07e513422a 100644 --- a/code/ui/manager/src/components/notifications/NotificationItem.tsx +++ b/code/ui/manager/src/components/notifications/NotificationItem.tsx @@ -8,6 +8,17 @@ import { IconButton, Icons } from '@storybook/components'; import { transparentize } from 'polished'; import { CloseAltIcon } from '@storybook/icons'; +const slideIn = keyframes({ + '0%': { + opacity: 0, + transform: 'translateY(30px)', + }, + '100%': { + opacity: 1, + transform: 'translateY(0)', + }, +}); + const grow = keyframes({ '0%': { width: '0%', @@ -26,6 +37,7 @@ const Notification = styled.div<{ duration?: number }>( borderRadius: 4, alignItems: 'center', + animation: `${slideIn} 500ms`, background: theme.base === 'light' ? 'hsla(203, 50%, 20%, .97)' : 'hsla(203, 30%, 95%, .97)', boxShadow: `0 2px 5px 0 rgba(0,0,0,0.05), 0 5px 15px 0 rgba(0,0,0,0.1)`, color: theme.color.inverseText, From 7f1c4e0272ebd974e0250e15417b3f85d962a3ba Mon Sep 17 00:00:00 2001 From: Gert Hengeveld Date: Sat, 30 Mar 2024 21:06:10 +0100 Subject: [PATCH 08/37] Fix logging onClear handler --- .../components/notifications/NotificationItem.stories.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/code/ui/manager/src/components/notifications/NotificationItem.stories.tsx b/code/ui/manager/src/components/notifications/NotificationItem.stories.tsx index 210623ee6c8c..254812ead9d9 100644 --- a/code/ui/manager/src/components/notifications/NotificationItem.stories.tsx +++ b/code/ui/manager/src/components/notifications/NotificationItem.stories.tsx @@ -1,4 +1,5 @@ import React from 'react'; +import { action } from '@storybook/addon-actions'; import { LocationProvider } from '@storybook/router'; import type { Meta, StoryObj } from '@storybook/react'; import NotificationItem from './NotificationItem'; @@ -7,7 +8,6 @@ import { BookIcon as BookIconIcon, FaceHappyIcon, } from '@storybook/icons'; -import { fn } from '@storybook/test'; const meta = { component: NotificationItem, @@ -30,8 +30,8 @@ const meta = { export default meta; type Story = StoryObj; -const onClear = fn(); -const onDismissNotification = fn(); +const onClear = action('onClear'); +const onDismissNotification = () => {}; export const Simple: Story = { args: { From 8338f595b66f593b9b28cbb05257f7ad057b73d8 Mon Sep 17 00:00:00 2001 From: Gert Hengeveld Date: Sat, 30 Mar 2024 21:10:27 +0100 Subject: [PATCH 09/37] Add missing property --- code/lib/manager-api/src/modules/notifications.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/lib/manager-api/src/modules/notifications.ts b/code/lib/manager-api/src/modules/notifications.ts index 0196fb1fcbc6..a8ee3195b6b7 100644 --- a/code/lib/manager-api/src/modules/notifications.ts +++ b/code/lib/manager-api/src/modules/notifications.ts @@ -30,7 +30,7 @@ export const init: ModuleFn = ({ store }) => { store.setState(({ notifications }) => { const [existing, others] = partition(notifications, (n) => n.id === newNotification.id); existing.forEach((notification) => { - if (notification.onClear) notification.onClear({ dismissed: false }); + if (notification.onClear) notification.onClear({ dismissed: false, timeout: false }); }); return { notifications: [...others, newNotification] }; }); @@ -40,7 +40,7 @@ export const init: ModuleFn = ({ store }) => { store.setState(({ notifications }) => { const [matching, others] = partition(notifications, (n) => n.id === notificationId); matching.forEach((notification) => { - if (notification.onClear) notification.onClear({ dismissed: false }); + if (notification.onClear) notification.onClear({ dismissed: false, timeout: false }); }); return { notifications: others }; }); From 908e92ec2b159bbedc15386a8b6e271200432224 Mon Sep 17 00:00:00 2001 From: Gert Hengeveld Date: Sat, 30 Mar 2024 21:26:16 +0100 Subject: [PATCH 10/37] Add onClick property to notifications --- code/lib/types/src/modules/api.ts | 8 +++++ .../NotificationItem.stories.tsx | 35 ++++++++++--------- .../notifications/NotificationItem.tsx | 32 +++++++++++++---- 3 files changed, 51 insertions(+), 24 deletions(-) diff --git a/code/lib/types/src/modules/api.ts b/code/lib/types/src/modules/api.ts index 4c6893d35ad4..481139e71792 100644 --- a/code/lib/types/src/modules/api.ts +++ b/code/lib/types/src/modules/api.ts @@ -124,6 +124,13 @@ interface OnClearOptions { timeout: boolean; } +interface OnClickOptions { + /** + * Function to dismiss the notification. + */ + onDismiss: () => void; +} + /** * @deprecated Use ReactNode for the icon instead. * @see https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#icons-is-deprecated @@ -143,6 +150,7 @@ export interface API_Notification { // TODO: Remove DeprecatedIconType in 9.0 icon?: React.ReactNode | DeprecatedIconType; onClear?: (options: OnClearOptions) => void; + onClick?: (options: OnClickOptions) => void; } type API_Versions = Record; diff --git a/code/ui/manager/src/components/notifications/NotificationItem.stories.tsx b/code/ui/manager/src/components/notifications/NotificationItem.stories.tsx index 254812ead9d9..13b20e0f7d99 100644 --- a/code/ui/manager/src/components/notifications/NotificationItem.stories.tsx +++ b/code/ui/manager/src/components/notifications/NotificationItem.stories.tsx @@ -25,13 +25,16 @@ const meta = { ), ], excludeStories: /.*Data$/, + args: { + onDismissNotification: () => {}, + }, } satisfies Meta; export default meta; type Story = StoryObj; const onClear = action('onClear'); -const onDismissNotification = () => {}; +const onClick = action('onClick'); export const Simple: Story = { args: { @@ -42,27 +45,24 @@ export const Simple: Story = { headline: 'Storybook cool!', }, }, - onDismissNotification, }, }; export const Timeout: Story = { args: { notification: { - id: '1', + id: 'Timeout', onClear, content: { headline: 'Storybook cool!', }, duration: 5000, }, - onDismissNotification, }, }; export const LongHeadline: Story = { args: { - ...Simple.args, notification: { id: '2', onClear, @@ -74,9 +74,21 @@ export const LongHeadline: Story = { }, }; +export const Clickable: Story = { + args: { + notification: { + id: 'Clickable', + onClear, + onClick, + content: { + headline: 'Storybook cool!', + }, + }, + }, +}; + export const Link: Story = { args: { - ...Simple.args, notification: { id: '3', onClear, @@ -90,7 +102,6 @@ export const Link: Story = { export const LinkIconWithColor: Story = { args: { - ...Simple.args, notification: { id: '4', onClear, @@ -105,7 +116,6 @@ export const LinkIconWithColor: Story = { export const LinkIconWithColorSubHeadline: Story = { args: { - ...Simple.args, notification: { id: '5', onClear, @@ -121,7 +131,6 @@ export const LinkIconWithColorSubHeadline: Story = { export const BookIcon: Story = { args: { - ...Simple.args, notification: { id: '6', onClear, @@ -136,7 +145,6 @@ export const BookIcon: Story = { export const StrongSubHeadline: Story = { args: { - ...Simple.args, notification: { id: '7', onClear, @@ -152,7 +160,6 @@ export const StrongSubHeadline: Story = { export const StrongEmphasizedSubHeadline: Story = { args: { - ...Simple.args, notification: { id: '8', onClear, @@ -172,7 +179,6 @@ export const StrongEmphasizedSubHeadline: Story = { export const BookIconSubHeadline: Story = { args: { - ...Simple.args, notification: { id: '9', onClear, @@ -188,7 +194,6 @@ export const BookIconSubHeadline: Story = { export const BookIconLongSubHeadline: Story = { args: { - ...Simple.args, notification: { id: '10', onClear, @@ -205,7 +210,6 @@ export const BookIconLongSubHeadline: Story = { export const AccessibilityIcon: Story = { args: { - ...Simple.args, notification: { id: '11', onClear, @@ -221,7 +225,6 @@ export const AccessibilityIcon: Story = { export const AccessibilityGoldIcon: Story = { args: { - ...Simple.args, notification: { id: '12', onClear, @@ -237,7 +240,6 @@ export const AccessibilityGoldIcon: Story = { export const AccessibilityGoldIconLongHeadLineNoSubHeadline: Story = { args: { - ...Simple.args, notification: { id: '13', onClear, @@ -252,7 +254,6 @@ export const AccessibilityGoldIconLongHeadLineNoSubHeadline: Story = { export const WithOldIconFormat: Story = { args: { - ...Simple.args, notification: { id: '13', onClear, diff --git a/code/ui/manager/src/components/notifications/NotificationItem.tsx b/code/ui/manager/src/components/notifications/NotificationItem.tsx index ca07e513422a..35403fab8296 100644 --- a/code/ui/manager/src/components/notifications/NotificationItem.tsx +++ b/code/ui/manager/src/components/notifications/NotificationItem.tsx @@ -60,6 +60,7 @@ const Notification = styled.div<{ duration?: number }>( ); const NotificationWithInteractiveStates = styled(Notification)(() => ({ + cursor: 'pointer', transition: 'all 150ms ease-out', transform: 'translate3d(0, 0, 0)', '&:hover': { @@ -158,6 +159,7 @@ const DismissNotificationItem: FC<{ title="Dismiss notification" onClick={(e: SyntheticEvent) => { e.preventDefault(); + e.stopPropagation(); onDismiss(); }} > @@ -172,7 +174,10 @@ export const NotificationItemSpacer = styled.div({ const NotificationItem: FC<{ notification: State['notifications'][0]; onDismissNotification: (id: string) => void; -}> = ({ notification: { content, duration, link, onClear, id, icon }, onDismissNotification }) => { +}> = ({ + notification: { content, duration, link, onClear, onClick, id, icon }, + onDismissNotification, +}) => { const onTimeout = useCallback(() => { onDismissNotification(id); if (onClear) onClear({ dismissed: false, timeout: true }); @@ -191,12 +196,25 @@ const NotificationItem: FC<{ if (onClear) onClear({ dismissed: true, timeout: false }); }, [onDismissNotification, onClear]); - return link ? ( - - - - - ) : ( + if (link) { + return ( + + + + + ); + } + + if (onClick) { + return ( + onClick({ onDismiss })} duration={duration}> + + + + ); + } + + return ( From d61bfd875916a1d4fea13ddec225e995c6f9d932 Mon Sep 17 00:00:00 2001 From: Gert Hengeveld Date: Sat, 30 Mar 2024 21:42:03 +0100 Subject: [PATCH 11/37] Use button element for clickable notification --- .../notifications/NotificationItem.stories.tsx | 1 + .../src/components/notifications/NotificationItem.tsx | 10 +++++++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/code/ui/manager/src/components/notifications/NotificationItem.stories.tsx b/code/ui/manager/src/components/notifications/NotificationItem.stories.tsx index 13b20e0f7d99..e9c56c7fa060 100644 --- a/code/ui/manager/src/components/notifications/NotificationItem.stories.tsx +++ b/code/ui/manager/src/components/notifications/NotificationItem.stories.tsx @@ -53,6 +53,7 @@ export const Timeout: Story = { notification: { id: 'Timeout', onClear, + onClick, content: { headline: 'Storybook cool!', }, diff --git a/code/ui/manager/src/components/notifications/NotificationItem.tsx b/code/ui/manager/src/components/notifications/NotificationItem.tsx index 35403fab8296..d47f539a3f1c 100644 --- a/code/ui/manager/src/components/notifications/NotificationItem.tsx +++ b/code/ui/manager/src/components/notifications/NotificationItem.tsx @@ -61,6 +61,9 @@ const Notification = styled.div<{ duration?: number }>( const NotificationWithInteractiveStates = styled(Notification)(() => ({ cursor: 'pointer', + border: 'none', + outline: 'none', + textAlign: 'left', transition: 'all 150ms ease-out', transform: 'translate3d(0, 0, 0)', '&:hover': { @@ -75,9 +78,10 @@ const NotificationWithInteractiveStates = styled(Notification)(() => ({ }, '&:focus': { boxShadow: - '0 1px 3px 0 rgba(30,167,253,0.5), 0 2px 5px 0 rgba(0,0,0,0.05), 0 5px 15px 0 rgba(0,0,0,0.1)', + 'rgba(2,156,253,1) 0 0 0 1px inset, 0 1px 3px 0 rgba(30,167,253,0.5), 0 2px 5px 0 rgba(0,0,0,0.05), 0 5px 15px 0 rgba(0,0,0,0.1)', }, })); +const NotificationButton = NotificationWithInteractiveStates.withComponent('button'); const NotificationLink = NotificationWithInteractiveStates.withComponent(Link); const NotificationIconWrapper = styled.div(() => ({ @@ -207,10 +211,10 @@ const NotificationItem: FC<{ if (onClick) { return ( - onClick({ onDismiss })} duration={duration}> + onClick({ onDismiss })}> - + ); } From b280b720ad8ac7d92864e3781a9266539b97357e Mon Sep 17 00:00:00 2001 From: Gert Hengeveld Date: Sun, 31 Mar 2024 15:57:00 +0200 Subject: [PATCH 12/37] Verify callback functionality --- .../NotificationItem.stories.tsx | 23 ++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/code/ui/manager/src/components/notifications/NotificationItem.stories.tsx b/code/ui/manager/src/components/notifications/NotificationItem.stories.tsx index e9c56c7fa060..af4c7fcc8e57 100644 --- a/code/ui/manager/src/components/notifications/NotificationItem.stories.tsx +++ b/code/ui/manager/src/components/notifications/NotificationItem.stories.tsx @@ -8,6 +8,7 @@ import { BookIcon as BookIconIcon, FaceHappyIcon, } from '@storybook/icons'; +import { expect, fn, userEvent, waitFor, within } from '@storybook/test'; const meta = { component: NotificationItem, @@ -33,8 +34,8 @@ const meta = { export default meta; type Story = StoryObj; -const onClear = action('onClear'); -const onClick = action('onClick'); +const onClear = fn(action('onClear')); +const onClick = fn(action('onClick')); export const Simple: Story = { args: { @@ -57,9 +58,19 @@ export const Timeout: Story = { content: { headline: 'Storybook cool!', }, - duration: 5000, + duration: 3000, }, }, + play: async ({ args }) => { + await waitFor( + () => { + expect(args.notification.onClear).toHaveBeenCalledWith({ dismissed: false, timeout: true }); + }, + { + timeout: 4000, + } + ); + }, }; export const LongHeadline: Story = { @@ -86,6 +97,12 @@ export const Clickable: Story = { }, }, }, + play: async ({ args, canvasElement }) => { + const canvas = within(canvasElement); + const [button] = await canvas.findAllByRole('button'); + await userEvent.click(button); + await expect(args.notification.onClick).toHaveBeenCalledWith({ onDismiss: expect.anything() }); + }, }; export const Link: Story = { From aa6984a67eda912a5f7c01707d5e080c69198c44 Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Sun, 31 Mar 2024 21:51:06 +0200 Subject: [PATCH 13/37] Fix next/font transformation on Windows machines --- code/frameworks/nextjs/src/css/webpack.ts | 2 +- .../nextjs/src/font/webpack/configureNextFont.ts | 2 +- .../webpack/loader/storybook-nextjs-font-loader.ts | 13 +++++++++++-- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/code/frameworks/nextjs/src/css/webpack.ts b/code/frameworks/nextjs/src/css/webpack.ts index 75718527e7dd..a2723529e2fd 100644 --- a/code/frameworks/nextjs/src/css/webpack.ts +++ b/code/frameworks/nextjs/src/css/webpack.ts @@ -36,7 +36,7 @@ export const configureCss = (baseConfig: WebpackConfig, nextConfig: NextConfig): ], // We transform the "target.css" files from next.js into Javascript // for Next.js to support fonts, so it should be ignored by the css-loader. - exclude: /next\/.*\/target.css$/, + exclude: /next(\\|\/|\\\\).*(\\|\/|\\\\)target\.css/, }; } }); diff --git a/code/frameworks/nextjs/src/font/webpack/configureNextFont.ts b/code/frameworks/nextjs/src/font/webpack/configureNextFont.ts index b1e3851611d6..bd3f1640ff36 100644 --- a/code/frameworks/nextjs/src/font/webpack/configureNextFont.ts +++ b/code/frameworks/nextjs/src/font/webpack/configureNextFont.ts @@ -7,7 +7,7 @@ export function configureNextFont(baseConfig: Configuration, isSWC?: boolean) { if (isSWC) { baseConfig.module?.rules?.push({ - test: /next\/.*\/target.css$/, + test: /next(\\|\/|\\\\).*(\\|\/|\\\\)target\.css$/, loader: fontLoaderPath, }); } else { diff --git a/code/frameworks/nextjs/src/font/webpack/loader/storybook-nextjs-font-loader.ts b/code/frameworks/nextjs/src/font/webpack/loader/storybook-nextjs-font-loader.ts index 2110701aae61..055d934f57a4 100644 --- a/code/frameworks/nextjs/src/font/webpack/loader/storybook-nextjs-font-loader.ts +++ b/code/frameworks/nextjs/src/font/webpack/loader/storybook-nextjs-font-loader.ts @@ -3,6 +3,7 @@ import { getFontFaceDeclarations as getLocalFontFaceDeclarations } from './local import type { LoaderOptions } from './types'; import { getCSSMeta } from './utils/get-css-meta'; import { setFontDeclarationsInHead } from './utils/set-font-declarations-in-head'; +import path from 'path'; type FontFaceDeclaration = { id: string; @@ -39,11 +40,19 @@ export default async function storybookNextjsFontLoader(this: any) { let fontFaceDeclaration: FontFaceDeclaration | undefined; - if (options.source.endsWith('next/font/google') || options.source.endsWith('@next/font/google')) { + const pathSep = path.sep; + + if ( + options.source.endsWith(`next${pathSep}font${pathSep}google`) || + options.source.endsWith(`@next${pathSep}font${pathSep}google`) + ) { fontFaceDeclaration = await getGoogleFontFaceDeclarations(options); } - if (options.source.endsWith('next/font/local') || options.source.endsWith('@next/font/local')) { + if ( + options.source.endsWith(`next${pathSep}font${pathSep}local`) || + options.source.endsWith(`@next${pathSep}font${pathSep}local`) + ) { fontFaceDeclaration = await getLocalFontFaceDeclarations(options, rootCtx, swcMode); } From 4267475bdb68e6222942c2be1126902b37a39c40 Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Sun, 31 Mar 2024 21:52:20 +0200 Subject: [PATCH 14/37] Fix local next/fonts on Windows machines --- .../webpack/loader/local/get-font-face-declarations.ts | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/code/frameworks/nextjs/src/font/webpack/loader/local/get-font-face-declarations.ts b/code/frameworks/nextjs/src/font/webpack/loader/local/get-font-face-declarations.ts index f3f35c2fc065..e980d15b0e3d 100644 --- a/code/frameworks/nextjs/src/font/webpack/loader/local/get-font-face-declarations.ts +++ b/code/frameworks/nextjs/src/font/webpack/loader/local/get-font-face-declarations.ts @@ -39,13 +39,9 @@ export async function getFontFaceDeclarations( .map(({ prop, value }: { prop: string; value: string }) => `${prop}: ${value};`) .join('\n'); - const arePathsWin32Format = /^[a-z]:\\/iu.test(options.filename); - const cleanWin32Path = (pathString: string): string => - arePathsWin32Format ? pathString.replace(/\\/gu, '/') : pathString; - const getFontFaceCSS = () => { if (typeof localFontSrc === 'string') { - const localFontPath = cleanWin32Path(path.join(parentFolder, localFontSrc)); + const localFontPath = path.join(parentFolder, localFontSrc).replaceAll('\\', '/'); return `@font-face { font-family: ${id}; @@ -55,7 +51,7 @@ export async function getFontFaceDeclarations( } return localFontSrc .map((font) => { - const localFontPath = cleanWin32Path(path.join(parentFolder, font.path)); + const localFontPath = path.join(parentFolder, font.path).replaceAll('\\', '/'); return `@font-face { font-family: ${id}; From e40d7840ba89965a7aedfcbfc12c53acb6218d62 Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Sun, 31 Mar 2024 22:04:06 +0200 Subject: [PATCH 15/37] Escape . character in regex --- code/frameworks/nextjs/src/css/webpack.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/frameworks/nextjs/src/css/webpack.ts b/code/frameworks/nextjs/src/css/webpack.ts index a2723529e2fd..f6c7d7838f0a 100644 --- a/code/frameworks/nextjs/src/css/webpack.ts +++ b/code/frameworks/nextjs/src/css/webpack.ts @@ -36,7 +36,7 @@ export const configureCss = (baseConfig: WebpackConfig, nextConfig: NextConfig): ], // We transform the "target.css" files from next.js into Javascript // for Next.js to support fonts, so it should be ignored by the css-loader. - exclude: /next(\\|\/|\\\\).*(\\|\/|\\\\)target\.css/, + exclude: /next(\\|\/|\\\\).*(\\|\/|\\\\)target\.css$/, }; } }); From e6bbb1411f2aead6bd5a9c586e6c351ee5f5c4a9 Mon Sep 17 00:00:00 2001 From: Kyle Gach Date: Sun, 17 Mar 2024 21:09:57 -0600 Subject: [PATCH 16/37] WIP: Update multiple components guidance --- ...checked.ts.mdx => reuse-story-csf2.ts.mdx} | 15 +--- .../reuse-story-render-function.ts.mdx | 36 ++++++++++ .../reuse-story-csf2.js.mdx} | 8 +-- ...ts-4-9.mdx => reuse-story-csf2.ts-4-9.mdx} | 8 +-- ...checked.ts.mdx => reuse-story-csf2.ts.mdx} | 8 +-- .../react/reuse-story-portable.js.mdx | 22 ++++++ .../react/reuse-story-portable.ts-4-9.mdx | 26 +++++++ .../react/reuse-story-portable.ts.mdx | 29 ++++++++ .../reuse-story-csf2.js.mdx} | 8 +-- ...ts-4-9.mdx => reuse-story-csf2.ts-4-9.mdx} | 8 +-- ...checked.ts.mdx => reuse-story-csf2.ts.mdx} | 8 +-- .../solid/reuse-story-render-function.js.mdx | 19 +++++ .../reuse-story-render-function.ts-4-9.mdx | 24 +++++++ .../solid/reuse-story-render-function.ts.mdx | 24 +++++++ ...ecked.3.js.mdx => reuse-story-csf2.js.mdx} | 14 ++-- ...ts-4-9.mdx => reuse-story-csf2.ts-4-9.mdx} | 8 +-- ...ecked.3.ts.mdx => reuse-story-csf2.ts.mdx} | 8 +-- docs/snippets/vue/reuse-story-portable.js.mdx | 28 ++++++++ .../vue/reuse-story-portable.ts-4-9.mdx | 32 +++++++++ docs/snippets/vue/reuse-story-portable.ts.mdx | 32 +++++++++ ...checked.js.mdx => reuse-story-csf2.js.mdx} | 3 +- ...checked.ts.mdx => reuse-story-csf2.ts.mdx} | 3 +- .../reuse-story-render-function.js.mdx | 16 +++++ .../reuse-story-render-function.ts.mdx | 21 ++++++ .../stories-for-multiple-components.md | 69 +++++++++++++++---- 25 files changed, 381 insertions(+), 96 deletions(-) rename docs/snippets/angular/{list-story-unchecked.ts.mdx => reuse-story-csf2.ts.mdx} (63%) create mode 100644 docs/snippets/angular/reuse-story-render-function.ts.mdx rename docs/snippets/{solid/list-story-unchecked.js.mdx => react/reuse-story-csf2.js.mdx} (53%) rename docs/snippets/react/{list-story-unchecked.ts-4-9.mdx => reuse-story-csf2.ts-4-9.mdx} (64%) rename docs/snippets/react/{list-story-unchecked.ts.mdx => reuse-story-csf2.ts.mdx} (63%) create mode 100644 docs/snippets/react/reuse-story-portable.js.mdx create mode 100644 docs/snippets/react/reuse-story-portable.ts-4-9.mdx create mode 100644 docs/snippets/react/reuse-story-portable.ts.mdx rename docs/snippets/{react/list-story-unchecked.js.mdx => solid/reuse-story-csf2.js.mdx} (53%) rename docs/snippets/solid/{list-story-unchecked.ts-4-9.mdx => reuse-story-csf2.ts-4-9.mdx} (64%) rename docs/snippets/solid/{list-story-unchecked.ts.mdx => reuse-story-csf2.ts.mdx} (63%) create mode 100644 docs/snippets/solid/reuse-story-render-function.js.mdx create mode 100644 docs/snippets/solid/reuse-story-render-function.ts-4-9.mdx create mode 100644 docs/snippets/solid/reuse-story-render-function.ts.mdx rename docs/snippets/vue/{list-story-unchecked.3.js.mdx => reuse-story-csf2.js.mdx} (74%) rename docs/snippets/vue/{list-story-unchecked.3.ts-4-9.mdx => reuse-story-csf2.ts-4-9.mdx} (78%) rename docs/snippets/vue/{list-story-unchecked.3.ts.mdx => reuse-story-csf2.ts.mdx} (77%) create mode 100644 docs/snippets/vue/reuse-story-portable.js.mdx create mode 100644 docs/snippets/vue/reuse-story-portable.ts-4-9.mdx create mode 100644 docs/snippets/vue/reuse-story-portable.ts.mdx rename docs/snippets/web-components/{list-story-unchecked.js.mdx => reuse-story-csf2.js.mdx} (84%) rename docs/snippets/web-components/{list-story-unchecked.ts.mdx => reuse-story-csf2.ts.mdx} (88%) create mode 100644 docs/snippets/web-components/reuse-story-render-function.js.mdx create mode 100644 docs/snippets/web-components/reuse-story-render-function.ts.mdx diff --git a/docs/snippets/angular/list-story-unchecked.ts.mdx b/docs/snippets/angular/reuse-story-csf2.ts.mdx similarity index 63% rename from docs/snippets/angular/list-story-unchecked.ts.mdx rename to docs/snippets/angular/reuse-story-csf2.ts.mdx index 31b0be7651c7..968d8f6c12d5 100644 --- a/docs/snippets/angular/list-story-unchecked.ts.mdx +++ b/docs/snippets/angular/reuse-story-csf2.ts.mdx @@ -1,24 +1,16 @@ ```ts // List.stories.ts - import type { Meta, StoryObj } from '@storybook/angular'; - import { moduleMetadata } from '@storybook/angular'; - import { CommonModule } from '@angular/common'; import { List } from './list.component'; import { ListItem } from './list-item.component'; -//👇 Imports a specific story from ListItem stories +//👇 Import the story from the CSF 2 stories file import { Unchecked } from './ListItem.stories'; const meta: Meta = { - /* 👇 The title prop is optional. - * See https://storybook.js.org/docs/configure/#configure-story-loading - * to learn how to generate automatic titles - */ - title: 'List', component: List, decorators: [ moduleMetadata({ @@ -31,11 +23,6 @@ const meta: Meta = { export default meta; type Story = StoryObj; -/* - *👇 Render functions are a framework specific feature to allow you control on how the component renders. - * See https://storybook.js.org/docs/api/csf - * to learn how to use render functions. - */ export const OneItem: Story = { render: (args) => ({ props: args, diff --git a/docs/snippets/angular/reuse-story-render-function.ts.mdx b/docs/snippets/angular/reuse-story-render-function.ts.mdx new file mode 100644 index 000000000000..dd16565a95c1 --- /dev/null +++ b/docs/snippets/angular/reuse-story-render-function.ts.mdx @@ -0,0 +1,36 @@ +```ts +// List.stories.ts +import type { Meta, StoryObj } from '@storybook/angular'; +import { moduleMetadata } from '@storybook/angular'; +import { CommonModule } from '@angular/common'; + +import { List } from './list.component'; +import { ListItem } from './list-item.component'; + +//👇 Import the story with a render function from the CSF 3 stories file +import { Unchecked } from './ListItem.stories'; + +const meta: Meta = { + component: List, + decorators: [ + moduleMetadata({ + declarations: [List, ListItem], + imports: [CommonModule], + }), + ], +}; + +export default meta; +type Story = StoryObj; + +export const OneItem: Story = { + render: (args) => ({ + props: args, + template: ` + + ${Unchecked.render({ ...Unchecked.args })} + + `, + }), +}; +``` diff --git a/docs/snippets/solid/list-story-unchecked.js.mdx b/docs/snippets/react/reuse-story-csf2.js.mdx similarity index 53% rename from docs/snippets/solid/list-story-unchecked.js.mdx rename to docs/snippets/react/reuse-story-csf2.js.mdx index e9df70ee1467..24d8894648a9 100644 --- a/docs/snippets/solid/list-story-unchecked.js.mdx +++ b/docs/snippets/react/reuse-story-csf2.js.mdx @@ -1,17 +1,11 @@ ```js // List.stories.js|jsx - import { List } from './List'; -//👇 Instead of importing ListItem, we import the stories +//👇 Import the story from the CSF 2 stories file import { Unchecked } from './ListItem.stories'; export default { - /* 👇 The title prop is optional. - * See https://storybook.js.org/docs/configure/#configure-story-loading - * to learn how to generate automatic titles - */ - title: 'List', component: List, }; diff --git a/docs/snippets/react/list-story-unchecked.ts-4-9.mdx b/docs/snippets/react/reuse-story-csf2.ts-4-9.mdx similarity index 64% rename from docs/snippets/react/list-story-unchecked.ts-4-9.mdx rename to docs/snippets/react/reuse-story-csf2.ts-4-9.mdx index e3664a92818f..183ee1c2d037 100644 --- a/docs/snippets/react/list-story-unchecked.ts-4-9.mdx +++ b/docs/snippets/react/reuse-story-csf2.ts-4-9.mdx @@ -1,19 +1,13 @@ ```ts // List.stories.ts|tsx - import type { Meta, StoryObj } from '@storybook/react'; import { List } from './List'; -//👇 Instead of importing ListItem, we import the stories +//👇 Import the story from the CSF 2 stories file import { Unchecked } from './ListItem.stories'; export const meta = { - /* 👇 The title prop is optional. - * See https://storybook.js.org/docs/configure/#configure-story-loading - * to learn how to generate automatic titles - */ - title: 'List', component: List, } satisfies Meta; diff --git a/docs/snippets/react/list-story-unchecked.ts.mdx b/docs/snippets/react/reuse-story-csf2.ts.mdx similarity index 63% rename from docs/snippets/react/list-story-unchecked.ts.mdx rename to docs/snippets/react/reuse-story-csf2.ts.mdx index 8ff062ecc89f..2d7bc40aa229 100644 --- a/docs/snippets/react/list-story-unchecked.ts.mdx +++ b/docs/snippets/react/reuse-story-csf2.ts.mdx @@ -1,19 +1,13 @@ ```tsx // List.stories.ts|tsx - import type { Meta, StoryObj } from '@storybook/react'; import { List } from './List'; -//👇 Instead of importing ListItem, we import the stories +//👇 Import the story from the CSF 2 stories file import { Unchecked } from './ListItem.stories'; export const meta: Meta = { - /* 👇 The title prop is optional. - * See https://storybook.js.org/docs/configure/#configure-story-loading - * to learn how to generate automatic titles - */ - title: 'List', component: List, }; diff --git a/docs/snippets/react/reuse-story-portable.js.mdx b/docs/snippets/react/reuse-story-portable.js.mdx new file mode 100644 index 000000000000..205b04a171ed --- /dev/null +++ b/docs/snippets/react/reuse-story-portable.js.mdx @@ -0,0 +1,22 @@ +```js +// List.stories.js|jsx +import { composeStories } from '@storybook/react'; + +import { List } from './List'; + +//👇 Import the stories and their meta from the stories file +import * as stories from './ListItem.stories'; + +// 👇 Compose the story +const { Unchecked } = composeStories(stories); + +export default { + component: List, +}; + +export const OneItem = { + render: (args) => ( + + ), +}; +``` diff --git a/docs/snippets/react/reuse-story-portable.ts-4-9.mdx b/docs/snippets/react/reuse-story-portable.ts-4-9.mdx new file mode 100644 index 000000000000..24a54edbd7fc --- /dev/null +++ b/docs/snippets/react/reuse-story-portable.ts-4-9.mdx @@ -0,0 +1,26 @@ +```ts +// List.stories.ts|tsx +import type { Meta, StoryObj } from '@storybook/react'; +import { composeStories } from '@storybook/react'; + +import { List } from './List'; + +//👇 Import the stories and their meta from the stories file +import * as stories from './ListItem.stories'; + +// 👇 Compose the story +const { Unchecked } = composeStories(stories); + +export const meta = { + component: List, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const OneItem: Story = { + render: (args) => ( + + ), +}; +``` diff --git a/docs/snippets/react/reuse-story-portable.ts.mdx b/docs/snippets/react/reuse-story-portable.ts.mdx new file mode 100644 index 000000000000..c7e287a09b5f --- /dev/null +++ b/docs/snippets/react/reuse-story-portable.ts.mdx @@ -0,0 +1,29 @@ +```tsx +// List.stories.ts|tsx +import type { Meta, StoryObj } from '@storybook/react'; +import { composeStories } from '@storybook/react'; + +import { List } from './List'; + +//👇 Import the stories and their meta from the stories file +import * as stories from './ListItem.stories'; + +// 👇 Compose the story +const { Unchecked } = composeStories(stories); + +export const meta: Meta = { + component: List, +}; + +export default meta; +type Story = StoryObj; + +export const OneItem: Story = { + render: (args) => ( + + ), +}; +``` + + + diff --git a/docs/snippets/react/list-story-unchecked.js.mdx b/docs/snippets/solid/reuse-story-csf2.js.mdx similarity index 53% rename from docs/snippets/react/list-story-unchecked.js.mdx rename to docs/snippets/solid/reuse-story-csf2.js.mdx index e9df70ee1467..24d8894648a9 100644 --- a/docs/snippets/react/list-story-unchecked.js.mdx +++ b/docs/snippets/solid/reuse-story-csf2.js.mdx @@ -1,17 +1,11 @@ ```js // List.stories.js|jsx - import { List } from './List'; -//👇 Instead of importing ListItem, we import the stories +//👇 Import the story from the CSF 2 stories file import { Unchecked } from './ListItem.stories'; export default { - /* 👇 The title prop is optional. - * See https://storybook.js.org/docs/configure/#configure-story-loading - * to learn how to generate automatic titles - */ - title: 'List', component: List, }; diff --git a/docs/snippets/solid/list-story-unchecked.ts-4-9.mdx b/docs/snippets/solid/reuse-story-csf2.ts-4-9.mdx similarity index 64% rename from docs/snippets/solid/list-story-unchecked.ts-4-9.mdx rename to docs/snippets/solid/reuse-story-csf2.ts-4-9.mdx index c88e42c9dbed..79ebacf11f73 100644 --- a/docs/snippets/solid/list-story-unchecked.ts-4-9.mdx +++ b/docs/snippets/solid/reuse-story-csf2.ts-4-9.mdx @@ -1,19 +1,13 @@ ```tsx // List.stories.ts|tsx - import type { Meta, StoryObj } from 'storybook-solidjs'; import { List } from './List'; -//👇 Instead of importing ListItem, we import the stories +//👇 Import the story from the CSF 2 stories file import { Unchecked } from './ListItem.stories'; export const meta = { - /* 👇 The title prop is optional. - * See https://storybook.js.org/docs/configure/#configure-story-loading - * to learn how to generate automatic titles - */ - title: 'List', component: List, } satisfies Meta; diff --git a/docs/snippets/solid/list-story-unchecked.ts.mdx b/docs/snippets/solid/reuse-story-csf2.ts.mdx similarity index 63% rename from docs/snippets/solid/list-story-unchecked.ts.mdx rename to docs/snippets/solid/reuse-story-csf2.ts.mdx index 30cc4d698609..ed0e86ec488f 100644 --- a/docs/snippets/solid/list-story-unchecked.ts.mdx +++ b/docs/snippets/solid/reuse-story-csf2.ts.mdx @@ -1,19 +1,13 @@ ```tsx // List.stories.ts|tsx - import type { Meta, StoryObj } from 'storybook-solidjs'; import { List } from './List'; -//👇 Instead of importing ListItem, we import the stories +//👇 Import the story from the CSF 2 stories file import { Unchecked } from './ListItem.stories'; export const meta: Meta = { - /* 👇 The title prop is optional. - * See https://storybook.js.org/docs/configure/#configure-story-loading - * to learn how to generate automatic titles - */ - title: 'List', component: List, }; diff --git a/docs/snippets/solid/reuse-story-render-function.js.mdx b/docs/snippets/solid/reuse-story-render-function.js.mdx new file mode 100644 index 000000000000..5d9511565367 --- /dev/null +++ b/docs/snippets/solid/reuse-story-render-function.js.mdx @@ -0,0 +1,19 @@ +```js +// List.stories.js|jsx +import { List } from './List'; + +//👇 Import the story with a render function from the CSF 3 stories file +import { Unchecked } from './ListItem.stories'; + +export default { + component: List, +}; + +export const OneItem = { + render: (args) => ( + + {Unchecked.render({...Unchecked.args})} + + ), +}; +``` diff --git a/docs/snippets/solid/reuse-story-render-function.ts-4-9.mdx b/docs/snippets/solid/reuse-story-render-function.ts-4-9.mdx new file mode 100644 index 000000000000..2bc85bc8e315 --- /dev/null +++ b/docs/snippets/solid/reuse-story-render-function.ts-4-9.mdx @@ -0,0 +1,24 @@ +```tsx +// List.stories.ts|tsx +import type { Meta, StoryObj } from 'storybook-solidjs'; + +import { List } from './List'; + +//👇 Import the story with a render function from the CSF 3 stories file +import { Unchecked } from './ListItem.stories'; + +export const meta = { + component: List, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const OneItem: Story = { + render: (args) => ( + + {Unchecked.render({...Unchecked.args})} + + ), +}; +``` diff --git a/docs/snippets/solid/reuse-story-render-function.ts.mdx b/docs/snippets/solid/reuse-story-render-function.ts.mdx new file mode 100644 index 000000000000..42ad3235ffd6 --- /dev/null +++ b/docs/snippets/solid/reuse-story-render-function.ts.mdx @@ -0,0 +1,24 @@ +```tsx +// List.stories.ts|tsx +import type { Meta, StoryObj } from 'storybook-solidjs'; + +import { List } from './List'; + +//👇 Import the story with a render function from the CSF 3 stories file +import { Unchecked } from './ListItem.stories'; + +export const meta: Meta = { + component: List, +}; + +export default meta; +type Story = StoryObj; + +export const OneItem: Story = { + render: (args) => ( + + {Unchecked.render({...Unchecked.args})}> + + ), +}; +``` diff --git a/docs/snippets/vue/list-story-unchecked.3.js.mdx b/docs/snippets/vue/reuse-story-csf2.js.mdx similarity index 74% rename from docs/snippets/vue/list-story-unchecked.3.js.mdx rename to docs/snippets/vue/reuse-story-csf2.js.mdx index 8d521c737efe..3499760b547b 100644 --- a/docs/snippets/vue/list-story-unchecked.3.js.mdx +++ b/docs/snippets/vue/reuse-story-csf2.js.mdx @@ -1,18 +1,12 @@ ```js // List.stories.js - import List from './List.vue'; import ListItem from './ListItem.vue'; -//👇 Imports a specific story from ListItem stories +//👇 Import the story from the CSF 2 stories file import { Unchecked } from './ListItem.stories'; export default { - /* 👇 The title prop is optional. - * See https://storybook.js.org/docs/configure/#configure-story-loading - * to learn how to generate automatic titles - */ - title: 'List', component: List, }; @@ -22,9 +16,6 @@ export default { * to learn how to use render functions. */ export const OneItem = { - args: { - ...Unchecked.args, - }, render: (args) => ({ components: { List, ListItem }, setup() { @@ -33,5 +24,8 @@ export const OneItem = { }, template: '', }), + args: { + ...Unchecked.args, + }, }; ``` diff --git a/docs/snippets/vue/list-story-unchecked.3.ts-4-9.mdx b/docs/snippets/vue/reuse-story-csf2.ts-4-9.mdx similarity index 78% rename from docs/snippets/vue/list-story-unchecked.3.ts-4-9.mdx rename to docs/snippets/vue/reuse-story-csf2.ts-4-9.mdx index 478e65d6f878..068f78d8006e 100644 --- a/docs/snippets/vue/list-story-unchecked.3.ts-4-9.mdx +++ b/docs/snippets/vue/reuse-story-csf2.ts-4-9.mdx @@ -1,20 +1,14 @@ ```ts // List.stories.js - import type { Meta, StoryObj } from '@storybook/vue3'; import List from './List.vue'; import ListItem from './ListItem.vue'; -//👇 Imports a specific story from ListItem stories +//👇 Import the story from the CSF 2 stories file import { Unchecked } from './ListItem.stories'; const meta = { - /* 👇 The title prop is optional. - * See https://storybook.js.org/docs/configure/#configure-story-loading - * to learn how to generate automatic titles - */ - title: 'List', component: List, } satisfies Meta; diff --git a/docs/snippets/vue/list-story-unchecked.3.ts.mdx b/docs/snippets/vue/reuse-story-csf2.ts.mdx similarity index 77% rename from docs/snippets/vue/list-story-unchecked.3.ts.mdx rename to docs/snippets/vue/reuse-story-csf2.ts.mdx index d928c99296a3..fd99cc271851 100644 --- a/docs/snippets/vue/list-story-unchecked.3.ts.mdx +++ b/docs/snippets/vue/reuse-story-csf2.ts.mdx @@ -1,20 +1,14 @@ ```ts // List.stories.js - import type { Meta, StoryObj } from '@storybook/vue3'; import List from './List.vue'; import ListItem from './ListItem.vue'; -//👇 Imports a specific story from ListItem stories +//👇 Import the story from the CSF 2 stories file import { Unchecked } from './ListItem.stories'; const meta: Meta = { - /* 👇 The title prop is optional. - * See https://storybook.js.org/docs/configure/#configure-story-loading - * to learn how to generate automatic titles - */ - title: 'List', component: List, }; diff --git a/docs/snippets/vue/reuse-story-portable.js.mdx b/docs/snippets/vue/reuse-story-portable.js.mdx new file mode 100644 index 000000000000..a2a57cbb1c5b --- /dev/null +++ b/docs/snippets/vue/reuse-story-portable.js.mdx @@ -0,0 +1,28 @@ +```js +// List.stories.js +import { composeStories } from '@storybook/vue3' + +import List from './List.vue'; +import ListItem from './ListItem.vue'; + +//👇 Import the stories and their meta from the stories file +import * as stories from './ListItem.stories'; + +//👇 Compose the story +const { Unchecked } = composeStories(stories); + +export default { + component: List, +}; + +export const OneItem = { + render: (args) => ({ + components: { List, ListItem }, + setup() { + //👇 The args will now be passed down to the template + return { args }; + }, + template: '', + }), +}; +``` diff --git a/docs/snippets/vue/reuse-story-portable.ts-4-9.mdx b/docs/snippets/vue/reuse-story-portable.ts-4-9.mdx new file mode 100644 index 000000000000..964ffbb467e9 --- /dev/null +++ b/docs/snippets/vue/reuse-story-portable.ts-4-9.mdx @@ -0,0 +1,32 @@ +```ts +// List.stories.js +import type { Meta, StoryObj } from '@storybook/vue3'; +import { composeStories } from '@storybook/vue3' + +import List from './List.vue'; +import ListItem from './ListItem.vue'; + +//👇 Import the stories and their meta from the stories file +import * as stories from './ListItem.stories'; + +//👇 Compose the story +const { Unchecked } = composeStories(stories); + +const meta = { + component: List, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const OneItem: Story = { + render: (args) => ({ + components: { List, ListItem }, + setup() { + //👇 The args will now be passed down to the template + return { args }; + }, + template: '', + }), +}; +``` diff --git a/docs/snippets/vue/reuse-story-portable.ts.mdx b/docs/snippets/vue/reuse-story-portable.ts.mdx new file mode 100644 index 000000000000..eab1b1ea72b9 --- /dev/null +++ b/docs/snippets/vue/reuse-story-portable.ts.mdx @@ -0,0 +1,32 @@ +```ts +// List.stories.js +import type { Meta, StoryObj } from '@storybook/vue3'; +import { composeStories } from '@storybook/vue3' + +import List from './List.vue'; +import ListItem from './ListItem.vue'; + +//👇 Import the stories and their meta from the stories file +import * as stories from './ListItem.stories'; + +//👇 Compose the story +const { Unchecked } = composeStories(stories); + +const meta: Meta = { + component: List, +}; + +export default meta; +type Story = StoryObj; + +export const OneItem: Story = { + render: (args) => ({ + components: { List, ListItem }, + setup() { + //👇 The args will now be passed down to the template + return { args }; + }, + template: '', + }), +}; +``` diff --git a/docs/snippets/web-components/list-story-unchecked.js.mdx b/docs/snippets/web-components/reuse-story-csf2.js.mdx similarity index 84% rename from docs/snippets/web-components/list-story-unchecked.js.mdx rename to docs/snippets/web-components/reuse-story-csf2.js.mdx index be30704c8341..0b04e69da378 100644 --- a/docs/snippets/web-components/list-story-unchecked.js.mdx +++ b/docs/snippets/web-components/reuse-story-csf2.js.mdx @@ -1,9 +1,8 @@ ```js // MyList.stories.js - import { html } from 'lit'; -// 👇 Import the stories of MyListItem +//👇 Import the story from the CSF 2 stories file import { Unchecked } from './MyListItem.stories'; export default { diff --git a/docs/snippets/web-components/list-story-unchecked.ts.mdx b/docs/snippets/web-components/reuse-story-csf2.ts.mdx similarity index 88% rename from docs/snippets/web-components/list-story-unchecked.ts.mdx rename to docs/snippets/web-components/reuse-story-csf2.ts.mdx index 80c135f68a4f..1b6ca2af48ab 100644 --- a/docs/snippets/web-components/list-story-unchecked.ts.mdx +++ b/docs/snippets/web-components/reuse-story-csf2.ts.mdx @@ -1,11 +1,10 @@ ```ts // MyList.stories.ts - import { Meta, StoryObj } from '@storybook/web-components'; import { html } from 'lit'; -// 👇 Import the stories of MyListItem +//👇 Import the story from the CSF 2 stories file import { Unchecked } from './my-list-item.stories'; const meta: Meta = { diff --git a/docs/snippets/web-components/reuse-story-render-function.js.mdx b/docs/snippets/web-components/reuse-story-render-function.js.mdx new file mode 100644 index 000000000000..57ac1aa0fbd8 --- /dev/null +++ b/docs/snippets/web-components/reuse-story-render-function.js.mdx @@ -0,0 +1,16 @@ +```js +// MyList.stories.js +import { html } from 'lit'; + +//👇 Import the story with a render function from the CSF 3 stories file +import { Unchecked } from './MyListItem.stories'; + +export default { + title: 'MyList', + component: 'demo-my-list', +}; + +export const OneItem = { + render: () => html` ${Unchecked.render({ ...Unchecked.args })} `, +}; +``` diff --git a/docs/snippets/web-components/reuse-story-render-function.ts.mdx b/docs/snippets/web-components/reuse-story-render-function.ts.mdx new file mode 100644 index 000000000000..f77d65410fc7 --- /dev/null +++ b/docs/snippets/web-components/reuse-story-render-function.ts.mdx @@ -0,0 +1,21 @@ +```ts +// MyList.stories.ts +import { Meta, StoryObj } from '@storybook/web-components'; + +import { html } from 'lit'; + +//👇 Import the story with a render function from the CSF 3 stories file +import { Unchecked } from './my-list-item.stories'; + +const meta: Meta = { + title: 'MyList', + component: 'demo-my-list', +}; +export default meta; + +type Story = StoryObj; + +export const OneItem: Story = { + render: () => html` ${Unchecked.render({ ...Unchecked.args })} `, +}; +``` diff --git a/docs/writing-stories/stories-for-multiple-components.md b/docs/writing-stories/stories-for-multiple-components.md index 708ccce28787..2c326f5b1c46 100644 --- a/docs/writing-stories/stories-for-multiple-components.md +++ b/docs/writing-stories/stories-for-multiple-components.md @@ -2,7 +2,7 @@ title: 'Stories for multiple components' --- -It's useful to write stories that [render two or more components](../writing-stories/index.md#stories-for-two-or-more-components) at once if those components are designed to work together. For example, `ButtonGroups`, `Lists`, and `Page` components. Here's an example with `List` and `ListItem` components: +It's useful to write stories that [render two or more components](../writing-stories/index.md#stories-for-two-or-more-components) at once if those components are designed to work together. For example, `ButtonGroup` or `List` components. Here's an example with `List` and `ListItem` components: @@ -35,28 +35,71 @@ Let's talk about some techniques you can use to mitigate the above, which are es ## Reusing subcomponent stories -The simplest change we can make to the above is to reuse the stories of the `ListItem` in the `List`: +We can also reuse the stories of the `ListItem` subcomponent in `List` stories. + +If the story to be reused is written in [CSF 2](../../../release-6-5/docs/api/csf.md), we can reuse it directly: + + + + + + + + + +If the story to be reused is written in [CSF 3](../api/csf.md), we can reuse it by composing it into a [portable story](../api/portable-stories-jest.md): + + + + + +If the story to be reused is written in [CSF 3](../api/csf.md) and defines a [`render` function](../api/csf.md#custom-render-functions), we can use that `render` function to reuse the story: + + + + + + + + + + By rendering the `Unchecked` story with its args, we are able to reuse the input data from the `ListItem` stories in the `List`. However, we still aren’t using args to control the `ListItem` stories, which means we cannot change them with controls and we cannot reuse them in other, more complex component stories. @@ -65,6 +108,8 @@ However, we still aren’t using args to control the `ListItem` stories, which m One way we improve that situation is by pulling the rendered subcomponent out into a `children` arg: + + Date: Wed, 20 Mar 2024 14:12:31 -0600 Subject: [PATCH 17/37] Revert "WIP: Update multiple components guidance" This reverts commit dba4179e2f4ca8a9c8669ecd28f36ca41f449a08. --- ...sf2.ts.mdx => list-story-unchecked.ts.mdx} | 15 +++- .../reuse-story-render-function.ts.mdx | 36 ---------- .../list-story-unchecked.js.mdx} | 8 ++- ...-9.mdx => list-story-unchecked.ts-4-9.mdx} | 8 ++- ...sf2.ts.mdx => list-story-unchecked.ts.mdx} | 8 ++- .../react/reuse-story-portable.js.mdx | 22 ------ .../react/reuse-story-portable.ts-4-9.mdx | 26 ------- .../react/reuse-story-portable.ts.mdx | 29 -------- .../list-story-unchecked.js.mdx} | 8 ++- ...-9.mdx => list-story-unchecked.ts-4-9.mdx} | 8 ++- ...sf2.ts.mdx => list-story-unchecked.ts.mdx} | 8 ++- .../solid/reuse-story-render-function.js.mdx | 19 ----- .../reuse-story-render-function.ts-4-9.mdx | 24 ------- .../solid/reuse-story-render-function.ts.mdx | 24 ------- ...2.js.mdx => list-story-unchecked.3.js.mdx} | 14 ++-- ....mdx => list-story-unchecked.3.ts-4-9.mdx} | 8 ++- ...2.ts.mdx => list-story-unchecked.3.ts.mdx} | 8 ++- docs/snippets/vue/reuse-story-portable.js.mdx | 28 -------- .../vue/reuse-story-portable.ts-4-9.mdx | 32 --------- docs/snippets/vue/reuse-story-portable.ts.mdx | 32 --------- ...sf2.js.mdx => list-story-unchecked.js.mdx} | 3 +- ...sf2.ts.mdx => list-story-unchecked.ts.mdx} | 3 +- .../reuse-story-render-function.js.mdx | 16 ----- .../reuse-story-render-function.ts.mdx | 21 ------ .../stories-for-multiple-components.md | 69 ++++--------------- 25 files changed, 96 insertions(+), 381 deletions(-) rename docs/snippets/angular/{reuse-story-csf2.ts.mdx => list-story-unchecked.ts.mdx} (63%) delete mode 100644 docs/snippets/angular/reuse-story-render-function.ts.mdx rename docs/snippets/{solid/reuse-story-csf2.js.mdx => react/list-story-unchecked.js.mdx} (53%) rename docs/snippets/react/{reuse-story-csf2.ts-4-9.mdx => list-story-unchecked.ts-4-9.mdx} (64%) rename docs/snippets/react/{reuse-story-csf2.ts.mdx => list-story-unchecked.ts.mdx} (63%) delete mode 100644 docs/snippets/react/reuse-story-portable.js.mdx delete mode 100644 docs/snippets/react/reuse-story-portable.ts-4-9.mdx delete mode 100644 docs/snippets/react/reuse-story-portable.ts.mdx rename docs/snippets/{react/reuse-story-csf2.js.mdx => solid/list-story-unchecked.js.mdx} (53%) rename docs/snippets/solid/{reuse-story-csf2.ts-4-9.mdx => list-story-unchecked.ts-4-9.mdx} (64%) rename docs/snippets/solid/{reuse-story-csf2.ts.mdx => list-story-unchecked.ts.mdx} (63%) delete mode 100644 docs/snippets/solid/reuse-story-render-function.js.mdx delete mode 100644 docs/snippets/solid/reuse-story-render-function.ts-4-9.mdx delete mode 100644 docs/snippets/solid/reuse-story-render-function.ts.mdx rename docs/snippets/vue/{reuse-story-csf2.js.mdx => list-story-unchecked.3.js.mdx} (74%) rename docs/snippets/vue/{reuse-story-csf2.ts-4-9.mdx => list-story-unchecked.3.ts-4-9.mdx} (78%) rename docs/snippets/vue/{reuse-story-csf2.ts.mdx => list-story-unchecked.3.ts.mdx} (77%) delete mode 100644 docs/snippets/vue/reuse-story-portable.js.mdx delete mode 100644 docs/snippets/vue/reuse-story-portable.ts-4-9.mdx delete mode 100644 docs/snippets/vue/reuse-story-portable.ts.mdx rename docs/snippets/web-components/{reuse-story-csf2.js.mdx => list-story-unchecked.js.mdx} (84%) rename docs/snippets/web-components/{reuse-story-csf2.ts.mdx => list-story-unchecked.ts.mdx} (88%) delete mode 100644 docs/snippets/web-components/reuse-story-render-function.js.mdx delete mode 100644 docs/snippets/web-components/reuse-story-render-function.ts.mdx diff --git a/docs/snippets/angular/reuse-story-csf2.ts.mdx b/docs/snippets/angular/list-story-unchecked.ts.mdx similarity index 63% rename from docs/snippets/angular/reuse-story-csf2.ts.mdx rename to docs/snippets/angular/list-story-unchecked.ts.mdx index 968d8f6c12d5..31b0be7651c7 100644 --- a/docs/snippets/angular/reuse-story-csf2.ts.mdx +++ b/docs/snippets/angular/list-story-unchecked.ts.mdx @@ -1,16 +1,24 @@ ```ts // List.stories.ts + import type { Meta, StoryObj } from '@storybook/angular'; + import { moduleMetadata } from '@storybook/angular'; + import { CommonModule } from '@angular/common'; import { List } from './list.component'; import { ListItem } from './list-item.component'; -//👇 Import the story from the CSF 2 stories file +//👇 Imports a specific story from ListItem stories import { Unchecked } from './ListItem.stories'; const meta: Meta = { + /* 👇 The title prop is optional. + * See https://storybook.js.org/docs/configure/#configure-story-loading + * to learn how to generate automatic titles + */ + title: 'List', component: List, decorators: [ moduleMetadata({ @@ -23,6 +31,11 @@ const meta: Meta = { export default meta; type Story = StoryObj; +/* + *👇 Render functions are a framework specific feature to allow you control on how the component renders. + * See https://storybook.js.org/docs/api/csf + * to learn how to use render functions. + */ export const OneItem: Story = { render: (args) => ({ props: args, diff --git a/docs/snippets/angular/reuse-story-render-function.ts.mdx b/docs/snippets/angular/reuse-story-render-function.ts.mdx deleted file mode 100644 index dd16565a95c1..000000000000 --- a/docs/snippets/angular/reuse-story-render-function.ts.mdx +++ /dev/null @@ -1,36 +0,0 @@ -```ts -// List.stories.ts -import type { Meta, StoryObj } from '@storybook/angular'; -import { moduleMetadata } from '@storybook/angular'; -import { CommonModule } from '@angular/common'; - -import { List } from './list.component'; -import { ListItem } from './list-item.component'; - -//👇 Import the story with a render function from the CSF 3 stories file -import { Unchecked } from './ListItem.stories'; - -const meta: Meta = { - component: List, - decorators: [ - moduleMetadata({ - declarations: [List, ListItem], - imports: [CommonModule], - }), - ], -}; - -export default meta; -type Story = StoryObj; - -export const OneItem: Story = { - render: (args) => ({ - props: args, - template: ` - - ${Unchecked.render({ ...Unchecked.args })} - - `, - }), -}; -``` diff --git a/docs/snippets/solid/reuse-story-csf2.js.mdx b/docs/snippets/react/list-story-unchecked.js.mdx similarity index 53% rename from docs/snippets/solid/reuse-story-csf2.js.mdx rename to docs/snippets/react/list-story-unchecked.js.mdx index 24d8894648a9..e9df70ee1467 100644 --- a/docs/snippets/solid/reuse-story-csf2.js.mdx +++ b/docs/snippets/react/list-story-unchecked.js.mdx @@ -1,11 +1,17 @@ ```js // List.stories.js|jsx + import { List } from './List'; -//👇 Import the story from the CSF 2 stories file +//👇 Instead of importing ListItem, we import the stories import { Unchecked } from './ListItem.stories'; export default { + /* 👇 The title prop is optional. + * See https://storybook.js.org/docs/configure/#configure-story-loading + * to learn how to generate automatic titles + */ + title: 'List', component: List, }; diff --git a/docs/snippets/react/reuse-story-csf2.ts-4-9.mdx b/docs/snippets/react/list-story-unchecked.ts-4-9.mdx similarity index 64% rename from docs/snippets/react/reuse-story-csf2.ts-4-9.mdx rename to docs/snippets/react/list-story-unchecked.ts-4-9.mdx index 183ee1c2d037..e3664a92818f 100644 --- a/docs/snippets/react/reuse-story-csf2.ts-4-9.mdx +++ b/docs/snippets/react/list-story-unchecked.ts-4-9.mdx @@ -1,13 +1,19 @@ ```ts // List.stories.ts|tsx + import type { Meta, StoryObj } from '@storybook/react'; import { List } from './List'; -//👇 Import the story from the CSF 2 stories file +//👇 Instead of importing ListItem, we import the stories import { Unchecked } from './ListItem.stories'; export const meta = { + /* 👇 The title prop is optional. + * See https://storybook.js.org/docs/configure/#configure-story-loading + * to learn how to generate automatic titles + */ + title: 'List', component: List, } satisfies Meta; diff --git a/docs/snippets/react/reuse-story-csf2.ts.mdx b/docs/snippets/react/list-story-unchecked.ts.mdx similarity index 63% rename from docs/snippets/react/reuse-story-csf2.ts.mdx rename to docs/snippets/react/list-story-unchecked.ts.mdx index 2d7bc40aa229..8ff062ecc89f 100644 --- a/docs/snippets/react/reuse-story-csf2.ts.mdx +++ b/docs/snippets/react/list-story-unchecked.ts.mdx @@ -1,13 +1,19 @@ ```tsx // List.stories.ts|tsx + import type { Meta, StoryObj } from '@storybook/react'; import { List } from './List'; -//👇 Import the story from the CSF 2 stories file +//👇 Instead of importing ListItem, we import the stories import { Unchecked } from './ListItem.stories'; export const meta: Meta = { + /* 👇 The title prop is optional. + * See https://storybook.js.org/docs/configure/#configure-story-loading + * to learn how to generate automatic titles + */ + title: 'List', component: List, }; diff --git a/docs/snippets/react/reuse-story-portable.js.mdx b/docs/snippets/react/reuse-story-portable.js.mdx deleted file mode 100644 index 205b04a171ed..000000000000 --- a/docs/snippets/react/reuse-story-portable.js.mdx +++ /dev/null @@ -1,22 +0,0 @@ -```js -// List.stories.js|jsx -import { composeStories } from '@storybook/react'; - -import { List } from './List'; - -//👇 Import the stories and their meta from the stories file -import * as stories from './ListItem.stories'; - -// 👇 Compose the story -const { Unchecked } = composeStories(stories); - -export default { - component: List, -}; - -export const OneItem = { - render: (args) => ( - - ), -}; -``` diff --git a/docs/snippets/react/reuse-story-portable.ts-4-9.mdx b/docs/snippets/react/reuse-story-portable.ts-4-9.mdx deleted file mode 100644 index 24a54edbd7fc..000000000000 --- a/docs/snippets/react/reuse-story-portable.ts-4-9.mdx +++ /dev/null @@ -1,26 +0,0 @@ -```ts -// List.stories.ts|tsx -import type { Meta, StoryObj } from '@storybook/react'; -import { composeStories } from '@storybook/react'; - -import { List } from './List'; - -//👇 Import the stories and their meta from the stories file -import * as stories from './ListItem.stories'; - -// 👇 Compose the story -const { Unchecked } = composeStories(stories); - -export const meta = { - component: List, -} satisfies Meta; - -export default meta; -type Story = StoryObj; - -export const OneItem: Story = { - render: (args) => ( - - ), -}; -``` diff --git a/docs/snippets/react/reuse-story-portable.ts.mdx b/docs/snippets/react/reuse-story-portable.ts.mdx deleted file mode 100644 index c7e287a09b5f..000000000000 --- a/docs/snippets/react/reuse-story-portable.ts.mdx +++ /dev/null @@ -1,29 +0,0 @@ -```tsx -// List.stories.ts|tsx -import type { Meta, StoryObj } from '@storybook/react'; -import { composeStories } from '@storybook/react'; - -import { List } from './List'; - -//👇 Import the stories and their meta from the stories file -import * as stories from './ListItem.stories'; - -// 👇 Compose the story -const { Unchecked } = composeStories(stories); - -export const meta: Meta = { - component: List, -}; - -export default meta; -type Story = StoryObj; - -export const OneItem: Story = { - render: (args) => ( - - ), -}; -``` - - - diff --git a/docs/snippets/react/reuse-story-csf2.js.mdx b/docs/snippets/solid/list-story-unchecked.js.mdx similarity index 53% rename from docs/snippets/react/reuse-story-csf2.js.mdx rename to docs/snippets/solid/list-story-unchecked.js.mdx index 24d8894648a9..e9df70ee1467 100644 --- a/docs/snippets/react/reuse-story-csf2.js.mdx +++ b/docs/snippets/solid/list-story-unchecked.js.mdx @@ -1,11 +1,17 @@ ```js // List.stories.js|jsx + import { List } from './List'; -//👇 Import the story from the CSF 2 stories file +//👇 Instead of importing ListItem, we import the stories import { Unchecked } from './ListItem.stories'; export default { + /* 👇 The title prop is optional. + * See https://storybook.js.org/docs/configure/#configure-story-loading + * to learn how to generate automatic titles + */ + title: 'List', component: List, }; diff --git a/docs/snippets/solid/reuse-story-csf2.ts-4-9.mdx b/docs/snippets/solid/list-story-unchecked.ts-4-9.mdx similarity index 64% rename from docs/snippets/solid/reuse-story-csf2.ts-4-9.mdx rename to docs/snippets/solid/list-story-unchecked.ts-4-9.mdx index 79ebacf11f73..c88e42c9dbed 100644 --- a/docs/snippets/solid/reuse-story-csf2.ts-4-9.mdx +++ b/docs/snippets/solid/list-story-unchecked.ts-4-9.mdx @@ -1,13 +1,19 @@ ```tsx // List.stories.ts|tsx + import type { Meta, StoryObj } from 'storybook-solidjs'; import { List } from './List'; -//👇 Import the story from the CSF 2 stories file +//👇 Instead of importing ListItem, we import the stories import { Unchecked } from './ListItem.stories'; export const meta = { + /* 👇 The title prop is optional. + * See https://storybook.js.org/docs/configure/#configure-story-loading + * to learn how to generate automatic titles + */ + title: 'List', component: List, } satisfies Meta; diff --git a/docs/snippets/solid/reuse-story-csf2.ts.mdx b/docs/snippets/solid/list-story-unchecked.ts.mdx similarity index 63% rename from docs/snippets/solid/reuse-story-csf2.ts.mdx rename to docs/snippets/solid/list-story-unchecked.ts.mdx index ed0e86ec488f..30cc4d698609 100644 --- a/docs/snippets/solid/reuse-story-csf2.ts.mdx +++ b/docs/snippets/solid/list-story-unchecked.ts.mdx @@ -1,13 +1,19 @@ ```tsx // List.stories.ts|tsx + import type { Meta, StoryObj } from 'storybook-solidjs'; import { List } from './List'; -//👇 Import the story from the CSF 2 stories file +//👇 Instead of importing ListItem, we import the stories import { Unchecked } from './ListItem.stories'; export const meta: Meta = { + /* 👇 The title prop is optional. + * See https://storybook.js.org/docs/configure/#configure-story-loading + * to learn how to generate automatic titles + */ + title: 'List', component: List, }; diff --git a/docs/snippets/solid/reuse-story-render-function.js.mdx b/docs/snippets/solid/reuse-story-render-function.js.mdx deleted file mode 100644 index 5d9511565367..000000000000 --- a/docs/snippets/solid/reuse-story-render-function.js.mdx +++ /dev/null @@ -1,19 +0,0 @@ -```js -// List.stories.js|jsx -import { List } from './List'; - -//👇 Import the story with a render function from the CSF 3 stories file -import { Unchecked } from './ListItem.stories'; - -export default { - component: List, -}; - -export const OneItem = { - render: (args) => ( - - {Unchecked.render({...Unchecked.args})} - - ), -}; -``` diff --git a/docs/snippets/solid/reuse-story-render-function.ts-4-9.mdx b/docs/snippets/solid/reuse-story-render-function.ts-4-9.mdx deleted file mode 100644 index 2bc85bc8e315..000000000000 --- a/docs/snippets/solid/reuse-story-render-function.ts-4-9.mdx +++ /dev/null @@ -1,24 +0,0 @@ -```tsx -// List.stories.ts|tsx -import type { Meta, StoryObj } from 'storybook-solidjs'; - -import { List } from './List'; - -//👇 Import the story with a render function from the CSF 3 stories file -import { Unchecked } from './ListItem.stories'; - -export const meta = { - component: List, -} satisfies Meta; - -export default meta; -type Story = StoryObj; - -export const OneItem: Story = { - render: (args) => ( - - {Unchecked.render({...Unchecked.args})} - - ), -}; -``` diff --git a/docs/snippets/solid/reuse-story-render-function.ts.mdx b/docs/snippets/solid/reuse-story-render-function.ts.mdx deleted file mode 100644 index 42ad3235ffd6..000000000000 --- a/docs/snippets/solid/reuse-story-render-function.ts.mdx +++ /dev/null @@ -1,24 +0,0 @@ -```tsx -// List.stories.ts|tsx -import type { Meta, StoryObj } from 'storybook-solidjs'; - -import { List } from './List'; - -//👇 Import the story with a render function from the CSF 3 stories file -import { Unchecked } from './ListItem.stories'; - -export const meta: Meta = { - component: List, -}; - -export default meta; -type Story = StoryObj; - -export const OneItem: Story = { - render: (args) => ( - - {Unchecked.render({...Unchecked.args})}> - - ), -}; -``` diff --git a/docs/snippets/vue/reuse-story-csf2.js.mdx b/docs/snippets/vue/list-story-unchecked.3.js.mdx similarity index 74% rename from docs/snippets/vue/reuse-story-csf2.js.mdx rename to docs/snippets/vue/list-story-unchecked.3.js.mdx index 3499760b547b..8d521c737efe 100644 --- a/docs/snippets/vue/reuse-story-csf2.js.mdx +++ b/docs/snippets/vue/list-story-unchecked.3.js.mdx @@ -1,12 +1,18 @@ ```js // List.stories.js + import List from './List.vue'; import ListItem from './ListItem.vue'; -//👇 Import the story from the CSF 2 stories file +//👇 Imports a specific story from ListItem stories import { Unchecked } from './ListItem.stories'; export default { + /* 👇 The title prop is optional. + * See https://storybook.js.org/docs/configure/#configure-story-loading + * to learn how to generate automatic titles + */ + title: 'List', component: List, }; @@ -16,6 +22,9 @@ export default { * to learn how to use render functions. */ export const OneItem = { + args: { + ...Unchecked.args, + }, render: (args) => ({ components: { List, ListItem }, setup() { @@ -24,8 +33,5 @@ export const OneItem = { }, template: '', }), - args: { - ...Unchecked.args, - }, }; ``` diff --git a/docs/snippets/vue/reuse-story-csf2.ts-4-9.mdx b/docs/snippets/vue/list-story-unchecked.3.ts-4-9.mdx similarity index 78% rename from docs/snippets/vue/reuse-story-csf2.ts-4-9.mdx rename to docs/snippets/vue/list-story-unchecked.3.ts-4-9.mdx index 068f78d8006e..478e65d6f878 100644 --- a/docs/snippets/vue/reuse-story-csf2.ts-4-9.mdx +++ b/docs/snippets/vue/list-story-unchecked.3.ts-4-9.mdx @@ -1,14 +1,20 @@ ```ts // List.stories.js + import type { Meta, StoryObj } from '@storybook/vue3'; import List from './List.vue'; import ListItem from './ListItem.vue'; -//👇 Import the story from the CSF 2 stories file +//👇 Imports a specific story from ListItem stories import { Unchecked } from './ListItem.stories'; const meta = { + /* 👇 The title prop is optional. + * See https://storybook.js.org/docs/configure/#configure-story-loading + * to learn how to generate automatic titles + */ + title: 'List', component: List, } satisfies Meta; diff --git a/docs/snippets/vue/reuse-story-csf2.ts.mdx b/docs/snippets/vue/list-story-unchecked.3.ts.mdx similarity index 77% rename from docs/snippets/vue/reuse-story-csf2.ts.mdx rename to docs/snippets/vue/list-story-unchecked.3.ts.mdx index fd99cc271851..d928c99296a3 100644 --- a/docs/snippets/vue/reuse-story-csf2.ts.mdx +++ b/docs/snippets/vue/list-story-unchecked.3.ts.mdx @@ -1,14 +1,20 @@ ```ts // List.stories.js + import type { Meta, StoryObj } from '@storybook/vue3'; import List from './List.vue'; import ListItem from './ListItem.vue'; -//👇 Import the story from the CSF 2 stories file +//👇 Imports a specific story from ListItem stories import { Unchecked } from './ListItem.stories'; const meta: Meta = { + /* 👇 The title prop is optional. + * See https://storybook.js.org/docs/configure/#configure-story-loading + * to learn how to generate automatic titles + */ + title: 'List', component: List, }; diff --git a/docs/snippets/vue/reuse-story-portable.js.mdx b/docs/snippets/vue/reuse-story-portable.js.mdx deleted file mode 100644 index a2a57cbb1c5b..000000000000 --- a/docs/snippets/vue/reuse-story-portable.js.mdx +++ /dev/null @@ -1,28 +0,0 @@ -```js -// List.stories.js -import { composeStories } from '@storybook/vue3' - -import List from './List.vue'; -import ListItem from './ListItem.vue'; - -//👇 Import the stories and their meta from the stories file -import * as stories from './ListItem.stories'; - -//👇 Compose the story -const { Unchecked } = composeStories(stories); - -export default { - component: List, -}; - -export const OneItem = { - render: (args) => ({ - components: { List, ListItem }, - setup() { - //👇 The args will now be passed down to the template - return { args }; - }, - template: '', - }), -}; -``` diff --git a/docs/snippets/vue/reuse-story-portable.ts-4-9.mdx b/docs/snippets/vue/reuse-story-portable.ts-4-9.mdx deleted file mode 100644 index 964ffbb467e9..000000000000 --- a/docs/snippets/vue/reuse-story-portable.ts-4-9.mdx +++ /dev/null @@ -1,32 +0,0 @@ -```ts -// List.stories.js -import type { Meta, StoryObj } from '@storybook/vue3'; -import { composeStories } from '@storybook/vue3' - -import List from './List.vue'; -import ListItem from './ListItem.vue'; - -//👇 Import the stories and their meta from the stories file -import * as stories from './ListItem.stories'; - -//👇 Compose the story -const { Unchecked } = composeStories(stories); - -const meta = { - component: List, -} satisfies Meta; - -export default meta; -type Story = StoryObj; - -export const OneItem: Story = { - render: (args) => ({ - components: { List, ListItem }, - setup() { - //👇 The args will now be passed down to the template - return { args }; - }, - template: '', - }), -}; -``` diff --git a/docs/snippets/vue/reuse-story-portable.ts.mdx b/docs/snippets/vue/reuse-story-portable.ts.mdx deleted file mode 100644 index eab1b1ea72b9..000000000000 --- a/docs/snippets/vue/reuse-story-portable.ts.mdx +++ /dev/null @@ -1,32 +0,0 @@ -```ts -// List.stories.js -import type { Meta, StoryObj } from '@storybook/vue3'; -import { composeStories } from '@storybook/vue3' - -import List from './List.vue'; -import ListItem from './ListItem.vue'; - -//👇 Import the stories and their meta from the stories file -import * as stories from './ListItem.stories'; - -//👇 Compose the story -const { Unchecked } = composeStories(stories); - -const meta: Meta = { - component: List, -}; - -export default meta; -type Story = StoryObj; - -export const OneItem: Story = { - render: (args) => ({ - components: { List, ListItem }, - setup() { - //👇 The args will now be passed down to the template - return { args }; - }, - template: '', - }), -}; -``` diff --git a/docs/snippets/web-components/reuse-story-csf2.js.mdx b/docs/snippets/web-components/list-story-unchecked.js.mdx similarity index 84% rename from docs/snippets/web-components/reuse-story-csf2.js.mdx rename to docs/snippets/web-components/list-story-unchecked.js.mdx index 0b04e69da378..be30704c8341 100644 --- a/docs/snippets/web-components/reuse-story-csf2.js.mdx +++ b/docs/snippets/web-components/list-story-unchecked.js.mdx @@ -1,8 +1,9 @@ ```js // MyList.stories.js + import { html } from 'lit'; -//👇 Import the story from the CSF 2 stories file +// 👇 Import the stories of MyListItem import { Unchecked } from './MyListItem.stories'; export default { diff --git a/docs/snippets/web-components/reuse-story-csf2.ts.mdx b/docs/snippets/web-components/list-story-unchecked.ts.mdx similarity index 88% rename from docs/snippets/web-components/reuse-story-csf2.ts.mdx rename to docs/snippets/web-components/list-story-unchecked.ts.mdx index 1b6ca2af48ab..80c135f68a4f 100644 --- a/docs/snippets/web-components/reuse-story-csf2.ts.mdx +++ b/docs/snippets/web-components/list-story-unchecked.ts.mdx @@ -1,10 +1,11 @@ ```ts // MyList.stories.ts + import { Meta, StoryObj } from '@storybook/web-components'; import { html } from 'lit'; -//👇 Import the story from the CSF 2 stories file +// 👇 Import the stories of MyListItem import { Unchecked } from './my-list-item.stories'; const meta: Meta = { diff --git a/docs/snippets/web-components/reuse-story-render-function.js.mdx b/docs/snippets/web-components/reuse-story-render-function.js.mdx deleted file mode 100644 index 57ac1aa0fbd8..000000000000 --- a/docs/snippets/web-components/reuse-story-render-function.js.mdx +++ /dev/null @@ -1,16 +0,0 @@ -```js -// MyList.stories.js -import { html } from 'lit'; - -//👇 Import the story with a render function from the CSF 3 stories file -import { Unchecked } from './MyListItem.stories'; - -export default { - title: 'MyList', - component: 'demo-my-list', -}; - -export const OneItem = { - render: () => html` ${Unchecked.render({ ...Unchecked.args })} `, -}; -``` diff --git a/docs/snippets/web-components/reuse-story-render-function.ts.mdx b/docs/snippets/web-components/reuse-story-render-function.ts.mdx deleted file mode 100644 index f77d65410fc7..000000000000 --- a/docs/snippets/web-components/reuse-story-render-function.ts.mdx +++ /dev/null @@ -1,21 +0,0 @@ -```ts -// MyList.stories.ts -import { Meta, StoryObj } from '@storybook/web-components'; - -import { html } from 'lit'; - -//👇 Import the story with a render function from the CSF 3 stories file -import { Unchecked } from './my-list-item.stories'; - -const meta: Meta = { - title: 'MyList', - component: 'demo-my-list', -}; -export default meta; - -type Story = StoryObj; - -export const OneItem: Story = { - render: () => html` ${Unchecked.render({ ...Unchecked.args })} `, -}; -``` diff --git a/docs/writing-stories/stories-for-multiple-components.md b/docs/writing-stories/stories-for-multiple-components.md index 2c326f5b1c46..708ccce28787 100644 --- a/docs/writing-stories/stories-for-multiple-components.md +++ b/docs/writing-stories/stories-for-multiple-components.md @@ -2,7 +2,7 @@ title: 'Stories for multiple components' --- -It's useful to write stories that [render two or more components](../writing-stories/index.md#stories-for-two-or-more-components) at once if those components are designed to work together. For example, `ButtonGroup` or `List` components. Here's an example with `List` and `ListItem` components: +It's useful to write stories that [render two or more components](../writing-stories/index.md#stories-for-two-or-more-components) at once if those components are designed to work together. For example, `ButtonGroups`, `Lists`, and `Page` components. Here's an example with `List` and `ListItem` components: @@ -35,71 +35,28 @@ Let's talk about some techniques you can use to mitigate the above, which are es ## Reusing subcomponent stories -We can also reuse the stories of the `ListItem` subcomponent in `List` stories. - -If the story to be reused is written in [CSF 2](../../../release-6-5/docs/api/csf.md), we can reuse it directly: - - - - - - - - - -If the story to be reused is written in [CSF 3](../api/csf.md), we can reuse it by composing it into a [portable story](../api/portable-stories-jest.md): +The simplest change we can make to the above is to reuse the stories of the `ListItem` in the `List`: - - - - - -If the story to be reused is written in [CSF 3](../api/csf.md) and defines a [`render` function](../api/csf.md#custom-render-functions), we can use that `render` function to reuse the story: - - - - - - - - - - By rendering the `Unchecked` story with its args, we are able to reuse the input data from the `ListItem` stories in the `List`. However, we still aren’t using args to control the `ListItem` stories, which means we cannot change them with controls and we cannot reuse them in other, more complex component stories. @@ -108,8 +65,6 @@ However, we still aren’t using args to control the `ListItem` stories, which m One way we improve that situation is by pulling the rendered subcomponent out into a `children` arg: - - Date: Tue, 26 Mar 2024 13:13:27 -0600 Subject: [PATCH 18/37] Update multiple components guidance - Remove guidance to reuse entire stories - Clarify other guidance --- .../angular/list-story-reuse-data.ts.mdx | 5 --- .../html/list-story-reuse-data.js.mdx | 9 ---- .../html/list-story-reuse-data.ts.mdx | 9 ---- .../react/list-story-reuse-data.js.mdx | 6 --- .../react/list-story-reuse-data.ts-4-9.mdx | 5 --- .../react/list-story-reuse-data.ts.mdx | 5 --- .../solid/list-story-reuse-data.js.mdx | 6 --- .../solid/list-story-reuse-data.ts-4-9.mdx | 5 --- .../solid/list-story-reuse-data.ts.mdx | 5 --- .../vue/list-story-reuse-data.3.js.mdx | 5 --- .../vue/list-story-reuse-data.3.ts-4-9.mdx | 5 --- .../vue/list-story-reuse-data.3.ts.mdx | 5 --- docs/writing-stories/index.md | 4 +- .../stories-for-multiple-components.md | 42 ++++++++++++------- 14 files changed, 30 insertions(+), 86 deletions(-) diff --git a/docs/snippets/angular/list-story-reuse-data.ts.mdx b/docs/snippets/angular/list-story-reuse-data.ts.mdx index 3ff20f0d824a..7f531c257527 100644 --- a/docs/snippets/angular/list-story-reuse-data.ts.mdx +++ b/docs/snippets/angular/list-story-reuse-data.ts.mdx @@ -26,11 +26,6 @@ const meta: Meta = { export default meta; type Story = StoryObj; -/* - *👇 Render functions are a framework specific feature to allow you control on how the component renders. - * See https://storybook.js.org/docs/api/csf - * to learn how to use render functions. - */ export const ManyItems: Story = { args: { Selected: Selected.args.isSelected, diff --git a/docs/snippets/html/list-story-reuse-data.js.mdx b/docs/snippets/html/list-story-reuse-data.js.mdx index 76a6f8820a3b..fe46d1a44f71 100644 --- a/docs/snippets/html/list-story-reuse-data.js.mdx +++ b/docs/snippets/html/list-story-reuse-data.js.mdx @@ -8,18 +8,9 @@ import { createListItem } from './ListItem'; import { Selected, Unselected } from './ListItem.stories'; export default { - /* 👇 The title prop is optional. - * See https://storybook.js.org/docs/configure/#configure-story-loading - * to learn how to generate automatic titles - */ title: 'List', }; -/* - *👇 Render functions are a framework specific feature to allow you control on how the component renders. - * See https://storybook.js.org/docs/api/csf - * to learn how to use render functions. - */ export const ManyItems = { render: (args) => { const list = createList(args); diff --git a/docs/snippets/html/list-story-reuse-data.ts.mdx b/docs/snippets/html/list-story-reuse-data.ts.mdx index 999a38a65c25..50f984c0bb85 100644 --- a/docs/snippets/html/list-story-reuse-data.ts.mdx +++ b/docs/snippets/html/list-story-reuse-data.ts.mdx @@ -10,21 +10,12 @@ import { createListItem } from './ListItem'; import { Selected, Unselected } from './ListItem.stories'; const meta: Meta = { - /* 👇 The title prop is optional. - * See https://storybook.js.org/docs/configure/#configure-story-loading - * to learn how to generate automatic titles - */ title: 'List', }; export default meta; type Story = StoryObj; -/* - *👇 Render functions are a framework specific feature to allow you control on how the component renders. - * See https://storybook.js.org/docs/api/csf - * to learn how to use render functions. - */ export const ManyItems: Story = { render: (args) => { const list = createList(args); diff --git a/docs/snippets/react/list-story-reuse-data.js.mdx b/docs/snippets/react/list-story-reuse-data.js.mdx index 2e35ca9c2dab..6f99fad942ef 100644 --- a/docs/snippets/react/list-story-reuse-data.js.mdx +++ b/docs/snippets/react/list-story-reuse-data.js.mdx @@ -13,12 +13,6 @@ export default { component: List, }; -/* - *👇 Render functions are a framework specific feature to allow you control on how the component renders. - * See https://storybook.js.org/docs/api/csf - * to learn how to use render functions. - */ - export const ManyItems = { render: (args) => ( diff --git a/docs/snippets/react/list-story-reuse-data.ts-4-9.mdx b/docs/snippets/react/list-story-reuse-data.ts-4-9.mdx index 07767df39468..6fbee90aa76a 100644 --- a/docs/snippets/react/list-story-reuse-data.ts-4-9.mdx +++ b/docs/snippets/react/list-story-reuse-data.ts-4-9.mdx @@ -16,11 +16,6 @@ const meta = { export default meta; type Story = StoryObj; -/* - *👇 Render functions are a framework specific feature to allow you control on how the component renders. - * See https://storybook.js.org/docs/api/csf - * to learn how to use render functions. - */ export const ManyItems: Story = { render: (args) => ( diff --git a/docs/snippets/react/list-story-reuse-data.ts.mdx b/docs/snippets/react/list-story-reuse-data.ts.mdx index 006e28639c99..5e8382162d6a 100644 --- a/docs/snippets/react/list-story-reuse-data.ts.mdx +++ b/docs/snippets/react/list-story-reuse-data.ts.mdx @@ -16,11 +16,6 @@ const meta: Meta = { export default meta; type Story = StoryObj; -/* - *👇 Render functions are a framework specific feature to allow you control on how the component renders. - * See https://storybook.js.org/docs/api/csf - * to learn how to use render functions. - */ export const ManyItems: Story = { render: (args) => ( diff --git a/docs/snippets/solid/list-story-reuse-data.js.mdx b/docs/snippets/solid/list-story-reuse-data.js.mdx index 812843a505e6..e893f403e914 100644 --- a/docs/snippets/solid/list-story-reuse-data.js.mdx +++ b/docs/snippets/solid/list-story-reuse-data.js.mdx @@ -11,12 +11,6 @@ export default { component: List, }; -/* - *👇 Render functions are a framework specific feature to allow you control on how the component renders. - * See https://storybook.js.org/docs/api/csf - * to learn how to use render functions. - */ - export const ManyItems = { render: (args) => ( diff --git a/docs/snippets/solid/list-story-reuse-data.ts-4-9.mdx b/docs/snippets/solid/list-story-reuse-data.ts-4-9.mdx index 5d4e5aae4e28..78e8b4d089fb 100644 --- a/docs/snippets/solid/list-story-reuse-data.ts-4-9.mdx +++ b/docs/snippets/solid/list-story-reuse-data.ts-4-9.mdx @@ -16,11 +16,6 @@ const meta = { export default meta; type Story = StoryObj; -/* - *👇 Render functions are a framework specific feature to allow you control on how the component renders. - * See https://storybook.js.org/docs/api/csf - * to learn how to use render functions. - */ export const ManyItems: Story = { render: (args) => ( diff --git a/docs/snippets/solid/list-story-reuse-data.ts.mdx b/docs/snippets/solid/list-story-reuse-data.ts.mdx index 636f66d6b020..cccd2b421cc8 100644 --- a/docs/snippets/solid/list-story-reuse-data.ts.mdx +++ b/docs/snippets/solid/list-story-reuse-data.ts.mdx @@ -16,11 +16,6 @@ const meta: Meta = { export default meta; type Story = StoryObj; -/* - *👇 Render functions are a framework specific feature to allow you control on how the component renders. - * See https://storybook.js.org/docs/api/csf - * to learn how to use render functions. - */ export const ManyItems: Story = { render: (args) => ( diff --git a/docs/snippets/vue/list-story-reuse-data.3.js.mdx b/docs/snippets/vue/list-story-reuse-data.3.js.mdx index d9384dd001d2..ab3b3f042072 100644 --- a/docs/snippets/vue/list-story-reuse-data.3.js.mdx +++ b/docs/snippets/vue/list-story-reuse-data.3.js.mdx @@ -11,11 +11,6 @@ export default { component: List, }; -/* - *👇 Render functions are a framework specific feature to allow you control on how the component renders. - * See https://storybook.js.org/docs/api/csf - * to learn how to use render functions. - */ export const ManyItems = { render: (args) => ({ components: { List, ListItem }, diff --git a/docs/snippets/vue/list-story-reuse-data.3.ts-4-9.mdx b/docs/snippets/vue/list-story-reuse-data.3.ts-4-9.mdx index 37c83e2a7edc..bfcc9be89175 100644 --- a/docs/snippets/vue/list-story-reuse-data.3.ts-4-9.mdx +++ b/docs/snippets/vue/list-story-reuse-data.3.ts-4-9.mdx @@ -16,11 +16,6 @@ const meta = { export default meta; type Story = StoryObj; -/* - *👇 Render functions are a framework specific feature to allow you control on how the component renders. - * See https://storybook.js.org/docs/api/csf - * to learn how to use render functions. - */ export const ManyItems: Story = { render: (args) => ({ components: { List, ListItem }, diff --git a/docs/snippets/vue/list-story-reuse-data.3.ts.mdx b/docs/snippets/vue/list-story-reuse-data.3.ts.mdx index 99c0bde71faa..93bf88a25d67 100644 --- a/docs/snippets/vue/list-story-reuse-data.3.ts.mdx +++ b/docs/snippets/vue/list-story-reuse-data.3.ts.mdx @@ -16,11 +16,6 @@ const meta: Meta = { export default meta; type Story = StoryObj; -/* - *👇 Render functions are a framework specific feature to allow you control on how the component renders. - * See https://storybook.js.org/docs/api/csf - * to learn how to use render functions. - */ export const ManyItems: Story = { render: (args) => ({ components: { List, ListItem }, diff --git a/docs/writing-stories/index.md b/docs/writing-stories/index.md index abc6632d90f8..7a99a45e1df7 100644 --- a/docs/writing-stories/index.md +++ b/docs/writing-stories/index.md @@ -357,7 +357,7 @@ Decorators [can be more complex](./decorators.md#context-for-mocking) and are of ## Stories for two or more components -When building design systems or component libraries, you may have two or more components created to work together. For instance, if you have a parent `List` component, it may require child `ListItem` components. +Sometimes, you may have two or more components created to work together. For instance, if you have a parent `List` component, it may require child `ListItem` components. @@ -405,7 +405,7 @@ In such cases, it makes sense to render a different function for each story: -You can also reuse stories from the child `ListItem` in your `List` component. That’s easier to maintain because you don’t have to keep the identical story definitions updated in multiple places. +You can also reuse story definitions from the child `ListItem` in your `List` component. That’s easier to maintain because you don’t have to keep the identical details updated in multiple places. diff --git a/docs/writing-stories/stories-for-multiple-components.md b/docs/writing-stories/stories-for-multiple-components.md index 708ccce28787..5a9889f17b4c 100644 --- a/docs/writing-stories/stories-for-multiple-components.md +++ b/docs/writing-stories/stories-for-multiple-components.md @@ -2,7 +2,13 @@ title: 'Stories for multiple components' --- -It's useful to write stories that [render two or more components](../writing-stories/index.md#stories-for-two-or-more-components) at once if those components are designed to work together. For example, `ButtonGroups`, `Lists`, and `Page` components. Here's an example with `List` and `ListItem` components: +It's useful to write stories that [render two or more components](../writing-stories/index.md#stories-for-two-or-more-components) at once if those components are designed to work together. For example, `ButtonGroup`, `List`, and `Page` components. + +## Subcomponents + +When the components you're documenting have a parent-child relationship, you can use the `subcomponents` property to document them together. This is especially useful when the child component is not meant to be used on its own, but only as part of the parent component. + +Here's an example with `List` and `ListItem` components: @@ -33,32 +39,36 @@ Subcomponents are only intended for documentation purposes and have some limitat Let's talk about some techniques you can use to mitigate the above, which are especially useful in more complicated situations. -## Reusing subcomponent stories +## Reusing story definitions -The simplest change we can make to the above is to reuse the stories of the `ListItem` in the `List`: +We can also reduce repitition in our stories by reusing story definitions. Here, we can reuse the `ListItem` stories' args in the story for `List`: By rendering the `Unchecked` story with its args, we are able to reuse the input data from the `ListItem` stories in the `List`. + + However, we still aren’t using args to control the `ListItem` stories, which means we cannot change them with controls and we cannot reuse them in other, more complex component stories. ## Using children as an arg @@ -82,9 +92,10 @@ Now that `children` is an arg, we can potentially reuse it in another story. However, there are some caveats when using this approach that you should be aware of. -The `children` `args` as any other arg needs to be JSON serializable. It means that you should: +The `children` arg, just like all args, needs to be JSON serializable. It means that you should: - Avoid using empty values +- Use [mapping](../essentials/controls.md#dealing-with-complex-values) if you want to adjust the value with [controls](../essentials/controls.md) - Use caution with components that include third party libraries As they could lead into errors with your Storybook. @@ -95,6 +106,9 @@ We're currently working on improving the overall experience for the children arg + + + ## Creating a Template Component Another option that is more “data”-based is to create a special “story-generating” template component: From 30e39545504d9d34cac2a21b66ff433241babdcf Mon Sep 17 00:00:00 2001 From: Kyle Gach Date: Mon, 1 Apr 2024 08:54:37 -0600 Subject: [PATCH 19/37] Apply suggestions from code review Co-authored-by: Michael Shilman Co-authored-by: jonniebigodes --- docs/writing-stories/index.md | 4 ++-- docs/writing-stories/stories-for-multiple-components.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/writing-stories/index.md b/docs/writing-stories/index.md index 7a99a45e1df7..ec51a7dc1d39 100644 --- a/docs/writing-stories/index.md +++ b/docs/writing-stories/index.md @@ -357,7 +357,7 @@ Decorators [can be more complex](./decorators.md#context-for-mocking) and are of ## Stories for two or more components -Sometimes, you may have two or more components created to work together. For instance, if you have a parent `List` component, it may require child `ListItem` components. +Sometimes you may have two or more components created to work together. For instance, if you have a parent `List` component, it may require child `ListItem` components. @@ -405,7 +405,7 @@ In such cases, it makes sense to render a different function for each story: -You can also reuse story definitions from the child `ListItem` in your `List` component. That’s easier to maintain because you don’t have to keep the identical details updated in multiple places. +You can also reuse _story data_ from the child `ListItem` in your `List` component. That’s easier to maintain because you don’t have to update it in multiple places. diff --git a/docs/writing-stories/stories-for-multiple-components.md b/docs/writing-stories/stories-for-multiple-components.md index 5a9889f17b4c..5ae20d893ae6 100644 --- a/docs/writing-stories/stories-for-multiple-components.md +++ b/docs/writing-stories/stories-for-multiple-components.md @@ -2,7 +2,7 @@ title: 'Stories for multiple components' --- -It's useful to write stories that [render two or more components](../writing-stories/index.md#stories-for-two-or-more-components) at once if those components are designed to work together. For example, `ButtonGroup`, `List`, and `Page` components. +It's useful to write stories that [render two or more components](./index.md#stories-for-two-or-more-components) at once if those components are designed to work together. For example, `ButtonGroup`, `List`, and `Page` components. ## Subcomponents From b8e46fea16c340a9ee38d6e7979bcc2446f3659b Mon Sep 17 00:00:00 2001 From: Kyle Gach Date: Mon, 1 Apr 2024 08:58:36 -0600 Subject: [PATCH 20/37] Address feedback --- docs/writing-stories/stories-for-multiple-components.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/docs/writing-stories/stories-for-multiple-components.md b/docs/writing-stories/stories-for-multiple-components.md index 5ae20d893ae6..a51a58867445 100644 --- a/docs/writing-stories/stories-for-multiple-components.md +++ b/docs/writing-stories/stories-for-multiple-components.md @@ -41,7 +41,7 @@ Let's talk about some techniques you can use to mitigate the above, which are es ## Reusing story definitions -We can also reduce repitition in our stories by reusing story definitions. Here, we can reuse the `ListItem` stories' args in the story for `List`: +We can also reduce repetition in our stories by reusing story definitions. Here, we can reuse the `ListItem` stories' args in the story for `List`: @@ -92,14 +92,12 @@ Now that `children` is an arg, we can potentially reuse it in another story. However, there are some caveats when using this approach that you should be aware of. -The `children` arg, just like all args, needs to be JSON serializable. It means that you should: +The `children` arg, just like all args, needs to be JSON serializable. To avoid errors with your Storybook, you should: - Avoid using empty values - Use [mapping](../essentials/controls.md#dealing-with-complex-values) if you want to adjust the value with [controls](../essentials/controls.md) - Use caution with components that include third party libraries -As they could lead into errors with your Storybook. - We're currently working on improving the overall experience for the children arg and allow you to edit children arg in a control and allow you to use other types of components in the near future. But for now you need to factor in this caveat when you're implementing your stories. From 6957b500eca2807fe670aa7355fcc81e32314353 Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Mon, 1 Apr 2024 20:53:15 +0200 Subject: [PATCH 21/37] Update postcss-loader in Next.js framework --- code/frameworks/nextjs/package.json | 4 +- code/yarn.lock | 57 +++++++++++------------------ 2 files changed, 24 insertions(+), 37 deletions(-) diff --git a/code/frameworks/nextjs/package.json b/code/frameworks/nextjs/package.json index a24a7896181f..a4fdc13f0c88 100644 --- a/code/frameworks/nextjs/package.json +++ b/code/frameworks/nextjs/package.json @@ -108,8 +108,8 @@ "loader-utils": "^3.2.1", "node-polyfill-webpack-plugin": "^2.0.1", "pnp-webpack-plugin": "^1.7.0", - "postcss": "^8.4.21", - "postcss-loader": "^7.0.2", + "postcss": "^8.4.38", + "postcss-loader": "^8.1.1", "react-refresh": "^0.14.0", "resolve-url-loader": "^5.0.0", "sass-loader": "^12.4.0", diff --git a/code/yarn.lock b/code/yarn.lock index f4deb1517325..c1b3d7720d4c 100644 --- a/code/yarn.lock +++ b/code/yarn.lock @@ -5956,8 +5956,8 @@ __metadata: next: "npm:^14.1.0" node-polyfill-webpack-plugin: "npm:^2.0.1" pnp-webpack-plugin: "npm:^1.7.0" - postcss: "npm:^8.4.21" - postcss-loader: "npm:^7.0.2" + postcss: "npm:^8.4.38" + postcss-loader: "npm:^8.1.1" react-refresh: "npm:^0.14.0" resolve-url-loader: "npm:^5.0.0" sass-loader: "npm:^12.4.0" @@ -12020,23 +12020,6 @@ __metadata: languageName: node linkType: hard -"cosmiconfig@npm:^8.3.5": - version: 8.3.6 - resolution: "cosmiconfig@npm:8.3.6" - dependencies: - import-fresh: "npm:^3.3.0" - js-yaml: "npm:^4.1.0" - parse-json: "npm:^5.2.0" - path-type: "npm:^4.0.0" - peerDependencies: - typescript: ">=4.9.5" - peerDependenciesMeta: - typescript: - optional: true - checksum: 10c0/0382a9ed13208f8bfc22ca2f62b364855207dffdb73dc26e150ade78c3093f1cf56172df2dd460c8caf2afa91c0ed4ec8a88c62f8f9cd1cf423d26506aa8797a - languageName: node - linkType: hard - "cosmiconfig@npm:^9.0.0": version: 9.0.0 resolution: "cosmiconfig@npm:9.0.0" @@ -22656,7 +22639,7 @@ __metadata: languageName: node linkType: hard -"postcss-loader@npm:8.1.1": +"postcss-loader@npm:8.1.1, postcss-loader@npm:^8.1.1": version: 8.1.1 resolution: "postcss-loader@npm:8.1.1" dependencies: @@ -22676,20 +22659,6 @@ __metadata: languageName: node linkType: hard -"postcss-loader@npm:^7.0.2": - version: 7.3.4 - resolution: "postcss-loader@npm:7.3.4" - dependencies: - cosmiconfig: "npm:^8.3.5" - jiti: "npm:^1.20.0" - semver: "npm:^7.5.4" - peerDependencies: - postcss: ^7.0.0 || ^8.0.1 - webpack: ^5.0.0 - checksum: 10c0/1bf7614aeea9ad1f8ee6be3a5451576c059391688ea67f825aedc2674056369597faeae4e4a81fe10843884c9904a71403d9a54197e1f560e8fbb9e61f2a2680 - languageName: node - linkType: hard - "postcss-media-query-parser@npm:^0.2.3": version: 0.2.3 resolution: "postcss-media-query-parser@npm:0.2.3" @@ -22827,7 +22796,7 @@ __metadata: languageName: node linkType: hard -"postcss@npm:8.4.35, postcss@npm:^8.2.14, postcss@npm:^8.4.21, postcss@npm:^8.4.23, postcss@npm:^8.4.27, postcss@npm:^8.4.32, postcss@npm:^8.4.33, postcss@npm:^8.4.35": +"postcss@npm:8.4.35, postcss@npm:^8.2.14, postcss@npm:^8.4.23, postcss@npm:^8.4.27, postcss@npm:^8.4.32, postcss@npm:^8.4.33, postcss@npm:^8.4.35": version: 8.4.35 resolution: "postcss@npm:8.4.35" dependencies: @@ -22848,6 +22817,17 @@ __metadata: languageName: node linkType: hard +"postcss@npm:^8.4.38": + version: 8.4.38 + resolution: "postcss@npm:8.4.38" + dependencies: + nanoid: "npm:^3.3.7" + picocolors: "npm:^1.0.0" + source-map-js: "npm:^1.2.0" + checksum: 10c0/955407b8f70cf0c14acf35dab3615899a2a60a26718a63c848cf3c29f2467b0533991b985a2b994430d890bd7ec2b1963e36352b0774a19143b5f591540f7c06 + languageName: node + linkType: hard + "preact@npm:^10.5.13": version: 10.19.3 resolution: "preact@npm:10.19.3" @@ -25793,6 +25773,13 @@ __metadata: languageName: node linkType: hard +"source-map-js@npm:^1.2.0": + version: 1.2.0 + resolution: "source-map-js@npm:1.2.0" + checksum: 10c0/7e5f896ac10a3a50fe2898e5009c58ff0dc102dcb056ed27a354623a0ece8954d4b2649e1a1b2b52ef2e161d26f8859c7710350930751640e71e374fe2d321a4 + languageName: node + linkType: hard + "source-map-loader@npm:5.0.0": version: 5.0.0 resolution: "source-map-loader@npm:5.0.0" From 2ef2c8042b0274791248d13450c4de41ee60184d Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Mon, 1 Apr 2024 21:16:43 +0200 Subject: [PATCH 22/37] Update TypeScript --- code/package.json | 2 +- code/yarn.lock | 22 +++++++++++++++++++++- scripts/package.json | 2 +- scripts/yarn.lock | 18 +++++++++--------- 4 files changed, 32 insertions(+), 12 deletions(-) diff --git a/code/package.json b/code/package.json index 399bf6dd0b11..0daa82df94f1 100644 --- a/code/package.json +++ b/code/package.json @@ -223,7 +223,7 @@ "trash": "^7.0.0", "ts-dedent": "^2.0.0", "ts-node": "^10.9.1", - "typescript": "^5.3.2", + "typescript": "^5.4.3", "util": "^0.12.4", "vite": "^4.0.0", "vitest": "^1.2.2", diff --git a/code/yarn.lock b/code/yarn.lock index f4deb1517325..1a4f5cdae397 100644 --- a/code/yarn.lock +++ b/code/yarn.lock @@ -6458,7 +6458,7 @@ __metadata: trash: "npm:^7.0.0" ts-dedent: "npm:^2.0.0" ts-node: "npm:^10.9.1" - typescript: "npm:^5.3.2" + typescript: "npm:^5.4.3" util: "npm:^0.12.4" vite: "npm:^4.0.0" vitest: "npm:^1.2.2" @@ -27534,6 +27534,16 @@ __metadata: languageName: node linkType: hard +"typescript@npm:^5.4.3": + version: 5.4.3 + resolution: "typescript@npm:5.4.3" + bin: + tsc: bin/tsc + tsserver: bin/tsserver + checksum: 10c0/22443a8760c3668e256c0b34b6b45c359ef6cecc10c42558806177a7d500ab1a7d7aac1f976d712e26989ddf6731d2fbdd3212b7c73290a45127c1c43ba2005a + languageName: node + linkType: hard + "typescript@patch:typescript@npm%3A^3.8.3#optional!builtin": version: 3.9.10 resolution: "typescript@patch:typescript@npm%3A3.9.10#optional!builtin::version=3.9.10&hash=3bd3d3" @@ -27554,6 +27564,16 @@ __metadata: languageName: node linkType: hard +"typescript@patch:typescript@npm%3A^5.4.3#optional!builtin": + version: 5.4.3 + resolution: "typescript@patch:typescript@npm%3A5.4.3#optional!builtin::version=5.4.3&hash=5adc0c" + bin: + tsc: bin/tsc + tsserver: bin/tsserver + checksum: 10c0/6e51f8b7e6ec55b897b9e56b67e864fe8f44e30f4a14357aad5dc0f7432db2f01efc0522df0b6c36d361c51f2dc3dcac5c832efd96a404cfabf884e915d38828 + languageName: node + linkType: hard + "ufo@npm:^1.3.0": version: 1.3.2 resolution: "ufo@npm:1.3.2" diff --git a/scripts/package.json b/scripts/package.json index bff065475ea5..bf44133234b4 100644 --- a/scripts/package.json +++ b/scripts/package.json @@ -177,7 +177,7 @@ "ts-dedent": "^2.0.0", "tsup": "^6.7.0", "type-fest": "~2.19", - "typescript": "^5.3.2", + "typescript": "^5.4.3", "util": "^0.12.4", "uuid": "^9.0.0", "vitest": "^1.2.2", diff --git a/scripts/yarn.lock b/scripts/yarn.lock index e48f40c7ef08..fb585cb2070b 100644 --- a/scripts/yarn.lock +++ b/scripts/yarn.lock @@ -2827,7 +2827,7 @@ __metadata: ts-loader: "npm:^9.4.2" tsup: "npm:^6.7.0" type-fest: "npm:~2.19" - typescript: "npm:^5.3.2" + typescript: "npm:^5.4.3" util: "npm:^0.12.4" uuid: "npm:^9.0.0" verdaccio: "npm:^5.19.1" @@ -14963,23 +14963,23 @@ __metadata: languageName: node linkType: hard -"typescript@npm:^5.3.2": - version: 5.4.2 - resolution: "typescript@npm:5.4.2" +"typescript@npm:^5.4.3": + version: 5.4.3 + resolution: "typescript@npm:5.4.3" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: 10c0/583ff68cafb0c076695f72d61df6feee71689568179fb0d3a4834dac343df6b6ed7cf7b6f6c801fa52d43cd1d324e2f2d8ae4497b09f9e6cfe3d80a6d6c9ca52 + checksum: 10c0/22443a8760c3668e256c0b34b6b45c359ef6cecc10c42558806177a7d500ab1a7d7aac1f976d712e26989ddf6731d2fbdd3212b7c73290a45127c1c43ba2005a languageName: node linkType: hard -"typescript@patch:typescript@npm%3A^5.3.2#optional!builtin": - version: 5.4.2 - resolution: "typescript@patch:typescript@npm%3A5.4.2#optional!builtin::version=5.4.2&hash=5adc0c" +"typescript@patch:typescript@npm%3A^5.4.3#optional!builtin": + version: 5.4.3 + resolution: "typescript@patch:typescript@npm%3A5.4.3#optional!builtin::version=5.4.3&hash=5adc0c" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: 10c0/fcf6658073d07283910d9a0e04b1d5d0ebc822c04dbb7abdd74c3151c7aa92fcddbac7d799404e358197222006ccdc4c0db219d223d2ee4ccd9e2b01333b49be + checksum: 10c0/6e51f8b7e6ec55b897b9e56b67e864fe8f44e30f4a14357aad5dc0f7432db2f01efc0522df0b6c36d361c51f2dc3dcac5c832efd96a404cfabf884e915d38828 languageName: node linkType: hard From 403fd8e5b25b4c55f61661858454d441dde782d2 Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Mon, 1 Apr 2024 21:34:42 +0200 Subject: [PATCH 23/37] Fix issues after TypeScript update --- .../core-common/src/js-package-manager/Yarn2Proxy.test.ts | 1 - code/lib/core-common/src/js-package-manager/Yarn2Proxy.ts | 7 +++++-- .../renderers/react/src/__test__/portable-stories.test.tsx | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/code/lib/core-common/src/js-package-manager/Yarn2Proxy.test.ts b/code/lib/core-common/src/js-package-manager/Yarn2Proxy.test.ts index f024d19c1133..985d0dbecf83 100644 --- a/code/lib/core-common/src/js-package-manager/Yarn2Proxy.test.ts +++ b/code/lib/core-common/src/js-package-manager/Yarn2Proxy.test.ts @@ -1,5 +1,4 @@ import { describe, beforeEach, it, expect, vi } from 'vitest'; -import dedent from 'ts-dedent'; import { Yarn2Proxy } from './Yarn2Proxy'; describe('Yarn 2 Proxy', () => { diff --git a/code/lib/core-common/src/js-package-manager/Yarn2Proxy.ts b/code/lib/core-common/src/js-package-manager/Yarn2Proxy.ts index 7014357cc44b..8ed0de57e826 100644 --- a/code/lib/core-common/src/js-package-manager/Yarn2Proxy.ts +++ b/code/lib/core-common/src/js-package-manager/Yarn2Proxy.ts @@ -36,6 +36,7 @@ const CRITICAL_YARN2_ERROR_CODES = { YN0083: 'AUTOMERGE_GIT_ERROR', }; +// @ts-expect-error The error codes might be helpful in the future const YARN2_ERROR_CODES = { ...CRITICAL_YARN2_ERROR_CODES, YN0000: 'UNNAMED', @@ -306,10 +307,12 @@ export class Yarn2Proxy extends JsPackageManager { while ((match = regex.exec(logs)) !== null) { const code = match[1]; const message = match[2].replace(/[┌│└]/g, '').trim(); - if (CRITICAL_YARN2_ERROR_CODES[code]) { + if (code in CRITICAL_YARN2_ERROR_CODES) { errorCodesWithMessages.push({ code, - message: `${CRITICAL_YARN2_ERROR_CODES[code]}\n-> ${message}\n`, + message: `${ + CRITICAL_YARN2_ERROR_CODES[code as keyof typeof CRITICAL_YARN2_ERROR_CODES] + }\n-> ${message}\n`, }); } } diff --git a/code/renderers/react/src/__test__/portable-stories.test.tsx b/code/renderers/react/src/__test__/portable-stories.test.tsx index f80a1bbd2cc6..6c3c38055065 100644 --- a/code/renderers/react/src/__test__/portable-stories.test.tsx +++ b/code/renderers/react/src/__test__/portable-stories.test.tsx @@ -3,7 +3,6 @@ import React from 'react'; import { vi, it, expect, afterEach, describe } from 'vitest'; import { render, screen, cleanup } from '@testing-library/react'; import { addons } from '@storybook/preview-api'; -//@ts-expect-error our tsconfig.jsn#moduleResolution is set to 'node', which doesn't support this import import * as addonInteractionsPreview from '@storybook/addon-interactions/preview'; @@ -92,6 +91,7 @@ describe('projectAnnotations', () => { }); it('has spies when addon-interactions annotations are added', async () => { + //@ts-expect-error TODO investigate const Story = composeStory(stories.WithActionArg, stories.default, addonInteractionsPreview); expect(vi.mocked(Story.args.someActionArg!).mock).toBeDefined(); From 88e5b0e0e8b33a48ea65f68d738094d9d02581c2 Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Tue, 2 Apr 2024 09:13:26 +0200 Subject: [PATCH 24/37] Add missing dependency --- code/presets/create-react-app/package.json | 1 + code/presets/create-react-app/src/types.ts | 1 + code/yarn.lock | 1 + 3 files changed, 3 insertions(+) diff --git a/code/presets/create-react-app/package.json b/code/presets/create-react-app/package.json index 4d0db3310dc4..405e368aad5f 100644 --- a/code/presets/create-react-app/package.json +++ b/code/presets/create-react-app/package.json @@ -50,6 +50,7 @@ }, "dependencies": { "@pmmmwh/react-refresh-webpack-plugin": "^0.5.1", + "@storybook/react-docgen-typescript-plugin": "1.0.6--canary.9.0c3f3b7.0", "@storybook/types": "workspace:*", "@types/semver": "^7.5.6", "pnp-webpack-plugin": "^1.7.0", diff --git a/code/presets/create-react-app/src/types.ts b/code/presets/create-react-app/src/types.ts index 14d9b6b59d88..197a4c9f467e 100644 --- a/code/presets/create-react-app/src/types.ts +++ b/code/presets/create-react-app/src/types.ts @@ -1,4 +1,5 @@ import type { Options } from '@storybook/types'; + import type { PluginOptions as RDTSPluginOptions } from '@storybook/react-docgen-typescript-plugin'; export interface PluginOptions extends Options { diff --git a/code/yarn.lock b/code/yarn.lock index 1a4f5cdae397..28f3aa376755 100644 --- a/code/yarn.lock +++ b/code/yarn.lock @@ -6048,6 +6048,7 @@ __metadata: dependencies: "@pmmmwh/react-refresh-webpack-plugin": "npm:^0.5.1" "@storybook/node-logger": "workspace:*" + "@storybook/react-docgen-typescript-plugin": "npm:1.0.6--canary.9.0c3f3b7.0" "@storybook/types": "workspace:*" "@types/node": "npm:^18.0.0" "@types/semver": "npm:^7.5.6" From 385f9b97f5e5446c88539b75e4fa9ae8d3c61da6 Mon Sep 17 00:00:00 2001 From: Gert Hengeveld Date: Tue, 2 Apr 2024 16:53:47 +0200 Subject: [PATCH 25/37] Update tests --- .../src/tests/notifications.test.js | 31 +++++++++---------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/code/lib/manager-api/src/tests/notifications.test.js b/code/lib/manager-api/src/tests/notifications.test.js index 51a53be2b1e3..105b973f3b3b 100644 --- a/code/lib/manager-api/src/tests/notifications.test.js +++ b/code/lib/manager-api/src/tests/notifications.test.js @@ -2,34 +2,33 @@ import { describe, it, expect, vi } from 'vitest'; import { init as initNotifications } from '../modules/notifications'; describe('notifications API', () => { - it('allows adding notifications', () => { - const store = { - getState: () => ({ - notifications: [], - }), - setState: vi.fn(), - }; + const store = { + state: { notifications: [] }, + getState: () => store.state, + setState: (update) => { + if (typeof update === 'function') { + store.state = update(store.state); + } else { + store.state = update; + } + }, + }; + it.only('allows adding notifications', () => { const { api } = initNotifications({ store }); api.addNotification({ id: '1' }); - expect(store.setState).toHaveBeenCalledWith({ + expect(store.getState()).toEqual({ notifications: [{ id: '1' }], }); }); it('allows removing notifications', () => { - const store = { - getState: () => ({ - notifications: [{ id: '1' }, { id: '2' }, { id: '3' }], - }), - setState: vi.fn(), - }; - + store.setState({ notifications: [{ id: '1' }, { id: '2' }, { id: '3' }] }); const { api } = initNotifications({ store }); api.clearNotification('2'); - expect(store.setState).toHaveBeenCalledWith({ + expect(store.getState()).toEqual({ notifications: [{ id: '1' }, { id: '3' }], }); }); From f3c4e001f50e1cdca08201bbc923a7d770172f21 Mon Sep 17 00:00:00 2001 From: Gert Hengeveld Date: Tue, 2 Apr 2024 20:20:00 +0200 Subject: [PATCH 26/37] Remove .only modifier --- code/lib/manager-api/src/tests/notifications.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/lib/manager-api/src/tests/notifications.test.js b/code/lib/manager-api/src/tests/notifications.test.js index 105b973f3b3b..8d2005db6837 100644 --- a/code/lib/manager-api/src/tests/notifications.test.js +++ b/code/lib/manager-api/src/tests/notifications.test.js @@ -14,7 +14,7 @@ describe('notifications API', () => { }, }; - it.only('allows adding notifications', () => { + it('allows adding notifications', () => { const { api } = initNotifications({ store }); api.addNotification({ id: '1' }); From 9dc6fe3d402567e6e22c225d0c01141707af68e5 Mon Sep 17 00:00:00 2001 From: Kyle Gach Date: Tue, 2 Apr 2024 14:00:37 -0600 Subject: [PATCH 27/37] Rename snippet --- ...-default-exports.js.mdx => button-story-default-export.js.mdx} | 0 ...-default-exports.ts.mdx => button-story-default-export.ts.mdx} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename docs/snippets/html/{button-story-default-exports.js.mdx => button-story-default-export.js.mdx} (100%) rename docs/snippets/html/{button-story-default-exports.ts.mdx => button-story-default-export.ts.mdx} (100%) diff --git a/docs/snippets/html/button-story-default-exports.js.mdx b/docs/snippets/html/button-story-default-export.js.mdx similarity index 100% rename from docs/snippets/html/button-story-default-exports.js.mdx rename to docs/snippets/html/button-story-default-export.js.mdx diff --git a/docs/snippets/html/button-story-default-exports.ts.mdx b/docs/snippets/html/button-story-default-export.ts.mdx similarity index 100% rename from docs/snippets/html/button-story-default-exports.ts.mdx rename to docs/snippets/html/button-story-default-export.ts.mdx From 65e66987c0a93be7606bdbf3573f33d65ab87b9b Mon Sep 17 00:00:00 2001 From: Yann Braga Date: Wed, 3 Apr 2024 10:06:08 +0200 Subject: [PATCH 28/37] CLI: Add --config-dir flag to migrate command --- code/lib/cli/src/generate.ts | 2 +- code/lib/cli/src/migrate.ts | 29 ++++++++++++++++++++++++----- 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/code/lib/cli/src/generate.ts b/code/lib/cli/src/generate.ts index 6830aea3d1c2..36de347730a7 100644 --- a/code/lib/cli/src/generate.ts +++ b/code/lib/cli/src/generate.ts @@ -126,6 +126,7 @@ command('migrate [migration]') .option('-l --list', 'List available migrations') .option('-g --glob ', 'Glob for files upon which to apply the migration', '**/*.js') .option('-p --parser ', 'jscodeshift parser') + .option('-c, --config-dir ', 'Directory where to load Storybook configurations from') .option( '-n --dry-run', 'Dry run: verify the migration exists and show the files to which it will be applied' @@ -142,7 +143,6 @@ command('migrate [migration]') list, rename, parser, - logger: consoleLogger, }).catch((err) => { logger.error(err); process.exit(1); diff --git a/code/lib/cli/src/migrate.ts b/code/lib/cli/src/migrate.ts index 29ee10dc82a3..fc85c75d9609 100644 --- a/code/lib/cli/src/migrate.ts +++ b/code/lib/cli/src/migrate.ts @@ -11,7 +11,25 @@ import { getStorybookVersionSpecifier } from './helpers'; const logger = console; -export async function migrate(migration: any, { glob, dryRun, list, rename, parser }: any) { +type CLIOptions = { + glob: string; + configDir?: string; + dryRun?: boolean; + list?: string[]; + /** + * Rename suffix of matching files after codemod has been applied, e.g. ".js:.ts" + */ + rename?: string; + /** + * jscodeshift parser + */ + parser?: 'babel' | 'babylon' | 'flow' | 'ts' | 'tsx'; +}; + +export async function migrate( + migration: any, + { glob, dryRun, list, rename, parser, configDir: userSpecifiedConfigDir }: CLIOptions +) { if (list) { listCodemods().forEach((key: any) => logger.log(key)); } else if (migration) { @@ -19,13 +37,14 @@ export async function migrate(migration: any, { glob, dryRun, list, rename, pars const packageManager = JsPackageManagerFactory.getPackageManager(); const [packageJson, storybookVersion] = await Promise.all([ - // packageManager.retrievePackageJson(), getCoercedStorybookVersion(packageManager), ]); - const { configDir: inferredConfigDir, mainConfig: mainConfigPath } = - getStorybookInfo(packageJson); - const configDir = inferredConfigDir || '.storybook'; + const { configDir: inferredConfigDir, mainConfig: mainConfigPath } = getStorybookInfo( + packageJson, + userSpecifiedConfigDir + ); + const configDir = userSpecifiedConfigDir || inferredConfigDir || '.storybook'; // GUARDS if (!storybookVersion) { From d7e5d5a52d4d4edfeae717d07c5159e90b0026ef Mon Sep 17 00:00:00 2001 From: Yann Braga Date: Wed, 3 Apr 2024 14:14:02 +0200 Subject: [PATCH 29/37] Documentation: add migrate and automigrate to the CLI Options page --- docs/api/cli-options.md | 153 ++++++++++++++++++++++++++++++++-------- 1 file changed, 123 insertions(+), 30 deletions(-) diff --git a/docs/api/cli-options.md b/docs/api/cli-options.md index 3aa9f0a3f0a1..e7078d552a5f 100644 --- a/docs/api/cli-options.md +++ b/docs/api/cli-options.md @@ -35,8 +35,10 @@ Options include: | `--help` | Output usage information
`storybook dev --help` | | `-V`, `--version` | Output the version number
`storybook dev -V` | | `-p`, `--port [number]` | Port to run Storybook
`storybook dev -p 9009` | +| `--exact-port [number]` | Use desired port and exit process if it's not available
`storybook dev --exact-port 9009` | | `-h`, `--host [string]` | Host to run Storybook
`storybook dev -h my-host.com` | | `-c`, `--config-dir [dir-name]` | Directory where to load Storybook configurations from
`storybook dev -c .storybook` | +| `--loglevel [level]` | Controls level of logging during build.
Available options: `silly`, `verbose`, `info` (default), `warn`, `error`, `silent`
`storybook dev --loglevel warn` | | `--https` | Serve Storybook over HTTPS. Note: You must provide your own certificate information
`storybook dev --https` | | `--ssl-ca` | Provide an SSL certificate authority. (Optional with --https, required if using a self-signed certificate)
`storybook dev --ssl-ca my-certificate` | | `--ssl-cert` | Provide an SSL certificate. (Required with --https)
`storybook dev --ssl-cert my-ssl-certificate` | @@ -45,9 +47,15 @@ Options include: | `--ci` | CI mode (skip interactive prompts, don't open browser)
`storybook dev --ci` | | `--no-open` | Do not open Storybook automatically in the browser
`storybook dev --no-open` | | `--quiet` | Suppress verbose build output
`storybook dev --quiet` | +| `--debug` | Outputs more logs in the CLI to assist debugging
`storybook dev --debug` | | `--debug-webpack` | Display final webpack configurations for debugging purposes
`storybook dev --debug-webpack` | -| `--stats-json` | Write stats JSON to disk
`storybook dev ---stats-json /tmp/stats`
NOTE: only works for webpack. | +| `--stats-json [dir-name]` | Write stats JSON to disk
`storybook dev --stats-json /tmp/stats`
NOTE: only works for Webpack. | +| `--no-version-updates` | Suppress Storybook's update check
`storybook dev --no-version-updates` | | `--docs` | Starts Storybook in documentation mode. Learn more about it in [here](../writing-docs/build-documentation.md#preview-storybooks-documentation)
`storybook dev --docs` | +| `--initial-path [path]` | URL path to be appended when visiting Storybook for the first time
`storybook dev --initial-path=/docs/getting-started--docs` | +| `--preview-url [path]` | Disables the default Storybook preview and lets your use your own
`storybook dev --preview-url=http://localhost:1337/external-iframe.html` | +| `--force-build-preview` | Build the preview iframe even if you are using --preview-url
`storybook dev --force-build-preview` | +| `--enable-crash-reports` | Enable sending crash reprots to Storybook's telemetry. Learn more about it [here](../configure/telemetry.md).
`storybook dev --disable-telemetry` | | `--disable-telemetry` | Disables Storybook's telemetry. Learn more about it [here](../configure/telemetry.md)
`storybook dev --disable-telemetry` | @@ -74,11 +82,15 @@ Options include: | `-c`, `--config-dir [dir-name]` | Directory where to load Storybook configurations from
`storybook build -c .storybook` | | `--loglevel [level]` | Controls level of logging during build.
Available options: `silly`, `verbose`, `info` (default), `warn`, `error`, `silent`
`storybook build --loglevel warn` | | `--quiet` | Suppress verbose build output
`storybook build --quiet` | +| `--debug` | Outputs more logs in the CLI to assist debugging
`storybook build --debug` | | `--debug-webpack` | Display final webpack configurations for debugging purposes
`storybook build --debug-webpack` | -| `---stats-json` | Write stats JSON to disk
`storybook build -stats-json /my-storybook/-stats` | +| `--stats-json [dir-name]` | Write stats JSON to disk
`storybook build --stats-json /tmp/stats` | | `--docs` | Builds Storybook in documentation mode. Learn more about it in [here](../writing-docs/build-documentation.md#publish-storybooks-documentation)
`storybook build --docs` | -| `--disable-telemetry` | Disables Storybook's telemetry. Learn more about it [here](../configure/telemetry.md).
`storybook build --disable-telemetry` | | `--test` | Optimize Storybook's production build for performance and tests by removing unnecessary features with the `test` option. Learn more [here](../api/main-config-build.md).
`storybook build --test` | +| `--preview-url [path]` | Disables the default Storybook preview and lets your use your own
`storybook build --preview-url=http://localhost:1337/external-iframe.html` | +| `--force-build-preview` | Build the preview iframe even if you are using --preview-url
`storybook build --force-build-preview` | +| `--enable-crash-reports` | Enable sending crash reprots to Storybook's telemetry. Learn more about it [here](../configure/telemetry.md).
`storybook build --disable-telemetry` | +| `--disable-telemetry` | Disables Storybook's telemetry. Learn more about it [here](../configure/telemetry.md).
`storybook build --disable-telemetry` | @@ -94,15 +106,20 @@ For example, `storybook@latest init` will install the latest version of Storyboo Options include: -| Option | Description | -| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| `-b`, `--builder` | Defines the [builder](../builders/index.md) to use for your Storybook instance
`storybook init --builder webpack5` | -| `-f`,`--force` | Forcefully installs Storybook into your project, prompting you to overwrite existing files
`storybook init --force` | -| `-s`, `--skip-install` | Skips the dependency installation step. Used only when you need to configure Storybook manually
`storybook init --skip-install` | -| `-t`, `--type` | Defines the [framework](../configure/frameworks.md) to use for your Storybook instance
`storybook init --type solid` | -| `-y`, `--yes` | Skips interactive prompts and automatically installs Storybook per specified version
`storybook init --yes` | -| `--package-manager` | Sets the package manager to use when installing the addon.
Available package managers include `npm`, `yarn`, and `pnpm`
`storybook init --package-manager pnpm` | -| `--use-pnp` | Enables [Plug'n'Play](https://yarnpkg.com/features/pnp) support for Yarn. This option is only available when using Yarn as your package manager
`storybook init --use-pnp` | +| Option | Description | +| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `--help` | Output usage information
`storybook init --help` | +| `-b`, `--builder` | Defines the [builder](../builders/index.md) to use for your Storybook instance
`storybook init --builder webpack5` | +| `-f`,`--force` | Forcefully installs Storybook into your project, prompting you to overwrite existing files
`storybook init --force` | +| `-s`, `--skip-install` | Skips the dependency installation step. Used only when you need to configure Storybook manually
`storybook init --skip-install` | +| `-t`, `--type` | Defines the [framework](../configure/frameworks.md) to use for your Storybook instance
`storybook init --type solid` | +| `-y`, `--yes` | Skips interactive prompts and automatically installs Storybook per specified version
`storybook init --yes` | +| `--package-manager` | Sets the package manager to use when installing the addon.
Available package managers include `npm`, `yarn`, and `pnpm`
`storybook init --package-manager pnpm` | +| `--use-pnp` | Enables [Plug'n'Play](https://yarnpkg.com/features/pnp) support for Yarn. This option is only available when using Yarn as your package manager
`storybook init --use-pnp` | +| `-p`, `--parser` | Sets the [jscodeshift parser](https://github.com/facebook/jscodeshift#parser).
Available parsers include `babel`, `babylon`, `flow`, `ts`, and `tsx`
`storybook init --parser tsx` | +| `--debug` | Outputs more logs in the CLI to assist debugging
`storybook init --debug` | +| `--disable-telemetry` | Disables Storybook's telemetry. Learn more about it [here](../configure/telemetry.md)
`storybook init --disable-telemetry` | +| `--enable-crash-reports` | Enable sending crash reprots to Storybook's telemetry. Learn more about it [here](../configure/telemetry.md).
`storybook init --disable-telemetry` | ### `add` @@ -116,8 +133,12 @@ Options include: | Option | Description | | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `--help` | Output usage information
`storybook add --help` | | `--package-manager` | Sets the package manager to use when installing the addon.
Available package managers include `npm`, `yarn`, and `pnpm`
`storybook add [addon] --package-manager pnpm` | | `-s`, `--skip-postinstall` | Skips post-install configuration. Used only when you need to configure the addon yourself
`storybook add [addon] --skip-postinstall` | +| `--debug` | Outputs more logs in the CLI to assist debugging
`storybook add --debug` | +| `--disable-telemetry` | Disables Storybook's telemetry. Learn more about it [here](../configure/telemetry.md)
`storybook add --disable-telemetry` | +| `--enable-crash-reports` | Enable sending crash reprots to Storybook's telemetry. Learn more about it [here](../configure/telemetry.md).
`storybook add --disable-telemetry` | ### `remove` @@ -129,9 +150,13 @@ storybook remove [addon] [options] Options include: -| Option | Description | -| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `--package-manager` | Sets the package manager to use when removing the addon.
Available package managers include `npm`, `yarn`, and `pnpm`
`storybook remove [addon]--package-manager pnpm` | +| Option | Description | +| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `--help` | Output usage information
`storybook remove --help` | +| `--package-manager` | Sets the package manager to use when removing the addon.
Available package managers include `npm`, `yarn`, and `pnpm`
`storybook remove [addon]--package-manager pnpm` | +| `--debug` | Outputs more logs in the CLI to assist debugging
`storybook remove --debug` | +| `--disable-telemetry` | Disables Storybook's telemetry. Learn more about it [here](../configure/telemetry.md)
`storybook remove --disable-telemetry` | +| `--enable-crash-reports` | Enable sending crash reprots to Storybook's telemetry. Learn more about it [here](../configure/telemetry.md).
`storybook remove --disable-telemetry` | ### `upgrade` @@ -145,13 +170,75 @@ For example, `storybook@latest upgrade --dry-run` will perform a dry run (no act Options include: -| Option | Description | -| -------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `-c`, `--config-dir` | Directory where to load Storybook configurations from
`storybook upgrade --config-dir .storybook` | -| `-n`, `--dry-run` | Checks for version upgrades without installing them
`storybook upgrade --dry-run` | -| `-s`, `--skip-check` | Skips the migration check step during the upgrade process
`storybook upgrade --skip-check` | -| `-y`, `--yes` | Skips interactive prompts and automatically upgrades Storybook to the latest version
`storybook upgrade --yes` | -| `--package-manager` | Sets the package manager to use when installing the addon.
Available package managers include `npm`, `yarn`, and `pnpm`
`storybook upgrade --package-manager pnpm` | +| Option | Description | +| ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `--help` | Output usage information
`storybook upgrade --help` | +| `-c`, `--config-dir` | Directory where to load Storybook configurations from
`storybook upgrade --config-dir .storybook` | +| `-n`, `--dry-run` | Checks for version upgrades without installing them
`storybook upgrade --dry-run` | +| `-s`, `--skip-check` | Skips the migration check step during the upgrade process
`storybook upgrade --skip-check` | +| `-y`, `--yes` | Skips interactive prompts and automatically upgrades Storybook to the latest version
`storybook upgrade --yes` | +| `-f`,`--force` | Force the upgrade, skipping autoblockers check
`storybook upgrade --force` | +| `--package-manager` | Sets the package manager to use when installing the addon.
Available package managers include `npm`, `yarn`, and `pnpm`
`storybook upgrade --package-manager pnpm` | +| `--debug` | Outputs more logs in the CLI to assist debugging
`storybook upgrade --debug` | +| `--disable-telemetry` | Disables Storybook's telemetry. Learn more about it [here](../configure/telemetry.md)
`storybook upgrade --disable-telemetry` | +| `--enable-crash-reports` | Enable sending crash reprots to Storybook's telemetry. Learn more about it [here](../configure/telemetry.md).
`storybook upgrade --disable-telemetry` | + +### `migrate` + +Runs a specified codemod to migrate your project to use more modern Storybook standards. + +```shell +storybook[@version] migrate [codemod] [options] +``` + + + +The command needs a specific codemod to be specified, e.g. `csf-2-to-3`. To get a list of available codemods, run the CLI command with the `--list` flag. + + + +For example, `storybook@latest migrate csf-2-to-3 --dry-run` will verify that the codemod is applicable to your files and will show which files would be affected by the codemod in a dry run (no actual changes). + +Options include: + +| Option | Description | +| -------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `--help` | Output usage information
`storybook migrate --help` | +| `-c`, `--config-dir` | Directory where to load Storybook configurations from
`storybook migrate --config-dir .storybook` | +| `-n`, `--dry-run` | Verify the migration exists and show the files to which it will be applied
`storybook migrate --dry-run` | +| `-l`, `--list` | Shows a list of available codemods
`storybook migrate --list` | +| `-g`, `--glob` | Glob for files upon which to apply the codemods
`storybook migrate --glob src/**/*.stories.tsx` | +| `-p`, `--parser` | Sets the [jscodeshift parser](https://github.com/facebook/jscodeshift#parser).
Available parsers include `babel`, `babylon`, `flow`, `ts`, and `tsx`
`storybook migrate --parser tsx` | +| `-r`, `--rename [from-to]` | Rename suffix of matching files after codemod has been applied, e.g. `.js:.ts`
`storybook migrate --rename ".js:.ts"` | +| `--debug` | Outputs more logs in the CLI to assist debugging
`storybook migrate --debug` | +| `--disable-telemetry` | Disables Storybook's telemetry. Learn more about it [here](../configure/telemetry.md)
`storybook migrate --disable-telemetry` | +| `--enable-crash-reports` | Enable sending crash reprots to Storybook's telemetry. Learn more about it [here](../configure/telemetry.md).
`storybook migrate --disable-telemetry` | + +### `automigrate` + +Check Storybook for incompatibilities or migrations and apply fixes. + +```shell +storybook[@version] automigrate [fixId] [options] +``` + +For example, `storybook@latest automigrate --dry-run` will scan your codebase and tell which automigrations are applicable in a dry run (no actual changes). + +Options include: + +| Option | Description | +| ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --- | +| `--help` | Output usage information
`storybook automigrate --help` | +| `-c`, `--config-dir` | Directory where to load Storybook configurations from
`storybook automigrate --config-dir .storybook` | +| `-n`, `--dry-run` | Only checks for fixes, not actually executing them
`storybook automigrate --dry-run` | +| `-s`, `--skip-install` | Skip installing dependencies whenever applicable
`storybook automigrate --skip-install` | +| `-y`, `--yes` | Skips interactive prompts and automatically accepts automigrations
`storybook automigrate --yes` | +| `-l`, `--list` | Shows a list of available automigrations
`storybook automigrate --list` | +| `--package-manager` | Sets the package manager to use when installing the addon.
Available package managers include `npm`, `yarn`, and `pnpm`
`storybook automigrate --package-manager pnpm` | | +| `--renderer` | Sets the renderer package for the framework Storybook is using.
Useful for monorepo settings where multiple Storybook renderers are present in the same package.json
`storybook automigrate --renderer vue` | | +| `--debug` | Outputs more logs in the CLI to assist debugging
`storybook automigrate --debug` | +| `--disable-telemetry` | Disables Storybook's telemetry. Learn more about it [here](../configure/telemetry.md)
`storybook automigrate --disable-telemetry` | +| `--enable-crash-reports` | Enable sending crash reprots to Storybook's telemetry. Learn more about it [here](../configure/telemetry.md).
`storybook automigrate --disable-telemetry` | ### `doctor` @@ -163,10 +250,13 @@ storybook doctor [options] Options include: -| Option | Description | -| -------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `-c`, `--config-dir` | Directory where to load Storybook configurations from
`storybook doctor --config-dir .storybook` | -| `--package-manager` | Sets the package manager to use when running the health check.
Available package managers include `npm`, `yarn`, and `pnpm`
`storybook doctor --package-manager pnpm` | +| Option | Description | +| ------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `-c`, `--config-dir` | Directory where to load Storybook configurations from
`storybook doctor --config-dir .storybook` | +| `--package-manager` | Sets the package manager to use when running the health check.
Available package managers include `npm`, `yarn`, and `pnpm`
`storybook doctor --package-manager pnpm` | +| `--debug` | Outputs more logs in the CLI to assist debugging
`storybook doctor --debug` | +| `--disable-telemetry` | Disables Storybook's telemetry. Learn more about it [here](../configure/telemetry.md)
`storybook doctor --disable-telemetry` | +| `--enable-crash-reports` | Enable sending crash reprots to Storybook's telemetry. Learn more about it [here](../configure/telemetry.md).
`storybook doctor --disable-telemetry` | ### `info` @@ -219,10 +309,13 @@ The `framework-filter` argument is optional and can filter the list of available Options include: -| Option | Description | -| --------------------------- | ---------------------------------------------------------------------------------------------------- | -| `-o`, `--output [dir-name]` | Configures the location of the sandbox project
`storybook sandbox --output /my-sandbox-project` | -| `--no-init` | Generates a sandbox project without without initializing Storybook
`storybook sandbox --no-init` | +| Option | Description | +| --------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `-o`, `--output [dir-name]` | Configures the location of the sandbox project
`storybook sandbox --output /my-sandbox-project` | +| `--no-init` | Generates a sandbox project without without initializing Storybook
`storybook sandbox --no-init` | +| `--debug` | Outputs more logs in the CLI to assist debugging
`storybook sandbox --debug` | +| `--disable-telemetry` | Disables Storybook's telemetry. Learn more about it [here](../configure/telemetry.md)
`storybook sandbox --disable-telemetry` | +| `--enable-crash-reports` | Enable sending crash reprots to Storybook's telemetry. Learn more about it [here](../configure/telemetry.md).
`storybook sandbox --disable-telemetry` | From d77f72ee8a42dd39d602be2bfdeb02ccef0aef90 Mon Sep 17 00:00:00 2001 From: Yann Braga Date: Thu, 4 Apr 2024 09:17:31 +0200 Subject: [PATCH 30/37] adjust docs based on review comments --- docs/api/cli-options.md | 200 ++++++++++++++++++++-------------------- 1 file changed, 98 insertions(+), 102 deletions(-) diff --git a/docs/api/cli-options.md b/docs/api/cli-options.md index e7078d552a5f..9e5bc10fb428 100644 --- a/docs/api/cli-options.md +++ b/docs/api/cli-options.md @@ -30,33 +30,33 @@ storybook dev [options] Options include: -| Option | Description | -| ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `--help` | Output usage information
`storybook dev --help` | -| `-V`, `--version` | Output the version number
`storybook dev -V` | -| `-p`, `--port [number]` | Port to run Storybook
`storybook dev -p 9009` | -| `--exact-port [number]` | Use desired port and exit process if it's not available
`storybook dev --exact-port 9009` | -| `-h`, `--host [string]` | Host to run Storybook
`storybook dev -h my-host.com` | -| `-c`, `--config-dir [dir-name]` | Directory where to load Storybook configurations from
`storybook dev -c .storybook` | -| `--loglevel [level]` | Controls level of logging during build.
Available options: `silly`, `verbose`, `info` (default), `warn`, `error`, `silent`
`storybook dev --loglevel warn` | -| `--https` | Serve Storybook over HTTPS. Note: You must provide your own certificate information
`storybook dev --https` | -| `--ssl-ca` | Provide an SSL certificate authority. (Optional with --https, required if using a self-signed certificate)
`storybook dev --ssl-ca my-certificate` | -| `--ssl-cert` | Provide an SSL certificate. (Required with --https)
`storybook dev --ssl-cert my-ssl-certificate` | -| `--ssl-key` | Provide an SSL key. (Required with --https)
`storybook dev --ssl-key my-ssl-key` | -| `--smoke-test` | Exit after successful start
`storybook dev --smoke-test` | -| `--ci` | CI mode (skip interactive prompts, don't open browser)
`storybook dev --ci` | -| `--no-open` | Do not open Storybook automatically in the browser
`storybook dev --no-open` | -| `--quiet` | Suppress verbose build output
`storybook dev --quiet` | -| `--debug` | Outputs more logs in the CLI to assist debugging
`storybook dev --debug` | -| `--debug-webpack` | Display final webpack configurations for debugging purposes
`storybook dev --debug-webpack` | -| `--stats-json [dir-name]` | Write stats JSON to disk
`storybook dev --stats-json /tmp/stats`
NOTE: only works for Webpack. | -| `--no-version-updates` | Suppress Storybook's update check
`storybook dev --no-version-updates` | -| `--docs` | Starts Storybook in documentation mode. Learn more about it in [here](../writing-docs/build-documentation.md#preview-storybooks-documentation)
`storybook dev --docs` | -| `--initial-path [path]` | URL path to be appended when visiting Storybook for the first time
`storybook dev --initial-path=/docs/getting-started--docs` | -| `--preview-url [path]` | Disables the default Storybook preview and lets your use your own
`storybook dev --preview-url=http://localhost:1337/external-iframe.html` | -| `--force-build-preview` | Build the preview iframe even if you are using --preview-url
`storybook dev --force-build-preview` | -| `--enable-crash-reports` | Enable sending crash reprots to Storybook's telemetry. Learn more about it [here](../configure/telemetry.md).
`storybook dev --disable-telemetry` | -| `--disable-telemetry` | Disables Storybook's telemetry. Learn more about it [here](../configure/telemetry.md)
`storybook dev --disable-telemetry` | +| Option | Description | +| ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `--help` | Output usage information
`storybook dev --help` | +| `-V`, `--version` | Output the version number
`storybook dev -V` | +| `-p`, `--port [number]` | Port to run Storybook
`storybook dev -p 9009` | +| `--exact-port [number]` | Attempts to run Storybook on the exact port number specified.
If the port is already in use, Storybook will exit with an error message
`storybook dev --exact-port 9009` | +| `-h`, `--host [string]` | Host to run Storybook
`storybook dev -h my-host.com` | +| `-c`, `--config-dir [dir-name]` | Directory where to load Storybook configurations from
`storybook dev -c .storybook` | +| `--loglevel [level]` | Controls level of logging during build.
Available options: `silly`, `verbose`, `info` (default), `warn`, `error`, `silent`
`storybook dev --loglevel warn` | +| `--https` | Serve Storybook over HTTPS. Note: You must provide your own certificate information
`storybook dev --https` | +| `--ssl-ca` | Provide an SSL certificate authority. (Optional with --https, required if using a self-signed certificate)
`storybook dev --ssl-ca my-certificate` | +| `--ssl-cert` | Provide an SSL certificate. (Required with --https)
`storybook dev --ssl-cert my-ssl-certificate` | +| `--ssl-key` | Provide an SSL key. (Required with --https)
`storybook dev --ssl-key my-ssl-key` | +| `--smoke-test` | Exit after successful start
`storybook dev --smoke-test` | +| `--ci` | CI mode (skip interactive prompts, don't open browser)
`storybook dev --ci` | +| `--no-open` | Do not open Storybook automatically in the browser
`storybook dev --no-open` | +| `--quiet` | Suppress verbose build output
`storybook dev --quiet` | +| `--debug` | Outputs more logs in the CLI to assist debugging
`storybook dev --debug` | +| `--debug-webpack` | Display final webpack configurations for debugging purposes
`storybook dev --debug-webpack` | +| `--stats-json [dir-name]` | Write stats JSON to disk
Requires Webpack
`storybook dev --stats-json /tmp/stats` | +| `--no-version-updates` | Skips Storybook's update check
`storybook dev --no-version-updates` | +| `--docs` | Starts Storybook in documentation mode. Learn more about it in [here](../writing-docs/build-documentation.md#preview-storybooks-documentation)
`storybook dev --docs` | +| `--initial-path [path]` | Configures the URL Storybook should open when it opens the browser for the first time
`storybook dev --initial-path=/docs/getting-started--docs` | +| `--preview-url [path]` | Overrides the default Storybook preview with a custom built preview URL
`storybook dev --preview-url=http://localhost:1337/external-iframe.html` | +| `--force-build-preview` | Forcefully builds Storybook's preview iframe.
Useful if you're experiencing issues, or combined with `--preview-url` to ensure the preview is up-to-date
`storybook dev --force-build-preview` | +| `--disable-telemetry` | Disables Storybook's telemetry. Learn more about it [here](../configure/telemetry.md#how-to-opt-out)
`storybook dev --disable-telemetry` | +| `--enable-crash-reports` | Enables sending crash reports to Storybook's telemetry. Learn more about it [here](../configure/telemetry.md#crash-reports-disabled-by-default).
`storybook dev --enable-crash-reports` | @@ -87,10 +87,10 @@ Options include: | `--stats-json [dir-name]` | Write stats JSON to disk
`storybook build --stats-json /tmp/stats` | | `--docs` | Builds Storybook in documentation mode. Learn more about it in [here](../writing-docs/build-documentation.md#publish-storybooks-documentation)
`storybook build --docs` | | `--test` | Optimize Storybook's production build for performance and tests by removing unnecessary features with the `test` option. Learn more [here](../api/main-config-build.md).
`storybook build --test` | -| `--preview-url [path]` | Disables the default Storybook preview and lets your use your own
`storybook build --preview-url=http://localhost:1337/external-iframe.html` | +| `--preview-url [path]` | Overrides the default Storybook preview with a custom built preview URL
`storybook build --preview-url=http://localhost:1337/external-iframe.html` | | `--force-build-preview` | Build the preview iframe even if you are using --preview-url
`storybook build --force-build-preview` | -| `--enable-crash-reports` | Enable sending crash reprots to Storybook's telemetry. Learn more about it [here](../configure/telemetry.md).
`storybook build --disable-telemetry` | -| `--disable-telemetry` | Disables Storybook's telemetry. Learn more about it [here](../configure/telemetry.md).
`storybook build --disable-telemetry` | +| `--disable-telemetry` | Disables Storybook's telemetry. Learn more about it [here](../configure/telemetry.md#how-to-opt-out).
`storybook build --disable-telemetry` | +| `--enable-crash-reports` | Enables sending crash reports to Storybook's telemetry. Learn more about it [here](../configure/telemetry.md#crash-reports-disabled-by-default).
`storybook build --enable-crash-reports` | @@ -106,20 +106,20 @@ For example, `storybook@latest init` will install the latest version of Storyboo Options include: -| Option | Description | -| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `--help` | Output usage information
`storybook init --help` | -| `-b`, `--builder` | Defines the [builder](../builders/index.md) to use for your Storybook instance
`storybook init --builder webpack5` | -| `-f`,`--force` | Forcefully installs Storybook into your project, prompting you to overwrite existing files
`storybook init --force` | -| `-s`, `--skip-install` | Skips the dependency installation step. Used only when you need to configure Storybook manually
`storybook init --skip-install` | -| `-t`, `--type` | Defines the [framework](../configure/frameworks.md) to use for your Storybook instance
`storybook init --type solid` | -| `-y`, `--yes` | Skips interactive prompts and automatically installs Storybook per specified version
`storybook init --yes` | -| `--package-manager` | Sets the package manager to use when installing the addon.
Available package managers include `npm`, `yarn`, and `pnpm`
`storybook init --package-manager pnpm` | -| `--use-pnp` | Enables [Plug'n'Play](https://yarnpkg.com/features/pnp) support for Yarn. This option is only available when using Yarn as your package manager
`storybook init --use-pnp` | -| `-p`, `--parser` | Sets the [jscodeshift parser](https://github.com/facebook/jscodeshift#parser).
Available parsers include `babel`, `babylon`, `flow`, `ts`, and `tsx`
`storybook init --parser tsx` | -| `--debug` | Outputs more logs in the CLI to assist debugging
`storybook init --debug` | -| `--disable-telemetry` | Disables Storybook's telemetry. Learn more about it [here](../configure/telemetry.md)
`storybook init --disable-telemetry` | -| `--enable-crash-reports` | Enable sending crash reprots to Storybook's telemetry. Learn more about it [here](../configure/telemetry.md).
`storybook init --disable-telemetry` | +| Option | Description | +| ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `-h`, `--help` | Output usage information
`storybook init --help` | +| `-b`, `--builder` | Defines the [builder](../builders/index.md) to use for your Storybook instance
`storybook init --builder webpack5` | +| `-f`,`--force` | Forcefully installs Storybook into your project, prompting you to overwrite existing files
`storybook init --force` | +| `-s`, `--skip-install` | Skips the dependency installation step. Used only when you need to configure Storybook manually
`storybook init --skip-install` | +| `-t`, `--type` | Defines the [framework](../configure/frameworks.md) to use for your Storybook instance
`storybook init --type solid` | +| `-y`, `--yes` | Skips interactive prompts and automatically installs Storybook per specified version
`storybook init --yes` | +| `--package-manager` | Sets the package manager to use when installing Storybook.
Available package managers include `npm`, `yarn`, and `pnpm`
`storybook init --package-manager pnpm` | +| `--use-pnp` | Enables [Plug'n'Play](https://yarnpkg.com/features/pnp) support for Yarn. This option is only available when using Yarn as your package manager
`storybook init --use-pnp` | +| `-p`, `--parser` | Sets the [jscodeshift parser](https://github.com/facebook/jscodeshift#parser).
Available parsers include `babel`, `babylon`, `flow`, `ts`, and `tsx`
`storybook init --parser tsx` | +| `--debug` | Outputs more logs in the CLI to assist debugging
`storybook init --debug` | +| `--disable-telemetry` | Disables Storybook's telemetry. Learn more about it [here](../configure/telemetry.md#how-to-opt-out)
`storybook init --disable-telemetry` | +| `--enable-crash-reports` | Enables sending crash reports to Storybook's telemetry. Learn more about it [here](../configure/telemetry.md#crash-reports-disabled-by-default).
`storybook init --enable-crash-reports` | ### `add` @@ -133,12 +133,10 @@ Options include: | Option | Description | | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `--help` | Output usage information
`storybook add --help` | +| `-h`, `--help` | Output usage information
`storybook add --help` | | `--package-manager` | Sets the package manager to use when installing the addon.
Available package managers include `npm`, `yarn`, and `pnpm`
`storybook add [addon] --package-manager pnpm` | | `-s`, `--skip-postinstall` | Skips post-install configuration. Used only when you need to configure the addon yourself
`storybook add [addon] --skip-postinstall` | | `--debug` | Outputs more logs in the CLI to assist debugging
`storybook add --debug` | -| `--disable-telemetry` | Disables Storybook's telemetry. Learn more about it [here](../configure/telemetry.md)
`storybook add --disable-telemetry` | -| `--enable-crash-reports` | Enable sending crash reprots to Storybook's telemetry. Learn more about it [here](../configure/telemetry.md).
`storybook add --disable-telemetry` | ### `remove` @@ -150,13 +148,13 @@ storybook remove [addon] [options] Options include: -| Option | Description | -| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| `--help` | Output usage information
`storybook remove --help` | -| `--package-manager` | Sets the package manager to use when removing the addon.
Available package managers include `npm`, `yarn`, and `pnpm`
`storybook remove [addon]--package-manager pnpm` | -| `--debug` | Outputs more logs in the CLI to assist debugging
`storybook remove --debug` | -| `--disable-telemetry` | Disables Storybook's telemetry. Learn more about it [here](../configure/telemetry.md)
`storybook remove --disable-telemetry` | -| `--enable-crash-reports` | Enable sending crash reprots to Storybook's telemetry. Learn more about it [here](../configure/telemetry.md).
`storybook remove --disable-telemetry` | +| Option | Description | +| ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `-h`, `--help` | Output usage information
`storybook remove --help` | +| `--package-manager` | Sets the package manager to use when removing the addon.
Available package managers include `npm`, `yarn`, and `pnpm`
`storybook remove [addon]--package-manager pnpm` | +| `--debug` | Outputs more logs in the CLI to assist debugging
`storybook remove --debug` | +| `--disable-telemetry` | Disables Storybook's telemetry. Learn more about it [here](../configure/telemetry.md#how-to-opt-out)
`storybook remove --disable-telemetry` | +| `--enable-crash-reports` | Enables sending crash reports to Storybook's telemetry. Learn more about it [here](../configure/telemetry.md#crash-reports-disabled-by-default).
`storybook remove --enable-crash-reports` | ### `upgrade` @@ -170,22 +168,22 @@ For example, `storybook@latest upgrade --dry-run` will perform a dry run (no act Options include: -| Option | Description | -| ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `--help` | Output usage information
`storybook upgrade --help` | -| `-c`, `--config-dir` | Directory where to load Storybook configurations from
`storybook upgrade --config-dir .storybook` | -| `-n`, `--dry-run` | Checks for version upgrades without installing them
`storybook upgrade --dry-run` | -| `-s`, `--skip-check` | Skips the migration check step during the upgrade process
`storybook upgrade --skip-check` | -| `-y`, `--yes` | Skips interactive prompts and automatically upgrades Storybook to the latest version
`storybook upgrade --yes` | -| `-f`,`--force` | Force the upgrade, skipping autoblockers check
`storybook upgrade --force` | -| `--package-manager` | Sets the package manager to use when installing the addon.
Available package managers include `npm`, `yarn`, and `pnpm`
`storybook upgrade --package-manager pnpm` | -| `--debug` | Outputs more logs in the CLI to assist debugging
`storybook upgrade --debug` | -| `--disable-telemetry` | Disables Storybook's telemetry. Learn more about it [here](../configure/telemetry.md)
`storybook upgrade --disable-telemetry` | -| `--enable-crash-reports` | Enable sending crash reprots to Storybook's telemetry. Learn more about it [here](../configure/telemetry.md).
`storybook upgrade --disable-telemetry` | +| Option | Description | +| ------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `-h`, `--help` | Output usage information
`storybook upgrade --help` | +| `-c`, `--config-dir` | Directory where to load Storybook configurations from
`storybook upgrade --config-dir .storybook` | +| `-n`, `--dry-run` | Checks for version upgrades without installing them
`storybook upgrade --dry-run` | +| `-s`, `--skip-check` | Skips the migration check step during the upgrade process
`storybook upgrade --skip-check` | +| `-y`, `--yes` | Skips interactive prompts and automatically upgrades Storybook to the latest version
`storybook upgrade --yes` | +| `-f`,`--force` | Force the upgrade, skipping autoblockers check
`storybook upgrade --force` | +| `--package-manager` | Sets the package manager to use when upgrading Storybook.
Available package managers include `npm`, `yarn`, and `pnpm`
`storybook upgrade --package-manager pnpm` | +| `--debug` | Outputs more logs in the CLI to assist debugging
`storybook upgrade --debug` | +| `--disable-telemetry` | Disables Storybook's telemetry. Learn more about it [here](../configure/telemetry.md#how-to-opt-out)
`storybook upgrade --disable-telemetry` | +| `--enable-crash-reports` | Enables sending crash reports to Storybook's telemetry. Learn more about it [here](../configure/telemetry.md#crash-reports-disabled-by-default).
`storybook upgrade --enable-crash-reports` | ### `migrate` -Runs a specified codemod to migrate your project to use more modern Storybook standards. +Runs the provided codemod to ensure your Storybook project is compatible with the specified version. Read more in the [migration guide](../configure/upgrading.md). ```shell storybook[@version] migrate [codemod] [options] @@ -193,52 +191,50 @@ storybook[@version] migrate [codemod] [options] -The command needs a specific codemod to be specified, e.g. `csf-2-to-3`. To get a list of available codemods, run the CLI command with the `--list` flag. +The command requires the codemod name (e.g., `csf-2-to-3`) as an argument to apply the necessary changes to your project. You can find the list of available codemods by running `storybook migrate --list`. -For example, `storybook@latest migrate csf-2-to-3 --dry-run` will verify that the codemod is applicable to your files and will show which files would be affected by the codemod in a dry run (no actual changes). +For example, `storybook@latest migrate csf-2-to-3 --dry-run`, checks your project to verify if the codemod can be applied without making any changes, providing you with a report of which files would be affected. Options include: | Option | Description | | -------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `--help` | Output usage information
`storybook migrate --help` | +| `-h`, `--help` | Output usage information
`storybook migrate --help` | | `-c`, `--config-dir` | Directory where to load Storybook configurations from
`storybook migrate --config-dir .storybook` | | `-n`, `--dry-run` | Verify the migration exists and show the files to which it will be applied
`storybook migrate --dry-run` | | `-l`, `--list` | Shows a list of available codemods
`storybook migrate --list` | | `-g`, `--glob` | Glob for files upon which to apply the codemods
`storybook migrate --glob src/**/*.stories.tsx` | | `-p`, `--parser` | Sets the [jscodeshift parser](https://github.com/facebook/jscodeshift#parser).
Available parsers include `babel`, `babylon`, `flow`, `ts`, and `tsx`
`storybook migrate --parser tsx` | -| `-r`, `--rename [from-to]` | Rename suffix of matching files after codemod has been applied, e.g. `.js:.ts`
`storybook migrate --rename ".js:.ts"` | +| `-r`, `--rename [from-to]` | Renames the files affected by the codemod to include the provided suffix
`storybook migrate --rename ".js:.ts"` | | `--debug` | Outputs more logs in the CLI to assist debugging
`storybook migrate --debug` | -| `--disable-telemetry` | Disables Storybook's telemetry. Learn more about it [here](../configure/telemetry.md)
`storybook migrate --disable-telemetry` | -| `--enable-crash-reports` | Enable sending crash reprots to Storybook's telemetry. Learn more about it [here](../configure/telemetry.md).
`storybook migrate --disable-telemetry` | ### `automigrate` -Check Storybook for incompatibilities or migrations and apply fixes. +Perform standard configuration checks to determine if your Storybook project can be automatically migrated to the specified version. Read more in the [migration guide](../configure/upgrading.md#automigrate-script). ```shell storybook[@version] automigrate [fixId] [options] ``` -For example, `storybook@latest automigrate --dry-run` will scan your codebase and tell which automigrations are applicable in a dry run (no actual changes). +For example, `storybook@latest automigrate --dry-run` scans your project for potential migrations that can be applied automatically without making any changes. Options include: -| Option | Description | -| ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --- | -| `--help` | Output usage information
`storybook automigrate --help` | -| `-c`, `--config-dir` | Directory where to load Storybook configurations from
`storybook automigrate --config-dir .storybook` | -| `-n`, `--dry-run` | Only checks for fixes, not actually executing them
`storybook automigrate --dry-run` | -| `-s`, `--skip-install` | Skip installing dependencies whenever applicable
`storybook automigrate --skip-install` | -| `-y`, `--yes` | Skips interactive prompts and automatically accepts automigrations
`storybook automigrate --yes` | -| `-l`, `--list` | Shows a list of available automigrations
`storybook automigrate --list` | -| `--package-manager` | Sets the package manager to use when installing the addon.
Available package managers include `npm`, `yarn`, and `pnpm`
`storybook automigrate --package-manager pnpm` | | -| `--renderer` | Sets the renderer package for the framework Storybook is using.
Useful for monorepo settings where multiple Storybook renderers are present in the same package.json
`storybook automigrate --renderer vue` | | -| `--debug` | Outputs more logs in the CLI to assist debugging
`storybook automigrate --debug` | -| `--disable-telemetry` | Disables Storybook's telemetry. Learn more about it [here](../configure/telemetry.md)
`storybook automigrate --disable-telemetry` | -| `--enable-crash-reports` | Enable sending crash reprots to Storybook's telemetry. Learn more about it [here](../configure/telemetry.md).
`storybook automigrate --disable-telemetry` | +| Option | Description | +| ------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --- | +| `-h`, `--help` | Output usage information
`storybook automigrate --help` | +| `-c`, `--config-dir` | Directory where to load Storybook configurations from
`storybook automigrate --config-dir .storybook` | +| `-n`, `--dry-run` | Checks for available migrations without applying them
`storybook automigrate --dry-run` | +| `-s`, `--skip-install` | Skip installing dependencies whenever applicable
`storybook automigrate --skip-install` | +| `-y`, `--yes` | Applies available migrations automatically without prompting for confirmation
`storybook automigrate --yes` | +| `-l`, `--list` | Shows a list of available automigrations
`storybook automigrate --list` | +| `--package-manager` | Sets the package manager to use when running the auto migration.
Available package managers include `npm`, `yarn`, and `pnpm`
`storybook automigrate --package-manager pnpm` | | +| `--renderer` | Specifies Storybook's renderer to use when running the automigration.
Useful for monorepo environments where multiple Storybook instances can exist in the same project
`storybook automigrate --renderer vue` | | +| `--debug` | Outputs more logs in the CLI to assist debugging
`storybook automigrate --debug` | +| `--disable-telemetry` | Disables Storybook's telemetry. Learn more about it [here](../configure/telemetry.md#how-to-opt-out)
`storybook automigrate --disable-telemetry` | +| `--enable-crash-reports` | Enables sending crash reports to Storybook's telemetry. Learn more about it [here](../configure/telemetry.md#crash-reports-disabled-by-default).
`storybook automigrate --enable-crash-reports` | ### `doctor` @@ -250,13 +246,12 @@ storybook doctor [options] Options include: -| Option | Description | -| ------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `-c`, `--config-dir` | Directory where to load Storybook configurations from
`storybook doctor --config-dir .storybook` | -| `--package-manager` | Sets the package manager to use when running the health check.
Available package managers include `npm`, `yarn`, and `pnpm`
`storybook doctor --package-manager pnpm` | -| `--debug` | Outputs more logs in the CLI to assist debugging
`storybook doctor --debug` | -| `--disable-telemetry` | Disables Storybook's telemetry. Learn more about it [here](../configure/telemetry.md)
`storybook doctor --disable-telemetry` | -| `--enable-crash-reports` | Enable sending crash reprots to Storybook's telemetry. Learn more about it [here](../configure/telemetry.md).
`storybook doctor --disable-telemetry` | +| Option | Description | +| -------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `-h`, `--help` | Output usage information
`storybook doctor --help` | +| `-c`, `--config-dir` | Directory where to load Storybook configurations from
`storybook doctor --config-dir .storybook` | +| `--package-manager` | Sets the package manager to use when running the health check.
Available package managers include `npm`, `yarn`, and `pnpm`
`storybook doctor --package-manager pnpm` | +| `--debug` | Outputs more logs in the CLI to assist debugging
`storybook doctor --debug` | ### `info` @@ -309,13 +304,14 @@ The `framework-filter` argument is optional and can filter the list of available Options include: -| Option | Description | -| --------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `-o`, `--output [dir-name]` | Configures the location of the sandbox project
`storybook sandbox --output /my-sandbox-project` | -| `--no-init` | Generates a sandbox project without without initializing Storybook
`storybook sandbox --no-init` | -| `--debug` | Outputs more logs in the CLI to assist debugging
`storybook sandbox --debug` | -| `--disable-telemetry` | Disables Storybook's telemetry. Learn more about it [here](../configure/telemetry.md)
`storybook sandbox --disable-telemetry` | -| `--enable-crash-reports` | Enable sending crash reprots to Storybook's telemetry. Learn more about it [here](../configure/telemetry.md).
`storybook sandbox --disable-telemetry` | +| Option | Description | +| --------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `-h`, `--help` | Output usage information
`storybook sandbox --help` | +| `-o`, `--output [dir-name]` | Configures the location of the sandbox project
`storybook sandbox --output /my-sandbox-project` | +| `--no-init` | Generates a sandbox project without without initializing Storybook
`storybook sandbox --no-init` | +| `--debug` | Outputs more logs in the CLI to assist debugging
`storybook sandbox --debug` | +| `--disable-telemetry` | Disables Storybook's telemetry. Learn more about it [here](../configure/telemetry.md#how-to-opt-out)
`storybook sandbox --disable-telemetry` | +| `--enable-crash-reports` | Enables sending crash reports to Storybook's telemetry. Learn more about it [here](../configure/telemetry.md#crash-reports-disabled-by-default).
`storybook sandbox --enable-crash-reports` | From 5819511fca6d9fc2f4433eb9226b1a25c5334d7a Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Thu, 4 Apr 2024 11:00:20 +0200 Subject: [PATCH 31/37] Bump globby dependency --- code/lib/cli/package.json | 2 +- .../cli/src/automigrate/fixes/mdx-1-to-3.ts | 4 +- .../cli/src/automigrate/fixes/mdx-gfm.test.ts | 2 +- code/lib/cli/src/automigrate/fixes/mdx-gfm.ts | 6 ++- code/lib/cli/src/warn.test.ts | 27 +++++++---- code/lib/cli/src/warn.ts | 11 +++-- code/lib/codemod/package.json | 2 +- code/lib/codemod/src/index.ts | 4 +- code/lib/core-server/package.json | 2 +- .../src/utils/StoryIndexGenerator.ts | 7 ++- .../src/utils/watch-story-specifiers.ts | 7 ++- code/yarn.lock | 45 ++++++++++++++++--- 12 files changed, 91 insertions(+), 28 deletions(-) diff --git a/code/lib/cli/package.json b/code/lib/cli/package.json index 3c0c985c8963..b54f29308a15 100644 --- a/code/lib/cli/package.json +++ b/code/lib/cli/package.json @@ -80,7 +80,7 @@ "fs-extra": "^11.1.0", "get-npm-tarball-url": "^2.0.3", "giget": "^1.0.0", - "globby": "^11.0.2", + "globby": "^14.0.1", "jscodeshift": "^0.15.1", "leven": "^3.1.0", "ora": "^5.4.1", diff --git a/code/lib/cli/src/automigrate/fixes/mdx-1-to-3.ts b/code/lib/cli/src/automigrate/fixes/mdx-1-to-3.ts index 3d81d0934447..8b556033a6ac 100644 --- a/code/lib/cli/src/automigrate/fixes/mdx-1-to-3.ts +++ b/code/lib/cli/src/automigrate/fixes/mdx-1-to-3.ts @@ -2,7 +2,6 @@ import chalk from 'chalk'; import { dedent } from 'ts-dedent'; import { basename } from 'path'; import fse from 'fs-extra'; -import globby from 'globby'; import type { Fix } from '../types'; const MDX1_STYLE_START = /