Merge branch '6.0-docs' into migrate_configure_6_0

This commit is contained in:
jonniebigodes 2020-07-30 16:37:18 +01:00 committed by GitHub
commit 6c8ecac48c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
89 changed files with 3163 additions and 13 deletions

View File

@ -0,0 +1,81 @@
---
title: 'Actions'
---
The actions addon is used to display data received by event handler (callback) arguments in your stories.
![Essential Actions addon usage](./addon-actions-screenshot.png)
### Action args
Actions works via supplying special Storybook-generated “action” arguments (referred to as "args" for short) to your stories. There are two ways to get an action arg:
#### Action argType annotation
You can use [argTypes](../api/stories#argtypes) to tell Storybook that an arg to your story should be an action. Usually it makes sense to do this at the component level (although it can be done per story):
```js
// Button.stories.js
import Button from './button';
export default {
title: 'Button',
argTypes: { onClick: { action: 'clicked' } },
};
```
When Storybook sees this argType it will create an arg that is set to a special “action” callback. If your component calls this arg (based on user interaction) the event will show up in the action panel:
<video autoPlay muted playsInline loop>
<source
src="addon-actions-optimized.mp4"
type="video/mp4"
/>
</video>
#### Automatically matching args
Another option is to use a parameter to match all [argTypes](../api/stories#argtypes) that match a certain pattern. The following configuration automatically creates actions for each `on` argType (which you can either specify manually or can be [inferred automatically](locate-link-for-this)).
```js
// Button.stories.js
import Button from './button';
export default {
title: 'Button',
component: Button,
parameters: { actions: { argTypesRegex: '^on.*' } },
};
```
<div class="aside">
NOTE: If you're generating argTypes in using another addon (like [docs](locate-docs), which is the common behavior) you'll need to make sure that the actions addon loads **AFTER** the other addon. You can do this by listing it later in the addons registration code in [`.storybook/main.js`](../configure/overview#configure-story-rendering). This is default in [essentials](./introduction).
</div>
### Action event handlers
It is also possible to detect if your component is emitting the correct HTML events using the `parameters.actions.handles` [parameter](../writing-stories/parameters).
```js
// Button.stories.js
import Button from './button';
export default {
title: 'Button',
parameters: {
actions: {
handles: ['mouseover', 'click .btn']
}
};
```
This will bind a standard HTML event handler to the outermost HTML element rendered by your component and trigger an action when the event is called for a given selector. The format is `<eventname> <selector>`. Selector is optional; it defaults to all elements.
### Advanced / legacy usage
There are also some older ways to use actions as documented in the [advanced README](../addons/actions/ADVANCED-README.md).

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 266 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,80 @@
---
title: 'Backgrounds'
---
The backgrounds toolbar item allows you to adjust the background that your story is rendered on via Storybooks UI:
<video autoPlay muted playsInline loop>
<source
src="addon-backgrounds-optimized.mp4"
type="video/mp4"
/>
</video>
### Configuration
By default, the background toolbar presents you with a light and dark background.
But you're not restricted to these two backgrounds, you can configure your own set of colors with the `parameters.backgrounds` [parameter](../writing-stories/parameters) in your [`.storybook/preview.js`](../configure/overview#configure-story-rendering):
```js
//.storybook/preview.js
export const parameters = {
backgrounds: {
default: 'twitter',
values: [
{
name: 'twitter',
value: '#00aced'
},
{
name: 'facebook',
value: '#3b5998'
},
],
}
```
You can also set backgrounds on per-story or per-component basis by using [parameter inheritance](../writing-stories/parameters#component-parameters):
```js
// Button.stories.js
// To apply a set of backgrounds to all stories of Button:
export default {
title: 'Button',
parameters: {
backgrounds: {
default: 'twitter',
values: [
{ name: 'twitter', value: '#00aced' },
{ name: 'facebook', value: '#3b5998' },
],
},
},
};
```
You can also only override a single key on the background parameter, for instance to set a different default value for a single story:
```js
// Button.stories.js
export const Large = ButtonStory.bind({});
Large.parameters = {
backgrounds: { default: 'facebook' }
};
```
If you want to disable backgrounds in a story, you can do so by setting the `backgrounds` parameter like so:
```js
// Button.stories.js
export const Large = ButtonStory.bind({});
Large.parameters = {
backgrounds: { disable: true }
};
```

196
docs/essentials/controls.md Normal file
View File

@ -0,0 +1,196 @@
---
title: 'Controls'
---
<video autoPlay muted playsInline loop>
<source
src="addon-controls-optimized.mp4"
type="video/mp4"
/>
</video>
Storybook Controls gives you a graphical UI to interact with a component's arguments dynamically, without needing to code. It creates an addon panel next to your component examples ("stories"), so you can edit them live.
Controls does not require any modification to your components. Stories for controls are:
- Convenient. Auto-generate controls based on React/Vue/Angular/etc. components.
- Portable. Reuse your interactive stories in documentation, tests, and even in designs.
- Rich. Customize the controls and interactive data to suit your exact needs.
To use the Controls addon, you need to write your stories using [args](../writing-stories/args). Storybook will automatically generate UI controls based on your args and what it can infer about your component; but you can configure the controls further using [argTypes](../api/stories#argtypes), see below.
<div class="aside">
If you have written stories in the older pre-Storybook 6 style, you may want to read the [args & controls migration guide](https://medium.com/storybookjs/storybook-6-migration-guide-200346241bb5) to help understand how to convert your stories for args.
</div>
### Choosing the control type
By default, Storybook will choose a control for each arg based on the initial value of the arg. This works well with some kind of args, such as boolean values or free-text strings, but in other cases you want a more restricted control.
For instance, suppose you have a `backgroundColor` arg on your story:
```js
// Button.stories.js
const Red = ButtonStory.bind({});
Red.args = {
backgroundColor: '#e00',
};
```
By default, Storybook will render a free text input for the `backgroundColor` arg:
![Essential addon Controls using a string](./addon-controls-args-background-string.png)
This works as long as you type a valid string into the auto-generated text control, but it's not the best UI for picking a color. Lets replace it with Storybooks color picker component.
We can specify which controls get used by declaring a custom [argType](../api/stories#argtypes) for the `backgroundColor` property. ArgTypes encode basic metadata for args, such as name, description, defaultValue for an arg. These get automatically filled in by Storybook Docs.
ArgTypes can also contain arbitrary annotations which can be overridden by the user. Since `backgroundColor` is a property of the component, let's put that annotation on the default export.
```js
import { Button } from './Button';
export default {
title: 'Button',
component: Button,
argTypes: {
backgroundColor: { control: 'color' },
},
};
```
This replaces the input with a color picker for a more intuitive developer experience.
![Essential Control addon with a color picker](./addon-controls-args-background-color.png)
### Fully custom args
Up until now, we only used auto-generated controls based on the component we're writing stories for. If we are writing [complex stories](../workflows/stories-for-multiple-components) we may want to add controls for args that arent part of the component.
```js
// Table.stories.js
const TableStory = ({ data, ...args }) => (
<Table {...args} >
{data.map(row => (<TR>{row.map(item => <TD>{item}</TD>}</TR>))}
</Table>
)
export const Numeric = TableStory.bind({});
Numeric.args = {
// This arg is for the story component
data: [[1, 2, 3], [4, 5, 6]],
// The remaining args get passed to the `Table` component
size: 'large',
}
```
By default, Storybook will add controls for all args that:
- It infers from the component definition [if your framework supports it](https://github.com/storybookjs/storybook/blob/next/addons/controls/README.md#framework-support).
- Appear in the list of args for your story.
You can determine the control by using `argTypes` in each case.
### Configuration
The Controls addon can be configured in two ways:
- Individual controls can be configured via control annotations.
- The addon's appearance can be configured via parameters.
#### Annotations
As shown above, you can configure individual controls with the “control" annotation in the [argTypes](../api/stories#argtypes) field of either a component or story.
Here is the full list of available controls you can use:
|Data Type |Control Type |Description |Options |
|:--------------|:-------------:|:-------------------------------------------------------------:|:------------:|
|**array** |array |serialize array into a comma-separated string inside a textbox |separator |
|**boolean** |boolean |checkbox input |- |
|**number** |number |a numeric text box input |min, max, step|
| |range |a range slider input |min, max, step|
|**object** |object |json editor text input |- |
|**enum** |radio |radio buttons input |options |
| |inline-radio |inline radio buttons input |options |
| |check |multi-select checkbox input |options |
| |inline-check |multi-select inline checkbox input |options |
| |select |select dropdown input |options |
| |multi-select |multi-select dropdown input |options |
|**string** |text |simple text input |- |
| |color |color picker input that assumes strings are color values |- |
| |date |date picker input |- |
If you need to customize a control to use a enum data type in your story, for instance the `inline-radio` you can do it like so:
```js
export default {
title: 'Widget',
component: Widget,
argTypes: {
loadingState: {
type: 'inline-radio',
options: ['loading', 'error', 'ready'],
},
},
};
```
<div class="aside">
If you don't provide a specific one, it defaults to select control type.
</div>
If you need to customize a control for a number data type in your story, you can do it like so:
```js
// Gizmo.story.js
export default {
title: 'Gizmo',
component: Gizmo,
argTypes: {
width: { type: 'range', min: 400, max: 1200, step: 50 };
},
};
```
<div class="aside">
If you don't provide a specific one, it defaults to number control type.
</div>
#### Parameters
Controls supports the following configuration [parameters](../writing-stories/parameters), either globally or on a per-story basis:
<details>
<summary>Show property documentation</summary>
Since Controls is built on the same engine as Storybook Docs, it can also show property documentation alongside your controls using the expanded parameter (defaults to false). This means you embed a complete [ArgsTable](../writing-docs/doc-blocks#argstable) doc block in the controls pane. The description and default value rendering can be [customized](#fully-custom-args) in the same way as the doc block.
To enable expanded mode globally, add the following to [`.storybook/preview.js`](../configure/overview#configure-story-rendering):
```js
// .storybook/preview.js
export const parameters = {
controls: { expanded: true },
};
```
And here's what the resulting UI looks like:
![Controls addon expanded](./addon-controls-expanded.png)
</details>
#### Hide NoControls warning
If you don't plan to handle the control args inside your Story, you can remove the warning with:
```js
Basic.parameters = {
controls: { hideNoControlsWarning: true },
};
```

View File

@ -0,0 +1,40 @@
---
title: 'Introduction'
---
A major strength of Storybook are [addons](/addons/) that extend Storybooks UI and behaviour. There are many third-party addons as well as “official” addons developed by the Storybook core team. Storybook ships by default with a set of “essential” addons that add to the initial user experience.
- [Actions](./actions)
- [Backgrounds](./backgrounds)
- [Controls](./controls)
- [Docs](../writing-docs/introduction)
- [Viewport](./viewports)
### Configuration
Essentials is "zero config”, it comes with a recommended configuration out of the box.
If you need to reconfigure any of the essential addons, install it manually, following the installation instructions and adjust the configuration to your needs.
When you start Storybook, Essentials will override its configuration with your own.
### Disabling addons
If you need to disable any of the Essential's addons, you can do it by changing your [`.storybook/main.js`](../configure/overview#configure-story-rendering) file.
As an example, if the background addon wasn't necessary to your work, you would need to make the following change:
```js
// .storybook/main.js
module.exports = {
addons: [{
name: '@storybook/addon-essentials',
options: {
backgrounds: false,
}
}]
};
```
You can use the following keys for each individual addon: `actions`, `backgrounds`, `controls`, `docs`, `viewport`

View File

@ -0,0 +1,182 @@
---
title: 'Toolbars & globals'
---
Storybook ships with toolbar items to control the [viewport](./viewport) and [background](./backgrounds) the story renders in. You can also create your own toolbar items which control special “globals” which you can then read to create [decorators](../writing-stories/decorators) to control story rendering.
### Globals
Globals in Storybook represent “global” (as in not story-specific) inputs to the rendering of the story. As they arent specific to the story, they arent passed in the `args` argument to the story function (although they are accessible as `context.globals`), but typically you use them in decorators which apply to all stories.
When the globals change, the story re-renders and the decorators rerun with the new values. The easiest way to change globals is to create a toolbar item for them.
Lets see how.
### Global types and the toolbar annotation
Storybook has a simple, declarative syntax for configuring toolbar menus. In your [`.storybook/preview.js`](../configure/overview#configure-story-rendering), you can add your own toolbars by creating `globalTypes` with a `toolbar` annotation:
```js
// .storybook/preview.js
export const globalTypes = {
theme: {
name: 'Theme'
description: 'Global theme for components',
defaultValue: 'light',
toolbar: {
icon: 'circlehollow',
// array of plain string values or MenuItem shape (see below)
items: ['light', 'dark'],
},
},
};
```
<div class="aside">
As globals are *global* you can *only* set `globalTypes` in [`.storybook/preview.js`](../configure/overview#configure-story-rendering).
</div>
When you start your Storybook, you should see a new dropdown in your toolbar with options `light` and `dark`.
### Create a decorator
We have a `global` defined, let's wire it up! We can consume our new `theme` global in a decorator using the `context.globals.theme` value.
For example, suppose you are using `styled-components`. You can add a theme provider decorator to your [`.storybook/preview.js`](../configure/overview#configure-story-rendering) config:
```js
// .storybook/preview.js
import { ThemeProvider } from 'styled-components';
import { StoryContext, StoryGetter, StoryWrapper } from '@storybook/addons';
const withThemeProvider=(Story,context)=>{
const theme = getTheme(context.globals.theme);
return (
<ThemeProvider theme={theme}>
<Story {...context} />
</ThemeProvider>
)
}
export const decorators = [withThemeProvider];
```
### Advanced usage
So far we've managed to create and consume a global inside Storybook.
Now let's take a look at a more complex example. Let's suppose we wanted to implement a new global called __locale__ for internationalization, which shows a flag on the right side of the toolbar.
In your [`.storybook/preview.js`](../configure/overview#configure-story-rendering), add the following:
```js
// ./storybook/preview.js
export const globalTypes = {
locale: {
name: 'Locale',
description: 'Internationalization locale',
defaultValue: 'en',
toolbar: {
icon: 'globe',
items: [
{ value: 'en', right: '🇺🇸', title: 'English' },
{ value: 'fr', right: '🇫🇷', title: 'Français' },
{ value: 'es', right: '🇪🇸', title: 'Español' },
{ value: 'zh', right: '🇨🇳', title: '中文' },
{ value: 'kr', right: '🇰🇷', title: '한국어' },
],
},
},
};
```
By adding the the configuration element `right`, the text will displayed on the right side in the toolbar menu, once you connect it to a decorator.
Here's a list of the configuration options available.
| MenuItem | Type | Description | Required |
| ------------- |:-------------:|:------------------------------------------------------------:|:--------:|
| **value** | String |The string value of the menu that gets set in the globals |Yes |
| **title** | String |The main text of the title |Yes |
| **left** | String |A string that gets shown in left side of the menu |No |
| **right** | String |A string that gets shown in right side of the menu |No |
| **icon** | String |An icon that gets shown in the toolbar if this item is selected|No |
### Consuming globals from within a story
We recomend consuming globals from within a decorator and define a global setting for all stories.
But we're aware that sometimes it's more useful to use toolbar options in a per-story basis.
Using the example above, you can modify any story to retrieve the __Locale__ `global` from the story context:
```js
// your-story.js
const getCaptionForLocale = (locale) => {
switch(locale) {
case 'es': return 'Hola!';
case 'fr': return 'Bonjour!';
case 'kr': return '안녕하세요!';
case 'zh': return '你好!';
default:
return 'Hello!',
}
}
export const StoryWithLocale = (args, { globals: { locale } }) => {
const caption = getCaptionForLocale(locale);
return <>{caption}</>;
};
```
<div class="aside">
In Storybook 6.0, if you set the global option `passArgsFirst: false` for backwards compatibility, the story context is passed as the second argument:
```js
// your-story.js
export const StoryWithLocale = ({ globals: { locale } }) => {
const caption = getCaptionForLocale(locale);
return <>{caption}</>;
};
```
</div>
### Consuming globals from within an addon
If you're working on a Storybook addon and you need to retrieve globals. You can do so, The `@storybook/api` package provides a hook for this scenario, you can use the `useGlobals()` hook to retrieve any globals you want.
Using the ThemeProvider example above, you could expand it to display which current theme is being shown inside a panel like so:
```js
// your-addon-register-file.js
import { useGlobals } from '@storybook/api';
import { AddonPanel, Placeholder, Separator, Source, Spaced, Title } from '@storybook/components';
const ThemePanel = props => {
const [{ theme: themeName }] = useGlobals();
const theme = getTheme(themeName);
return (
<AddonPanel {...props}>
{theme ? (
<Spaced row={3} outer={1}>
<Title>{theme.name}</Title>
<p>The full theme object/p>
<Source code={JSON.stringify(theme, null, 2)} language="js" copyable padded showLineNumbers />
</Spaced>
) : (
<Placeholder>No theme selected</Placeholder>
)}
</AddonPanel>
);
};
```

View File

@ -0,0 +1,210 @@
---
title: 'Viewports'
---
The Viewports toolbar item allows you to adjust the dimensions of the iframe your story is rendered in. This makes it easy to develop responsive UIs.
<video autoPlay muted playsInline loop>
<source
src="addon-viewports-optimized.mp4"
type="video/mp4"
/>
</video>
### Configuration
By default, you are presented with a set of common viewports.
If you want to change the default set of viewports, you can set the global `parameters.viewport` [parameter](../writing-stories/parameters) in your [`.storybook/preview.js`](../configure/overview#configure-story-rendering):
```js
// .storybook/preview.js
export const parameters: {
viewport: {
viewports: newViewports, // newViewports would be an ViewportMap. (see below for examples)
defaultViewport: 'someDefault',
},
}
```
The viewport global can take a object with the following keys:
| Field | Type | Description |Default Value |
| -----------------------|:-------------:|:------------------------------------------------------:|:------------:|
| **defaultViewport** | String |Sets the default viewport |`'responsive'`|
| **disable** | Boolean |Disables the viewport |N/A |
| **viewports** | Object |The configuration object for the viewport |`{}` |
The viewports object needs the following keys:
| Field | Type | Description |Example values |
| -----------------------|:-------------:|:-------------------------------------------------------|:-----------------------------------------:|
| **name** | String |Name for the viewport |`'Responsive'` |
| **styles** | Object |Sets Inline styles to be applied to the story |`{width:0,height:0}` |
| **type** | String |Type of the device (e.g. desktop, mobile, or tablet) |`desktop` |
### Use detailed set of devices
By default Storybook uses a [minimal set of viewports](https://github.com/storybookjs/storybook/blob/master/addons/viewport/src/defaults.ts#L135) to get you started. But you're not restricted to these, the addon offers a more granular list of devices that you can use.
Change your [`.storybook/preview.js`](../configure/overview#configure-story-rendering) to the following:
```js
// .storybook/preview.js
import { INITIAL_VIEWPORTS } from '@storybook/addon-viewport';
export const parameters = {
viewport: {
viewports: INITIAL_VIEWPORTS,
},
};
```
Once you start your Storybook, you'll see that now you have a whole different set of devices to use.
See [here](https://github.com/storybookjs/storybook/blob/master/addons/viewport/src/defaults.ts#L3) the complete list of devices and their configurations.
### Add new devices
If you have either a specific viewport, or a list of viewports that you need to use. You can modify your [`.storybook/preview.js`](../configure/overview#configure-story-rendering) file to include them like so:
```js
//.storybook/preview.js
const customViewports = {
kindleFire2: {
name: 'Kindle Fire 2',
styles: {
width: '600px',
height: '963px',
},
},
kindleFireHD: {
name: 'Kindle Fire HD',
styles: {
width: '533px',
height: '801px',
},
},
};
```
To use them in your Storybook you'll need to make the following change:
```js
//.storybook/preview.js
export const parameters = {
viewport: { viewports: customViewports },
};
```
Once you start Storybook, you'll see your new viewports and devices.
If you need, you can also add these two to another list of viewports.
For instance, if you wanted to use these two with the minimal set of viewports, you can do it like so:
```js
//.storybook/preview.js
import { MINIMAL_VIEWPORTS} from '@storybook/addon-viewport';
const customViewports = {
kindleFire2: {
name: 'Kindle Fire 2',
styles: {
width: '600px',
height: '963px',
},
},
kindleFireHD: {
name: 'Kindle Fire HD',
styles: {
width: '533px',
height: '801px',
},
},
};
export const parameters = {
viewport: {
viewports: {
...MINIMAL_VIEWPORTS,
...customViewports,
},
},
};
```
This will add both `Kindle Fire 2` and `Kindle Fire HD` to the list of devices. This is achieved by making use of the exported [`MINIMAL_VIEWPORTS`](https://github.com/storybookjs/storybook/blob/master/addons/viewport/src/defaults.ts#L135) property, by merging it with the new ones.
```js
import {
INITIAL_VIEWPORTS,
// or MINIMAL_VIEWPORTS,
} from '@storybook/addon-viewport';
const customViewports = {
kindleFire2: {
name: 'Kindle Fire 2',
styles: {
width: '600px',
height: '963px',
},
},
kindleFireHD: {
name: 'Kindle Fire HD',
styles: {
width: '533px',
height: '801px',
},
},
};
export const parameters = {
viewport: {
viewports: {
...INITIAL_VIEWPORTS,
// or ...MINIMAL_VIEWPORTS,
...customViewports,
},
},
};
```
### Configuring per component or story
There are cases where it's not effective for you to use a certain visual viewport on a global scale and you need it to adjust it to a individual story.
You can change your story through [parameters](../writing-stories/parameters) to include the viewports you need to use for your component.
[Parameters](../writing-stories/parameters) can be configured for a whole set of stories or a single story via the standard parameter API:
```js
// my-story.story.js
export default {
title: 'Stories',
parameters: {
// the viewports object from the Essentials addon
viewport: {
// the viewports you want to use
viewports: INITIAL_VIEWPORTS,
// your own default viewport
defaultViewport: 'iphone6'
},
};
};
export const myStory = () => <div />;
myStory.parameters = {
viewport: {
defaultViewport: 'iphonex'
},
};
```

Binary file not shown.

BIN
docs/get-started/addons.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

@ -1,3 +1,67 @@
---
title: 'Browse Stories'
---
Last chapter we learned that stories correspond with discrete component states. This chapter demonstrates how to use Storybook as a workshop for building components.
### Sidebar and Canvas
A `*.stories.js` file defines all the stories for a component. Each story has a corresponding sidebar item. When you click on a story it renders in the Canvas, an isolated preview iframe.
<video autoPlay muted playsInline loop>
<source
src="example-browse-all-stories-optimized.mp4"
type="video/mp4"
/>
</video>
Navigate between stories by clicking on them in the sidebar or use keyboard shortcuts (for instance use opt/alt + ◀️ ▶️). Try the sidebar search to find a story by name.
### Toolbar
Storybook ships with time-saving tools built in. The **toolbar** contains tools that allow you to adjust how the story renders in the Canvas:
![Storybook toolbar](./toolbar.png)
- 🔍Zooming visually scales the component so you can check the details.
- 🖼 Background changes the rendered background behind your component so you can verify how your component renders in different visual contexts.
- 📱 Viewport renders the component in a variety of dimensions and orientations. Its ideal for checking the responsiveness of components.
<video autoPlay muted playsInline loop>
<source
src="toolbar-walkthrough-optimized.mp4"
type="video/mp4"
/>
</video>
The [“Docs”](../writing-docs/introduction) tab shows auto-generated documentation about components (inferred from the source code). Usage docs are helpful when sharing reusable components with your team. For example, in a design system or component library.
<video autoPlay muted playsInline loop>
<source
src="toolbar-docs-tab-optimized.mp4"
type="video/mp4"
/>
</video>
The toolbar is customizable. You can use [globals](../essentials/toolbars-and-globals) to quickly toggle themes and languages. Or install Storybook toolbar [addons](../configure/user-interface#addons-description) from the community to enable advanced workflows.
### Addons
Addons are plugins that extend Storybook's core functionality. You can find them in the addons panel, a reserved place in the Storybook UI below the Canvas. Each tab shows the generated metadata, logs, or static analysis for the selected story by the addon.
![Storybook addon examples](./addons.png)
- **Source** displays the source code of the currently rendered story. (to be determined)
- **Controls** allows you to dynamically interact with a components args (inputs). Experiment with alternate configurations of the component to discover edge cases.
- **Actions** help you verify interactions produce the correct outputs via callbacks. For instance if you view the “Logged In” story of the Header component, we can verify that clicking the “Log out” button triggers the `onLogout` callback, which would be provided by the component that made use of the Header.
<video autoPlay muted playsInline loop>
<source
src="addons-walkthrough-optimized.mp4"
type="video/mp4"
/>
</video>
Storybook is extensible. Our rich ecosystem of addons helps you test, document, and optimize your stories. You can also create an addon to satisfy your workflow requirements. Read more in the [addons section](../api/addons).
In the next chapter, we'll get your components rendering in Storybook so you can use it to supercharge component development.

View File

@ -1,3 +1,12 @@
---
title: 'Conclusion'
---
Congratulations! You learned the basics. Storybook is the most popular tool for UI component development and documentation. Youll be able to transfer these skills to thousands of companies that use Storybook to build UIs including GitHub, Airbnb, and Stripe.
If youd like to learn workflows for building app UIs with Storybook, check out the in-depth guides on [Learn Storybook](https://www.learnstorybook.com/). Continue reading for detailed information on how to use Storybook APIs.
What to learn next:
- [Write stories](../writing-stories/introduction)
- [Write component docs](../writing-docs/introduction)

Binary file not shown.

After

Width:  |  Height:  |  Size: 143 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 107 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 225 KiB

View File

@ -2,8 +2,67 @@
title: 'Install'
---
Test content
Use the Storybook CLI to install it in a single command. Run this inside your existing projects root directory:
![optimize](./optimize.gif)
```sh
npx sb init
```
## Heading
<details>
<summary><code>sb init</code> is not made for empty projects</summary>
Storybook needs to be installed into a project that is already setup with a framework. It will not work on an empty project. There are many ways to bootstrap an app in given framework including:
- 📦 [Create React App](https://reactjs.org/docs/create-a-new-react-app.html)
- 📦 [Vue CLI](https://cli.vuejs.org/)
- Or any other tooling available.
</details>
During its install process, Storybook will look into your project's dependencies and provide you with the best configuration available.
The command above will make the following changes to your local environment:
- 📦 Install the required dependencies.
- 🛠 Setup the necessary scripts to run and build Storybook.
- 🛠 Add the default Storybook configuration.
- 📝 Add some boilerplate stories to get you started.
Check that everything worked by running:
```sh
npx storybook
```
It will start Storybook locally and output the address. Depending on your system configuration, it will automatically open the address in a new browser tab and you'll be greeted by a welcome screen. In that screen there are some noteworthy items:
- A collection of useful links for more in depth configuration and customization options you have at your disposal.
- A second set of links for you to expand your Storybook knowledge and get involved with the ever growing Storybook community.
- A few example stories to get you started.
![Storybook welcome screen](./example-welcome.png)
<details>
<summary>Troubleshooting</summary>
You can also setup Storybook manually through the Storybook CLI.
You can use the `--type` flag to tell Storybook to configure itself based on the flag.
For instance you can use:
- `--type react` to setup Storybook with the React configuration options.
- `--type vue` to setup Storybook with the Vue configuration options.
- `--type angular` to setup Storybook with the Angular configuration options.
If there's an installation problem, check the README for your framework (e.g <a href="https://github.com/storybookjs/storybook/blob/next/app/react/README.md">Storybook for React</a>).
If all else fails, try asking for [help](https://storybook.js.org/support/)
</details>
Now that you installed Storybook successfully, lets take a look at a story that was written for us.

View File

@ -4,24 +4,27 @@ title: 'Introduction'
Storybook is a tool for UI development. It makes development faster and easier by isolating components. This allows you to work on one component at a time. You can develop entire UIs without needing to start up a complex dev stack, force certain data into your database or navigate around your application.
![This is a test image](./test-image.png)
<SS>
<video autoPlay muted playsInline loop>
<source
src="storybook-hero-video-optimized.mp4"
type="video/mp4"
/>
</video>
Use Storybook to build small atomic components and complex pages in your web application. If it is a UI, you can build it with Storybook.
<SSs>
![Storybook relationship](./storybook-relationship.png)
Storybook helps you document components for reuse and automatically visually test your components to prevent bugs. Extend Storybook with an ecosystem of addons that help you do things like fine tune responsive layouts or verify accessibility.
Storybook helps you **document** components for reuse and automatically **visually test** your components to prevent bugs. Extend Storybook with an ecosystem of **addons** that help you do things like fine tune responsive layouts or verify accessibility.
Storybook integrates with many popular JavaScript UI frameworks and (experimentally) supports server-rendered component frameworks such as Ruby on Rails.
Storybook integrates with many popular JavaScript UI frameworks and (experimentally) supports server-rendered component frameworks such as [Ruby on Rails](https://rubyonrails.org/).
## Learning resources
If you want to learn more about the component-driven approach that Storybook enables, this blog post is a good place to start.
If you want to learn more about the component-driven approach that Storybook enables, this [site](http://componentdriven.org) is a good place to start.
If you want a guided tutorial through building a simple application with Storybook in your framework and language, LearnStorybook has your back.
If you want a guided tutorial through building a simple application with Storybook in your framework and language, [LearnStorybook](https://www.learnstorybook.com/) has your back.
If you want to just learn the basics and APIs of Storybook, read on!
Read on to learn Storybook basics and API!
> > [Get started installing Storybook into your project](./install.md#heading)
Get started installing Storybook into your project

Binary file not shown.

Before

Width:  |  Height:  |  Size: 325 KiB

View File

@ -1,3 +1,116 @@
---
title: 'Setup'
---
Now that youve learned what stories are and how to browse them, lets demo working on one of your components. Pick a simple component from your project, like a Button, and write a `.stories.js` file to go along with it. It might look something like this:
```js
// YourComponent.stories.js
import { YourComponent } from './YourComponent';
// This default export determines where you story goes in the story list
export default {
component: YourComponent,
title: 'YourComponent',
}
const Template = (args) => <YourComponent {...args} />;
export const FirstStory = Template.bind({});
FirstStory.args = {
/* the args you need here will depend on your component */
};
```
Go to your Storybook to view the rendered component. Its OK if it looks a bit unusual right now.
Depending on your technology stack, you also might need to configure the Storybook environment further.
### Configure Storybook for your stack
Storybook comes with a permissive [default configuration](../configure/overview). It attempts to customize itself to fit your setup. But its not foolproof.
Your project may have additional requirements before components can be rendered in isolation. This warrants customizing configuration further. There are three broad categories of configuration you might need.
<details>
<summary>Build configuration like webpack and Babel</summary>
If you see errors on the CLI when you run the `yarn storybook` command. Its likely you need to make changes to Storybooks build configuration. Here are some things to try:
- [Presets](../api/addons#addon-presets) bundle common configurations for various technologies into Storybook. In particular presets exist for Create React App, SCSS and Ant Design.
- Specify a custom [Babel configuration](../configure/integration#custom-babel-config) for Storybook. Storybook automatically tries to use your projects config if it can.
- Adjust the [webpack configuration](../configure/integration#webpack) that Storybook uses. Try patching in your own configuration if needed.
</details>
<details>
<summary>Runtime configuration</summary>
If Storybook builds but you see an error immediately when connecting to it in the browser, then chances are one of your input files is not compiling/transpiling correctly to be interpreted by the browser. Storybook supports modern browsers and IE11, but you may need to check the Babel and webpack settings (see above) to ensure your component code works correctly.
</details>
<details id="component-context" name="component-context">
<summary>Component context</summary>
If a particular story has a problem rendering, often it means your component expects a certain environment is available to the component.
A common frontend pattern is for components to assume that they render in a certain “context” with parent components higher up the rendering hierarchy (for instance theme providers)
Use [decorators](../writing-stories/decorators) to “wrap” every story in the necessary context providers. [`.storybook/preview.js`](../configure/overview#configure-story-rendering) allows you to customize how components render in Canvas, the preview iframe. In this decorator example, we wrap every component rendered in Storybook with `ThemeProvider`.
```js
// .storybook/preview.js
import { ThemeProvider } from 'styled-components';
export const decorators = [
(Story) => <ThemeProvider theme="default"><Story/></ThemeProvider>,
];
```
</details>
### Render component styles
Storybook isnt opinionated about how you generate or load CSS. It renders whatever DOM elements you provide. But sometimes things wont “look right” out of the box.
You may have to configure your CSS tooling for Storybooks rendering environment. Here are some tips on what could help:
<details>
<summary>CSS-in-JS like styled-components and Emotion</summary>
If you are using CSS-in-JS, chances are your styles are working because theyre generated in JavaScript and served alongside each component.
Theme users may need to add a decorator to `.storybook/preview.js`, [see above](#component-context).
</details>
<details>
<summary>@import CSS into components</summary>
Storybook allows you to import CSS files in your components directly. But in some cases you may need to [tweak the webpack config](../configure/integration#webpack). Angular components require [a special import](../configure/integration#importing-css-files).
</details>
<details>
<summary>Global imported styles</summary>
If you have global imported styles, create a file called [`.storybook/preview.js`](../configure/overview#configure-story-rendering) and import the styles there. The styles will be added by Storybook automatically for all stories.
</details>
<details>
<summary>Add external CSS or fonts in the &#60head&#62</summary>
Alternatively if you want to inject a CSS link tag to the `<head>` directly (or some other resource like a font link), you can use [`.storybook/preview-head.html`](/configure/story-rendering#adding-to-&#60head&#62) to add arbitrary HTML.
</details>
### Load assets and resources
If you want to link to static files in your project or stories (e.g. `/fonts/XYZ.woff`), use the `-s path/to/folder` to specify a static folder to serve from when you start up Storybook. To do so, edit the `storybook` and `build-storybook` scripts in `package. json`.
We recommend serving external resources and assets requested in your components statically with Storybook. This ensures that assets are always available to your stories.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 270 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

View File

@ -1,3 +1,80 @@
---
title: "What's a Story"
---
**A story captures the rendered state of a UI component**. Developers write multiple stories per component that describe all the “interesting” states a component can support.
The CLI created example components that demonstrate the types of components you can build with Storybook: Button, Header, and Page.
Each example component has a set of stories that show the states it supports. You can browse the stories in the UI and see the code behind them in files that end with `.stories.js` or `.stories.ts`. The stories are written in Component Story Format (CSF), an ES6 modules-based standard, for writing component examples.
Lets start with the `Button` component. A story is a function that describes how to render the component in question. Heres how to render `Button` in the “primary” state and export a story called `Primary`.
```js
// Button.stories.js
import React from 'react';
import { Button } from './Button';
export const Primary = () => <Button primary>Button</Button>;
```
![Initial button story](./example-button-noargs.png)
View the rendered `Button` by clicking on it in the Storybook sidebar.
The above story definition can be further improved to take advantage of [Storybooks “args”](../writing-stories/args) concept. Args describes the arguments to Button in a machine readable way. This unlocks Storybooks superpower of altering and composing arguments dynamically.
```js
// We create a “template” of how args map to rendering
const Template = (args) => <Button {...args} />;
// Each story then reuses that template
export const Primary = Template.bind({});
Primary.args = {
primary: true,
label: 'Button',
};
```
![Button story with args](./example-button-args.png)
Both story examples render the same thing because Storybook feeds the given `args` property into the story during render. But you get timesaving conveniences with args:
- `Button`s callbacks are logged into the Actions tab. Click to try it.
- `Button`s arguments are dynamically editable in the Controls tab. Adjust the controls
<div class="aside">
Note that `Template.bind({})` is a standard JavaScript technique for making a copy of a function. We copy the `Template` so each exported story can set its own properties on it.
</div>
### Edit a story
Storybook makes it easy to work on one component in one state (aka a story) at a time. When you edit the Button code or stories, Storybook will instantly re-render in the browser. No need to manually refresh.
Update the `label` of the `Primary` story then see your change in Storybook.
<video autoPlay muted playsInline loop>
<source
src="example-button-hot-module-reload-optimized.mp4"
type="video/mp4"
/>
</video>
Stories are also useful for checking that UI continues to look correct as you make changes. The `Button` component has four stories that show it in different use cases. View those stories now to confirm that your change to `Primary` didnt introduce unintentional bugs in the other stories.
<video autoPlay muted playsInline loop>
<source
src="example-button-browse-stories-optimized.mp4"
type="video/mp4"
/>
</video>
Checking a components stories as you develop helps prevent accidental regressions. Tools that integrate with Storybook can also [automate](..workflows/testing-with-storybook) this for you.
Now weve seen the basic anatomy of a story, lets see how we use Storybooks UI to develop stories

View File

@ -25,6 +25,27 @@ module.exports = {
title: 'Configure',
prefix: 'configure',
pages: ['overview', 'integration', 'story-rendering', 'user-interface'],
title: 'Essentials',
prefix:'essentials',
pages:['introduction','controls','actions','viewports','backgrounds','toolbars-and-globals']
},
title:'Workflows',
prefix:'workflows',
pages:[
'publish-storybook',
'build-pages-with-storybook',
'stories-for-multiple-components',
'testing-with-storybook',
'unit-testing',
'visual-testing',
'interaction-testing',
'snapshot-testing',
'storybook-composition',
'package-composition'
]
}
],
};

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View File

@ -0,0 +1,133 @@
---
title: 'Building pages with Storybook'
---
Storybook helps you build any component, from small “atomic” components to composed pages. But as you move up the component hierarchy toward the level of pages, you end up dealing with more complexity.
There are many ways to build pages in Storybook. Here are common patterns and solutions.
- Pure presentational pages.
- Connected components (e.g. network requests, context, browser environment).
### Pure presentational pages
Teams at the BBC, The Guardian, and the Storybook maintainers themselves build pure presentational pages. If you take this approach, you don't need to do anything special to render your pages in Storybook.
It's straightforward to write components to be fully presentational all the way up to the screen level. That makes it easy to show in Storybook. The idea is you then do all the messy “connected” logic in a single wrapper component in your app outside of Storybook. You can see an example of this approach in the [Data](https://www.learnstorybook.com/intro-to-storybook/react/en/data/) chapter of Learn Storybook.
The benefits:
- Easy to write stories once components are in this form.
- All the data for the story is encoded in the args of the story, which works well with other parts of Storybook's tooling (e.g. [controls](../essentials/controls)).
The downsides:
- Your existing app may not be structured in this way and it may be difficult to change it.
- Fetching data in one place means that you need to drill it down to the components that actually use it. This can be natural in a page that composes one big GraphQL query (for instance), but in other data fetching approaches may make this less appropriate.
- It's less flexible if you want to load data incrementally in different places on the screen.
#### Args composition for presentational screens
When you are building screens in this way, it is typical that the inputs of a composite component are a combination of the inputs of the various sub-components it renders. For instance, if your screen renders a page layout (containing details of the current user), a header (describing the document you are looking at), and a list (of the subdocuments), the inputs of the screen may consist of the user, document and subdocuments.
```js
// your-page.js
import React from 'react';
import PageLayout from './PageLayout';
import DocumentHeader from './DocumentHeader';
import DocumentList from './DocumentList';
function DocumentScreen({ user, document, subdocuments }) {
return (
<PageLayout user={user}>
<DocumentHeader document={document} />
<DocumentList documents={subdocuments} />
</PageLayout>
);
}
```
In such cases it is natural to use [args composition](../writing-stories/args#args-composition) to build the stories for the page based on the stories of the sub-components:
```js
// your-page.story.js
import React from 'react';
import DocumentScreen from './DocumentScreen';
import PageLayout from './PageLayout.stories';
import DocumentHeader from './DocumentHeader.stories';
import DocumentList from './DocumentList.stories';
export default {
component: DocumentScreen,
title: 'DocumentScreen',
}
const Template = (args) => <DocumentScreen {...args} />;
export const Simple = Template.bind({});
Simple.args = {
user: PageLayout.Simple.user,
document: DocumentHeader.Simple.document,
subdocuments: DocumentList.Simple.documents,
};
```
This approach is particularly useful when the various subcomponents export a complex list of different stories, which you can pick and choose to build realistic scenarios for your screen-level stories without repeating yourself. By reusing the data and taking a Don't-Repeat-Yourself(DRY) philosophy, your story maintenance burden is minimal.
### Mocking connected components
Render a connected component in Storybook by mocking the network requests that it makes to fetch its data. There are various layers in which you can do that.
#### Mocking providers
If you are using a provider that supplies data via the context, you can wrap your story in a decorator that supplies a mocked version of that provider. For example, in the [Screens](https://www.learnstorybook.com/intro-to-storybook/react/en/screen/) chapter of Learn Storybook we mock a Redux provider with mock data.
Additionally, there may be addons that supply such providers and nice APIs to set the data they provide. For instance [`storybook-addon-apollo-client`](https://www.npmjs.com/package/storybook-addon-apollo-client) provides this API:
```js
// my-component-with-query.story.js
import MyComponentThatHasAQuery, {
MyQuery,
} from '../component-that-has-a-query';
export const LoggedOut = () => <MyComponentThatHasAQuery />;
LoggedOut.parameters: {
apolloClient: {
mocks: [
{ request: { query: MyQuery }, result: { data: { viewer: null } } },
],
},
};
```
#### Mocking imports
It is also possible to mock imports directly, similar to Jest, using webpacks aliasing. This is useful if your component makes network requests directly.
```js
// .storybook/main.js
module.exports = {
// your Storybook configuration
webpackFinal: config => {
config.resolve.alias.fetch = '../__mocks__/fetch.js'
return config;
}
};
```
You would still need to write the fetch mock and wire up a decorator to provide results to it based on the current story.
#### Specific mocks
Another mocking approach is to use libraries that intercept calls at a lower level. For instance you can use [`fetch-mock`](https://www.npmjs.com/package/fetch-mock) to mock fetch requests specifically, or [`msw`](https://www.npmjs.com/package/msw) to mock all kinds of network traffic.
Similar to the import mocking above, once you have a mock youll still want to set the return value of the mock on a per-story basis. Do this in Storybook with a decorator that reads story parameters.

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 319 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 499 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View File

@ -0,0 +1,23 @@
---
title: 'Interaction testing'
---
Stories are useful for verifying the known states of a component. But sometimes you need to test how a component changes in response to user interaction.
Stories are convenient **starting points** and **harnesses** for interaction tests using end-to-end tools like [Enzyme](https://enzymejs.github.io/enzyme/) and [Cypress](https://www.cypress.io/).
Luckily, this is straightforward. Point your interaction testing tool at Storybooks isolated iframe [URL for a specific story](../configure/user-interface#permalinking-to-stories) then execute the test script as usual. Heres an example using Cypress:
```js
// My-component_spec.js
describe('My Component', () => {
it('should respond to click on button with warning', () => {
cy.visit('http://localhost:6006/iframe.html?id=my-component--basic-story);
cy.get('#button').click();
cy.get('#warning').should('contain.text', 'You need to fill in the form!');
});
})
```

View File

@ -0,0 +1,96 @@
---
title: 'Package Composition'
---
Storybook is widely used by component libraries and design systems. Design system authors can automatically compose their design systems inside their consumers Storybooks.
For example, if you use a design system package, its stories can appear alongside your own. That makes it convenient to cross reference usage documentation without leaving Storybook.
### For package consumers
Composition happens automatically if the package [supports](#for-package-authors) it. When you install the package, Storybook will load its stories alongside your own.
![Package composition workflow](./package-composition.png)
#### Configuring
If you want to configure how the composed Storybook behaves, you can disable the `ref` element in your [`.storybook/main.js`](../configure/overview#configure-story-rendering)
```js
// .storybook/main.js
module.exports = {
// your Storybook configuration
refs: {
'package-name': { disable: true }
}
```
#### Changing versions
Change the version of the composed Storybook to see how the library evolves. This requires [configuration](#providing-a-version-section) from the package author.
![Package composition workflow](./composition-versioning.png)
### For package authors
Component library authors can expand adoption by composing their components in their consumers Storybooks.
Add a `storybook` property in your published `package.json `that contains an object with a `url` field. Point the URL field to a published Storybook at the version you want.
```json
// Your component librarys package.json
{
"storybook": {
"url": "https://host.com/your-storybook-for-this-version"
}
}
```
#### Automatic version selection
If you are using a [CHP level 1 service](#chp-level-1) for hosting (such as [Chromatic.com](https://www.chromatic.com/)), you can provide a single URL for your Storybook in the `storybook.url` field. You do not need to change the URL each time you publish a new version. Storybook will automatically find the correct URL for your package.
For example, for Chromatic, you might do:
```json
{
"storybook": {
"url": "https://master--xyz123.chromatic.com"
}
}
```
In this example `xyz123` is your projects id. Storybook will automatically compose in the Storybook published to that project corresponding to the version the user has installed.
#### Providing a version section
Similarly, if you're using a [CHP level 1 service](#chp-level-1) (such as chromatic.com) for hosting, you can provide a list of versions for the user to [choose from](#changing-versions) to experiment with other versions of your package.
### Component Hosting Protocol (CHP)
Storybook can communicate with services that host built Storybooks online. This enables features such as [Composition](./storybook-composition). We categorize services via compliance with the "Component Hosting Protocol" (CHP) with various levels of support in Storybook.
#### CHP level 1
<div style="background-color:#F8FAFC">
TODO: "version=x.y.z query parameter".(vet this)
</div>
The service serves uploaded Storybooks and makes the following available:
- Versioned endpoints, URLs that resolve to different published Storybooks depending on a version=x.y.z query parameter.
- Support for /stories.json
- Support for /metadata.json and the releases field.
Examples of such services:
- [chromatic.com](https://www.chromatic.com/)
#### CHP level 0
The service can serve uploaded Storybooks. There is no special integration with Storybook APIs.
Examples of such services:
- [Netlify](https://www.netlify.com/)
- [S3](https://aws.amazon.com/en/s3/)

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View File

@ -0,0 +1,57 @@
---
title: 'Publish Storybook'
---
Storybook is more than a UI component development tool. Teams also publish Storybook online to review and collaborate on works in progress. That allows developers, designers, and PMs to check if UI looks right without touching code or needing a local dev environment.
### Build Storybook as a static web application
First, well need to build Storybook as a static web application using `build-storybook`, a command thats installed by default.
```shell
yarn build-storybook -o ./path/to/build
```
Storybook will create a static web application at the path you specify. This can be served by any web server. Try it out locally by running:
```shell
npx http-server ./path/to/build
```
### Publish Storybook online
Once your Storybook is built as a static web app it can be deployed to any static site hosting services. The Storybook team uses [Chromatic](https://www.chromatic.com/), a free publishing service made by Storybook maintainers that documents, versions, and indexes your UI components securely in the cloud.
We also maintain [`storybook-deployer`](https://github.com/storybookjs/storybook-deployer) to deploy to GitHub pages or AWS S3.
<video autoPlay muted playsInline loop>
<source
src="storybook-publish-review-optimized.mp4"
type="video/mp4"
/>
</video>
### Review with your team
Publishing Storybook as part of the development process makes it quick and easy to [gather team feedback](https://www.learnstorybook.com/design-systems-for-developers/react/en/review/).
A common method to ask for review is to paste a link to the published Storybook in a pull request or Slack.
If you publish your Storybook to Chromatic, you can use the [UI Review](https://www.chromatic.com/features/publish) feature to automatically scan your PRs for new and updated stories. That makes it easy to identify what changed and give feedback.
![Storybook publishing workflow](./workflow-publish.png)
### Reference external Storybooks
Storybook allows you to browse components from any [Storybook published online](./storybook-composition) inside your local Storybook. It unlocks common workflows that teams often struggle with:
- 👩‍💻 UI developers can quickly reference prior art without switching between Storybooks.
- 🎨 Design systems can expand adoption by composing themselves into their users Storybooks.
- 🛠 Frontend platform can audit how components are used across projects.
![Storybook reference external](./reference-external-storybooks-composition.jpg)
Toggle between multiple versions of Storybook to see how components change between versions. This is useful for design system package authors who maintain many versions at once.
**Requires** a [CHP level 1](./package-composition#chp-level-1) server (such as [chromatic.com](https://www.chromatic.com/)),

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View File

@ -0,0 +1,54 @@
---
title: 'Snapshot testing'
---
Snapshot tests compare the rendered markup of every story against known baselines. Its an easy way to identify markup changes that trigger rendering errors and warnings.
Storybook is a convenient tool for snapshot testing because every story is essentially a test specification. Any time you write or update a story you get a snapshot test for free.
> Snapshot vs visual tests. Visual tests take screenshots of stories and compare them against known baselines. When used to test appearance, visual tests are often a more robust solution than snapshot tests because verifying markup doesnt test for visual changes.
Storyshots is an [official addon](https://github.com/storybookjs/storybook/tree/master/addons/storyshots/storyshots-core) that enables snapshot testing. Its powered by Jest so youll need to [install that](https://jestjs.io/docs/en/getting-started) first. Continue on if you already have Jest.
Install the addon. **Make sure** the version of Storyshots and your projects Storybook version are identical.
```shell
yarn add --dev @storybook/addon-storyshots
```
Configure Storyshots by adding the following test file to your project:
```js
// storybook.test.js
import initStoryshots from '@storybook/addon-storyshots';
initStoryshots();
```
> You can name the file whatever you like as long as it's picked up by Jest.
Run your first test. Storyshot will recognize all your CSF files (based on [`.storybook/main.js`](../configure/overview#configure-story-rendering)) and produces snapshots.
```shell
yarn test storybook.test.js
```
<div style="background-color:#F8FAFC">
TODO: ask for clarification on this note below. What extra steps?
</div>
> If you are loading stories via `.storybook/main.js`, you will need to follow some more steps to ensure Jest finds them.
This will create an initial set of snapshots inside your Storybook config directory.
![Successfull snapshot tests](./storyshots-pass.png)
When you make changes to your components or stories, run the test again to identify the changes to the rendered markup.
![Failing snapshots](./storyshots-fail.png)
If the changes are intentional we can accept them as new baselines. If the changes are bugs, fix the underlying code then run the snapshot tests again.
Storyshots has many options for advanced use cases; read more in the [addons documentation](https://github.com/storybookjs/storybook/tree/master/addons/storyshots/storyshots-core).

View File

@ -0,0 +1,107 @@
---
title: 'Stories for multiple components'
---
It's useful to write stories that [render two or more components](../writing-stories/introduction#stories-for-two-or-more-components) at once if those components are designed to work together. For example, `ButtonGroups`, `Lists`, and `Page` components.
```js
// List.story.js
import List from './List';
import ListItem from './ListItem';
export default {
component: List,
subcomponents: [ListItem],
title: 'List',
};
export const Empty = (args) => <List {...args} />;
export const OneItem = (args) => (
<List {...args}>
<ListItem />
</List>
);
```
Note that by adding `subcomponents` to the default export, we get an extra pane on the ArgsTable, listing the props of `ListItem`:
![Storybook story with subcomponent argstable](./argstable-subcomponents.png)
The downside of the above approach is that it does not take advantage of Storybook [Args](../writing-stories/args) meaning:
1. You cannot change the stories via the controls panel
2. There is no [args reuse](../writing-stories/introduction#using-args) possible, which makes the stories harder to maintain.
Let's talk about some techniques you can use to mitigate the above, which are especially useful in more complicated situations.
### Reusing subcomponent stories
The simplest change we can make to the above is to reuse the stories of the `ListItem` in the `List`:
```js
// List.story.js
import List from './List';
// Instead of importing the ListItem, we import its stories
import { Unchecked } from './ListItem.stories';
export const OneItem = (args) => (
<List {...args}>
<Unchecked {...Unchecked.args} />
</List>
);
```
By rendering the `Unchecked` story with its args, we are able to reuse the input data from the `ListItem` stories in the `List`.
However, we still arent using args to control the `ListItem` stories, which means we cannot change them with controls and we cannot reuse them in other, more complex component stories.
### Using children as an arg
One way we improve that situation is by pulling the render subcomponent out into a `children` arg:
```js
// List.story.js
const Template = (args) => <List {...args} />
export const OneItem = Template.bind({});
OneItem.args = {
children: <Unchecked {...Unchecked.args} />
}
```
Now that `children` is an arg, we can potentially reuse it in another story. As things stand (we hope to improve this soon) you cannot edit children in a control yet.
### Creating a Template Component
Another option that is more “data”-based is to create a special “story-generating” template component:
```js
// List.story.js
import React from 'react';
import List from './List';
import ListItem from './ListItem';
import { Unchecked } from './ListItem.stories';
const ListTemplate = ({ items, ...args }) => (
<List>
{items.map(item => <ListItem {...item} />)}
</List>
);
export const Empty = ListTemplate.bind({});
Empty.args = { items: [] };
export const OneItem = ListTemplate.bind({});
OneItem.args = { items: [Unchecked.args] };
```
This approach is a little more complex to setup, but it means you can more easily reuse the `args` to each story in a composite component. It also means that you can alter the args to the component with the Controls addon:
<div style="background-color:#F8FAFC">
TODO: mention of a gif in the SB 6.0 doc (needs to be vetted)
</div>

View File

@ -0,0 +1,53 @@
---
title: 'Storybook Composition'
---
Composition allows you to embed components from any Storybook inside your local Storybook.
Its made for teams who adopt Storybook in multiple projects but cant ensure that the projects have the same tech stack or share the same repo.
You can compose any Storybook [published online](./publish-storybook) or running locally no matter the view layer, tech stack, or dependencies.
![Storybook composition](./combine-storybooks.png)
### Compose published Storybooks
In your [`storybook/main.js`](../configure/overview#configure-story-rendering) file add a `refs` field with information about the reference Storybook. Pass in a URL to a statically built Storybook.
```js
//.storybook/main.js
module.exports={
// your Storybook configuration
refs: {
'design-system': {
title: "Storybook Design System",
url: "https://5ccbc373887ca40020446347-yldsqjoxzb.chromatic.com"
}
}`
}
```
### Compose local Storybooks
You can also compose Storybook that are running locally. For instance, if you have a React Storybook and a Angular Storybook running on different ports:
```js
//.storybook/main.js
module.exports={
// your Storybook configuration
refs: {
react: {
title: "React",
url: 'http://localhost:7007'
},
angular: {
title: "Angular",
url: 'http://localhost:7008'
}
}
}
```
This composes the React and Angular Storybooks into your current Storybook. When either code base changes, hot-module-reload will work perfectly. That enables you to develop both frameworks in sync.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 439 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

View File

@ -0,0 +1,19 @@
---
title: 'Testing with Storybook'
---
Storybook is a development tool that helps you build components in isolation and record their states as stories. Stories make it easy to explore a component in all its permutations no matter how complex. They also serve as excellent visual test cases.
A story records a way your component can be used. That means your complete set of stories is a catalogue of all the important use cases to test in your component.
The simplest testing method is manual. [Publish](./publish-storybook) your Storybook or run it locally, then look at every story to verify its appearance and behavior. This is appropriate for smaller Storybooks.
![Changing stories with Storybook](./storybook-switch-stories.gif)
As you add more stories, manual testing becomes infeasible. We recommend automating testing to catch bugs and regressions. A complete Storybook testing strategy combines the following techniques to balance coverage, accuracy, and maintainability:
- Manual tests rely on developers to manually look at a component to verify it for correctness. They help us sanity check a components appearance as we build.
- [Unit tests](./unit-testing) verify that the output of a component remains the same given a fixed input. Theyre great for testing the functional qualities of a component.
- [Visual regression tests](./visual-testing) capturing screenshots of every story and comparing them against known baselines. Theyre great for catching UI appearance bugs.
- [Interaction tests](./interaction-testing) will render a story and then interact with it in the browser, asserting things about the way it renders and changes.
- [Snapshot tests](./snapshot-testing) compare the rendered markup of every story against known baselines. This catches markup changes that cause rendering errors and warnings.

View File

@ -0,0 +1,32 @@
---
title: 'Unit testing'
---
Unit tests are useful for verifying functional aspects of components. They verify that the output of a component remains the same given a fixed input.
![Unit testing with a component](./component-unit-testing.gif)
Thanks to the [CSF format](../../formats/component-story-format/), your stories are reusable in unit testing tools. Each [named export](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/export) is “renderable” without depending on Storybook. That means your testing framework will also be able to render that story.
Additionally, the Storybook framework packages have an export that makes this easy and doesnt rely on any other Storybook dependencies.
Here is an example of how you can use it in a testing library:
```js
// Button.test.js
import React from 'react';
import { render, screen } from '@testing-library/react';
import '@testing-library/jest-dom/extend-expect';
import { renderStory } from '@storybook/react/render';
import { Primary } from './Button.stories';
it('renders the button in the primary state, () => {
render(renderStory(Primary));
expect(screen.getByRole('button')).toHaveTextContent(Primary);
});
```
Unit tests can be brittle and expensive to maintain for _every_ component. We recommend combining unit tests with other testing methods like [visual regression testing](./visual-testing) for comprehensive coverage with less maintenance work.

View File

@ -0,0 +1,29 @@
---
title: 'Visual Testing'
---
Visual tests, also called visual regression tests, catch bugs in UI appearance. They work by taking screenshots of every story and comparing them commit-to-commit to identify changes.
This is ideal for verifying what the user sees:
- 🖼️ Layout.
- 🎨 Color.
- 📐 Size.
- 🔳 Contrast.
Storybook is a fantastic tool for visual testing because every story is essentially a test specification. Any time you write or update a story you get a spec for free.
> Visual vs snapshot tests. Snapshot tests compare the rendered markup of every story against known baselines. When used to test how things look, snapshot tests generate a lot of false positives because code changes dont always yield visual changes.
![Visually testing a component in Storybook](./component-visual-testing.gif)
There are [many tools](https://github.com/mojoaxel/awesome-regression-testing) for visual testing. Storybook uses [Chromatic](https://www.chromatic.com), a visual testing service made by Storybook maintainers to run tests in the cloud across browsers.
This prevents UI bugs in our:
- 🖥️ [Application](https://www.chromatic.com/library?appId=5a375b97f4b14f0020b0cda3).
- ⚙️ [Design system](https://www.chromatic.com/library?appId=5ccbc373887ca40020446347)
- 🔗 [Website](https://www.chromatic.com/library?appId=5be26744d2f6250024a9117d).
We also maintain [StoryShots](https://github.com/storybookjs/storybook/tree/master/addons/storyshots), a snapshot testing addon that integrates with [jest-image-snapshot](https://github.com/storybookjs/storybook/tree/master/addons/storyshots#configure-storyshots-for-image-snapshots).

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,322 @@
---
title: 'Doc Blocks'
---
Doc Blocks are the building blocks of Storybook documentation pages. By default, [DocsPage](./docs-page) uses a combination of the blocks below to build a page for each of your components automatically.
Custom [addons](../configure/user-interface#storybook-addons) can also provide their own doc blocks.
### ArgsTable
Storybook Docs automatically generates component props tables for components in supported frameworks. These tables list the arguments ([args for short](../writing-stories/args)) of the component, and even integrate with [controls](../essentials/controls) to allow you to change the args of the currently rendered story.
<video autoPlay muted playsInline loop>
<source
src="addon-controls-docs-optimized.mp4"
type="video/mp4"
/>
</video>
#### DocsPage
To use the ArgsTable in [DocsPage](./docspage#component-parameter), export a component property on your stories metadata:
```js
// MyComponent.stories.js
import { MyComponent } from './MyComponent';
export default {
title: 'MyComponent',
component: MyComponent,
};
// your templates and stories
```
#### MDX
To use the ArgsTable in MDX, use the Props block:
```js
// MyComponent.stories.mdx
import { Props } from '@storybook/addon-docs/blocks';
import { MyComponent } from './MyComponent';
# My Component!
<Props of={MyComponent} />
```
#### Customizing
ArgsTables are automatically inferred from your components and stories, but sometimes it's useful to customize the results.
ArgsTables are rendered from an internal data structure called [ArgTypes](../api/stories#argtypes). When you declare a story's component metadata, Docs automatically extracts ArgTypes based on the component's properties.
You can customize what's shown in the ArgsTable by customizing the ArgTypes data. This is currently available for [DocsPage](./docs-page) and `<Props story="xxx">` construct, but not for the `<Props of={component} />` construct.
<div class="aside">
NOTE: This API is experimental and may change outside of the typical semver release cycle
</div>
The API documentation of ArgTypes is detailed in a [separate section](../api/stories#argtypes), but to control the description and default values, use the following fields:
| Field | Description |
|:-----------------------------|:----------------------------------------------------------------------------------------------:|
| **name** |The name of the property |
| **type.required** |The stories to be show, ordered by supplied name |
| **description** |A Markdown description for the property |
|**table.type.summary** |A short version of the type |
|**table.type.detail** |A short version of the type |
|**table.defaultValue.summary**|A short version of the type |
|**table.defaultValue.detail** |A short version of the type |
|**control** |See [addon-controls README ](https://github.com/storybookjs/storybook/tree/next/addons/controls)|
For instance:
```js
export default {
title: 'Button',
component: Button,
argTypes: {
label: {
description: 'overwritten description',
table: {
type: {
summary: 'something short',
detail: 'something really really long'
},
},
control: {
type: null,
},
},
},
};
```
This would render a row with a modified description, a type display with a dropdown that shows the detail, and no control.
If you find yourself writing the same definition over and over again, Storybook provides some convenient shorthands, that help you streamline your work.
For instance you can use:
- `number`, which is shorthand for `type: {name: 'number'}`
- `radio`, which is a shorhand for `control: {type: 'radio' }`
##### MDX
To customize argTypes in MDX, you can set an `mdx` prop on the `Meta` or `Story` components:
```js
<Meta
title="MyComponent"
component={MyComponent}
argTypes={{
label: {
name: 'label',
/* other argtypes required */
},
}}
/>
<Story name="some story" argTypes={{
label: {
name: 'different label',
/* other required data */
}
}}>
{/* story contents */}
</Story>
```
#### Controls
The controls inside an ArgsTable are configured in exactly the same way as the [controls](../essentials/controls) addon pane. In fact youll probably notice the table is very similar! It uses the same component and mechanism behind the scenes.
### Source
Storybook Docs displays a storys source code using the `Source` block. The snippet has built-in syntax highlighting and can be copied with the click of a button.
![Docs blocks with source](./docblock-source.png)
#### DocsPage
In DocsPage, the `Source` block appears automatically within each storys [Preview] block.
To customize the source snippet thats displayed for a story, set the `docs.source.code` parameter:
```js
export const CustomSource = () => Template.bind({});
CustomSource.parameters = {
docs: {
source: {
code: 'Some custom string here';
}
},
};
```
#### MDX
You can also use the `Source` block in MDX. It accepts either a story ID or `code` snippet. Use the `language` for syntax highlighting.
```js
import { Source } from '@storybook/addon-docs/blocks';
import dedent from 'ts-dedent';
<Source
language='css'
code={dedent`
.container {
display: grid | inline-grid;
}
`}
/>
```
#### ⚒️ Description
Storybook Docs shows a components description extracted from the source code or based on a user-provided string.
![Docs blocks with description](./docblock-description.png)
#### DocsPage
In DocsPage, a components description is shown at the top of the page. For [supported frameworks](https://github.com/storybookjs/storybook/tree/next/addons/docs#framework-support), the component description is automatically extracted from a docgen component above the component in its source code. It can also be set by the `docs.description` parameter.
```js
export default {
title: 'CustomDescription'
parameters: {
docs: {
description: {
component: 'some component _markdown_'
}
},
}
};
export const WithStoryDescription = Template.bind({});
WithStoryDescription.parameters = {
docs: {
description: {
story: 'some story **markdown**'
}
},
};
```
#### MDX
In MDX, the `Description` shows the components description using the same heuristics as the DocsPage. It also accepts a `markdown` parameter to show any user-provided Markdown string.
```js
import { Description } from '@storybook/addon-docs/blocks';
import dedent from 'ts-dedent';
import { Button } from './Button';
<Description of={Button} />
<Description markdown={dedent`
## Custom description
Insert fancy markdown here.
`}/>
```
### Story
Stories (component examples) are the basic building blocks in Storybook. In Storybook Docs, stories are rendered in the `Story` block.
![Docs blocks with stories](./docblock-story.png)
#### DocsPage
In DocsPage, a `Story` block is generated for each story in your [CSF] file, it's wrapped with a `Preview` wrapper that gives it a toolbar on top (in the case of the first “primary” story) and a source code preview underneath.
#### MDX
In MDX, the `Story` block is not only a way of displaying stories, but also the primary way to define them. Storybook looks for `Story` instances with the `name` prop, either defined at the top level of the document, or directly beneath a [Preview](#preview) block defined at the top level:
```js
import { Story } from '@storybook/addon-docs/blocks';
import { Button } from './Button';
export const Template = (args) => <Button {...args} />;
<Story name="Basic" args={{ label: hello }}>
{Template.bind({})
</Story>
```
You can also reference existing stories in Storybook by ID:
```js
import { Story } from '@storybook/addon-docs/blocks';
<Story id="some-component--some-name" />
```
#### Inline rendering
In Storybooks Canvas, all stories are rendered in the [Preview iframe] for isolated development. In Storybook Docs, when [inline rendering is supported by your framework](./docs-page#inline-stories-vs-iframe-stories), inline rendering is used by default for performance and convenience. However, you can force iframe rendering with `docs: { inlineStories: false }` parameter, or `inline={false}` in MDX.
### Preview
Storybook Docs `Preview` block is a wrapper that provides a toolbar for interacting with its contents, and also also provides [Source](#Source) snippets automatically.
![Docs block with a story preview](./docblock-preview.png)
#### DocsPage
In DocsPage, every story is wrapped in a `Preview` block. The first story on the page is called the _primary_, and it has a toolbar. The other stories are also wrapped with `Previews`, but there is no toolbar by default.
![Docs blocks preview toolbar](./docblock-preview-toolbar.png)
#### MDX
In MDX, `Preview` is more flexible: in addition to the DocsPage behavior, it can show multiple stories in one, and even show non-story content.
When you
```js
import { Preview } from '@storybook/addon-docs/blocks';
export const Template = (args) => <Badge {...args } />
<Preview>
<Story name="warning" args={{status: 'warning', label: 'Warning'}}>
{Template.bind({})}
</Story>
<Story name="neutral" args={{status: 'neutral', label: 'Neutral' }}>
{Template.bind({})}
</Story>
<Story name="error" args={{status: 'error', label: 'Error' }}>
{Template.bind({})}
</Story>
</Preview>
```
You can also place non-story content inside a `Preview` block:
```js
import { Preview } from '@storybook/addon-docs/blocks';
import { MyComponent } from './MyComponent';
<Preview>
<h2>Some here</h2>
<MyComponent />
</Preview>
```
This renders the JSX content exactly as it would if youd placed it directly in the MDX, but it also inserts the source snippet in a [Source](#source) block beneath the block.

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View File

@ -0,0 +1,185 @@
---
title: 'DocsPage'
---
When you install [Storybook Docs](https://github.com/storybookjs/storybook/blob/next/addons/docs/README.md), DocsPage is the zero-config default documentation that all stories get out of the box. It aggregates your stories, text descriptions, docgen comments, props tables, and code examples into a single page for each component.
The best practice for docs is for each component to have its own set of documentation and stories.
### Component parameter
Storybook uses the `component` key in the story files default export to extract the component's description and props.
```js
// Button.stories.js
import { Button } from './Button';
export default {
title: 'Storybook Examples/Button',
component: Button,
};
```
### Subcomponents parameter
Sometimes it's useful to document multiple components together. For example, a component librarys List and ListItem components might not make sense without one another.
DocsPage has the concept of a "primary" component that is defined by the `component` parameter. It also accepts one or more `subcomponents`.
```js
// List.stories.js
import { List, ListHeading, ListItem } from './List';
export default {
title: 'Path/to/List',
component: List,
subcomponents: { ListHeading, ListItem },
};
```
![Subcomponents in Docs Page](./docspage-subcomponents.png)
Subcomponent ArgsTables will show up in a tabbed interface along with the primary component. The tab titles will correspond to the keys of the subcomponents object.
If you want to organize your documentation differently for component groups, we recommend using MDX. It gives you complete control over display and supports any configuration.
### Replacing DocsPage
Replace DocsPage template with your own for the entire Storybook, a specific component, or a specific story.
Override the `docs.page` [parameter](../writing-stories/parameters):
- With null to remove docs.
- With MDX docs.
- With a custom component
#### Story-level
Override the `docs.page` [parameter](../writing-stories/parameters#story-parameters) in the story definition.
```js
// Button.stories.js
export const Primary = ButtonStory.bind({});
Primary.parameters = { docs: { page: null } }
```
#### Component-level
Override the `docs.page` [parameter](../writing-stories/parameters#component-parameters) in the default export of the story file.
```js
// Button.stories.js
import { Button } from './Button';
export default {
title: 'Storybook Examples/Button',
component: Button,
parameters: {
docs: {
page: null
}
},
};
```
#### Global-level
Override the `docs.page` [parameter](../writing-stories/parameters#global-parameters) in [`.storybook/preview.js`](../configure/overview#configure-story-rendering).
```js
// .storybook/preview.js
export const parameters { docs: { page: null } });
```
### Remixing DocsPage using doc blocks
Doc blocks are the basic building blocks of Storybook Docs. DocsPage composes them to provide a reasonable UI documentation experience out of the box.
If you want to make minor customizations to the default DocsPage but dont want to write your own MDX you can remix DocsPage. That allows you to reorder, add, or omit doc blocks without losing Storybooks automatic docgen capabilities.
Here's an example of rebuilding DocsPage for the Button component using doc blocks:
```js
// Button.stories.js
import React from 'react';
import {
Title,
Subtitle,
Description,
Primary,
Props,
Stories,
} from '@storybook/addon-docs/blocks';
import { Button } from './Button';
export default {
title: 'Components/Button',
component: Button,
parameters: {
docs: {
page: () => (
<>
<Title />
<Subtitle />
<Description />
<Primary />
<Props />
<Stories />
</>
),
},
},
};
```
Apply a similar technique to remix the DocsPage at the [story](#story-level), [component](#component-level), or [global](#global-level) level.
In addition, you can interleave your own components to customize the auto-generated contents of the page, or pass in different options to the blocks to customize their appearance. Read more about [Doc Blocks](./docs-blocks).
### Story file names
Unless you use a custom [webpack configuration](../configure/integration#extending-storybooks-webpack-config), all of your story files should have the suffix `*.stories.@(j|t)sx?`. For example, "Badge.stories.js" or "Badge.stories.tsx". This tells Storybook and its docs preset to display the docs based on the file contents.
### Inline stories vs. iframe stories
DocsPage displays all the stories of a component in one page. You have the option of rendering those stories inline or in an iframe.
By default, we render React and Vue stories inline. Stories from other supported frameworks will render in an `<iframe>` by default.
The iframe creates a clean separation between your code and Storybooks UI. But using an iframe has disadvantages. You have to explicitly set the height of iframe stories or youll see a scroll bar. And certain dev tools might not work right.
Render your frameworks stories inline using two docs configuration options in tandem, `inlineStories` and `prepareForInline`.
Setting `inlineStories` to `true` tells Storybook to stop putting your stories in an iframe. The `prepareForInline` accepts a function that transforms story content from your given framework to something React can render (Storybooks UI is built in React).
Different frameworks will need to approach this in different ways. Angular, for example, might convert its story content into a custom element (you can read about that [here](https://angular.io/guide/elements)).
Heres an example of how to render Vue stories inline. The following docs config block uses `prepareForInline` along with an effect hook provided by [@egoist/vue-to-react](https://github.com/egoist/vue-to-react).
```js
// .storybook/preview.js
import React from 'react';
import { render } from 'react-dom';
import toReact from '@egoist/vue-to-react';
export const parameters = {
docs: {
prepareForInline: (storyFn, { args }) => {
const Story = toReact(storyFn());
return <Story {...args} />;
},
},
};
```
With this function, anyone using the docs addon for [@storybook/vue](https://github.com/storybookjs/storybook/tree/master/app/vue) can make their stories render inline, either globally with the inlineStories docs parameter, or on a per-story-basis using the inline prop on the `<Story>` doc block.
If you come up with an elegant and flexible implementation for the `prepareForInline` function for your own framework, let us know. We'd love to make it the default configuration to make inline stories more accessible for a larger variety of frameworks!

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.8 KiB

View File

@ -0,0 +1,23 @@
---
title: 'Introduction'
---
When you write component stories during development, you also create basic documentation to revisit later.
Storybook gives you tools to expand this basic documentation with prose and layout that feature your components and stories prominently. That allows you to create UI library usage guidelines, design system sites, and more.
<video autoPlay muted playsInline loop>
<source
src="addon-docs-optimized.mp4"
type="video/mp4"
/>
</video>
Out of the box, Storybook ships with [DocsPage](./docs-page), a documentation template that lists all the stories for a component and associated metadata. It infers metadata values based on source code, types and JSDoc comments. [Customize](./docs-page#replacing-docspage) this page to create a new template if you have specific requirements.
You can also create free-form pages for each component using [MDX](./mdx), a format for simultaneously documenting components and writing stories.
In both cases, youll use [Doc Blocks](./docs-blocks) as the building blocks to create full featured documentation.
Docs is autoconfigured to work out of the box in most use cases. In some cases you may need or want to tweak the configuration. Read more about it in the [ADVANCED README](../../addons/docs/ADVANCED-README.md).

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

215
docs/writing-docs/mdx.md Normal file
View File

@ -0,0 +1,215 @@
---
title: 'MDX'
---
MDX is a [standard file format](https://mdxjs.com/) that combines Markdown with JSX. This means you can use Markdowns terse syntax (such as # heading) for your documentation, write stories that compile to our component story format, and freely embed JSX component blocks at any point in the file. All at once.
In addition, you can write pure documentation pages in MDX and add them to Storybook alongside your stories.
![MDX simple example result](./mdx-hero.png)
### Basic example
Let's get started with an example that combines Markdown with a single story:
```js
// Checkbox.stories.mdx
import { Meta, Story, Preview } from '@storybook/addon-docs/blocks';
import { Checkbox } from './Checkbox';
<Meta title="MDX/Checkbox" component={Checkbox} />
# Checkbox
With `MDX` we can define a story for `Checkbox` right in the middle of our
Markdown documentation.
export const Template = (args) => <Checkbox {...args} />
<Preview>
<Story name="Unchecked" args={{
label: 'Unchecked'
}}>
{Template.bind({})}
</Story>
<Story name="Checked" args={{
label: 'Unchecked',
checked: true
}}>
{Template.bind({})}
</Story>
<Story name="Secondary" args={{
label: 'Secondary',
checked: true,
appearance: 'secondary'
}}>
{Template.bind({})}
</Story>
</Preview>
```
And here's how that's rendered in Storybook:
![MDX simple example result](./mdx-simple.png)
As you can see there's a lot going on here. We're writing Markdown, we're writing JSX, and we're also defining Storybook stories that are drop-in compatible with the entire Storybook ecosystem.
Let's break it down.
### MDX-flavored CSF
MDX-flavored [Component Story Format (CSF)](../formats/component-story-format/) includes a collection of components called ["Doc Blocks"](./docs-blocks), that allow Storybook to translate MDX files into Storybook stories. MDX-defined stories are identical to regular Storybook stories, so they can be used with Storybook's entire ecosystem of addons and view layers.
For example, here's the first story from the Checkbox example above, rewritten in CSF:
```js
// Checkbox.stories.js
import React from 'react';
import { Checkbox } from './Checkbox';
export default {
title: "MDX/Checkbox",
component: Checkbox
};
const Template = (args) => <Checkbox {...args} />
export const Unchecked = Template.bind({});
Unchecked.args = { label: 'Unchecked' };
```
There's a one-to-one mapping from the code in MDX to CSF. As a user, this means your existing Storybook knowledge should translate between the two.
### Writing stories
Let's look at a more realistic example to see how MDX works:
```js
// Badge.stories.mdx
import { Meta, Story, Preview } from '@storybook/addon-docs/blocks';
import { Badge } from './Badge';
import { Icon } from './Icon';
<Meta title="MDX/Badge" component={Badge} />
export const Template = (args) => <Badge {...args } />
# Badge
Let's define a story for our `Badge` component:
<Story name="positive" args={{
status: 'positive',
label: 'Positive'
}}>
{Template.bind({})}
</Story>
We can drop it in a `Preview` to get a code snippet:
<Preview>
<Story name="negative" args={{
status: 'negative',
label: 'Negative'
}}>
{Template.bind({})}
</Story>
</Preview>
We can even preview multiple Stories in a block. This
gets rendered as a group, but defines individual stories
with unique URLs which is great for review and testing.
<Preview>
<Story name="warning" args={{
status: warning,
label: 'Warning'
}}>
{Template.bind({})}
</Story>
<Story name="neutral" args={{
status: 'neutral',
label: 'Neutral'
}}>
{Template.bind({})}
</Story>
<Story name="error" args={{
status: 'error',
label: 'Error'
}}>
{Template.bind({})}
</Story>
<Story name="with icon" args={{
status: warning,
label: (<Icon icon="check" inline /> with icon)
)}}>
{Template.bind({})}
</Story>
</Story>
</Preview>
```
And here's how that gets rendered in Storybook:
![MDX page](./mdx-page.png)
### Embedding stories
Suppose you have an existing story and want to embed it into your docs. Here's how to show a story with ID some--id. Check the browser URL in Storybook v5+ to find a story's ID.
```js
import { Story } from "@storybook/addon-docs/blocks";
# Some header
And Markdown here
<Story id="some--id" />
```
You can also use the rest of the MDX features in conjunction with embedding. That includes source, preview, and prop tables.
### Decorators and parameters
To add decorators and parameters in MDX:
```js
<Meta
title='MyComponent'
decorators={[ ... ]}
parameters={{ ... }}
/>
<Story name="story" decorators={[ ... ]} parameters={{ ... }} >
...
</Story>
```
Global parameters and decorators work just like before.
### Documentation-only MDX
Typically, when you use Storybook MDX, you define stories in the MDX and documentation is automatically associated with those stories. But what if you want to write Markdown-style documentation without any stories inside?
If you don't define stories in your MDX, you can write MDX documentation and associate it with an existing story, or embed that MDX as its own documentation node in your Storybook's navigation.
If you don't define a Meta, you can write Markdown and associate with an existing story. See ["CSF Stories with MDX Docs"](https://github.com/storybookjs/storybook/blob/master/addons/docs/docs/recipes.md#csf-stories-with-mdx-docs).
To get a "documentation-only story", in your UI, define a `<Meta>` as you normally would, but don't define any stories. It will show up in your UI as a documentation node:
![MDX docs only story](./mdx-documentation-only.png)
### MDX file names
Unless you use a custom [webpack configuration](../configure/integration#extending-storybooks-webpack-config), all of your MDX files should have the suffix `*.stories.mdx`. This tells Storybook to apply its special processing to the `<Meta>` and `<Story>` elements in the file.
<div class="aside">
Be sure to update [.storybook/main.js](../configure/overview#configure-story-rendering) file to load `.stories.mdx` stories, as per the addon-docs installation instructions.
</div>

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,145 @@
---
title: 'Args'
---
A story is a component with a set of arguments (props, slots, inputs, etc). “Args” are Storybooks mechanism for defining those arguments as a first class entity thats machine readable. This allows Storybook and its addons to live edit components. You *do not* need to change your underlying component code to use args.
When an args value is changed, the component re-renders, allowing you to interact with components in Storybooks UI via addons that affect args.
Learn how and why to write stories with args [here](./introduction#using-args) section. For details on how args work, read on.
### Args object
The args object can be defined at the story and component level (see below). It is an object with string keys, where values can have any type that is allowed to be passed into a component in your framework.
### Story args
To define the args of a single story, use the `args` CSF story key:
```js
export const Primary = Template.bind({});
Primary.args = {
primary: true,
label: 'Primary',
}
```
These args will only apply to the story for which they are attached, although you can [reuse](../workflows/build-pages-with-storybook#args-composition-for-presentational-screens) them via JavaScript object reuse:
```js
export const PrimaryLongName = Template.bind({});
PrimaryLongName.args = {
...Primary.args,
label: 'Primary with a really long name',
}
```
In the above example, we use the [object spread](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax) feature of ES 2015.
### Component args
You can also define args at the component level; such args will apply to all stories of the component unless they are overwritten. To do so, use the `args` key of the `default` CSF export:
```js
import Button from './Button';
export default {
title: "Button",
component: Button,
args: {
// Now all Button stories will be primary.
primary: true,
},
};
```
### Args composition
You can separate the arguments to a story to compose in other stories. Heres how args can be used in multiple stories for the same component.
```js
const Primary = ButtonStory.bind({});
Primary.args = {
primary: true,
label: 'Button',
}
const Secondary = ButtonStory.bind({});
Secondary.args = {
...Primary.args,
primary: false,
}
```
<div class="aside">
Note that if you are doing the above often, you may want to consider using [component-level args](#component-args).
</div>
Args are useful when writing stories for composite components that are assembled from other components. Composite components often pass their arguments unchanged to their child components, and similarly their stories can be compositions of their child components stories. With args, you can directly compose the arguments:
```js
/// Page.stories.js
import Page from './Page';
import * as Header from './Header.stories';
export const default {
component: Page,
title: 'Page',
};
const Template = (args) => <Page {...args} />
export const LoggedIn = Template.bind({});
LoggedIn.args = {
...Header.LoggedIn.args,
};
```
<details>
<summary>Using args in addons</summary>
If you are [writing an addon](../api/addons#getting-started) that wants to read or update args, use the `useArgs` hook exported by `@storybook/api`:
```js
import { useArgs } from '@storybook/api';
const [args, updateArgs,resetArgs] = useArgs();
// To update one or more args:
updateArgs({ key: 'value' });
// To reset one (or more) args:
resetArgs(argNames:['key']);
// To reset all args
resetArgs();
```
</details>
<details>
<summary>parameters.passArgsFirst</summary>
In Storybook 6+, we pass the args as the first argument to the story function. The second argument is the “context” which contains things like the story parameters etc.
In Storybook 5 and before we passed the context as the first argument. If youd like to revert to that functionality set the `parameters.passArgsFirst` parameter in [`.storybook/preview.js`](../configure/overview#configure-story-rendering):
```js
export const parameter = { passArgsFirst : false }.
```
<div class="aside">
Note that `args` is still available as a key on the context.
</div>
</details>

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 KiB

View File

@ -0,0 +1,93 @@
---
title: 'Decorators'
---
A decorator is a way to wrap a story in extra “rendering” functionality. Many addons define decorators in order to augment your stories with extra rendering or gather details about how your story is rendered.
When writing stories, decorators are typically used to wrap stories with extra markup or context mocking.
### Wrap stories with extra markup
Some components require a “harness” to render in a useful way. For instance if a component runs right up to its edges, you might want to space it inside Storybook. Use a decorator to add spacing for all stories of the component.
![Story without padding](./decorators-no-padding.png)
```js
export default {
component: TextComponent,
decorators: [(Story) => <div style={{ margin: '3em' }}><Story/></div>]
}
```
![Story with padding](./decorators-padding.png)
### “Context” for mocking
Some libraries require components higher up in the component hierarchy to render properly. For example in Styled Components, a `ThemeProvider` is required if your components make use of themes. Add a single global decorator that add this context to to all stories in [`.storybook/preview.js`](../configure/overview#configure-story-rendering):
```js
// .storybook/preview.js
import { ThemeProvider } from 'styled-components';
export const decorators = [
(Story) => <ThemeProvider theme="default"><Story/></ThemeProvider>,
];
```
In the example above, the theme is hardcoded to a mock value of `default` but you may want to vary that value, either on a per-story basis (if it is data you are mocking that is relevant to the other args of the story) or in a user controlled way (for instance to provide a theme switcher).
The second argument to a decorator function is the **story context** which in particular contains the keys:
- `args` - the story arguments. You can use some args in your decorators and drop them in the story implementation itself.
- `globals` - the Storybook-wide [globals](../essentials/toolbars-and-globals#globals). In particular you can use the [toolbars feature](../essentials/toolbars-and-globals#global-types-toolbar-annotations) to allow you to change these values using Storybooks UI.
#### Using decorators to provide data
If your components are “connected” and require side-loaded data to render, you can use decorators to provide that data in a mocked way, without having to refactor your components to take that data as an arg. There are several techniques to achieve this, depending on exactly how you are loading that data -- read more in the [building pages in Storybook](../workflows/build-pages-with-storybook) section.
### Story decorators
To define a decorator for a single story, use the `decorators` key on a named export:
```js
export const Primary = …
Primary.decorators = [(Story) => <div style={{ margin: '3em' }}><Story/></div>]
```
This is useful to ensure that the story remains a “pure” rendering of the component under test and any extra HTML or components you need to add dont pollute that. In particular the [Source](../writing-docs/docs-blocks#source) docblock works best when you do this.
### Component decorators
To define a decorator for all stories of a component, use the `decorators` key of the default CSF export:
```js
import Button from './Button';
export default {
title: "Button",
component: Button,
decorators: [(Story) => <div style={{ margin: '3em' }}><Story/></div>]
};
```
### Global decorators
We can also set a decorator for **all stories** via the `decorators` export of your [`.storybook/preview.js`](../configure/overview#configure-story-rendering) file (this is the file where you configure all stories):
```js
export const decorators = [(Story) => <div style={{ margin: '3em' }}><Story/></div>]
```
### Decorator inheritance
Like parameters, decorators can be defined globally, at the component level and for a single story (as weve seen).
All decorators, defined at all levels that apply to a story will run whenever that story is rendered, in the order:
- Global decorators, in the order they are defined
- Component decorators, in the order they are defined
- Story decorators, in the order they are defined.

View File

@ -0,0 +1,239 @@
---
title: 'Introduction'
---
**A story captures the rendered state of a UI component**. Its a function that returns a components state given a set of arguments.
Storybook uses the generic term arguments (args for short) when talking about Reacts `props`, Vues `slots`, Angulars `@input`, and other similar concepts.
### Where to put stories
A components stories are defined in a story file that lives alongside the component file. The story file is for development-only, it won't be included in your production bundle.
```
Button.js | ts
Button.stories.js | ts
```
### Component Story Format
We define stories according to the [Component Story Format](../formats/component-story-format) (CSF), an ES6 module-based standard that is portable between tools and easy to write.
The key ingredients are the [**`default` export**](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/export#Using_the_default_export) that describes the component, and [**named exports**](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/export#Using_named_exports) that describe the stories.
#### Default export
The default export metadata controls how Storybook lists your stories and provides information used by addons. For example, heres the default export for a story file `Button.stories.js`:
```js
// Button.stories.js
import { Button } from './Button';
export default {
title: 'Components/Button',
component: Button,
}
```
#### Defining stories
Use the named exports of a CSF file to define your components stories. Heres how to render `Button` in the “primary” state and export a story called `Primary`.
```js
// Button.stories.js
import { Button } from './Button';
export default {
title: 'Components/YourComponent',
component: YourComponent,
}
export const Primary = () => <Button primary label="Button" />;
```
### How to write stories
A story is a function that describes how to render a component. You can have multiple stories per component. The simplest way to create stories is to render a component with different arguments multiple times.
```js
// Button.stories.js
export const Primary = () => <Button background="#ff0" label="Button" />;
export const Secondary = () => <Button background="#ff0" label=”😄👍😍💯" />;
export const Tertiary = () => <Button background="#ff0" label="📚📕📈🤓" />;
```
This is straightforward for components with few stories, but can be repetitive with many stories.
#### Using args
Refine this pattern by defining a master template for a components stories that allows you to pass in `args`. This reduces the unique code youll need to write and maintain for each story.
```js
// We create a “template” of how args map to rendering
const Template = (args) => <Button {...args} />;
// Each story then reuses that template
export const Primary = Template.bind({});
Primary.args = { background="#ff0", label: 'Button' };
export const Secondary = Template.bind({});
Secondary.args = { ...Primary.args, label: '😄👍😍💯',};
export const Tertiary = Template.bind({});
Tertiary.args = { ...Primary.args, label: '📚📕📈🤓',};
```
The template is reused across stories. Template.bind({}) makes a copy of the function which reduces code duplication. Similarly,`...Primary.args` makes a copy of the data, reducing data duplication.
Whats more, you can import args to reuse when writing stories for other components. This is useful when youre building composite components. For example, if we make a `ButtonGroup` story, we might remix two stories from its child component `Button`.
```js
// ButtonGroup.stories.js
import { ButtonGroup } from '../ButtonGroup';
import { Primary, Secondary } from '../Button.stories';
export default {
title: 'ButtonGroup',
component: ButtonGroup,
}
const Template = (args) => <ButtonGroup {...args} />
export const Pair = Template.bind({});
Pair.args = {
buttons: [ Primary.args, Secondary.args ],
orientation: 'horizontal',
};
```
When Buttons signature changes, you only need to change Buttons stories to reflect the new schema. ButtonGroups stories will automatically be updated. This pattern allows you to reuse your data definitions up and down your component hierarchy, making your stories more maintainable.
Thats not all! Each of the args from the story function are live editable using Storybooks [controls](../essentials/controls) panel. This means your team can dynamically change components in Storybook to stress test and find edge cases.
<video autoPlay muted playsInline loop>
<source
src="addon-controls-demo-optimized.mp4"
type="video/mp4"
/>
</video>
Addons can enhance args. For instance, [Actions](../essentials/actions) auto detects which args are callbacks and appends a logging function to them. That way interactions (like clicks) get logged in the actions panel.
<video autoPlay muted playsInline loop>
<source
src="addon-actions-demo-optimized.mp4"
type="video/mp4"
/>
</video>
#### Using parameters
Parameters are Storybooks method of defining static metadata for stories. A storys parameters can be used to provide configuration to various addons at the level of a story or group of stories.
For instance, suppose you wanted to test your Button component against a different set of backgrounds than the other components in your app. You might add a component-level `backgrounds` parameter:
```js
// Button.stories.js
import Button from './Button';
export default {
title: 'Button',
component: Button,
parameters: {
backgrounds: {
values: [
{ name: 'red', value: '#f00', },
{ name: 'green', value: '#0f0', },
{ name: 'blue', value: '#00f', },
]
}
}
}
```
![Background colors parameter](./parameters-background-colors.png)
This parameter would instruct the backgrounds addon to reconfigure itself whenever a Button story is selected. Most addons are configured via a parameter-based API and can be influenced at a [global](./parameters#global-parameters), [component](./parameters#component-parameters) and [story](./parameters#story-parameters) level.
#### Using decorators
Decorators are a mechanism to wrap a component in arbitrary markup when rendering a story. Components are often created with assumptions about where they render. Your styles might expect a theme or layout wrapper. Or your UI might expect certain context or data providers.
A simple example is adding padding to a components stories. Accomplish this using a decorator that wraps the stories in a `div` with padding, like so:
```js
// Button.stories.js
import Button from './Button';
export default {
title: 'Button',
component: Button,
decorators: [(Story) => <div style={{ padding: '3em' }}><Story /></div>]
}
```
Decorators [can be more complex](./decorators#context-for-mocking) and are often provided by [addons](../configure/user-interface#storybook-addons). You can also configure decorators at the [story](./decorators#story-decorators), [component](./decorators#component-decorators) and [global](./decorators#global-decorators) level.
### Stories for two or more components
When building design systems or component libraries, you may have two or more components that are designed to work together. For instance, if you have a parent `List` component, it may require child `ListItem` components.
```js
import List from './List'
export default {
component: List,
title: 'List',
};
// Always an empty list, not super interesting
const Template = (args) => <List {...args} />
```
In such cases, it makes sense to render something a different function for each story:
```js
import List from './List'
import ListItem from './ListItem'
export default {
component: List,
title: 'List',
};
export const Empty = (args) => <List {...args} />;
export const OneItem = (args) => (
<List {...args}>
<ListItem />
</List>
);
export const ManyItems = (args) => (
<List {...args}>
<ListItem />
<ListItem />
<ListItem />
</List>
);
```
You can also reuse stories from the child `ListItem` in your `List` component. Thats easier to maintain because you dont have to keep the identical story definitions up to date in multiple places.
```js
import { Selected, Unselected } from './ListItem.stories';
export const ManyItems = (args) => (
<List {...args}>
<Selected {...Selected.args} />
<Unselected {...Unselected.args} />
<Unselected {...Unselected.args} />
</List>
);
```
<div class="aside">
Note that there are disadvantages in writing stories like this as you cannot take full advantage of the args mechanism and composing args as you build more complex composite components. For more discussion, set the [multi component stories](../workflows/stories-for-multiple-components) workflow article.
</div>

View File

@ -0,0 +1,114 @@
---
title: 'Naming components and hierarchy'
---
The title of the component you export in the `default` export controls the name shown in the sidebar.
```js
// Button.stories.js
export default {
title: 'Button'
}
```
Yields this:
![Stories hierarchy without paths](./naming-hierarchy-no-path.png)
### Grouping
It is also possible to group related components in an expandable interface in order to help with Storybook organization. To do so, use the `/` as a separator:
```js
// Button.stories.js
export default {
title: 'Design System/Atoms/Button'
}
```
```js
// Checkbox.stories.js
export default {
title: 'Design System/Atoms/Checkbox'
}
```
Yields this:
![Stories hierarchy with paths](./naming-hierarchy-with-path.png)
### Roots
By default the top-level grouping will be displayed as a “root” in the UI (the all-caps, non expandable grouping in the screenshot above). If you prefer, you can [configure Storybook](../configure/user-interface#roots) to not show roots.
We recommend naming components according to the file hierarchy.
### Sorting stories
By default, stories are sorted in the order in which they were imported. This can be overridden by adding `storySort` to the `options` parameters in your `preview.js` file.
The most powerful method of sorting is to provide a function to `storySort`. Any custom sorting can be achieved with this method.
```js
// .storybook/preview.js
export const parameters = {
options: {
storySort: (a, b) =>
a[1].kind === b[1].kind ? 0 : a[1].id.localeCompare(b[1].id, undefined, { numeric: true }),
},
};
```
The `storySort` can also accept a configuration object.
```js
// .storybook/preview.js
export const parameters = {
options: {
storySort: {
method: '',
order: [],
locales: '',
},
},
};
```
| Field | Type | Description | Required | Default Value |Example |
| ------------- |:-------------:|:------------------------------------------------------:|:--------:|:----------------------:|:-----------------------:|
| **method** | String |Tells Storybook in which order the stories are displayed|No |Storybook configuration |`'alphabetical'` |
| **order** | Array |The stories to be show, ordered by supplied name |No |Empty Array `[]` |`['Intro', 'Components']`|
| **locales** | String |The locale required to be displayed |No |System locale |`en-US` |
To sort your stories alphabetically, set `method` to `'alphabetical'` and optionally set the `locales` string. To sort your stories using a custom list, use the `order` array; stories that don't match an item in the `order` list will appear after the items in the list.
The `order` array can accept a nested array in order to sort 2nd-level story kinds. For example:
```js
export const parameters = {
options: {
storySort: {
order: ['Intro', 'Pages', ['Home', 'Login', 'Admin'], 'Components'],
},
},
};
```
Which would result in this story ordering:
1. `Intro` and then `Intro/*` stories
2. `Pages` story
3. `Pages/Home` and `Pages/Home/*` stories
4. `Pages/Login` and `Pages/Login/*` stories
5. `Pages/Admin` and `Pages/Admin/*` stories
6. `Pages/*` stories
7. `Components` and `Components/*` stories
8. All other stories
Note that the `order` option is independent of the `method` option; stories are sorted first by the `order` array and then by either the `method: 'alphabetical'` or the default `configure()` import order.

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 KiB

View File

@ -0,0 +1,76 @@
---
title: 'Parameters'
---
**Parameters** are a set of static, named metadata about a story, typically used to control the behaviour of Storybook features and addons.
For example, lets customize the backgrounds addon via a parameter. Well use `parameters.backgrounds` to define which backgrounds appear in the backgrounds toolbar when a story is selected.
### Story parameters
We can set a parameter for a single story with the `parameters` key on a CSF export:
```js
export const Primary = Template.bind({});
Primary.args ={
primary: true,
label: 'Button',
}
Primary.parameters = {
backgrounds:{
values: [
{ name: 'red', value: '#f00', },
{ name: 'green', value: '#0f0', },
],
}
};
```
### Component parameters
We can set the parameters for all stories of a component using the `parameters` key on the default CSF export:
```js
import Button from './';
export default {
title: "Button",
component: Button,
parameters: {
backgrounds: {
values: [
{ name: 'red', value: '#f00', },
{ name: 'green', value: '#0f0', },
],
}
}
};
```
### Global parameters
We can also set the parameters for **all stories** via the `parameters` export of your [`.storybook/preview.js`](../configure/overview#configure-story-rendering) file (this is the file where you configure all stories):
```js
export const parameters = {
backgrounds: {
values: [
{ name: 'red', value: '#f00', },
{ name: 'green', value: '#0f0', },
],
},
}
```
Setting a global parameter is a common way to configure addons. With backgrounds, you configure the list of backgrounds that every story can render in.
### Rules of parameter inheritance
The way the global, component and story parameters are combined is:
- More specific parameters take precedence (so a story parameter overwrites a component parameter which overwrites a global parameter).
- Parameters are **merged** so keys are only ever overwritten, never dropped.
The merging of parameters is important. It means it is possible to override a single specific sub-parameter on a per-story basis but still retain the majority of the parameters defined globally.
If you are defining an API that relies on parameters (e..g an [__addon__](../api/addons#geting-started)) it is a good idea to take this behaviour into account.