From cbfa75732be20c4a723ecbac1d011da33dd7bcae Mon Sep 17 00:00:00 2001 From: Jeppe Reinhold Date: Wed, 1 May 2024 21:48:13 +0200 Subject: [PATCH 01/10] initial warning --- .../store/csf/portable-stories.test.ts | 42 +++++++++++++++++++ .../src/modules/store/csf/portable-stories.ts | 34 +++++++++++++-- code/lib/types/src/modules/frameworks.ts | 2 + docs/api/portable-stories-jest.md | 18 ++++---- docs/api/portable-stories-vitest.md | 18 ++++---- 5 files changed, 92 insertions(+), 22 deletions(-) diff --git a/code/lib/preview-api/src/modules/store/csf/portable-stories.test.ts b/code/lib/preview-api/src/modules/store/csf/portable-stories.test.ts index 832ad437139f..84217ce004e3 100644 --- a/code/lib/preview-api/src/modules/store/csf/portable-stories.test.ts +++ b/code/lib/preview-api/src/modules/store/csf/portable-stories.test.ts @@ -255,6 +255,48 @@ describe('composeStory', () => { expect(spyFn).toHaveBeenNthCalledWith(2, 'from beforeEach'); }); + it.only('should warn when previous cleanups are still around when rendering a story', async () => { + const consoleWarnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {}); + const cleanupSpy = vi.fn(); + const beforeEachSpy = vi.fn(() => { + return () => { + cleanupSpy('cleanup from story'); + }; + }); + + const PreviousStory: Story = { + render: () => 'first', + beforeEach: beforeEachSpy, + }; + const CurrentStory: Story = { + render: () => 'second', + args: { + firstArg: false, + secondArg: true, + }, + }; + const firstComposedStory = composeStory(PreviousStory, {}); + await firstComposedStory.load(); + firstComposedStory(); + + expect(beforeEachSpy).toHaveBeenCalled(); + expect(cleanupSpy).not.toHaveBeenCalled(); + expect(consoleWarnSpy).not.toHaveBeenCalled(); + + const secondComposedStory = composeStory(CurrentStory, {}); + secondComposedStory(); + + expect(cleanupSpy).not.toHaveBeenCalled(); + expect(consoleWarnSpy).toHaveBeenCalledOnce(); + expect(consoleWarnSpy.mock.calls[0][0]).toMatchInlineSnapshot( + ` + "Some stories were not cleaned up before rendering 'Unnamed Story (firstArg, secondArg)'. + You should load the story with \`await Story.load()\` before rendering it. + See XYZ for more information." + ` + ); + }); + it('should throw an error if Story is undefined', () => { expect(() => { // @ts-expect-error (invalid input) diff --git a/code/lib/preview-api/src/modules/store/csf/portable-stories.ts b/code/lib/preview-api/src/modules/store/csf/portable-stories.ts index c4aa34874040..edd096ada36f 100644 --- a/code/lib/preview-api/src/modules/store/csf/portable-stories.ts +++ b/code/lib/preview-api/src/modules/store/csf/portable-stories.ts @@ -47,7 +47,7 @@ export function setProjectAnnotations( globalProjectAnnotations = composeConfigs(annotations.map(extractAnnotation)); } -const cleanupCallbacks: CleanupCallback[] = []; +const cleanups: { storyName: string; callback: CleanupCallback }[] = []; export function composeStory( storyAnnotations: LegacyStoryAnnotationsOrFn, @@ -115,6 +115,8 @@ export function composeStory> = Object.assign( function storyFn(extraArgs?: Partial) { context.args = { @@ -122,6 +124,24 @@ export function composeStory 0 && !previousCleanupsDone) { + let humanReadableIdentifier = storyName; + if (story.title !== 'ComposedStory') { + // prefix with title unless it's the generic ComposedStory title + humanReadableIdentifier = `${story.title} - ${humanReadableIdentifier}`; + } + if (storyName === 'Unnamed Story' && Object.keys(context.args).length > 0) { + // suffix with args if it's an unnamed story and there are args + humanReadableIdentifier = `${humanReadableIdentifier} (${Object.keys(context.args).join( + ', ' + )})`; + } + console.warn( + dedent`Some stories were not cleaned up before rendering '${humanReadableIdentifier}'. + You should load the story with \`await Story.load()\` before rendering it. + See XYZ for more information.` + ); + } return story.unboundStoryFn(prepareContext(context)); }, { @@ -129,13 +149,19 @@ export function composeStory { // First run any registered cleanup function - for (const callback of [...cleanupCallbacks].reverse()) await callback(); - cleanupCallbacks.length = 0; + for (const { callback } of [...cleanups].reverse()) await callback(); + cleanups.length = 0; + + previousCleanupsDone = true; const loadedContext = await story.applyLoaders(context); context.loaded = loadedContext.loaded; - cleanupCallbacks.push(...(await story.applyBeforeEach(context))); + cleanups.push( + ...(await story.applyBeforeEach(context)) + .filter(Boolean) + .map((callback) => ({ storyName, callback })) + ); }, args: story.initialArgs as Partial, parameters: story.parameters as Parameters, diff --git a/code/lib/types/src/modules/frameworks.ts b/code/lib/types/src/modules/frameworks.ts index c1ea25abe7b0..0785763f46e5 100644 --- a/code/lib/types/src/modules/frameworks.ts +++ b/code/lib/types/src/modules/frameworks.ts @@ -14,6 +14,8 @@ export type SupportedFrameworks = | 'svelte-vite' | 'svelte-webpack5' | 'sveltekit' + | 'vue-vite' + | 'vue-webpack5' | 'vue3-vite' | 'vue3-webpack5' | 'web-components-vite' diff --git a/docs/api/portable-stories-jest.md b/docs/api/portable-stories-jest.md index 4c4141a53922..64bf34eb2c6b 100644 --- a/docs/api/portable-stories-jest.md +++ b/docs/api/portable-stories-jest.md @@ -91,15 +91,15 @@ An object where the keys are the names of the stories and the values are the com Additionally, the composed story will have the following properties: -| Property | Type | Description | -| ---------- | -------------------------------------------------------- | --------------------------------------------------------------- | -| storyName | `string` | The story's name | -| args | `Record` | The story's [args](../writing-stories/args.md) | -| argTypes | `ArgType` | The story's [argTypes](./arg-types.md) | -| id | `string` | The story's id | -| parameters | `Record` | The story's [parameters](./parameters.md) | -| load | `() => Promise` | Executes all the [loaders](#2-load-optional) for a given story | -| play | `(context?: StoryContext) => Promise \| undefined` | Executes the [play function](#4-play-optional) of a given story | +| Property | Type | Description | +| ---------- | -------------------------------------------------------- | ------------------------------------------------------------------------------------------- | +| storyName | `string` | The story's name | +| args | `Record` | The story's [args](../writing-stories/args.md) | +| argTypes | `ArgType` | The story's [argTypes](./arg-types.md) | +| id | `string` | The story's id | +| parameters | `Record` | The story's [parameters](./parameters.md) | +| load | `() => Promise` | Executes all the [loaders](#2-load-optional) for a given story and cleanup previous stories | +| play | `(context?: StoryContext) => Promise \| undefined` | Executes the [play function](#4-play-optional) of a given story | ## composeStory diff --git a/docs/api/portable-stories-vitest.md b/docs/api/portable-stories-vitest.md index 0342b7cc1e21..a427e8d8fa7f 100644 --- a/docs/api/portable-stories-vitest.md +++ b/docs/api/portable-stories-vitest.md @@ -99,15 +99,15 @@ An object where the keys are the names of the stories and the values are the com Additionally, the composed story will have the following properties: -| Property | Type | Description | -| ---------- | ----------------------------------------- | --------------------------------------------------------------- | -| storyName | `string` | The story's name | -| args | `Record` | The story's [args](../writing-stories/args.md) | -| argTypes | `ArgType` | The story's [argTypes](./arg-types.md) | -| id | `string` | The story's id | -| parameters | `Record` | The story's [parameters](./parameters.md) | -| load | `() => Promise` | Executes all the [loaders](#2-load-optional) for a given story | -| play | `(context) => Promise \| undefined` | Executes the [play function](#4-play-optional) of a given story | +| Property | Type | Description | +| ---------- | ----------------------------------------- | ------------------------------------------------------------------------------------------- | +| storyName | `string` | The story's name | +| args | `Record` | The story's [args](../writing-stories/args.md) | +| argTypes | `ArgType` | The story's [argTypes](./arg-types.md) | +| id | `string` | The story's id | +| parameters | `Record` | The story's [parameters](./parameters.md) | +| load | `() => Promise` | Executes all the [loaders](#2-load-optional) for a given story and cleanup previous stories | +| play | `(context) => Promise \| undefined` | Executes the [play function](#4-play-optional) of a given story | ## composeStory From e4d1b06c20cde0aa09ef770f25f17dfeaec10ae6 Mon Sep 17 00:00:00 2001 From: Jeppe Reinhold Date: Thu, 2 May 2024 10:34:10 +0200 Subject: [PATCH 02/10] remove optional from load api docs --- docs/api/portable-stories-jest.md | 12 ++++++++---- docs/api/portable-stories-vitest.md | 28 ++++++++++++++++------------ 2 files changed, 24 insertions(+), 16 deletions(-) diff --git a/docs/api/portable-stories-jest.md b/docs/api/portable-stories-jest.md index 64bf34eb2c6b..53f988403bb3 100644 --- a/docs/api/portable-stories-jest.md +++ b/docs/api/portable-stories-jest.md @@ -98,7 +98,7 @@ Additionally, the composed story will have the following properties: | argTypes | `ArgType` | The story's [argTypes](./arg-types.md) | | id | `string` | The story's id | | parameters | `Record` | The story's [parameters](./parameters.md) | -| load | `() => Promise` | Executes all the [loaders](#2-load-optional) for a given story and cleanup previous stories | +| load | `() => Promise` | [Prepares](#3-load) the story for rendering and and cleans up all previous stories | | play | `(context?: StoryContext) => Promise \| undefined` | Executes the [play function](#4-play-optional) of a given story | ## composeStory @@ -245,12 +245,16 @@ The story is prepared by running [`composeStories`](#composestories) or [`compos ### 3. Load -**(optional)** - -Stories can prepare data they need (e.g. setting up some mocks or fetching data) before rendering by defining [loaders](../writing-stories/loaders.md). In portable stories, the loaders are not applied automatically—you have to apply them yourself. +Stories can prepare data they need (e.g. setting up some mocks or fetching data) before rendering by defining [loaders](../writing-stories/loaders.md) or [beforeEach](../writing-stories/mocking-modules.md#setting-up-and-cleaning-up). In portable stories, loaders and beforeEach are not applied automatically — you have to apply them yourself. 👉 For this, you use the [`composeStories`](#composestories) or [`composeStory`](#composestory) API. The composed story will return a `load` method to be called **before** it is rendered. + + +While it's technically optional to run `load` before rendering, it is highly encouraged to always do this, even if the story doesn't have any loaders or beforeEach. If you later add any of these to the story, you don't need to remember to also call `load`. Cleaning up previous stories is also important, and calling `load` ensures that later modifying other stories doesn't affect the current story. + + + ` | The story's [args](../writing-stories/args.md) | -| argTypes | `ArgType` | The story's [argTypes](./arg-types.md) | -| id | `string` | The story's id | -| parameters | `Record` | The story's [parameters](./parameters.md) | -| load | `() => Promise` | Executes all the [loaders](#2-load-optional) for a given story and cleanup previous stories | -| play | `(context) => Promise \| undefined` | Executes the [play function](#4-play-optional) of a given story | +| Property | Type | Description | +| ---------- | ----------------------------------------- | ---------------------------------------------------------------------------------- | +| storyName | `string` | The story's name | +| args | `Record` | The story's [args](../writing-stories/args.md) | +| argTypes | `ArgType` | The story's [argTypes](./arg-types.md) | +| id | `string` | The story's id | +| parameters | `Record` | The story's [parameters](./parameters.md) | +| load | `() => Promise` | [Prepares](#3-load) the story for rendering and and cleans up all previous stories | +| play | `(context) => Promise \| undefined` | Executes the [play function](#4-play-optional) of a given story | ## composeStory @@ -240,12 +240,16 @@ The story is prepared by running [`composeStories`](#composestories) or [`compos ### 3. Load -**(optional)** - -Stories can prepare data they need (e.g. setting up some mocks or fetching data) before rendering by defining [loaders](../writing-stories/loaders.md). In portable stories, the loaders are not applied automatically—you have to apply them yourself. +Stories can prepare data they need (e.g. setting up some mocks or fetching data) before rendering by defining [loaders](../writing-stories/loaders.md) or [beforeEach](../writing-stories/mocking-modules.md#setting-up-and-cleaning-up). In portable stories, loaders and beforeEach are not applied automatically — you have to apply them yourself. 👉 For this, you use the [`composeStories`](#composestories) or [`composeStory`](#composestory) API. The composed story will return a `load` method to be called **before** it is rendered. + + +While it's technically optional to run `load` before rendering, it is highly encouraged to always do this, even if the story doesn't have any loaders or beforeEach. If you later add any of these to the story, you don't need to remember to also call `load`. Cleaning up previous stories is also important, and calling `load` ensures that later modifying other stories doesn't affect the current story. + + + Date: Thu, 2 May 2024 13:38:17 +0200 Subject: [PATCH 03/10] add correct link to portable stories docs --- .../lib/preview-api/src/modules/store/csf/portable-stories.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/code/lib/preview-api/src/modules/store/csf/portable-stories.ts b/code/lib/preview-api/src/modules/store/csf/portable-stories.ts index edd096ada36f..97237003ab44 100644 --- a/code/lib/preview-api/src/modules/store/csf/portable-stories.ts +++ b/code/lib/preview-api/src/modules/store/csf/portable-stories.ts @@ -139,7 +139,9 @@ export function composeStory Date: Thu, 2 May 2024 13:41:28 +0200 Subject: [PATCH 04/10] improve default title and name typesafety --- .../src/modules/store/csf/portable-stories.ts | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/code/lib/preview-api/src/modules/store/csf/portable-stories.ts b/code/lib/preview-api/src/modules/store/csf/portable-stories.ts index 97237003ab44..9c18e46a6c79 100644 --- a/code/lib/preview-api/src/modules/store/csf/portable-stories.ts +++ b/code/lib/preview-api/src/modules/store/csf/portable-stories.ts @@ -29,6 +29,9 @@ import { normalizeProjectAnnotations } from './normalizeProjectAnnotations'; let globalProjectAnnotations: ProjectAnnotations = {}; +const DEFAULT_TITLE = 'ComposedStory'; +const DEFAULT_NAME = 'Unnamed Story'; + function extractAnnotation( annotation: NamedOrDefaultProjectAnnotations ) { @@ -63,7 +66,7 @@ export function composeStory(componentAnnotations); @@ -72,7 +75,7 @@ export function composeStory( storyName, @@ -126,11 +129,11 @@ export function composeStory 0 && !previousCleanupsDone) { let humanReadableIdentifier = storyName; - if (story.title !== 'ComposedStory') { + if (story.title !== DEFAULT_TITLE) { // prefix with title unless it's the generic ComposedStory title humanReadableIdentifier = `${story.title} - ${humanReadableIdentifier}`; } - if (storyName === 'Unnamed Story' && Object.keys(context.args).length > 0) { + if (storyName === DEFAULT_NAME && Object.keys(context.args).length > 0) { // suffix with args if it's an unnamed story and there are args humanReadableIdentifier = `${humanReadableIdentifier} (${Object.keys(context.args).join( ', ' From 0b88b643f3d0313aa8ddf5178f0d56e9e1840f0a Mon Sep 17 00:00:00 2001 From: Jeppe Reinhold Date: Thu, 2 May 2024 13:44:04 +0200 Subject: [PATCH 05/10] remove it.only --- .../preview-api/src/modules/store/csf/portable-stories.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/lib/preview-api/src/modules/store/csf/portable-stories.test.ts b/code/lib/preview-api/src/modules/store/csf/portable-stories.test.ts index 84217ce004e3..e212e4ba12be 100644 --- a/code/lib/preview-api/src/modules/store/csf/portable-stories.test.ts +++ b/code/lib/preview-api/src/modules/store/csf/portable-stories.test.ts @@ -255,7 +255,7 @@ describe('composeStory', () => { expect(spyFn).toHaveBeenNthCalledWith(2, 'from beforeEach'); }); - it.only('should warn when previous cleanups are still around when rendering a story', async () => { + it('should warn when previous cleanups are still around when rendering a story', async () => { const consoleWarnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {}); const cleanupSpy = vi.fn(); const beforeEachSpy = vi.fn(() => { From 24148ad353d15ab00b88eb507f8da2f5e777861d Mon Sep 17 00:00:00 2001 From: Jeppe Reinhold Date: Thu, 2 May 2024 13:51:13 +0200 Subject: [PATCH 06/10] update stories --- .../src/modules/store/csf/portable-stories.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/lib/preview-api/src/modules/store/csf/portable-stories.test.ts b/code/lib/preview-api/src/modules/store/csf/portable-stories.test.ts index e212e4ba12be..90115c5aeceb 100644 --- a/code/lib/preview-api/src/modules/store/csf/portable-stories.test.ts +++ b/code/lib/preview-api/src/modules/store/csf/portable-stories.test.ts @@ -260,7 +260,7 @@ describe('composeStory', () => { const cleanupSpy = vi.fn(); const beforeEachSpy = vi.fn(() => { return () => { - cleanupSpy('cleanup from story'); + cleanupSpy(); }; }); @@ -292,7 +292,7 @@ describe('composeStory', () => { ` "Some stories were not cleaned up before rendering 'Unnamed Story (firstArg, secondArg)'. You should load the story with \`await Story.load()\` before rendering it. - See XYZ for more information." + See https://storybook.js.org/docs/api/portable-stories-vitest#3-load for more information." ` ); }); From f7d809a801ecb5fff22669425899e286a6860962 Mon Sep 17 00:00:00 2001 From: Jeppe Reinhold Date: Thu, 2 May 2024 14:08:53 +0200 Subject: [PATCH 07/10] improve readability --- .../src/modules/store/csf/portable-stories.ts | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/code/lib/preview-api/src/modules/store/csf/portable-stories.ts b/code/lib/preview-api/src/modules/store/csf/portable-stories.ts index 9c18e46a6c79..a4385605685e 100644 --- a/code/lib/preview-api/src/modules/store/csf/portable-stories.ts +++ b/code/lib/preview-api/src/modules/store/csf/portable-stories.ts @@ -29,8 +29,8 @@ import { normalizeProjectAnnotations } from './normalizeProjectAnnotations'; let globalProjectAnnotations: ProjectAnnotations = {}; -const DEFAULT_TITLE = 'ComposedStory'; -const DEFAULT_NAME = 'Unnamed Story'; +const DEFAULT_STORY_TITLE = 'ComposedStory'; +const DEFAULT_STORY_NAME = 'Unnamed Story'; function extractAnnotation( annotation: NamedOrDefaultProjectAnnotations @@ -66,7 +66,7 @@ export function composeStory(componentAnnotations); @@ -75,7 +75,7 @@ export function composeStory( storyName, @@ -129,11 +129,11 @@ export function composeStory 0 && !previousCleanupsDone) { let humanReadableIdentifier = storyName; - if (story.title !== DEFAULT_TITLE) { + if (story.title !== DEFAULT_STORY_TITLE) { // prefix with title unless it's the generic ComposedStory title humanReadableIdentifier = `${story.title} - ${humanReadableIdentifier}`; } - if (storyName === DEFAULT_NAME && Object.keys(context.args).length > 0) { + if (storyName === DEFAULT_STORY_NAME && Object.keys(context.args).length > 0) { // suffix with args if it's an unnamed story and there are args humanReadableIdentifier = `${humanReadableIdentifier} (${Object.keys(context.args).join( ', ' @@ -141,6 +141,7 @@ export function composeStory Date: Thu, 2 May 2024 14:35:26 +0200 Subject: [PATCH 08/10] update test snapshots --- .../preview-api/src/modules/store/csf/portable-stories.test.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/code/lib/preview-api/src/modules/store/csf/portable-stories.test.ts b/code/lib/preview-api/src/modules/store/csf/portable-stories.test.ts index 90115c5aeceb..9322d3c9d2a3 100644 --- a/code/lib/preview-api/src/modules/store/csf/portable-stories.test.ts +++ b/code/lib/preview-api/src/modules/store/csf/portable-stories.test.ts @@ -291,6 +291,7 @@ describe('composeStory', () => { expect(consoleWarnSpy.mock.calls[0][0]).toMatchInlineSnapshot( ` "Some stories were not cleaned up before rendering 'Unnamed Story (firstArg, secondArg)'. + You should load the story with \`await Story.load()\` before rendering it. See https://storybook.js.org/docs/api/portable-stories-vitest#3-load for more information." ` From 0690c53d6a13a1c6075e15f1f9d7060e98a21abf Mon Sep 17 00:00:00 2001 From: Jeppe Reinhold Date: Fri, 3 May 2024 20:48:46 +0200 Subject: [PATCH 09/10] update portable stories docs --- docs/api/portable-stories-jest.md | 26 +++++++++++++------------- docs/api/portable-stories-vitest.md | 26 +++++++++++++------------- 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/docs/api/portable-stories-jest.md b/docs/api/portable-stories-jest.md index 53f988403bb3..3abe9798112c 100644 --- a/docs/api/portable-stories-jest.md +++ b/docs/api/portable-stories-jest.md @@ -91,15 +91,15 @@ An object where the keys are the names of the stories and the values are the com Additionally, the composed story will have the following properties: -| Property | Type | Description | -| ---------- | -------------------------------------------------------- | ------------------------------------------------------------------------------------------- | -| storyName | `string` | The story's name | -| args | `Record` | The story's [args](../writing-stories/args.md) | -| argTypes | `ArgType` | The story's [argTypes](./arg-types.md) | -| id | `string` | The story's id | -| parameters | `Record` | The story's [parameters](./parameters.md) | -| load | `() => Promise` | [Prepares](#3-load) the story for rendering and and cleans up all previous stories | -| play | `(context?: StoryContext) => Promise \| undefined` | Executes the [play function](#4-play-optional) of a given story | +| Property | Type | Description | +| ---------- | -------------------------------------------------------- | ------------------------------------------------------------------------------------- | +| storyName | `string` | The story's name | +| args | `Record` | The story's [args](../writing-stories/args.md) | +| argTypes | `ArgType` | The story's [argTypes](./arg-types.md) | +| id | `string` | The story's id | +| parameters | `Record` | The story's [parameters](./parameters.md) | +| load | `() => Promise` | [Prepares](#3-prepare) the story for rendering and and cleans up all previous stories | +| play | `(context?: StoryContext) => Promise \| undefined` | Executes the [play function](#5-play) of a given story | ## composeStory @@ -239,19 +239,19 @@ When you want to reuse a story in a different environment, however, it's crucial 👉 For this, you use the [`setProjectAnnotations`](#setprojectannotations) API. -### 2. Prepare +### 2. Compose The story is prepared by running [`composeStories`](#composestories) or [`composeStory`](#composestory). You do not need to do anything for this step. -### 3. Load +### 3. Prepare -Stories can prepare data they need (e.g. setting up some mocks or fetching data) before rendering by defining [loaders](../writing-stories/loaders.md) or [beforeEach](../writing-stories/mocking-modules.md#setting-up-and-cleaning-up). In portable stories, loaders and beforeEach are not applied automatically — you have to apply them yourself. +Stories can prepare data they need (e.g. setting up some mocks or fetching data) before rendering by defining [loaders](../writing-stories/loaders.md) or [beforeEach](../writing-tests/interaction-testing.md#run-code-before-each-test). In portable stories, loaders and beforeEach are not applied automatically — you have to apply them yourself. 👉 For this, you use the [`composeStories`](#composestories) or [`composeStory`](#composestory) API. The composed story will return a `load` method to be called **before** it is rendered. -While it's technically optional to run `load` before rendering, it is highly encouraged to always do this, even if the story doesn't have any loaders or beforeEach. If you later add any of these to the story, you don't need to remember to also call `load`. Cleaning up previous stories is also important, and calling `load` ensures that later modifying other stories doesn't affect the current story. +It is recommended to always run `load` before rendering, even if the story doesn't have any loaders or beforeEach applied. By doing so, you ensure that the tests are cleaned up properly to maintain isolation and you will not have to update your test if you later add them to your story. diff --git a/docs/api/portable-stories-vitest.md b/docs/api/portable-stories-vitest.md index feab828de68b..2a934f68736e 100644 --- a/docs/api/portable-stories-vitest.md +++ b/docs/api/portable-stories-vitest.md @@ -99,15 +99,15 @@ An object where the keys are the names of the stories and the values are the com Additionally, the composed story will have the following properties: -| Property | Type | Description | -| ---------- | ----------------------------------------- | ---------------------------------------------------------------------------------- | -| storyName | `string` | The story's name | -| args | `Record` | The story's [args](../writing-stories/args.md) | -| argTypes | `ArgType` | The story's [argTypes](./arg-types.md) | -| id | `string` | The story's id | -| parameters | `Record` | The story's [parameters](./parameters.md) | -| load | `() => Promise` | [Prepares](#3-load) the story for rendering and and cleans up all previous stories | -| play | `(context) => Promise \| undefined` | Executes the [play function](#4-play-optional) of a given story | +| Property | Type | Description | +| ---------- | ----------------------------------------- | ------------------------------------------------------------------------------------- | +| storyName | `string` | The story's name | +| args | `Record` | The story's [args](../writing-stories/args.md) | +| argTypes | `ArgType` | The story's [argTypes](./arg-types.md) | +| id | `string` | The story's id | +| parameters | `Record` | The story's [parameters](./parameters.md) | +| load | `() => Promise` | [Prepares](#3-prepare) the story for rendering and and cleans up all previous stories | +| play | `(context) => Promise \| undefined` | Executes the [play function](#5-play) of a given story | ## composeStory @@ -234,19 +234,19 @@ When you want to reuse a story in a different environment, however, it's crucial 👉 For this, you use the [`setProjectAnnotations`](#setprojectannotations) API. -### 2. Prepare +### 2. Compose The story is prepared by running [`composeStories`](#composestories) or [`composeStory`](#composestory). You do not need to do anything for this step. -### 3. Load +### 3. Prepare -Stories can prepare data they need (e.g. setting up some mocks or fetching data) before rendering by defining [loaders](../writing-stories/loaders.md) or [beforeEach](../writing-stories/mocking-modules.md#setting-up-and-cleaning-up). In portable stories, loaders and beforeEach are not applied automatically — you have to apply them yourself. +Stories can prepare data they need (e.g. setting up some mocks or fetching data) before rendering by defining [loaders](../writing-stories/loaders.md) or [beforeEach](../writing-tests/interaction-testing.md#run-code-before-each-test). In portable stories, loaders and beforeEach are not applied automatically — you have to apply them yourself. 👉 For this, you use the [`composeStories`](#composestories) or [`composeStory`](#composestory) API. The composed story will return a `load` method to be called **before** it is rendered. -While it's technically optional to run `load` before rendering, it is highly encouraged to always do this, even if the story doesn't have any loaders or beforeEach. If you later add any of these to the story, you don't need to remember to also call `load`. Cleaning up previous stories is also important, and calling `load` ensures that later modifying other stories doesn't affect the current story. +It is recommended to always run `load` before rendering, even if the story doesn't have any loaders or beforeEach applied. By doing so, you ensure that the tests are cleaned up properly to maintain isolation and you will not have to update your test if you later add them to your story. From eebfd15df5c9912e3d7de28b6231ddfc16ff7a4d Mon Sep 17 00:00:00 2001 From: Jeppe Reinhold Date: Fri, 3 May 2024 20:55:06 +0200 Subject: [PATCH 10/10] fix mistakes. --- code/lib/types/src/modules/frameworks.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/code/lib/types/src/modules/frameworks.ts b/code/lib/types/src/modules/frameworks.ts index 0785763f46e5..c1ea25abe7b0 100644 --- a/code/lib/types/src/modules/frameworks.ts +++ b/code/lib/types/src/modules/frameworks.ts @@ -14,8 +14,6 @@ export type SupportedFrameworks = | 'svelte-vite' | 'svelte-webpack5' | 'sveltekit' - | 'vue-vite' - | 'vue-webpack5' | 'vue3-vite' | 'vue3-webpack5' | 'web-components-vite'