文档
Storybook 文档

自动文档和 Storybook

观看视频教程

Storybook Autodocs 是一个强大的工具,可以帮助您快速为 UI 组件生成全面的文档。 通过利用 Autodocs,您可以将您的 stories 转换为实时文档,并通过 MDXDoc Blocks 进一步扩展,从而清晰简洁地了解组件的功能。

Storybook 推断相关的元数据 (例如,args, argTypes, parameters),并自动生成一个文档页面,其中包含此信息,并将其放置在侧边栏中组件树的根级别。

Storybook autodocs

设置自动文档

Autodocs 通过 tags 配置。 如果 CSF 文件包含至少一个标记为 autodocs 的 story,则会为该组件生成一个文档页面。

要为项目中的所有 stories 启用自动文档,请将其添加到您的 tags 中的 .storybook/preview.js|ts 文件中

.storybook/preview.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;

您也可以在组件(或 story)级别启用它

Button.stories.ts
// 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;

您可以通过删除 tag 来禁用特定组件的自动文档

Page.stories.ts
// Replace your-framework with the framework you are using (e.g., nextjs, vue3-vite)
import type { Meta } 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;

同样,您可以通过删除 tag 从自动文档页面中排除特定的 story

Button.stories.ts
// 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)并提供其他选项来控制文档的创建方式。 下面列出了可用的选项以及如何使用它们的示例。

.storybook/main.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)'],
  addons: ['@storybook/addon-essentials'],
  docs: {
    //👇 See the table below for the list of supported options
    defaultName: 'Documentation',
  },
};
 
export default config;
选项描述
defaultName重命名自动生成的文档页面
默认值: docs: { defaultName: '文档' }

编写自定义模板

观看视频教程

要替换 Storybook 使用的默认文档模板,您可以扩展您的 UI 配置文件(即 .storybook/preview.js|ts)并引入 docs 参数。 此参数接受一个 page 函数,该函数返回一个 React 组件,您可以使用该组件生成所需的模板。 例如

.storybook/preview.tsx
// 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 使用类似的实现来生成默认模板。 请参阅 Doc Blocks API 参考,以了解有关 Doc Blocks 工作原理的更多信息。

更详细地了解代码片段。 当 Storybook 启动时,它将使用以下组成的自定义模板覆盖默认模板

  1. 一个标头,其中包含由 TitleSubtitleDescription Doc Blocks 检索的组件元数据。
  2. 文件中通过 Primary Doc Block 定义的第一个 story,带有一组方便的 UI 控件,用于放大和缩小组件。
  3. 一个交互式表格,其中包含通过 Controls Doc Block 在 story 中定义的所有相关 argsargTypes
  4. 通过 Stories Doc Block 概述其余的 stories。

使用 MDX

您还可以使用 MDX 生成文档模板。 这在未配置 JSX 处理的非 React 项目中非常有用。 通常,当您在项目中创建 MDX 文件时,它被视为普通文档。 要指示 MDX 文件是文档模板,请将 isTemplate 属性提供给其 Meta Doc Block。 例如

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|ts 或单个 story 文件中使用它

.storybook/preview.jsx
import DocumentationTemplate from './DocumentationTemplate.mdx';
 
export default {
  parameters: {
    docs: {
      page: DocumentationTemplate,
    },
  },
};

如果您只需要覆盖单个组件的文档页面,我们建议创建一个 MDX 文件,并通过 <Meta of={} /> Doc Block 直接引用它。

生成目录

Storybook 的自动生成的文档页面可能很长且难以导航。 为了帮助解决这个问题,您可以启用目录功能,以提供文档页面的快速概览,并允许用户跳转到特定部分。 要启用它,请扩展您的 Storybook UI 配置文件(即 .storybook/preview.js|ts)并提供带有 toc 属性的 docs 参数

.storybook/preview.ts
// 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配置目录以忽略特定的标题或 stories。 默认情况下,目录将忽略放置在 Story blocks 中的所有内容
toc: { ignoreSelector: '.docs-story h2' }
title定义目录的标题。
接受以下之一:string, null, React 元素
toc: { title: '目录' }
unsafeTocbotOptions提供额外的 TocBot 配置选项
toc: { unsafeTocbotOptions: { orderedList: true } }

contentsSelector, headingSelector, 和 ignoreSelector 属性允许进行额外的自定义。 有关使用它们的更多信息,请参阅 Tocbot 文档

.storybook/preview.ts
// 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;

组件级配置

如果您想为特定的 Story 自定义目录,可以在 Story 的默认导出中包含 toc 属性,并提供所需的配置。例如,如果您需要隐藏特定 Story 的目录,请按照如下方式调整您的 Story:

MyComponent.stories.ts|tsx
// 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 的 Doc Blocks 来编写您的文档。

高级配置

为多个组件编写文档

有时,将多个组件一起编写文档会很有帮助。例如,组件库的 ButtonGroup 和 Button 组件如果缺少其中一个,可能就失去了意义。

Autodocs 允许您为您通过 component 属性定义的“主要”组件以及与其相关的一个或多个 subcomponents 编写文档。

List.stories.ts|tsx
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>
  ),
};

Subcomponents in ArgTypes doc block

主要组件及其子组件将以选项卡形式显示在 ArgTypes doc block 中。选项卡标题将与 subcomponents 对象的键相对应。

如果您想以不同的方式组织组件组的文档,我们建议使用 MDX。它可以让您完全控制组件的显示方式,并支持任何配置。

自定义 Docs Container

Docs Container 是包装文档页面的组件。它负责在 Storybook 的 UI 中渲染文档页面。您可以通过创建自己的组件并更新您的 Storybook UI 配置文件(即 .storybook/preview.js|ts)来引用它,从而对其进行自定义。

.storybook/preview.ts
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 提供了两个主题:lightdark。如果您需要自定义文档使用的主题以匹配现有主题,您可以更新您的 Storybook UI 配置文件(即 .storybook/preview.js|ts)并应用它。

.storybook/preview.ts
// 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>,将不会被您的自定义实现替换。

.storybook/preview.ts
// 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 编写未附加的文档,则主要由于当前实现不支持基于当前实现定义参数,因此您无法自定义目录。因此,目录将始终恢复为全局提供的默认配置

自动生成的文档未在 monorepo 设置中显示

开箱即用,Storybook 的 Autodocs 功能旨在自动为您的 Story 生成文档。然而,如果您正在使用 monorepo 设置(例如 Yarn Workspaces, pnpm Workspaces),您可能会遇到部分文档未为您生成的问题。为了帮助您排查这些问题,我们准备了一些可能对您有所帮助的建议。

更新您的导入语句以直接引用组件,而不是包的根目录。例如

MyComponent.stories.ts|tsx
// 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)以包含以下内容

.storybook/main.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 discussions)联系社区。

控件未在自动生成的文档中更新 Story

如果您通过 inline 配置选项关闭了 Story 的内联渲染,您将遇到关联的控件未在文档页面中更新 Story 的情况。这是当前实现的一个已知限制,将在未来的版本中解决。

了解更多关于 Storybook 文档的信息

  • Autodocs 用于为您的 Story 创建文档
  • MDX 用于自定义您的文档
  • Doc Blocks 用于编写您的文档
  • 发布文档 以自动化发布文档的过程