Merge pull request #20053 from storybookjs/add-csf-2-to-3-banner

This commit is contained in:
Kyle Gach 2022-12-05 13:53:06 -07:00 committed by GitHub
commit 098664d009
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
73 changed files with 666 additions and 68 deletions

View File

@ -50,29 +50,29 @@ Addon authors can develop their UIs using any React library. But we recommend us
Use the components listed below with your next addon. Use the components listed below with your next addon.
| Component | Source | Story | | Component | Source | Story |
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | | ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
| Action Bar | [See component implementation](https://github.com/storybookjs/storybook/blob/master/code/ui/components/src/ActionBar/ActionBar.tsx) | [See component story](https://5a375b97f4b14f0020b0cda3-wbeulgbetj.chromatic.com/?path=/story/basics-actionbar--single-item) | | Action Bar | [See component implementation](https://github.com/storybookjs/storybook/blob/main/code/ui/components/src/ActionBar/ActionBar.tsx) | [See component story](https://main--5a375b97f4b14f0020b0cda3.chromatic.com/?path=/story/basics-actionbar--single-item) |
| Addon Panel | [See component implementation](https://github.com/storybookjs/storybook/blob/master/code/ui/components/src/addon-panel/addon-panel.tsx) | N/A | | Addon Panel | [See component implementation](https://github.com/storybookjs/storybook/blob/main/code/ui/components/src/addon-panel/addon-panel.tsx) | N/A |
| Badge | [See component implementation](https://github.com/storybookjs/storybook/blob/master/code/ui/components/src/Badge/Badge.tsx) | [See component story](https://5a375b97f4b14f0020b0cda3-wbeulgbetj.chromatic.com/?path=/story/basics-badge--all-badges) | | Badge | [See component implementation](https://github.com/storybookjs/storybook/blob/main/code/ui/components/src/Badge/Badge.tsx) | [See component story](https://main--5a375b97f4b14f0020b0cda3.chromatic.com/?path=/story/basics-badge--all-badges) |
| Button | [See component implementation](https://github.com/storybookjs/storybook/blob/master/code/ui/components/src/Button/Button.tsx) | [See component story](https://5a375b97f4b14f0020b0cda3-wbeulgbetj.chromatic.com/?path=/story/basics-button--all-buttons) | | Button | [See component implementation](https://github.com/storybookjs/storybook/blob/main/code/ui/components/src/Button/Button.tsx) | [See component story](https://main--5a375b97f4b14f0020b0cda3.chromatic.com/?path=/story/basics-button--all-buttons) |
| Form | [See component implementation](https://github.com/storybookjs/storybook/blob/master/code/ui/components/src/form/index.tsx) | [See component story](https://5a375b97f4b14f0020b0cda3-wbeulgbetj.chromatic.com/?path=/story/basics-form-button--sizes) | | Form | [See component implementation](https://github.com/storybookjs/storybook/blob/main/code/ui/components/src/form/index.tsx) | [See component story](https://main--5a375b97f4b14f0020b0cda3.chromatic.com/?path=/story/basics-form-button--sizes) |
| Loader | [See component implementation](https://github.com/storybookjs/storybook/blob/master/code/ui/components/src/Loader/Loader.tsx) | [See component story](https://5a375b97f4b14f0020b0cda3-wbeulgbetj.chromatic.com/?path=/story/basics-loader--progress-bar) | | Loader | [See component implementation](https://github.com/storybookjs/storybook/blob/main/code/ui/components/src/Loader/Loader.tsx) | [See component story](https://main--5a375b97f4b14f0020b0cda3.chromatic.com/?path=/story/basics-loader--progress-bar) |
| PlaceHolder | [See component implementation](https://github.com/storybookjs/storybook/blob/master/code/ui/components/src/placeholder/placeholder.tsx) | [See component story](https://5a375b97f4b14f0020b0cda3-wbeulgbetj.chromatic.com/?path=/story/basics-placeholder--single-child) | | PlaceHolder | [See component implementation](https://github.com/storybookjs/storybook/blob/main/code/ui/components/src/placeholder/placeholder.tsx) | [See component story](https://main--5a375b97f4b14f0020b0cda3.chromatic.com/?path=/story/basics-placeholder--single-child) |
| Scroll Area | [See component implementation](https://github.com/storybookjs/storybook/blob/master/code/ui/components/src/ScrollArea/ScrollArea.tsx) | [See component story](https://5a375b97f4b14f0020b0cda3-wbeulgbetj.chromatic.com/?path=/story/basics-scrollarea--vertical) | | Scroll Area | [See component implementation](https://github.com/storybookjs/storybook/blob/main/code/ui/components/src/ScrollArea/ScrollArea.tsx) | [See component story](https://main--5a375b97f4b14f0020b0cda3.chromatic.com/?path=/story/basics-scrollarea--vertical) |
| Space | [See component implementation](https://github.com/storybookjs/storybook/blob/master/code/ui/components/src/spaced/Spaced.tsx) | [See component story](https://5a375b97f4b14f0020b0cda3-wbeulgbetj.chromatic.com/?path=/story/basics-spaced--row) | | Space | [See component implementation](https://github.com/storybookjs/storybook/blob/main/code/ui/components/src/spaced/Spaced.tsx) | [See component story](https://main--5a375b97f4b14f0020b0cda3.chromatic.com/?path=/story/basics-spaced--row) |
| Syntax Highlighter | [See component implementation](https://github.com/storybookjs/storybook/blob/master/code/ui/components/src/syntaxhighlighter/syntaxhighlighter.tsx) | [See component story](https://5a375b97f4b14f0020b0cda3-wbeulgbetj.chromatic.com/?path=/story/basics-syntaxhighlighter--bash) | | Syntax Highlighter | [See component implementation](https://github.com/storybookjs/storybook/blob/main/code/ui/components/src/syntaxhighlighter/syntaxhighlighter.tsx) | [See component story](https://main--5a375b97f4b14f0020b0cda3.chromatic.com/?path=/story/basics-syntaxhighlighter--bash) |
| Tabs | [See component implementation](https://github.com/storybookjs/storybook/blob/master/code/ui/components/src/tabs/tabs.tsx) | [See component story](https://5a375b97f4b14f0020b0cda3-wbeulgbetj.chromatic.com/?path=/story/basics-tabs--stateful-static) | | Tabs | [See component implementation](https://github.com/storybookjs/storybook/blob/main/code/ui/components/src/tabs/tabs.tsx) | [See component story](https://main--5a375b97f4b14f0020b0cda3.chromatic.com/?path=/story/basics-tabs--stateful-static) |
| ToolBar | [See component implementation](https://github.com/storybookjs/storybook/blob/master/code/ui/components/src/bar/bar.tsx) | N/A | | ToolBar | [See component implementation](https://github.com/storybookjs/storybook/blob/main/code/ui/components/src/bar/bar.tsx) | N/A |
| ToolTip | [See component implementation](https://github.com/storybookjs/storybook/blob/master/code/ui/components/src/tooltip/Tooltip.tsx) | [See component story](https://5a375b97f4b14f0020b0cda3-wbeulgbetj.chromatic.com/?path=/story/basics-tooltip-tooltip--basic-default) | | ToolTip | [See component implementation](https://github.com/storybookjs/storybook/blob/main/code/ui/components/src/tooltip/Tooltip.tsx) | [See component story](https://main--5a375b97f4b14f0020b0cda3.chromatic.com/?path=/story/basics-tooltip-tooltip--basic-default) |
| Zoom | [See component implementation](https://github.com/storybookjs/storybook/blob/master/code/ui/components/src/Zoom/Zoom.tsx) | [See component story](https://5a375b97f4b14f0020b0cda3-wbeulgbetj.chromatic.com/?path=/story/basics-zoom--element-actual-size) | | Zoom | [See component implementation](https://github.com/storybookjs/storybook/blob/main/code/ui/components/src/Zoom/Zoom.tsx) | [See component story](https://main--5a375b97f4b14f0020b0cda3.chromatic.com/?path=/story/basics-zoom--element-actual-size) |
Complementing the components, also included is a set of UI primitives. Use the content listed below as a reference for styling your addon. Complementing the components, also included is a set of UI primitives. Use the content listed below as a reference for styling your addon.
| Component | Source | Story | | Component | Source | Story |
| ------------------------------ | ---------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------- | | ------------------------------ | -------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- |
| Color Palette (see note below) | [See implementation](https://github.com/storybookjs/storybook/tree/master/code/ui/components/src/Colors) | [See story](https://5a375b97f4b14f0020b0cda3-wbeulgbetj.chromatic.com/?path=/story/basics-colorpalette--page) | | Color Palette (see note below) | [See implementation](https://github.com/storybookjs/storybook/tree/master/code/ui/components/src/Colors) | [See story](https://main--5a375b97f4b14f0020b0cda3.chromatic.com/?path=/story/basics-colorpalette--page) |
| Icon | [See implementation](https://github.com/storybookjs/storybook/blob/master/code/ui/components/src/icon/icons.tsx) | [See story](https://5a375b97f4b14f0020b0cda3-wbeulgbetj.chromatic.com/?path=/story/basics-icon--labels) | | Icon | [See implementation](https://github.com/storybookjs/storybook/blob/main/code/ui/components/src/icon/icons.tsx) | [See story](https://main--5a375b97f4b14f0020b0cda3.chromatic.com/?path=/story/basics-icon--labels) |
| Typography | [See implementation](https://github.com/storybookjs/storybook/tree/master/code/ui/components/src/typography) | [See story](https://5a375b97f4b14f0020b0cda3-wbeulgbetj.chromatic.com/?path=/story/basics-typography--all) | | Typography | [See implementation](https://github.com/storybookjs/storybook/tree/master/code/ui/components/src/typography) | [See story](https://main--5a375b97f4b14f0020b0cda3.chromatic.com/?path=/story/basics-typography--all) |
<div class="aside"> <div class="aside">
The color palette implemented by <code>@storybook/components</code> is a high-level abstraction of the <a href="https://github.com/storybookjs/storybook/tree/next/code/lib/theming/src"><code>@storybook/theming</code></a> package. The color palette implemented by <code>@storybook/components</code> is a high-level abstraction of the <a href="https://github.com/storybookjs/storybook/tree/next/code/lib/theming/src"><code>@storybook/theming</code></a> package.

View File

@ -236,6 +236,8 @@ Let's say you've got a story like this:
'angular/button-story-with-addon-example.ts.mdx', 'angular/button-story-with-addon-example.ts.mdx',
'svelte/button-story-with-addon-example.js.mdx', 'svelte/button-story-with-addon-example.js.mdx',
]} ]}
usesCsf3
csf2Path="addons/addons-api#snippet-button-story-with-addon-example"
/> />
<!-- prettier-ignore-end --> <!-- prettier-ignore-end -->

View File

@ -23,8 +23,10 @@ For example, the [Pseudo States addon](https://storybook.js.org/addons/storybook
Use the [`useParameter`](./addons-api.md#useparameter) hook to access the parameter values within your addon. Use the [`useParameter`](./addons-api.md#useparameter) hook to access the parameter values within your addon.
```js ```js
export const Hover = () => <Button>Label</Button>; export const Hover = {
Hover.parameters = { pseudo: { hover: true } }; render: () => <Button>Label</Button>,
parameters: { pseudo: { hover: true } },
};
``` ```
## Channels ## Channels

View File

@ -201,6 +201,8 @@ When Storybook was initialized, it provided a small set of example stories. Chan
'angular/button-story-with-addon-example.ts.mdx', 'angular/button-story-with-addon-example.ts.mdx',
'svelte/button-story-with-addon-example.js.mdx', 'svelte/button-story-with-addon-example.js.mdx',
]} ]}
usesCsf3
csf2Path="addons/writing-addons#snippet-button-story-with-addon-example"
/> />
<!-- prettier-ignore-end --> <!-- prettier-ignore-end -->

View File

@ -48,6 +48,8 @@ With CSF, every named export in the file represents a story object by default.
'svelte/my-component-story-basic-and-props.js.mdx', 'svelte/my-component-story-basic-and-props.js.mdx',
'angular/my-component-story-basic-and-props.ts.mdx', 'angular/my-component-story-basic-and-props.ts.mdx',
]} ]}
usesCsf3
csf2Path="api/csf#snippet-my-component-story-basic-and-props"
/> />
<!-- prettier-ignore-end --> <!-- prettier-ignore-end -->
@ -74,6 +76,8 @@ Storybook's `name` configuration element is helpful in specific circumstances. C
paths={[ paths={[
'common/my-component-story-with-storyname.js.mdx', 'common/my-component-story-with-storyname.js.mdx',
]} ]}
usesCsf3
csf2Path="api/csf#snippet-my-component-story-with-storyname"
/> />
<!-- prettier-ignore-end --> <!-- prettier-ignore-end -->
@ -95,6 +99,8 @@ Consider Storybooks ["Button" example](../writing-stories/introduction.md#def
'svelte/button-story-click-handler.js.mdx', 'svelte/button-story-click-handler.js.mdx',
'angular/button-story-click-handler.ts.mdx', 'angular/button-story-click-handler.ts.mdx',
]} ]}
usesCsf3
csf2Path="api/csf#snippet-button-story-click-handler"
/> />
<!-- prettier-ignore-end --> <!-- prettier-ignore-end -->
@ -111,6 +117,8 @@ Now consider the same example, re-written with args:
'angular/button-story-click-handler-args.ts.mdx', 'angular/button-story-click-handler-args.ts.mdx',
'svelte/button-story-click-handler-args.js.mdx', 'svelte/button-story-click-handler-args.js.mdx',
]} ]}
usesCsf3
csf2Path="api/csf#snippet-button-story-click-handler-args"
/> />
<!-- prettier-ignore-end --> <!-- prettier-ignore-end -->
@ -125,6 +133,8 @@ Or even more simply:
'angular/button-story-click-handler-simplificated.ts.mdx', 'angular/button-story-click-handler-simplificated.ts.mdx',
'vue/button-story-click-handler-simplificated.js.mdx', 'vue/button-story-click-handler-simplificated.js.mdx',
]} ]}
usesCsf3
csf2Path="api/csf#snippet-button-story-click-handler-simplificated"
/> />
<!-- prettier-ignore-end --> <!-- prettier-ignore-end -->
@ -150,6 +160,8 @@ A good use case for the `play` function is a form component. With previous Story
'vue/login-form-with-play-function.3.js.mdx', 'vue/login-form-with-play-function.3.js.mdx',
'svelte/login-form-with-play-function.js.mdx', 'svelte/login-form-with-play-function.js.mdx',
]} ]}
usesCsf3
csf2Path="api/csf#snippet-login-form-with-play-function"
/> />
<!-- prettier-ignore-end --> <!-- prettier-ignore-end -->
@ -172,6 +184,7 @@ Starting in Storybook 6.4, you can write your stories as JavaScript objects, red
'preact/component-story-with-custom-render-function.js.mdx', 'preact/component-story-with-custom-render-function.js.mdx',
'web-components/component-story-with-custom-render-function.js.mdx', 'web-components/component-story-with-custom-render-function.js.mdx',
]} ]}
usesCsf3
/> />
<!-- prettier-ignore-end --> <!-- prettier-ignore-end -->
@ -222,6 +235,8 @@ Consider the following story file:
'svelte/my-component-story-with-nonstory.js.mdx', 'svelte/my-component-story-with-nonstory.js.mdx',
'angular/my-component-story-with-nonstory.ts.mdx' 'angular/my-component-story-with-nonstory.ts.mdx'
]} ]}
usesCsf3
csf2Path="api/csf#snippet-my-component-story-with-nonstory"
/> />
<!-- prettier-ignore-end --> <!-- prettier-ignore-end -->
@ -238,3 +253,158 @@ For this particular example, you could achieve the same result in different ways
- `excludeStories: ['simpleData', 'complexData']` - `excludeStories: ['simpleData', 'complexData']`
The first option is the recommended solution if you follow the best practice of starting story exports with an uppercase letter (i.e., use UpperCamelCase). The first option is the recommended solution if you follow the best practice of starting story exports with an uppercase letter (i.e., use UpperCamelCase).
## Upgrading from CSF 2 to CSF 3
In CSF 2, the named exports are always functions that instantiate a component, and those functions can be annotated with configuration options. For example:
<!-- prettier-ignore-start -->
<CodeSnippets
paths={[
'react/csf-2-example-starter.js.mdx',
'react/csf-2-example-starter.ts.mdx',
'vue/csf-2-example-starter.2.js.mdx',
'vue/csf-2-example-starter.ts-2.ts.mdx',
'vue/csf-2-example-starter.3.js.mdx',
'vue/csf-2-example-starter.ts-3.ts.mdx',
'angular/csf-2-example-starter.ts.mdx',
'web-components/csf-2-example-starter.js.mdx',
]}
/>
<!-- prettier-ignore-end -->
This declares a Primary story for a Button that renders itself by spreading `{ primary: true }` into the component. The `default.title` metadata says where to place the story in a navigation hierarchy.
Here's the CSF 3 equivalent:
<!-- prettier-ignore-start -->
<CodeSnippets
paths={[
'common/csf-3-example-starter.js.mdx',
'react/csf-3-example-starter.ts.mdx',
'vue/csf-3-example-starter.ts-2.ts.mdx',
'vue/csf-3-example-starter.ts-3.ts.mdx',
'angular/csf-3-example-starter.ts.mdx',
]}
/>
<!-- prettier-ignore-end -->
Let's go through the changes individually to understand what's going on.
### Spreadable story objects
In CSF 3, the named exports are **objects**, not functions. This allows us to reuse stories more efficiently with the JS spread operator.
Consider the following addition to the intro example, which creates a `PrimaryOnDark` story that renders against a dark background:
Here's the CSF 2 implementation:
<!-- prettier-ignore-start -->
<CodeSnippets
paths={[
'common/csf-2-example-primary-dark-story.js.mdx'
]}
/>
<!-- prettier-ignore-end -->
`Primary.bind({})` copies the story function, but it doesn't copy the annotations hanging off the function, so we must add `PrimaryOnDark.args = Primary.args` to inherit the args.
In CSF 3, we can spread the `Primary` object to carry over all its annotations:
<!-- prettier-ignore-start -->
<CodeSnippets
paths={[
'common/csf-3-example-primary-dark-story.js.mdx'
]}
/>
Learn more about [named story exports](#named-story-exports).
<!-- prettier-ignore-end -->
### Default render functions
In CSF 3, you specify how a story renders through a `render` function. We can rewrite a CSF 2 example to CSF 3 through the following steps.
Let's start with a simple CSF 2 story function:
<!-- prettier-ignore-start -->
<CodeSnippets
paths={[
'react/csf-2-example-story.js.mdx',
'vue/csf-2-example-story.2.js.mdx',
'vue/csf-2-example-story.3.js.mdx',
'angular/csf-2-example-story.ts.mdx',
'web-components/csf-2-example-story.js.mdx',
]}
/>
<!-- prettier-ignore-end -->
Now, let's rewrite it as a story object in CSF 3 with an explicit `render` function that tells the story how to render itself. Like CSF 2, this gives us full control of how we render a component or even a collection of components.
<!-- prettier-ignore-start -->
<CodeSnippets
paths={[
'react/csf-3-example-render.js.mdx',
'vue/csf-3-example-render.2.js.mdx',
'vue/csf-3-example-render.3.js.mdx',
'angular/csf-3-example-render.ts.mdx',
'web-components/csf-3-example-render.js.mdx',
]}
/>
Learn more about [render functions](#custom-render-functions).
<!-- prettier-ignore-end -->
But in CSF 2, a lot of story functions are identical: take the component specified in the default export and spread args into it. What's interesting about these stories is not the function, but the args passed into the function.
CSF 3 provides default render functions for each renderer. If all you're doing is spreading args into your component—which is the most common case—you don't need to specify any `render` function at all:
<!-- prettier-ignore-start -->
<CodeSnippets
paths={[
'common/csf-3-example-default-render.js.mdx'
]}
/>
<!-- prettier-ignore-end -->
For more information, see the section on [custom render functions](#custom-render-functions).
### Generate titles automatically
Finally, CSF 3 can automatically generate titles.
<!-- prettier-ignore-start -->
<CodeSnippets
paths={[
'common/csf-2-example-title.js.mdx'
]}
/>
<!-- prettier-ignore-end -->
<!-- prettier-ignore-start -->
<CodeSnippets
paths={[
'common/csf-3-example-auto-title.js.mdx'
]}
/>
<!-- prettier-ignore-end -->
You can still specify a title like in CSF 2, but if you don't specify one, it can be inferred from the story's path on disk. For more information, see the section on [configuring story loading](../configure/overview#configure-story-loading).

View File

@ -45,6 +45,8 @@ For example, here's the story from the `Checkbox` example above, rewritten in CS
'vue/checkbox-story-csf.js.mdx', 'vue/checkbox-story-csf.js.mdx',
'angular/checkbox-story-csf.ts.mdx', 'angular/checkbox-story-csf.ts.mdx',
]} ]}
usesCsf3
csf2Path="api/mdx#snippet-checkbox-story-csf"
/> />
<!-- prettier-ignore-end --> <!-- prettier-ignore-end -->

View File

@ -107,6 +107,8 @@ Consider the following React story:
paths={[ paths={[
'react/button-story-with-sample.js.mdx' 'react/button-story-with-sample.js.mdx'
]} ]}
usesCsf3
csf2Path="api/new-frameworks#snippet-button-story-with-sample"
/> />
<!-- prettier-ignore-end --> <!-- prettier-ignore-end -->
@ -123,6 +125,8 @@ Consider the following hypothetical example:
paths={[ paths={[
'common/button-story-hypothetical-example.js.mdx' 'common/button-story-hypothetical-example.js.mdx'
]} ]}
usesCsf3
csf2Path="api/new-frameworks#snippet-button-story-hypothetical-example"
/> />
<!-- prettier-ignore-end --> <!-- prettier-ignore-end -->

View File

@ -59,6 +59,8 @@ Then you can access this environment variable anywhere, even within your stories
'web-components/my-component-with-env-variables.js.mdx', 'web-components/my-component-with-env-variables.js.mdx',
'svelte/my-component-with-env-variables.js.mdx', 'svelte/my-component-with-env-variables.js.mdx',
]} ]}
usesCsf3
csf2Path="configure/environment-variables#snippet-my-component-with-env-variables"
/> />
<!-- prettier-ignore-end --> <!-- prettier-ignore-end -->
@ -94,6 +96,8 @@ When Storybook loads, it will enable you to access them in your stories similar
'common/my-component-env-var-config.js.mdx', 'common/my-component-env-var-config.js.mdx',
'common/my-component-env-var-config.ts.mdx', 'common/my-component-env-var-config.ts.mdx',
]} ]}
usesCsf3
csf2Path="configure/environment-variables#snippet-my-component-env-var-config"
/> />
<!-- prettier-ignore-end --> <!-- prettier-ignore-end -->

View File

@ -23,6 +23,8 @@ Afterward, you can use any asset in your stories:
'angular/component-story-static-asset-with-import.ts.mdx', 'angular/component-story-static-asset-with-import.ts.mdx',
'svelte/component-story-static-asset-with-import.js.mdx', 'svelte/component-story-static-asset-with-import.js.mdx',
]} ]}
usesCsf3
csf2Path="configure/images-and-assets#snippet-component-story-static-asset-with-import"
/> />
<!-- prettier-ignore-end --> <!-- prettier-ignore-end -->
@ -56,6 +58,8 @@ Here `../public` is your static directory. Now use it in a component or story li
'angular/component-story-static-asset-without-import.ts.mdx', 'angular/component-story-static-asset-without-import.ts.mdx',
'svelte/component-story-static-asset-without-import.js.mdx', 'svelte/component-story-static-asset-without-import.js.mdx',
]} ]}
usesCsf3
csf2Path="configure/images-and-assets#snippet-component-story-static-asset-without-import"
/> />
<!-- prettier-ignore-end --> <!-- prettier-ignore-end -->
@ -103,6 +107,8 @@ Upload your files to an online CDN and reference them. In this example, were
'angular/component-story-static-asset-cdn.ts.mdx', 'angular/component-story-static-asset-cdn.ts.mdx',
'svelte/component-story-static-asset-cdn.js.mdx', 'svelte/component-story-static-asset-cdn.js.mdx',
]} ]}
usesCsf3
csf2Path="configure/images-and-assets#snippet-component-story-static-asset-cdn"
/> />
<!-- prettier-ignore-end --> <!-- prettier-ignore-end -->

View File

@ -38,6 +38,8 @@ Consider the following story:
paths={[ paths={[
'common/foo-bar-baz-story.js.mdx', 'common/foo-bar-baz-story.js.mdx',
]} ]}
usesCsf3
csf2Path="configure/sidebar-and-urls#snippet-foo-bar-baz-story"
/> />
<!-- prettier-ignore-end --> <!-- prettier-ignore-end -->
@ -52,6 +54,8 @@ It is possible to manually set the story's id, which is helpful if you want to r
paths={[ paths={[
'common/other-foo-bar-story.js.mdx', 'common/other-foo-bar-story.js.mdx',
]} ]}
usesCsf3
csf2Path="configure/sidebar-and-urls#snippet-other-foo-bar-story"
/> />
<!-- prettier-ignore-end --> <!-- prettier-ignore-end -->
@ -104,6 +108,7 @@ If you need to preserve the naming scheme, you can add the `title` element to th
paths={[ paths={[
'common/storybook-csf-3-auto-title-redundant.js.mdx', 'common/storybook-csf-3-auto-title-redundant.js.mdx',
]} ]}
usesCsf3
/> />
<!-- prettier-ignore-end --> <!-- prettier-ignore-end -->

View File

@ -52,6 +52,8 @@ Or even apply it to specific stories like so:
'common/storybook-story-layout-param.js.mdx', 'common/storybook-story-layout-param.js.mdx',
'common/storybook-story-layout-param.ts.mdx', 'common/storybook-story-layout-param.ts.mdx',
]} ]}
usesCsf3
csf2Path="configure/story-layout#snippet-storybook-story-layout-param"
/> />
<!-- prettier-ignore-end --> <!-- prettier-ignore-end -->

View File

@ -53,6 +53,8 @@ You can also override a single key on the `backgrounds` parameter, for instance,
'common/storybook-addon-backgrounds-override-background-color.js.mdx', 'common/storybook-addon-backgrounds-override-background-color.js.mdx',
'common/storybook-addon-backgrounds-override-background-color.ts.mdx', 'common/storybook-addon-backgrounds-override-background-color.ts.mdx',
]} ]}
usesCsf3
csf2Path="essentials/backgrounds#snippet-storybook-addon-backgrounds-override-background-color"
/> />
<!-- prettier-ignore-end --> <!-- prettier-ignore-end -->
@ -68,6 +70,8 @@ If you want to disable backgrounds in a story, you can do so by setting the `bac
'common/storybook-addon-backgrounds-disable-backgrounds.js.mdx', 'common/storybook-addon-backgrounds-disable-backgrounds.js.mdx',
'common/storybook-addon-backgrounds-disable-backgrounds.ts.mdx', 'common/storybook-addon-backgrounds-disable-backgrounds.ts.mdx',
]} ]}
usesCsf3
csf2Path="essentials/backgrounds#snippet-storybook-addon-backgrounds-disable-backgrounds"
/> />
<!-- prettier-ignore-end --> <!-- prettier-ignore-end -->
@ -100,6 +104,8 @@ If you need to disable the grid for a specific story, set the `backgrounds` para
'common/storybook-addon-backgrounds-disable-grid.js.mdx', 'common/storybook-addon-backgrounds-disable-grid.js.mdx',
'common/storybook-addon-backgrounds-disable-grid.ts.mdx', 'common/storybook-addon-backgrounds-disable-grid.ts.mdx',
]} ]}
usesCsf3
csf2Path="essentials/backgrounds#snippet-storybook-addon-backgrounds-disable-grid"
/> />
<!-- prettier-ignore-end --> <!-- prettier-ignore-end -->

View File

@ -55,6 +55,8 @@ For instance, suppose you have a `variant` arg on your story that should be `pri
'common/button-story-controls-primary-variant.js.mdx', 'common/button-story-controls-primary-variant.js.mdx',
'common/button-story-controls-primary-variant.ts.mdx', 'common/button-story-controls-primary-variant.ts.mdx',
]} ]}
usesCsf3
csf2Path="essentials/controls#snippet-button-story-controls-primary-variant"
/> />
<!-- prettier-ignore-end --> <!-- prettier-ignore-end -->
@ -127,6 +129,8 @@ Until now, we only used auto-generated controls based on the component we're wri
'vue/table-story-fully-customize-controls.ts-3.ts.mdx', 'vue/table-story-fully-customize-controls.ts-3.ts.mdx',
'angular/table-story-fully-customize-controls.ts.mdx', 'angular/table-story-fully-customize-controls.ts.mdx',
]} ]}
usesCsf3
csf2Path="essentials/controls#snippet-table-story-fully-customize-controls"
/> />
<!-- prettier-ignore-end --> <!-- prettier-ignore-end -->
@ -156,6 +160,8 @@ One way to deal with this is to use primitive values (e.g., strings) as arg valu
'angular/component-story-custom-args-complex.ts.mdx', 'angular/component-story-custom-args-complex.ts.mdx',
'svelte/component-story-custom-args-complex.js.mdx', 'svelte/component-story-custom-args-complex.js.mdx',
]} ]}
usesCsf3
csf2Path="essentials/controls#snippet-component-story-custom-args-complex"
/> />
<!-- prettier-ignore-end --> <!-- prettier-ignore-end -->
@ -368,6 +374,8 @@ If you don't plan to handle the control args inside your Story, you can remove t
'common/button-story-hide-nocontrols-warning.js.mdx', 'common/button-story-hide-nocontrols-warning.js.mdx',
'common/button-story-hide-nocontrols-warning.ts.mdx', 'common/button-story-hide-nocontrols-warning.ts.mdx',
]} ]}
usesCsf3
csf2Path="essentials/controls#snippet-button-story-hide-nocontrols-warning"
/> />
<!-- prettier-ignore-end --> <!-- prettier-ignore-end -->
@ -387,6 +395,8 @@ Consider the following story snippets:
'common/component-story-disable-controls-regex.js.mdx', 'common/component-story-disable-controls-regex.js.mdx',
'common/component-story-disable-controls-regex.ts.mdx', 'common/component-story-disable-controls-regex.ts.mdx',
]} ]}
usesCsf3
csf2Path="essentials/controls#snippet-component-story-disable-controls-regex"
/> />
<!-- prettier-ignore-end --> <!-- prettier-ignore-end -->

View File

@ -68,6 +68,8 @@ Make sure to import the Storybook wrappers for Jest and Testing Library rather t
'common/storybook-interactions-play-function.js.mdx', 'common/storybook-interactions-play-function.js.mdx',
'common/storybook-interactions-play-function.ts.mdx', 'common/storybook-interactions-play-function.ts.mdx',
]} ]}
usesCsf3
csf2Path="essentials/interactions#snippet-storybook-interactions-play-function"
/> />
<!-- prettier-ignore-end --> <!-- prettier-ignore-end -->

View File

@ -109,6 +109,8 @@ Using the example above, you can modify any story to retrieve the **Locale** `gl
'svelte/my-component-story-use-globaltype.js.mdx', 'svelte/my-component-story-use-globaltype.js.mdx',
'web-components/my-component-story-use-globaltype.js.mdx', 'web-components/my-component-story-use-globaltype.js.mdx',
]} ]}
usesCsf3
csf2Path="essentials/toolbars-and-globals#snippet-my-component-story-use-globaltype"
/> />
<!-- prettier-ignore-end --> <!-- prettier-ignore-end -->

View File

@ -127,6 +127,8 @@ Update your story through [parameters](../writing-stories/parameters.md) to incl
'web-components/my-component-story-configure-viewports.js.mdx', 'web-components/my-component-story-configure-viewports.js.mdx',
'svelte/my-component-story-configure-viewports.js.mdx', 'svelte/my-component-story-configure-viewports.js.mdx',
]} ]}
usesCsf3
csf2Path="essentials/viewport#snippet-my-component-story-configure-viewports"
/> />
<!-- prettier-ignore-end --> <!-- prettier-ignore-end -->

View File

@ -23,6 +23,8 @@ Pick a simple component from your project, like a Button, and write a `.stories.
'html/your-component.ts.mdx', 'html/your-component.ts.mdx',
'preact/your-component.js.mdx', 'preact/your-component.js.mdx',
]} ]}
usesCsf3
csf2Path="get-started/setup#snippet-your-component"
/> />
<!-- prettier-ignore-end --> <!-- prettier-ignore-end -->

View File

@ -26,6 +26,8 @@ Lets start with the `Button` component. A story is a function that describes
'html/button-story.ts.mdx', 'html/button-story.ts.mdx',
'preact/button-story.js.mdx', 'preact/button-story.js.mdx',
]} ]}
usesCsf3
csf2Path="get-started/whats-a-story#snippet-button-story"
/> />
<!-- prettier-ignore-end --> <!-- prettier-ignore-end -->
@ -53,6 +55,8 @@ The above story definition can be further improved to take advantage of [Storybo
'html/button-story-with-args.ts.mdx', 'html/button-story-with-args.ts.mdx',
'preact/button-story-with-args.js.mdx', 'preact/button-story-with-args.js.mdx',
]} ]}
usesCsf3
csf2Path="get-started/whats-a-story#snippet-button-story-with-args"
/> />
<!-- prettier-ignore-end --> <!-- prettier-ignore-end -->

View File

@ -107,6 +107,8 @@ In Storybook, add a new [parameter](../writing-stories/parameters.md) named `des
'angular/component-story-figma-integration.ts.mdx', 'angular/component-story-figma-integration.ts.mdx',
'svelte/component-story-figma-integration.js.mdx', 'svelte/component-story-figma-integration.js.mdx',
]} ]}
usesCsf3
csf2Path="sharing/design-integrations#snippet-component-story-figma-integration"
/> />
<!-- prettier-ignore-end --> <!-- prettier-ignore-end -->

View File

@ -0,0 +1,15 @@
```ts
// CSF 2
import { Meta, Story } from '@storybook/angular';
import { Button } from './button.component';
export default {
title: 'components/Button',
component: Button,
} as Meta;
export const Primary: Story = (args) => ({
props: args,
});
Primary.args = { primary: true };
```

View File

@ -0,0 +1,6 @@
```ts
// CSF 2
export const Default: Story = (args) => ({
props: args,
});
```

View File

@ -0,0 +1,8 @@
```ts
// CSF 3
export const Default: Story = {
render: (args) => ({
props: args,
}),
};
```

View File

@ -0,0 +1,12 @@
```ts
// CSF 3
import { Meta, StoryObj } from '@storybook/angular';
import { Button } from './button.component';
const meta: Meta<Button> = { component: Button };
export default meta;
type Story = StoryObj<Button>;
export const Primary: Story = { args: { primary: true } };
```

View File

@ -1,17 +0,0 @@
```md
<!-- Button.stories.mdx -->
import { Meta, Story } from '@storybook/addon-docs';
import { Button } from './Button';
<Meta title="Button" component={Button} />
<Story
name="Primary"
args={{
variant: 'primary',
}}
render={() => ({ // Your implementation here })} />
</Story>
```

View File

@ -0,0 +1,6 @@
```js
// CSF 2
export const PrimaryOnDark = Primary.bind({});
PrimaryOnDark.args = Primary.args;
PrimaryOnDark.parameters = { background: { default: 'dark' } };
```

View File

@ -0,0 +1,4 @@
```js
// CSF 2
export default { title: 'components/Button', component: Button };
```

View File

@ -0,0 +1,4 @@
```js
// CSF 3
export default { component: Button };
```

View File

@ -0,0 +1,4 @@
```js
// CSF 3 - default render function
export const Default = {};
```

View File

@ -0,0 +1,7 @@
```js
// CSF 3
export const PrimaryOnDark = {
...Primary,
parameters: { background: { default: 'dark' } },
};
```

View File

@ -0,0 +1,8 @@
```js
// CSF 3
import { Button } from './Button';
export default { component: Button };
export const Primary = { args: { primary: true } };
```

View File

@ -1,5 +1,6 @@
```js ```js
Submitted.play = async ({ args, canvasElement, step }) => { Submitted = {
play: async ({ args, canvasElement, step }) => {
const canvas = within(canvasElement); const canvas = within(canvasElement);
await step('Enter email and password', async () => { await step('Enter email and password', async () => {
@ -10,5 +11,6 @@ Submitted.play = async ({ args, canvasElement, step }) => {
await step('Submit form', async () => { await step('Submit form', async () => {
await userEvent.click(canvas.getByRole('button')); await userEvent.click(canvas.getByRole('button'));
}); });
},
}; };
``` ```

View File

@ -7,8 +7,6 @@ import { Checkbox } from './Checkbox';
<Meta title="MDX/Checkbox" component={Checkbox} /> <Meta title="MDX/Checkbox" component={Checkbox} />
export const Template = (args) => <Checkbox {...args} />;
# Checkbox # Checkbox
With `MDX`, we can define a story for `Checkbox` right in the middle of our With `MDX`, we can define a story for `Checkbox` right in the middle of our

View File

@ -0,0 +1,12 @@
```js
// CSF 2
import { Button } from './Button';
export default {
title: 'components/Button',
component: Button,
};
export const Primary = (args) => <Button {...args} />;
Primary.args = { primary: true };
```

View File

@ -0,0 +1,13 @@
```tsx
// CSF 2
import { ComponentStory, ComponentMeta } from '@storybook/react';
import { Button } from './Button';
export default {
title: 'components/Button',
component: Button,
} as ComponentMeta<typeof Button>;
export const Primary: ComponentStory<typeof Button> = (args) => <Button {...args} />;
Primary.args = { primary: true };
```

View File

@ -0,0 +1,4 @@
```js
// CSF 2
export const Default = (args) => <Button {...args} />;
```

View File

@ -0,0 +1,6 @@
```js
// CSF 3 - explicit render function
export const Default = {
render: (args) => <Button {...args} />,
};
```

View File

@ -0,0 +1,12 @@
```ts
// CSF 3
import type { Meta, StoryObj } from '@storybook/react';
import { Button } from './Button';
const meta: Meta<typeof Button> = { component: Button };
export default meta;
type Story = StoryObj<typeof Button>;
export const Primary: Story = { args: { primary: true } };
```

View File

@ -17,9 +17,11 @@ export default {
component: List, component: List,
}; };
export const OneItem = (args) => ( export const OneItem = {
render: (args) => (
<List {...args}> <List {...args}>
<Unchecked {...Unchecked.args} /> <Unchecked {...Unchecked.args} />
</List> </List>
); ),
};
``` ```

View File

@ -20,7 +20,7 @@ export const meta: Meta<typeof List> = {
export default meta; export default meta;
type Story = StoryObj<typeof List>; type Story = StoryObj<typeof List>;
const OneItem: Story = { export const OneItem: Story = {
render: (args) => ( render: (args) => (
<List {...args}> <List {...args}>
<Unchecked {...Unchecked.args} /> <Unchecked {...Unchecked.args} />

View File

@ -17,10 +17,9 @@ export default {
component: List, component: List,
}; };
const Template = (args) => <List {...args} />; export const OneItem = {
args: {
export const OneItem = Template.bind({});
OneItem.args = {
children: <Unchecked {...Unchecked.args} />, children: <Unchecked {...Unchecked.args} />,
},
}; };
``` ```

View File

@ -20,7 +20,7 @@ const meta: Meta<typeof List> = {
export default meta; export default meta;
type Story = StoryObj<typeof List>; type Story = StoryObj<typeof List>;
export const OneItem = { export const OneItem: Story = {
args: { args: {
children: <Unchecked {...Unchecked.args} />, children: <Unchecked {...Unchecked.args} />,
}, },

View File

@ -0,0 +1,15 @@
```js
// CSF 2
import { Button } from './Button';
export default {
title: 'components/Button',
component: Button,
};
export const Primary = (args, { argTypes }) => ({
props: Object.keys(argTypes),
components: { Button },
});
Primary.args = { primary: true };
```

View File

@ -0,0 +1,18 @@
```js
// CSF 2
import Button from './Button.vue';
export default {
title: 'components/Button',
component: Button,
};
export const Primary = (args) => ({
components: { Button },
setup() {
return { args };
},
template: '<Button v-bind="args" />',
});
Primary.args = { primary: true };
```

View File

@ -0,0 +1,16 @@
```ts
// CSF 2
import { Meta, StoryFn } from '@storybook/vue';
import { Button } from './Button';
export default {
title: 'components/Button',
component: Button,
} as Meta<typeof Button>;
export const Primary: StoryFn<typeof Button> = (args, { argTypes }) => ({
props: Object.keys(argTypes),
components: { Button },
});
Primary.args = { primary: true };
```

View File

@ -0,0 +1,22 @@
```ts
// CSF 2
import { Meta, StoryFn } from '@storybook/vue3';
import Button from './Button.vue';
export default {
title: 'components/Button',
component: Button,
} as Meta<typeof Button>;
export const Primary: StoryFn<typeof Button> = (args) => ({
components: { Button },
setup() {
return { args };
},
template: '<Button v-bind="args" />',
});
Primary.args = {
primary: true,
label: 'Button',
};
```

View File

@ -0,0 +1,7 @@
```js
// CSF 2
export const Default = (args, { argTypes }) => ({
props: Object.keys(argTypes),
components: { Button },
});
```

View File

@ -0,0 +1,10 @@
```js
// CSF 2
export const Default = (args) => ({
components: { Button },
setup() {
return { args };
},
template: '<Button v-bind="args" />',
});
```

View File

@ -0,0 +1,9 @@
```js
// CSF 3 - explicit render function
export const Default = {
render: (args, { argTypes }) => ({
props: Object.keys(argTypes),
components: { Button },
}),
};
```

View File

@ -0,0 +1,12 @@
```js
// CSF 3 - explicit render function
export const Default = {
render: (args) => ({
components: { Button },
setup() {
return { args };
},
template: '<Button v-bind="args" />',
}),
};
```

View File

@ -0,0 +1,12 @@
```ts
// CSF 3
import { Meta, StoryFn } from '@storybook/vue';
import { Button } from './Button';
const meta: Meta<typeof Button> = { component: Button };
export default meta;
type Story = StoryObj<typeof Button>;
export const Primary: Story = { args: { primary: true } };
```

View File

@ -0,0 +1,12 @@
```ts
// CSF 3
import { Meta, StoryFn } from '@storybook/vue3';
import { Button } from './Button';
const meta: Meta<typeof Button> = { component: Button };
export default meta;
type Story = StoryObj<typeof Button>;
export const Primary: Story = { args: { primary: true } };
```

View File

@ -0,0 +1,15 @@
```js
// CSF 2
import { html } from 'lit-html';
import './demo-button';
export default {
title: 'components/demo-button',
component: 'demo-button',
};
export const Primary = ({ primary }) => html`<demo-button ?primary=${primary}></demo-button>`;
Primary.args = {
primary: true,
};
```

View File

@ -0,0 +1,4 @@
```js
// CSF 2
export const Default = () => html`<demo-button></demo-button>`;
```

View File

@ -0,0 +1,6 @@
```js
// CSF 2
export const Default = {
render: (args) => Button(args),
};
```

View File

@ -18,7 +18,7 @@ const meta: Meta<typeof Button> = {
title: 'my-list', title: 'my-list',
}; };
export const OneItem: Story<IList> = () => html` export const OneItem: Story<IList> = {
<List> ${Unchecked({ ...Unchecked.args })} </List> render: () => html` <List> ${Unchecked({ ...Unchecked.args })} </List> `,
`; };
``` ```

View File

@ -52,6 +52,8 @@ You write stories for granular UI component variation and then use those stories
'html/histogram-story.js.mdx', 'html/histogram-story.js.mdx',
'html/histogram-story.ts.mdx', 'html/histogram-story.ts.mdx',
]} ]}
usesCsf3
csf2Path="why-storybook#snippet-histogram-story"
/> />
<!-- prettier-ignore-end --> <!-- prettier-ignore-end -->

View File

@ -45,6 +45,8 @@ If you want, you can also group multiple stories and render them inside a single
'vue/mdx-canvas-multiple-stories.mdx-3.mdx.mdx', 'vue/mdx-canvas-multiple-stories.mdx-3.mdx.mdx',
'svelte/mdx-canvas-multiple-stories.mdx.mdx', 'svelte/mdx-canvas-multiple-stories.mdx.mdx',
]} ]}
usesCsf3
csf2Path="writing-docs/doc-block-canvas#snippet-mdx-canvas-multiple-stories"
/> />
<!-- prettier-ignore-end --> <!-- prettier-ignore-end -->

View File

@ -16,6 +16,8 @@ Storybook extracts the component's description and renders it at the top of the
paths={[ paths={[
'common/component-story-csf-description.js.mdx', 'common/component-story-csf-description.js.mdx',
]} ]}
usesCsf3
csf2Path="writing-docs/doc-block-description#snippet-component-story-csf-description"
/> />
<!-- prettier-ignore-end --> <!-- prettier-ignore-end -->

View File

@ -17,6 +17,8 @@ It includes additional customization via parameters. Below is a condensed exampl
paths={[ paths={[
'common/component-story-custom-source.js.mdx', 'common/component-story-custom-source.js.mdx',
]} ]}
usesCsf3
csf2Path="writing-docs/doc-block-source#snippet-component-story-custom-source"
/> />
<!-- prettier-ignore-end --> <!-- prettier-ignore-end -->

View File

@ -41,6 +41,8 @@ With MDX, the `Story` block is not only a way of rendering stories, but how you
'svelte/component-story-mdx-story-by-name.mdx.mdx', 'svelte/component-story-mdx-story-by-name.mdx.mdx',
'common/component-story-mdx-reference-storyid.mdx.mdx', 'common/component-story-mdx-reference-storyid.mdx.mdx',
]} ]}
usesCsf3
csf2Path="writing-docs/doc-block-story#snippet-component-story-mdx-story-by-name"
/> />
<!-- prettier-ignore-end --> <!-- prettier-ignore-end -->

View File

@ -28,6 +28,8 @@ Let's get started with an example that combines Markdown with a single story:
'vue/checkbox-story.mdx-3.mdx.mdx', 'vue/checkbox-story.mdx-3.mdx.mdx',
'svelte/checkbox-story.mdx.mdx', 'svelte/checkbox-story.mdx.mdx',
]} ]}
usesCsf3
csf2Path="writing-docs/mdx#snippet-checkbox-story"
/> />
<!-- prettier-ignore-end --> <!-- prettier-ignore-end -->
@ -52,6 +54,8 @@ For example, here's the first story from the Checkbox example above, rewritten i
paths={[ paths={[
'common/checkbox-story-csf.js.mdx', 'common/checkbox-story-csf.js.mdx',
]} ]}
usesCsf3
csf2Path="writing-docs/mdx#snippet-checkbox-story-csf"
/> />
<!-- prettier-ignore-end --> <!-- prettier-ignore-end -->
@ -72,6 +76,8 @@ Let's look at a more realistic example to see how MDX works:
'vue/badge-story.mdx-3.mdx.mdx', 'vue/badge-story.mdx-3.mdx.mdx',
'svelte/badge-story.mdx.mdx', 'svelte/badge-story.mdx.mdx',
]} ]}
usesCsf3
csf2Path="writing-docs/mdx#snippet-badge-story"
/> />
<!-- prettier-ignore-end --> <!-- prettier-ignore-end -->

View File

@ -32,6 +32,8 @@ To define the args of a single story, use the `args` CSF story key:
'html/button-story-with-args.ts.mdx', 'html/button-story-with-args.ts.mdx',
'html/button-story-with-args.js.mdx', 'html/button-story-with-args.js.mdx',
]} ]}
usesCsf3
csf2Path="writing-stories/args#snippet-button-story-with-args"
/> />
@ -46,6 +48,8 @@ These args will only apply to the story for which they are attached, although yo
'common/button-story-primary-long-name.js.mdx', 'common/button-story-primary-long-name.js.mdx',
'common/button-story-primary-long-name.ts.mdx', 'common/button-story-primary-long-name.ts.mdx',
]} ]}
usesCsf3
csf2Path="writing-stories/args#snippet-button-story-primary-long-name"
/> />
<!-- prettier-ignore-end --> <!-- prettier-ignore-end -->
@ -69,6 +73,8 @@ You can also define args at the component level; they will apply to all the comp
'svelte/button-story-component-args-primary.js.mdx', 'svelte/button-story-component-args-primary.js.mdx',
'web-components/button-story-component-args-primary.js.mdx', 'web-components/button-story-component-args-primary.js.mdx',
]} ]}
usesCsf3
csf2Path="writing-stories/args#snippet-button-story-component-args-primary"
/> />
<!-- prettier-ignore-end --> <!-- prettier-ignore-end -->
@ -98,6 +104,8 @@ You can separate the arguments to a story to compose in other stories. Here's ho
'common/button-story-primary-composition.js.mdx', 'common/button-story-primary-composition.js.mdx',
'common/button-story-primary-composition.ts.mdx', 'common/button-story-primary-composition.ts.mdx',
]} ]}
usesCsf3
csf2Path="writing-stories/args#snippet-button-story-primary-composition"
/> />
<!-- prettier-ignore-end --> <!-- prettier-ignore-end -->
@ -123,6 +131,8 @@ Args are useful when writing stories for composite components that are assembled
'vue/page-story.ts-3.ts.mdx', 'vue/page-story.ts-3.ts.mdx',
'svelte/page-story.js.mdx', 'svelte/page-story.js.mdx',
]} ]}
usesCsf3
csf2Path="writing-stories/args#snippet-page-story"
/> />
<!-- prettier-ignore-end --> <!-- prettier-ignore-end -->
@ -143,6 +153,8 @@ You can use args in your stories to configure the component's appearance, simila
'vue/page-story-slots.ts-3.ts.mdx', 'vue/page-story-slots.ts-3.ts.mdx',
'angular/page-story-slots.ts.mdx', 'angular/page-story-slots.ts.mdx',
]} ]}
usesCsf3
csf2Path="writing-stories/args#snippet-page-story-slots"
/> />
<!-- prettier-ignore-end --> <!-- prettier-ignore-end -->

View File

@ -62,6 +62,8 @@ In such cases, it is natural to use [args composition](./args.md#args-compositio
'angular/page-story-with-args-composition.ts.mdx', 'angular/page-story-with-args-composition.ts.mdx',
'svelte/page-story-with-args-composition.js.mdx', 'svelte/page-story-with-args-composition.js.mdx',
]} ]}
usesCsf3
csf2Path="writing-stories/build-pages-with-storybook#snippet-page-story-with-args-composition"
/> />
<!-- prettier-ignore-end --> <!-- prettier-ignore-end -->
@ -155,6 +157,8 @@ To test your screen with the mocked data, you could write a similar set of stori
'angular/documentscreen-story-msw-rest-request.ts.mdx', 'angular/documentscreen-story-msw-rest-request.ts.mdx',
'svelte/documentscreen-story-msw-rest-request.js.mdx', 'svelte/documentscreen-story-msw-rest-request.js.mdx',
]} ]}
usesCsf3
csf2Path="writing-stories/build-pages-with-storybook#snippet-documentscreen-story-msw-rest-request"
/> />
<!-- prettier-ignore-end --> <!-- prettier-ignore-end -->
@ -197,6 +201,8 @@ To test your screen with the GraphQL mocked data, you could write the following
'svelte/documentscreen-story-msw-graphql-query.js.mdx', 'svelte/documentscreen-story-msw-graphql-query.js.mdx',
'svelte/apollo-wrapper-component.with-mock-implementation.js.mdx', 'svelte/apollo-wrapper-component.with-mock-implementation.js.mdx',
]} ]}
usesCsf3
csf2Path="writing-stories/build-pages-with-storybook#snippet-documentscreen-story-msw-graphql-query"
/> />
<!-- prettier-ignore-end --> <!-- prettier-ignore-end -->
@ -258,6 +264,8 @@ Finally, we can set the mock values in a specific story. Let's borrow an example
'vue/app-story-with-mock.ts.mdx', 'vue/app-story-with-mock.ts.mdx',
'angular/app-story-with-mock.ts.mdx', 'angular/app-story-with-mock.ts.mdx',
]} ]}
usesCsf3
csf2Path="writing-stories/build-pages-with-storybook#snippet-app-story-with-mock"
/> />
<!-- prettier-ignore-end --> <!-- prettier-ignore-end -->
@ -327,6 +335,8 @@ In the context of Storybook, instead of providing container components through c
paths={[ paths={[
'react/mock-context-container.js.mdx', 'react/mock-context-container.js.mdx',
]} ]}
usesCsf3
csf2Path="writing-stories/build-pages-with-storybook#snippet-mock-context-container"
/> />
<!-- prettier-ignore-end --> <!-- prettier-ignore-end -->

View File

@ -95,6 +95,8 @@ To define a decorator for a single story, use the `decorators` key on a named ex
'svelte/button-story-decorator.js.mdx', 'svelte/button-story-decorator.js.mdx',
'web-components/button-story-decorator.js.mdx', 'web-components/button-story-decorator.js.mdx',
]} ]}
usesCsf3
csf2Path="writing-stories/decorators#snippet-button-story-decorator"
/> />

View File

@ -63,6 +63,8 @@ Use the _named_ exports of a CSF file to define your components stories. We r
'html/button-story.js.mdx', 'html/button-story.js.mdx',
'html/button-story.ts.mdx', 'html/button-story.ts.mdx',
]} ]}
usesCsf3
csf2Path="writing-stories/introduction#snippet-button-story"
/> />
<!-- prettier-ignore-end --> <!-- prettier-ignore-end -->
@ -77,6 +79,8 @@ Use the _named_ exports of a CSF file to define your components stories. We r
paths={[ paths={[
'react/button-story.with-hooks.js.mdx', 'react/button-story.with-hooks.js.mdx',
]} ]}
usesCsf3
csf2Path="writing-stories/introduction#snippet-button-story-with-hooks"
/> />
<!-- prettier-ignore-end --> <!-- prettier-ignore-end -->
@ -103,6 +107,8 @@ You can rename any particular story you need. For instance, to give it a more ac
'html/button-story-rename-story.js.mdx', 'html/button-story-rename-story.js.mdx',
'html/button-story-rename-story.ts.mdx', 'html/button-story-rename-story.ts.mdx',
]} ]}
usesCsf3
csf2Path="writing-stories/introduction#snippet-button-story-rename-story"
/> />
<!-- prettier-ignore-end --> <!-- prettier-ignore-end -->
@ -128,6 +134,8 @@ A story is a function that describes how to render a component. You can have mul
'html/button-story-with-emojis.js.mdx', 'html/button-story-with-emojis.js.mdx',
'html/button-story-with-emojis.ts.mdx', 'html/button-story-with-emojis.ts.mdx',
]} ]}
usesCsf3
csf2Path="writing-stories/introduction#snippet-button-story-with-emojis"
/> />
<!-- prettier-ignore-end --> <!-- prettier-ignore-end -->
@ -154,6 +162,8 @@ Refine this pattern by introducing `args` for your component's stories. It reduc
'html/button-story-using-args.js.mdx', 'html/button-story-using-args.js.mdx',
'html/button-story-using-args.ts.mdx', 'html/button-story-using-args.ts.mdx',
]} ]}
usesCsf3
csf2Path="writing-stories/introduction#snippet-button-story-using-args"
/> />
<!-- prettier-ignore-end --> <!-- prettier-ignore-end -->
@ -176,6 +186,8 @@ Whats more, you can import `args` to reuse when writing stories for other com
'svelte/button-group-story.js.mdx', 'svelte/button-group-story.js.mdx',
'web-components/button-group-story.js.mdx', 'web-components/button-group-story.js.mdx',
]} ]}
usesCsf3
csf2Path="writing-stories/introduction#snippet-button-group-story"
/> />
@ -218,6 +230,8 @@ Storybook's `play` function and the [`@storybook/addon-interactions`](https://st
'vue/login-form-with-play-function.ts-3.ts.mdx', 'vue/login-form-with-play-function.ts-3.ts.mdx',
'svelte/login-form-with-play-function.js.mdx', 'svelte/login-form-with-play-function.js.mdx',
]} ]}
usesCsf3
csf2Path="writing-stories/introduction#snippet-login-form-with-play-function"
/> />
Without the help of the `play` function and the `@storybook/addon-interactions`, you had to write your own stories and manually interact with the component to test out each use case scenario possible. Without the help of the `play` function and the `@storybook/addon-interactions`, you had to write your own stories and manually interact with the component to test out each use case scenario possible.
@ -302,6 +316,8 @@ When building design systems or component libraries, you may have two or more co
'html/list-story-starter.js.mdx', 'html/list-story-starter.js.mdx',
'html/list-story-starter.ts.mdx', 'html/list-story-starter.ts.mdx',
]} ]}
usesCsf3
csf2Path="writing-stories/introduction#snippet-list-story-starter"
/> />
<!-- prettier-ignore-end --> <!-- prettier-ignore-end -->
@ -323,6 +339,8 @@ In such cases, it makes sense to render a different function for each story:
'html/list-story-expanded.js.mdx', 'html/list-story-expanded.js.mdx',
'html/list-story-expanded.ts.mdx', 'html/list-story-expanded.ts.mdx',
]} ]}
usesCsf3
csf2Path="writing-stories/introduction#snippet-list-story-expanded"
/> />
<!-- prettier-ignore-end --> <!-- prettier-ignore-end -->
@ -344,6 +362,8 @@ You can also reuse stories from the child `ListItem` in your `List` component. T
'html/list-story-reuse-data.js.mdx', 'html/list-story-reuse-data.js.mdx',
'html/list-story-reuse-data.ts.mdx', 'html/list-story-reuse-data.ts.mdx',
]} ]}
usesCsf3
csf2Path="writing-stories/introduction#snippet-list-story-reuse-data"
/> />
<!-- prettier-ignore-end --> <!-- prettier-ignore-end -->

View File

@ -24,6 +24,8 @@ Loaders are helpful when you need to load story data externally (e.g., from a re
'angular/loader-story.ts.mdx', 'angular/loader-story.ts.mdx',
'svelte/loader-story.js.mdx', 'svelte/loader-story.js.mdx',
]} ]}
usesCsf3
csf2Path="writing-stories/loaders#snippet-loader-story"
/> />
<!-- prettier-ignore-end --> <!-- prettier-ignore-end -->

View File

@ -66,6 +66,8 @@ Stories which have **no siblings** (i.e. the component has only one story) and w
'common/button-story-hoisted.js.mdx', 'common/button-story-hoisted.js.mdx',
'common/button-story-hoisted.ts.mdx', 'common/button-story-hoisted.ts.mdx',
]} ]}
usesCsf3
csf2Path="writing-stories/naming-components-and-hierarchy#button-story-hoisted"
/> />
<!-- prettier-ignore-end --> <!-- prettier-ignore-end -->

View File

@ -17,6 +17,8 @@ We can set a parameter for a single story with the `parameters` key on a CSF exp
'common/component-story-custom-params.js.mdx', 'common/component-story-custom-params.js.mdx',
'common/component-story-custom-params.ts.mdx', 'common/component-story-custom-params.ts.mdx',
]} ]}
usesCsf3
csf2Path="writing-stories/parameters#snippet-component-story-custom-params"
/> />
<!-- prettier-ignore-end --> <!-- prettier-ignore-end -->

View File

@ -50,6 +50,8 @@ Storybook's `play` functions are small code snippets that run once the story fin
'vue/register-component-with-play-function.ts.mdx', 'vue/register-component-with-play-function.ts.mdx',
'svelte/register-component-with-play-function.js.mdx', 'svelte/register-component-with-play-function.js.mdx',
]} ]}
usesCsf3
csf2Path="writing-stories/play-function#snippet-register-component-with-play-function"
/> />
<!-- prettier-ignore-end --> <!-- prettier-ignore-end -->
@ -77,6 +79,8 @@ Thanks to the [Component Story Format](../api/csf.md), an ES6 module based file
'vue/my-component-play-function-composition.ts.mdx', 'vue/my-component-play-function-composition.ts.mdx',
'svelte/my-component-play-function-composition.js.mdx', 'svelte/my-component-play-function-composition.js.mdx',
]} ]}
usesCsf3
csf2Path="writing-stories/play-function#snippet-my-component-play-function-composition"
/> />
<!-- prettier-ignore-end --> <!-- prettier-ignore-end -->
@ -100,6 +104,8 @@ A common type of component interaction is a button click. If you need to reprodu
'vue/my-component-play-function-with-clickevent.ts.mdx', 'vue/my-component-play-function-with-clickevent.ts.mdx',
'svelte/my-component-play-function-with-clickevent.js.mdx', 'svelte/my-component-play-function-with-clickevent.js.mdx',
]} ]}
usesCsf3
csf2Path="writing-stories/play-function#snippet-my-component-play-function-with-clickevent"
/> />
<!-- prettier-ignore-end --> <!-- prettier-ignore-end -->
@ -119,6 +125,8 @@ Asides from click events, you can also script additional events with the `play`
'vue/my-component-play-function-with-selectevent.ts.mdx', 'vue/my-component-play-function-with-selectevent.ts.mdx',
'svelte/my-component-play-function-with-selectevent.js.mdx', 'svelte/my-component-play-function-with-selectevent.js.mdx',
]} ]}
usesCsf3
csf2Path="writing-stories/play-function#snippet-my-component-play-function-with-selectevent"
/> />
<!-- prettier-ignore-end --> <!-- prettier-ignore-end -->
@ -136,6 +144,8 @@ In addition to events, you can also create interactions with the `play` function
'vue/my-component-play-function-with-delay.ts.mdx', 'vue/my-component-play-function-with-delay.ts.mdx',
'svelte/my-component-play-function-with-delay.js.mdx', 'svelte/my-component-play-function-with-delay.js.mdx',
]} ]}
usesCsf3
csf2Path="writing-stories/play-function#snippet-my-component-play-function-with-delay"
/> />
<!-- prettier-ignore-end --> <!-- prettier-ignore-end -->
@ -155,6 +165,8 @@ You can also use the `play` function to verify the existence of an element based
'vue/my-component-play-function-waitfor.ts.mdx', 'vue/my-component-play-function-waitfor.ts.mdx',
'svelte/my-component-play-function-waitfor.js.mdx', 'svelte/my-component-play-function-waitfor.js.mdx',
]} ]}
usesCsf3
csf2Path="writing-stories/play-function#snippet-my-component-play-function-waitfor"
/> />
<!-- prettier-ignore-end --> <!-- prettier-ignore-end -->
@ -174,6 +186,8 @@ If you need, you can also adjust your `play` function to find elements based on
'vue/my-component-play-function-alt-queries.ts.mdx', 'vue/my-component-play-function-alt-queries.ts.mdx',
'svelte/my-component-play-function-alt-queries.js.mdx', 'svelte/my-component-play-function-alt-queries.js.mdx',
]} ]}
usesCsf3
csf2Path="writing-stories/play-function#snippet-my-component-play-function-alt-queries"
/> />
<!-- prettier-ignore-end --> <!-- prettier-ignore-end -->
@ -197,6 +211,8 @@ Otherwise, if the component is not immediately available, for instance, due to a
'vue/my-component-play-function-query-findby.ts.mdx', 'vue/my-component-play-function-query-findby.ts.mdx',
'svelte/my-component-play-function-query-findby.js.mdx', 'svelte/my-component-play-function-query-findby.js.mdx',
]} ]}
usesCsf3
csf2Path="writing-stories/play-function#snippet-my-component-play-function-query-findby"
/> />
<!-- prettier-ignore-end --> <!-- prettier-ignore-end -->
@ -216,6 +232,8 @@ By default, each interaction you write inside your `play` function will be execu
'vue/my-component-play-function-with-canvas.ts.mdx', 'vue/my-component-play-function-with-canvas.ts.mdx',
'svelte/my-component-play-function-with-canvas.js.mdx', 'svelte/my-component-play-function-with-canvas.js.mdx',
]} ]}
usesCsf3
csf2Path="writing-stories/play-function#snippet-my-component-play-function-with-canvas"
/> />
<!-- prettier-ignore-end --> <!-- prettier-ignore-end -->

View File

@ -16,6 +16,8 @@ It's useful to write stories that [render two or more components](../writing-sto
'vue/list-story-with-sub-components.3.js.mdx', 'vue/list-story-with-sub-components.3.js.mdx',
'vue/list-story-with-sub-components.ts-3.ts.mdx', 'vue/list-story-with-sub-components.ts-3.ts.mdx',
]} ]}
usesCsf3
csf2Path="writing-stories/stories-for-multiple-components#snippet-list-story-with-subcomponents"
/> />
<!-- prettier-ignore-end --> <!-- prettier-ignore-end -->
@ -49,6 +51,8 @@ The simplest change we can make to the above is to reuse the stories of the `Lis
'web-components/list-story-unchecked.js.mdx', 'web-components/list-story-unchecked.js.mdx',
'web-components/list-story-unchecked.ts.mdx', 'web-components/list-story-unchecked.ts.mdx',
]} ]}
usesCsf3
csf2Path="writing-stories/stories-for-multiple-components#snippet-list-story-unchecked"
/> />
<!-- prettier-ignore-end --> <!-- prettier-ignore-end -->
@ -68,6 +72,8 @@ One way we improve that situation is by pulling the rendered subcomponent out in
'react/list-story-with-unchecked-children.js.mdx', 'react/list-story-with-unchecked-children.js.mdx',
'react/list-story-with-unchecked-children.ts.mdx', 'react/list-story-with-unchecked-children.ts.mdx',
]} ]}
usesCsf3
csf2Path="writing-stories/stories-for-multiple-components#snippet-list-story-with-unchecked-children"
/> />
<!-- prettier-ignore-end --> <!-- prettier-ignore-end -->
@ -105,6 +111,8 @@ Another option that is more “data”-based is to create a special “story-gen
'vue/list-story-template.ts-3.ts.mdx', 'vue/list-story-template.ts-3.ts.mdx',
'angular/list-story-template.ts.mdx', 'angular/list-story-template.ts.mdx',
]} ]}
usesCsf3
csf2Path="writing-stories/stories-for-multiple-components#snippet-list-story-template"
/> />
<!-- prettier-ignore-end --> <!-- prettier-ignore-end -->

View File

@ -66,6 +66,8 @@ Storybook's a11y addon runs [Axe](https://github.com/dequelabs/axe-core) on the
'vue/component-story-with-accessibility.3.js.mdx', 'vue/component-story-with-accessibility.3.js.mdx',
'svelte/component-story-with-accessibility.js.mdx', 'svelte/component-story-with-accessibility.js.mdx',
]} ]}
usesCsf3
csf2Path="writing-tests/accessibility-testing#snippet-component-story-with-accessibility"
/> />
<!-- prettier-ignore-end --> <!-- prettier-ignore-end -->
@ -120,6 +122,8 @@ Customize the a11y ruleset at the story level by updating your story to include
'vue/storybook-addon-a11y-story-config.js.mdx', 'vue/storybook-addon-a11y-story-config.js.mdx',
'svelte/storybook-addon-a11y-story-config.js.mdx', 'svelte/storybook-addon-a11y-story-config.js.mdx',
]} ]}
usesCsf3
csf2Path="writing-tests/accessibility-testing#snippet-storybook-addon-a11y-story-config"
/> />
<!-- prettier-ignore-end --> <!-- prettier-ignore-end -->
@ -138,6 +142,8 @@ Disable accessibility testing for stories or components by adding the following
'vue/storybook-addon-a11y-disable.js.mdx', 'vue/storybook-addon-a11y-disable.js.mdx',
'svelte/storybook-addon-a11y-disable.js.mdx', 'svelte/storybook-addon-a11y-disable.js.mdx',
]} ]}
usesCsf3
csf2Path="writing-tests/accessibility-testing#snippet-storybook-addon-a11y-disable"
/> />
<!-- prettier-ignore-end --> <!-- prettier-ignore-end -->

View File

@ -112,6 +112,8 @@ An example of an end-to-end test with Cypress and Storybook is testing a login c
'vue/login-form-with-play-function.3.js.mdx', 'vue/login-form-with-play-function.3.js.mdx',
'svelte/login-form-with-play-function.js.mdx', 'svelte/login-form-with-play-function.js.mdx',
]} ]}
usesCsf3
csf2Path="writing-tests/importing-stories-in-tests#snippet-login-form-with-play-function"
/> />
<!-- prettier-ignore-end --> <!-- prettier-ignore-end -->
@ -154,6 +156,8 @@ A real-life scenario of user flow testing with Playwright would be how to test a
'vue/login-form-with-play-function.3.js.mdx', 'vue/login-form-with-play-function.3.js.mdx',
'svelte/login-form-with-play-function.js.mdx', 'svelte/login-form-with-play-function.js.mdx',
]} ]}
usesCsf3
csf2Path="writing-tests/importing-stories-in-tests#snippet-login-form-with-play-function"
/> />
<!-- prettier-ignore-end --> <!-- prettier-ignore-end -->

View File

@ -63,6 +63,8 @@ The test itself is defined inside a `play` function connected to a story. Here's
'vue/login-form-with-play-function.3.js.mdx', 'vue/login-form-with-play-function.3.js.mdx',
'svelte/login-form-with-play-function.js.mdx', 'svelte/login-form-with-play-function.js.mdx',
]} ]}
usesCsf3
csf2Path="writing-tests/interaction-testing#snippet-login-form-with-play-function"
/> />
<!-- prettier-ignore-end --> <!-- prettier-ignore-end -->
@ -104,6 +106,8 @@ For complex flows, it can be worthwhile to group sets of related interactions to
paths={[ paths={[
'common/storybook-interactions-step-function.js.mdx', 'common/storybook-interactions-step-function.js.mdx',
]} ]}
usesCsf3
csf2Path="writing-tests/interaction-testing#snippet-storybook-interactions-step-function"
/> />
<!-- prettier-ignore-end --> <!-- prettier-ignore-end -->