自动文档和 Storybook
观看视频教程
Storybook 自动文档是一个强大的工具,可以帮助您快速为 UI 组件生成全面的文档。通过利用自动文档,您将故事转变为活的文档,可以进一步扩展使用 MDX 和 文档块 来提供对组件功能的清晰简洁的理解。
Storybook 推断相关元数据(例如,args
,argTypes
,parameters
)并自动生成一个文档页面,其中包含此信息,该信息位于组件树的根级别(在侧边栏中)。
设置自动文档
自动文档通过 标签 配置。如果 CSF 文件包含至少一个标记为 autodocs
的故事,则将为该组件生成一个文档页面。
要为项目中的所有故事启用自动文档,请将其添加到 tags
中的 .storybook/preview.js|ts
文件中
// Replace your-renderer with the renderer you are using (e.g., react, vue3)
import type { Preview } from '@storybook/your-renderer';
const preview: Preview = {
// ...rest of preview
//👇 Enables auto-generated documentation for all stories
tags: ['autodocs'],
};
export default preview;
您也可以在组件(或故事)级别启用它
// Replace your-framework with the framework you are using (e.g., nextjs, vue3-vite)
import type { Meta } from '@storybook/your-framework';
import { Button } from './Button';
const meta: Meta<typeof Button> = {
component: Button,
//👇 Enables auto-generated documentation for this component and includes all stories in this file
tags: ['autodocs'],
};
export default meta;
您可以通过 删除标签 来禁用特定组件的自动文档
// Replace your-framework with the framework you are using (e.g., nextjs, vue3-vite)
import type { Meta, StoryObj } from '@storybook/your-framework';
import { Page } from './Page';
const meta: Meta<typeof Page> = {
component: Page,
// 👇 Disable auto-generated documentation for this component
tags: ['!autodocs'],
};
export default meta;
同样,您可以通过删除标签来将特定故事从自动文档页面中排除
// Replace your-framework with the framework you are using (e.g., nextjs, vue3-vite)
import type { Meta, StoryObj } from '@storybook/your-framework';
import { Button } from './Button';
const meta: Meta<typeof Button> = {
component: Button,
//👇 Enables auto-generated documentation for this component and includes all stories in this file
tags: ['autodocs'],
};
export default meta;
type Story = StoryObj<typeof Button>;
export const UndocumentedStory: Story = {
// 👇 Removes this story from auto-generated documentation
tags: ['!autodocs'],
};
配置
除了使用 tags
启用该功能外,您还可以扩展 Storybook 配置文件(即 .storybook/main.js|ts|cjs
),并提供其他选项来控制文档的创建方式。以下是可用的选项以及如何使用它们的示例。
// Replace your-framework with the framework you are using (e.g., react-webpack5, vue3-vite)
import type { StorybookConfig } from '@storybook/your-framework';
const config: StorybookConfig = {
framework: '@storybook/your-framework',
stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
addons: ['@storybook/addon-essentials'],
docs: {
//👇 See the table below for the list of supported options
defaultName: 'Documentation',
},
};
export default config;
选项 | 描述 |
---|---|
defaultName | 重命名自动生成的文档页面 默认值: docs: { defaultName: 'Documentation' } |
编写自定义模板
观看视频教程
要替换 Storybook 使用的默认文档模板,您可以扩展 UI 配置文件(即 .storybook/preview.js|ts
)并引入一个 docs
参数。此参数接受一个 page
函数,该函数返回一个 React 组件,您可以使用它来生成所需的模板。例如
// Replace your-framework with the framework you are using (e.g., react, vue3)
import { Preview } from '@storybook/your-framework';
import { Title, Subtitle, Description, Primary, Controls, Stories } from '@storybook/blocks';
const preview: Preview = {
parameters: {
controls: {
matchers: {
color: /(background|color)$/i,
date: /Date$/,
},
},
docs: {
page: () => (
<>
<Title />
<Subtitle />
<Description />
<Primary />
<Controls />
<Stories />
</>
),
},
},
};
export default preview;
在内部,Storybook 使用类似的实现来生成默认模板。请参阅文档块 API 参考 以了解有关文档块工作原理的更多信息。
更详细地介绍代码段。当 Storybook 启动时,它将使用以下自定义模板覆盖默认模板
- 一个标题,其中包含通过
Title
、Subtitle
和Description
文档块检索的组件元数据。 - 文件中通过
Primary
文档块定义的第一个故事,以及一套方便的 UI 控件,用于放大和缩小组件。 - 一个交互式表格,其中包含通过
Controls
文档块定义的故事中所有相关的args
和argTypes
。 - 通过
Stories
文档块对剩余故事的概述。
使用 MDX
您也可以使用 MDX 生成文档模板。这在没有配置 JSX 处理的非 React 项目中非常有用。通常,当您在项目中创建 MDX 文件时,它会被视为普通文档。为了指示 MDX 文件是一个文档模板,请在其 Meta
文档块中提供 isTemplate
属性。例如
{/* DocumentationTemplate.mdx */}
import { Meta, Title, Primary, Controls, Stories } from '@storybook/blocks';
{/*
* 👇 The isTemplate property is required to tell Storybook that this is a template
* See https://storybook.org.cn/docs/api/doc-blocks/doc-block-meta
* to learn how to use
*/}
<Meta isTemplate />
<Title />
# Default implementation
<Primary />
## Inputs
The component accepts the following inputs (props):
<Controls />
---
## Additional variations
Listed below are additional variations of the component.
<Stories />
然后您可以在您的 .storybook/preview.js
或单个故事文件中通过导入它来使用它
import DocumentationTemplate from './DocumentationTemplate.mdx';
export default {
parameters: {
docs: {
page: DocumentationTemplate,
},
},
};
如果您只需要覆盖单个组件的文档页面,建议创建一个 MDX 文件并通过 <Meta of={} />
文档块直接引用它。
生成目录
Storybook 的自动生成的文档页面可能很长且难以浏览。为了帮助解决这个问题,您可以启用目录功能,提供文档页面的快速概述,并允许用户跳转到特定部分。要启用它,请扩展您的 Storybook UI 配置文件(例如,.storybook/preview.js
)并提供一个带有 toc
属性的 docs
参数。
// Replace your-framework with the framework you are using (e.g., react, vue3)
import { Preview } from '@storybook/your-framework';
const preview: Preview = {
parameters: {
docs: {
toc: true, // 👈 Enables the table of contents
},
},
};
export default preview;
配置目录
默认情况下,文档页面上的目录只会显示自动生成的 h3
标题。但是,如果您想自定义目录,可以向 toc
属性添加更多参数。以下选项和使用示例可用。
选项 | 描述 |
---|---|
contentsSelector | 定义用于搜索标题的容器的 CSS 选择器toc: { contentsSelector: '.sbdocs-content' } |
disable | 隐藏文档页面的目录toc: { disable: true } |
headingSelector | 定义要显示在目录中的标题列表toc: { headingSelector: 'h1, h2, h3' } |
ignoreSelector | 配置目录以忽略特定标题或故事。默认情况下,目录将忽略放置在故事块中的所有内容toc: { ignoreSelector: '.docs-story h2' } |
title | 定义目录的标题说明文字。 接受以下之一: string 、null 、React 元素toc: { title: '目录' } |
unsafeTocbotOptions | 提供其他 TocBot 配置选项toc: { unsafeTocbotOptions: { orderedList: true } } |
的 contentsSelector
、headingSelector
和 ignoreSelector
属性允许进一步自定义。有关使用它们的更多信息,请参阅 Tocbot
文档。
// Replace your-framework with the framework you are using (e.g., react, vue3)
import { Preview } from '@storybook/your-framework';
const preview: Preview = {
parameters: {
docs: {
toc: {
contentsSelector: '.sbdocs-content',
headingSelector: 'h1, h2, h3',
ignoreSelector: '#primary',
title: 'Table of Contents',
disable: false,
unsafeTocbotOptions: {
orderedList: false,
},
},
},
},
};
export default preview;
组件级配置
如果您想自定义特定故事的目录,您可以在故事的默认导出中包含一个 toc
属性,并提供所需的 配置。例如,如果您需要隐藏特定故事的目录,请调整您的故事,如下所示
// Replace your-framework with the name of your framework
import type { Meta } from '@storybook/your-framework';
import { MyComponent } from './MyComponent';
const meta: Meta<typeof MyComponent> = {
component: MyComponent,
tags: ['autodocs'],
parameters: {
docs: {
toc: {
disable: true, // 👈 Disables the table of contents
},
},
},
};
export default meta;
自定义组件文档
使用 Storybook 的 Autodocs 创建自动文档,为您构建可持续文档模式提供了起点。但是,它可能不适合所有情况,您可能希望扩展它并提供其他信息。我们建议将 MDX 与 Storybook 的 文档块 结合使用,以解决此类情况并编写您的文档。
高级配置
记录多个组件
有时将多个组件一起记录很有帮助。例如,组件库的 ButtonGroup 和 Button 组件可能只有彼此存在才有意义。
Autodocs 允许您记录由 component
属性定义的“主”组件,以及一个或多个与其相关的 subcomponents
。
import React from 'react';
import type { Meta, StoryObj } from '@storybook/react';
import { List } from './List';
import { ListItem } from './ListItem';
const meta: Meta<typeof List> = {
component: List,
subcomponents: { ListItem }, //👈 Adds the ListItem component as a subcomponent
};
export default meta;
type Story = StoryObj<typeof List>;
export const Empty: Story = {};
export const OneItem: Story = {
render: (args) => (
<List {...args}>
<ListItem />
</List>
),
};
主组件及其子组件将显示在 ArgTypes
文档块 的选项卡版本中。选项卡标题将对应于 subcomponents
对象的键。
如果您想为组件组以不同的方式组织文档,建议您 使用 MDX。它使您能够完全控制组件的显示方式,并支持任何配置。
自定义文档容器
文档容器是包装文档页面的组件。它负责在 Storybook 的 UI 中渲染文档页面。您可以通过创建自己的组件并更新您的 Storybook UI 配置文件(例如,.storybook/preview.js
)来引用它来自定义它。
import * as React from 'react';
// Replace your-framework with the framework you are using (e.g., react, vue3)
import { Preview } from '@storybook/your-framework';
import { DocsContainer } from '@storybook/blocks';
const ExampleContainer = ({ children, ...props }) => {
return <DocsContainer {...props}>{children}</DocsContainer>;
};
const preview: Preview = {
parameters: {
controls: {
matchers: {
color: /(background|color)$/i,
date: /Date$/,
},
},
docs: {
container: ExampleContainer,
},
},
};
export default preview;
覆盖默认主题
默认情况下,Storybook 为 UI 提供两个主题:light
和 dark
。如果您需要自定义文档使用的主题以匹配现有主题,您可以更新您的 Storybook UI 配置文件(例如,.storybook/preview.js
)并应用它。
// Replace your-framework with the framework you are using (e.g., react, vue3)
import { Preview } from '@storybook/your-framework';
import { themes, ensure } from '@storybook/theming';
const preview: Preview = {
parameters: {
controls: {
matchers: {
color: /(background|color)$/i,
date: /Date$/,
},
},
docs: {
theme: ensure(themes.dark), // The replacement theme to use
},
},
};
export default preview;
使用自定义 MDX 组件
开箱即用,Storybook 有一组您可以用来自定义文档页面的组件。如果您正在使用设计系统或组件库,并希望将它们添加到您的文档页面,您可以用自己的组件覆盖从 @mdx-js/react
继承的 MDXProvider
组件。但是,这有一个需要注意的地方,组件替换只有在您使用 Markdown 语法(例如,#
用于标题)编写文档时才会有影响。本机 HTML 元素(例如,<h1>
)不会被替换为您的自定义实现。
// Replace your-framework with the framework you are using (e.g., react, vue3)
import { Preview } from '@storybook/your-framework';
import { MDXProvider } from '@mdx-js/react';
import { DocsContainer } from '@storybook/blocks';
import * as DesignSystem from 'your-design-system';
export const MyDocsContainer = (props) => (
<MDXProvider
components={{
h1: DesignSystem.H1,
h2: DesignSystem.H2,
}}
>
<DocsContainer {...props} />
</MDXProvider>
);
const preview: Preview = {
parameters: {
controls: {
matchers: {
color: /(background|color)$/i,
date: /Date$/,
},
},
docs: {
container: MyDocsContainer,
},
},
};
export default preview;
这不是 Storybook 问题,而是 MDX 工作方式的细节。从他们的 迁移指南
“我们现在对组件进行‘沙盒’处理,因为没有更好的名字。这意味着当您为 h1 传递一个组件时,它确实会用于 # hi
,但不会用于 <h1>hi</h1>
”
疑难解答
目录无法按预期呈现
使用 Autodocs 的目录时,您可能会遇到它与预期显示不同的情况。为了帮助您解决这些问题,我们整理了一份可能导致问题的潜在场景列表。
使用简单的文档页面
如果您有一个文档页面,它只有一个匹配的标题,并且为此页面创建了一个目录,则目录默认情况下不会隐藏。解决此问题的潜在方法是添加第二个标题或完全关闭它。
使用小屏幕
如果屏幕宽度小于 1200px,则目录默认情况下将隐藏。目前,还没有内置的解决方案可以解决此问题,而不会影响文档页面的样式兼容性。
使用 MDX
如果您使用 MDX 编写分离的文档,您无法自定义目录,这主要是因为当前实现不支持定义基于当前实现的参数。因此,目录将始终恢复到全局提供的默认配置。
自动生成的文档没有在单仓库设置中显示
Storybook 的 Autodocs 功能开箱即用,旨在自动为您的故事生成文档。但是,如果您使用的是单仓库设置(例如,Yarn Workspaces
,pnpm Workspaces
),您可能会遇到部分文档无法为您生成的问题。为了帮助您解决这些问题,我们准备了一些可能对您有所帮助的建议。
更新您的导入语句,直接引用组件,而不是包的根目录。例如
// Replace your-framework with the name of your framework
import type { Meta } from '@storybook/your-framework';
// ❌ Don't use the package's index file to import the component.
import { MyComponent } from '@component-package';
// ✅ Use the component's export to import it directly.
import { MyComponent } from '@component-package/src/MyComponent';
const meta: Meta<typeof MyComponent> = {
/* 👇 The title prop is optional.
* See https://storybook.org.cn/docs/configure/#configure-story-loading
* to learn how to generate automatic titles
*/
title: 'MyComponent',
component: MyComponent,
};
export default meta;
此外,如果您使用的是 TypeScript,则可能需要更新 Storybook 的配置文件(即 .storybook/main.js|ts
),以包含以下内容
// Replace your-framework with the framework you are using (e.g., react-webpack5, vue3-vite)
import type { StorybookConfig } from '@storybook/your-framework';
const config: StorybookConfig = {
framework: '@storybook/your-framework',
stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
typescript: {
// Overrides the default Typescript configuration to allow multi-package components to be documented via Autodocs.
reactDocgen: 'react-docgen',
check: false,
},
};
export default config;
如果您仍然遇到问题,我们建议您通过默认的通信渠道(例如,GitHub 讨论)联系社区。
控件没有更新自动生成的文档中的故事
如果您通过inline
配置选项关闭了故事的内联渲染,则会遇到相关控件不会更新文档页面中的故事的情况。这是当前实现已知的一个限制,将在未来的版本中解决。
详细了解 Storybook 文档
- Autodocs 用于创建故事文档
- MDX 用于自定义您的文档
- Doc Blocks 用于编写您的文档
- 发布文档 用于自动化发布文档的过程