title |
---|
Doc Blocks |
💡 NOTE: Currently there's an issue when using MDX stories with IE11. This issue does not apply to DocsPage. If you're interested in helping us fix this issue, read our Contribution guidelines and submit a pull request.
Doc Blocks are the building blocks of Storybook documentation pages. By default, DocsPage uses a combination of the blocks below to build a page for each of your components automatically.
Custom addons can also provide their own doc blocks.
Storybook Docs automatically generates component args tables for components in supported frameworks. These tables list the arguments (args for short) of the component, and even integrate with controls to allow you to change the args of the currently rendered story.
This is extremely useful, but it can be further expanded. Additional information can be added to the component to better document it:
<CodeSnippets paths={[ 'react/button-component-with-proptypes.js.mdx', 'react/button-component-with-proptypes.ts.mdx', 'angular/button-component-with-proptypes.ts.mdx', 'vue/button-component-with-proptypes.2.mdx', 'vue/button-component-with-proptypes.3.mdx', 'svelte/button-component-with-proptypes.js.mdx', ]} />
By including the additional information, the args table will be updated. Offering a richer experience for any stakeholders involved.
To use the ArgsTable
in DocsPage, export a component property on your stories metadata:
<CodeSnippets paths={[ 'common/my-component-story.js.mdx', ]} />
To use the ArgsTable
block in MDX, add the following:
<CodeSnippets paths={[ 'common/component-story-mdx-argstable-block.mdx.mdx', ]} />
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. 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 and <ArgsTable story="xxx">
construct, but not for the <ArgsTable of={component} />
construct.
NOTE: This API is experimental and may change outside of the typical semver release cycle
The API documentation of ArgTypes
is detailed in a separate section, 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 long version of the type |
table.defaultValue.summary | A short version of the default value |
table.defaultValue.detail | A long version of the default value |
control | See addon-controls README |
For instance:
<CodeSnippets paths={[ 'common/component-story-csf-argstable-customization.js.mdx', ]} />
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 fortype: {name: 'number'}
radio
, which is a shorthand forcontrol: {type: 'radio' }
One other relevant aspect of customization related to the ArgsTables is grouping.
Similar argTypes can be grouped into specific categories or even subcategories.
Looking at the following component:
<CodeSnippets paths={[ 'react/button-implementation.js.mdx', 'react/button-implementation.ts.mdx', 'angular/button-implementation.ts.mdx', 'vue/button-implementation.2.mdx', 'vue/button-implementation.3.mdx', 'svelte/button-implementation.js.mdx', ]} />
Similar properties could be grouped together to allow better structuring and organization.
We could use the following pattern to group them:
Field | Category |
---|---|
backgroundColor | Colors |
primary | Colors |
label | Text |
onClick | Events |
size | Sizes |
Which will result in the following story implementation:
<CodeSnippets paths={[ 'common/button-story-argtypes-with-categories.js.mdx' ]} />
And the following change in the Storybook UI:
The formula used above can be improved even further and include subcategories.
Turning the table above into:
Field | Category | Subcategory |
---|---|---|
backgroundColor | Colors | Button colors |
primary | Colors | Button style |
label | Text | Button contents |
onClick | Events | Button Events |
size | Sizes |
Leading to the following change in the story implementation and UI:
<CodeSnippets paths={[ 'common/button-story-argtypes-with-subcategories.js.mdx' ]} />
To customize argTypes
in MDX, you can set an mdx
prop on the Meta
or Story
components:
<CodeSnippets paths={[ 'common/component-story-mdx-argtypes.mdx.mdx', ]} />
The controls inside an ArgsTable
are configured in exactly the same way as the controls addon pane. In fact you’ll probably notice the table is very similar! It uses the same component and mechanism behind the scenes.
Storybook Docs displays a story’s source code using the Source
block. The snippet has built-in syntax highlighting and can be copied with the click of a button.
In DocsPage, the Source
block appears automatically within each story’s Canvas block.
To customize the source snippet that’s displayed for a story, set the docs.source.code
and optionally the docs.source.language
parameters:
<CodeSnippets paths={[ 'common/component-story-custom-source.js.mdx', ]} />
There is also a docs.source.type
parameter that controls how source is auto-generated. Valid values include:
Value | Description | Support |
---|---|---|
auto (default) | Use dynamic snippets if the story is written using Args and the framework supports it. |
All |
dynamic | Dynamically generated snippet based on the output of the story function, e.g. JSX code for react. | Limited |
code | Use the raw story source as written in the story file. | All |
As an example, if you had the following story:
<CodeSnippets paths={[ 'react/button-story-default-docs-code.js.mdx', 'react/button-story-default-docs-code.ts.mdx', 'vue/button-story-default-docs-code.2.js.mdx', 'vue/button-story-default-docs-code.3.js.mdx', 'angular/button-story-default-docs-code.ts.mdx', 'svelte/button-story-default-docs-code.js.mdx', 'svelte/button-story-default-docs-code.native-format.mdx', ]} />
If you click the Show code
button, you'll see the default behavior being applied:
To visualize the source as code, you'll need to include the code option in the docs.source.type
parameter:
<CodeSnippets paths={[ 'common/button-story-docs-code-type.js.mdx' ]} />
Which leads to the following change in the code
shown in the Docs
tab:
The pattern described will be applied to all the stories for the component. If you need, you can apply this to individual stories for more granular cases. Read more about story-level parameters here.
You can also use the Source
block in MDX. It accepts either a story ID or code
snippet. Use the language
for syntax highlighting. It supports the following languages: javascript
, jsx
, json
, yml
, ,md
, bash
, css
, html
, tsx
, typescript
, graphql
.
<CodeSnippets paths={[ 'common/component-story-mdx-dedent.mdx.mdx', ]} />
Storybook Docs shows a component’s description extracted from the source code or based on a user-provided string.
In DocsPage, a component’s description is shown at the top of the page. For supported frameworks, 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.
<CodeSnippets paths={[ 'common/component-story-csf-description.js.mdx', ]} />
In MDX, the Description
shows the component’s description using the same heuristics as the DocsPage. It also accepts a markdown
parameter to show any user-provided Markdown string.
<CodeSnippets paths={[ 'common/component-story-mdx-description.mdx.mdx', ]} />
Stories (component examples) are the basic building blocks in Storybook. In Storybook Docs, stories are rendered in the Story
block.
In DocsPage, a Story
block is generated for each story in your CSF file, it's wrapped with a Canvas
wrapper that gives it a toolbar on top (in the case of the first “primary” story) and a source code preview underneath.
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 Canvas block defined at the top level:
<CodeSnippets paths={[ 'common/component-story-mdx-story-by-name.mdx.mdx', ]} />
You can also reference existing stories in Storybook by ID:
<CodeSnippets paths={[ 'common/component-story-mdx-reference-storyid.mdx.mdx', ]} />
In Storybook’s Canvas, all stories are rendered in the Preview iframe for isolated development. In Storybook Docs, when inline rendering is supported by your framework, 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.
Storybook Docs’ Canvas
block is a wrapper that provides a toolbar for interacting with its contents, and also also provides Source snippets automatically.
In DocsPage, every story is wrapped in a Canvas
block. The first story on the page is called the primary, and it has a toolbar. The other stories are also wrapped with Canvas
, but there is no toolbar by default.
In MDX, Canvas
is more flexible: in addition to the DocsPage behavior, it can show multiple stories in one:
<CodeSnippets paths={[ 'common/mdx-canvas-multiple-stories.mdx.mdx', ]} />
By default, each story will display side by side (css block). You can display stories one above the other by adding isColumn
property to the Canvas component.
You can also place non-story content inside a Canvas
block:
<CodeSnippets paths={[ 'common/my-component-with-story-content.mdx.mdx', ]} />
This renders the JSX content exactly as it would if you’d placed it directly in the MDX, but it also inserts the source snippet in a Source block beneath the block.