文档
Storybook Docs

MDX

MDX 文件混合了 Markdown 和 Javascript/JSX,以创建丰富的交互式文档。您可以使用 Markdown 的可读语法(例如 # heading)来编写文档,包含在 组件故事格式 (CSF) 中定义的 stories,并可以在文件的任何位置自由嵌入 JSX 组件块。一切尽在一个地方。

此外,您还可以编写纯粹的文档页面(使用 MDX),并将其与您的 stories 一起添加到 Storybook 中。

MDX simple example result

基本示例

让我们从一个示例开始,Checkbox.mdx,它将 Markdown 与单个 story 结合起来。

Checkbox.mdx
import { Canvas, Meta } from '@storybook/addon-docs/blocks';
 
import * as CheckboxStories from './Checkbox.stories';
 
<Meta of={CheckboxStories} />
 
# Checkbox
 
A checkbox is a square box that can be activated or deactivated when ticked.
 
Use checkboxes to select one or more options from a list of choices.
 
<Canvas of={CheckboxStories.Unchecked} />

此 MDX 文件引用了一个用 组件故事格式 (CSF) 编写的 story 文件 Checkbox.stories.js|ts

Checkbox.stories.ts|tsx
// Replace your-framework with the framework you are using, e.g. react-vite, nextjs, vue3-vite, etc.
import type { Meta, StoryObj } from '@storybook/your-framework';
 
import { Checkbox } from './Checkbox';
 
const meta = {
  component: Checkbox,
} satisfies Meta<typeof Checkbox>;
 
export default meta;
type Story = StoryObj<typeof meta>;
 
export const Unchecked: Story = {
  args: {
    label: 'Unchecked',
  },
};

以下是它在 Storybook 中的渲染方式。

MDX simple example result

这里有很多内容。我们编写了 Markdown,编写了 JSX,并且还定义和引用了与整个 Storybook 生态系统兼容的 Storybook stories。

让我们来分解一下。

MDX 和 CSF

您会注意到的第一点是,组件文档分为不同的格式:一种用于编写描述每个可能组件状态的 stories,另一种用于记录如何使用它们。这种分离利用了每种格式的最佳特性。

  • CSF 非常适合简洁地定义 stories(组件示例)。如果您使用 TypeScript,它还提供类型安全和自动补全功能。
  • MDX 非常适合编写结构化文档并将其与交互式 JSX 元素组合。

MDX 的结构

假设您已经熟悉使用 CSF 编写 stories,我们可以更详细地剖析 MDX 部分。

文档由多个由空行分隔的块组成。由于 MDX 混合了多种语言,它使用这些空行来帮助区分一个块何时开始,下一个块何时开始。未能通过空格分隔块会导致(有时是神秘的)解析错误。

按顺序查看代码块。

{ /* Checkbox.mdx */ }

MDX 中的注释是包含 JS 注释的 JSX 块。

Checkbox.mdx
import { Canvas, Meta } from '@storybook/addon-docs/blocks';
 
import * as CheckboxStories from './Checkbox.stories';

导入将在文件中其余 JSX 中使用的组件和 stories。

Checkbox.mdx
import { Meta } from '@storybook/addon-docs/blocks';
 
import * as CheckboxStories from './Checkbox.stories';
 
<Meta of={CheckboxStories} />

在为 Meta 块提供 of 属性时,请确保您引用的是 story 文件的 默认导出,而不是组件本身,以防止生成文档时出现渲染问题。

Meta 块定义了文档在侧边栏中的位置。在这种情况下,它紧邻 Checkbox 的 stories。默认情况下,docs 侧边栏节点被命名为 "Docs",但这可以通过传递 name 属性来定制(例如,<Meta of={CheckboxStories} name="Info" />)。如果您想将文档节点放置在导航层次结构的任意位置,可以使用 title 属性(例如,<Meta title="path/to/node" />)。

# Checkbox
 
A checkbox is a square box that can be activated or deactivated when ticked.
 
Use checkboxes to select one or more options from a list of choices.

MDX 默认支持标准的 Markdown(“commonmark”),并且可以扩展以支持 GitHub Flavored Markdown (GFM) 和其他扩展(请参阅 故障排除部分 以了解一些当前限制)。

Checkbox.mdx
import { Canvas } from '@storybook/addon-docs/blocks';
 
import * as CheckboxStories from './Checkbox.stories';
 
<Canvas of={CheckboxStories.Unchecked} />

最后,MDX 支持任意 JSX 块。

在这种情况下,我们正在利用“Doc Blocks”,这是一个文档组件库,旨在与 Storybook stories 配合使用,以展示您的 stories、组件 API 和控件,用于在文档中与组件交互,以及其他实用功能。

除了 Doc Blocks,MDX 还可以包含任意 React 组件,使其成为一个非常灵活的文档系统。如果您想为您的组件提供一个风格化的“dos and don'ts”列表,您可以使用现成的组件或编写自己的组件。

Guideline.mdx
<Guidelines>
  <Dos>
    - Use buttons for the main actions on your page
    - Identify the primary action and make it `primary`
  </Dos>
  <Donts>
    - Use a button when a link will do (e.g., for navigation-only actions)
    - Use multiple `primary` buttons in a single UI state
  </Donts>
</Guidelines>

已知限制

虽然 MDX 支持多种运行时(ReactPreactVue),但 Storybook 的实现仅限于 React。这意味着您的文档以 React 渲染,而您的 stories 则以您选择的运行时(React、Vue、Angular、Web Components、Svelte 等)渲染。

设置自定义文档

此外,除了记录您的组件之外,您还可以扩展 MDX 来编写其他类型的内容,例如如何使用它们的指南或最佳实践。要使用此格式为您的 stories 启用自定义文档,请首先更新您的 Storybook 配置文件(即 .storybook/main.js|ts|cjs)。

.storybook/main.ts
// Replace your-framework with the framework you are using, e.g. react-vite, nextjs, vue3-vite, etc.
import type { StorybookConfig } from '@storybook/your-framework';
 
const config: StorybookConfig = {
  // Replace your-framework with the framework you are using, e.g. react-vite, nextjs, vue3-vite, etc.
  framework: '@storybook/your-framework',
  stories: [
    //👇 Your documentation written in MDX along with your stories goes here
    '../src/**/*.mdx',
    '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)',
  ],
  addons: ['@storybook/addon-docs'],
};
 
export default config;

创建一个 MDX 文件来添加您的自定义文档。根据您希望文档如何在 UI 中呈现,您需要考虑以下用例。

使用 Meta Doc Block

如果您需要将组件文档与现有 story 匹配,您可以配置 Meta Doc Block 来控制文档的渲染方式。开箱即用,它允许您定义自定义标题或对您需要文档化的 story 的引用(即通过 of 属性)。例如:

Button.mdx
import { Meta, Controls } from '@storybook/addon-docs/blocks';
 
<Meta title="Button" />
 
# Definition
 
Button is a clickable interactive element that triggers a response.
 
You can place text and icons inside of a button.
 
Buttons are often used for form submissions and to toggle elements into view.
 
## Usage
 
The component comes in different variants such as `primary`, `secondary`, `large` and `small` which you can use to alter the look and feel of the button.
 
## Inputs
 
Button has the following properties:
 
<Controls />

编写未关联的文档

如果您只提供 Meta Doc Block 而没有其他属性或块,来记录一个现有的组件。在这种情况下,Storybook 会将其视为“未关联”的文档,换句话说,是一个“仅文档”页面,并且它会在侧边栏导航菜单中以不同的方式渲染它。

ExampleDocumentation.mdx
import { Meta } from '@storybook/addon-docs/blocks';
 
import * as ExampleComponentStories from './ExampleComponent.stories';
 
{/* 👇 Documentation-only page */}
 
<Meta title="Documentation" />
 
{/* 👇 Component documentation page */}
 
<Meta of={ExampleComponentStories} />

MDX docs only story

使用文件系统

然而,对于某些用例,例如独立页面或作为测试组件的指南,可能不需要提供 Meta Doc Block。在这种情况下,您可以安全地省略它。Storybook 将依赖于文件在物理位置来将文档放置在侧边栏中,从而覆盖任何预先存在的 自动生成的文档,并用您自己的文档替换。

src/components/Select.mdx
# Select
 
Select is a type of input that allows users to choose one or more options from a list of choices.
 
The options are hidden by default and revealed when a user interacts with an element.
 
It shows the currently selected option in its default collapsed state.
 
## Design implementation
 
To help users get acquainted with the existing UI elements, it is recommended to use check the Figma file to see how the select input is implemented.
 
### When to use?
 
In a select input where there are less than 3-4 items, consider using radio boxes, or radio inputs instead.
 
### How to use?
 
To help users understand the options available in a select input, include a default option that is unselectable and acts as a label.

如果您覆盖了通过 tags 配置属性启用的现有自动生成文档页面,我们建议将其删除以避免错误。

一旦加载了自定义 MDX 文档,Storybook 将使用相同的启发式规则来推断标题和位置,以生成 自动标题 stories,并在侧边栏中将其渲染为 Docs 条目。

处理独立文档页面

编写独立文档页面是一种常见的用例,它不仅适用于单个组件,也适用于整个项目。例如,您可能希望记录您项目的入职流程,并提供使用说明。为此,您可以创建一个包含文档的新 MDX 文件,使用类似的结构和内容。

src/GettingStarted.mdx
# Getting Started
 
Welcome! Whether you're a designer or a developer, this guide will help you get started and connect you to the essential resources you need.
 
## Table of Contents
 
- [Design Resources](#design-resources)
 
  - [Figma](#figma)
  - [UI/UX Design Guidelines](#uiux-design-guidelines)
  - [Design Assets](#design-assets)
 
- [Development Resources](#development-resources)
  - [Coding Standards](#coding-standards)
  - [Version Control](#version-control)
  - [Development Tools](#development-tools)
 
---
 
## Design Resources
 
### Figma
 
[Figma](https://www.figma.com/) is a collaborative design and prototyping tool. It's the heart of the design process, allowing designers to work together seamlessly.
 
- **Get Access**: If you're not already part of the Figma project, request access from the project lead or manager.
 
### UI/UX Design Guidelines
 
Before you dive into designing, familiarize yourself with our UI/UX design guidelines. They provide valuable insights into our design philosophy and standards.
 
- [UI/UX Guidelines Document](https://your-design-guidelines-link.com)
 
### Design Assets
 
All the essential design assets like logos, icons, and brand guidelines can be found in the Figma project. Ensure you have access and familiarize yourself with these assets for consistency.
 
---
 
## Development Resources
 
### Coding Standards
 
Maintaining a consistent code style is essential for collaborative development. Our coding standards document will guide you on best practices.
 
- [Coding Standards Document](https://your-coding-standards-link.com)
 
### Version Control
 
We use Git for version control. Make sure you have Git installed and are familiar with its basics.
 
### Development Tools
 
Your development environment is critical. Here are some tools and resources to help you set up your workspace:
 
- **Code Editor**: We recommend using [Visual Studio Code](https://vscode.js.cn/) for development. It's highly customizable and supports a wide range of extensions.
 
- **Package Manager**: [npm](https://npmjs.net.cn/) is the package manager we use for JavaScript projects. Install it to manage project dependencies.
 
---

MDX guidelines page

当 Storybook 加载文档时,它将使用文件的物理位置来推断页面在侧边栏导航菜单中的位置,并将其渲染为 Docs 条目。

完全控制自定义文档

文档的维护和更新成本可能很高,尤其是当应用于每个项目组件时。为了简化此过程,Storybook 提供了一套有用的 UI 组件(即 Doc Blocks),以帮助涵盖更高级的用例。如果您需要额外的内容,请使用它们来帮助创建您的自定义文档。

Button.mdx
import { Meta, Story } from '@storybook/addon-docs/blocks';
 
import * as ButtonStories from './Button.stories';
 
<Meta of={ButtonStories} />
 
# Button
 
Button is a clickable interactive element that triggers a response.
 
You can place text and icons inside of a button.
 
Buttons are often used for form submissions and to toggle elements into view.
 
## Usage
 
<Story of={ButtonStories.Basic} />

处理多个组件

如果您需要在单个文档页面中记录多个组件,您可以直接在 MDX 文件中引用它们。在内部,Storybook 会查找 story 元数据并将其与您现有的文档组合。例如:

Page.mdx
import { Canvas, Meta, Story } from '@storybook/addon-docs/blocks';
 
import * as ListStories from './List.stories';
 
import * as ListItemStories from './ListItem.stories';
 
import * as PageStories from './Page.stories';
 
<Meta of={PageStories} />
 
# Page
 
Page is a layout container that is used to position children in predetermined areas.
 
It's often used to apply consistent positioning for content across pages in an application
 
## Usage
 
<Canvas of={PageStories.Basic} />
 
# List
 
List is a grouping of related items. List can be ordered with multiple levels of nesting.
 
## Usage
 
<Story of={ListStories.Filled} />
 
# List Item
 
List items are used to group related content in a list. They must be nested within a List component.
 
## Usage
 
<Story of={ListItemStories.Starter} meta={ListItemStories} />

从 Markdown 生成文档

如果您需要用 Markdown 编写的额外内容来扩展您的文档,您可以使用 Markdown Doc Block 来导入可用内容,Storybook 会将其与您现有的文档一起渲染。例如,如果您有一个 CHANGELOG.md 文件,您可以将其导入并在文档页面中渲染,如下所示:

Changelog.mdx
import { Meta, Markdown } from '@storybook/addon-docs/blocks';
 
import Readme from '../../Changelog.md?raw';
 
<Meta title="Changelog" />
 
# Changelog
 
<Markdown>{Readme}</Markdown>

Markdown Doc Block 提供了额外的配置选项来定制文档的渲染。有关更多信息,请参阅 API 文档

Changelog markdown in an MDX story

改进文档的另一种方法是链接到其他 stories 和页面。假设您已经有一个具有以下唯一标识符 some--id 的组件 story,并且您想将其链接到您的文档页面。在这种情况下,您可以使用 path 查询字符串重定向到与该 story 相关的文档条目。

[Go to specific documentation page](?path=/docs/some--id)

相反,如果您需要定位特定的文档部分,您可以调整链接以指向它。例如:

[Go to the conclusion of the documentation page](?path=/docs/some--id#conclusion)

但是,跨文档链接不限于文档页面。如果您需要引用特定的 story,您可以调整 path 查询并提供 story 的唯一标识符。例如:

[Go to specific story canvas](?path=/story/some--id)

将此模式应用于 Controls 功能,由于 Storybook 处理 URL 以跟踪 args 值的方式,所有锚点都将被忽略。

故障排除

Markdown 表格未正确渲染

如果您正在将文档扩展到包含特定功能(例如表格、脚注),您可能会在正确渲染它们时遇到一些问题,使用 Storybook 当前支持的 MDX 版本。我们建议在您的配置文件(即 .storybook/main.js|ts)中启用 remark-gfm 插件,以正确渲染它们。

.storybook/main.ts
import remarkGfm from 'remark-gfm';
 
// Replace your-framework with the framework you are using, e.g. react-vite, nextjs, vue3-vite, etc.
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: [
    // Other addons go here
    {
      name: '@storybook/addon-docs',
      options: {
        mdxPluginOptions: {
          mdxCompileOptions: {
            remarkPlugins: [remarkGfm],
          },
        },
      },
    },
  ],
};
 
export default config;

remark-gfm 包默认不包含在 Storybook 中,必须单独安装为开发依赖项。要了解有关如何使用它以及 MDX 引入的其他重大更改的更多信息,请参阅 MDX 团队提供的 GFM 指南迁移指南

MDX 文档未在我的环境中渲染

由于 Storybook 依赖 MDX 3 来渲染文档,一些技术限制可能会阻止您迁移到此版本。如果情况是这样,我们已准备好一系列说明来帮助您过渡到此新版本。

Storybook 未为我的 component stories 创建文档

如果您遇到 Storybook 无法检测和渲染您的 component stories 的文档的情况,这可能是由于您的 Storybook 配置错误。请检查您的配置文件(即 .storybook/main.js|ts)并确保 stories 配置元素提供了指向您的 stories 位置的正确路径(例如,../src/**/*.stories.@(js|jsx|mjs|ts|tsx))。

迁移似乎不稳定且持续失败

默认情况下,运行 迁移 命令会提示您更新项目中现有的 MDX 文件以适应 Storybook 支持的 MDX 版本。但是,这可能是一个破坏性的过程,特别是如果您从早期版本的 Storybook 升级,当时您使用的是旧版 MDX 格式。为了帮助您解决这些问题,我们准备了一些建议,或许能帮到您。

首先,在项目目录中运行以下命令:

npx @hipster/mdx2-issue-checker

根据数量,您可能需要多次运行该命令来修复所有问题。

完成后,它将输出导致问题的文件的列表。然后,您可以使用此信息手动修复问题。

此外,如果您正在使用 VSCode,可以添加 MDX 扩展,并通过将以下内容添加到用户设置中来启用 MDX 实验性支持,以实现 linting、类型检查和自动补全:

{
  "mdx.server.enable": true
}

如果您仍然遇到问题,我们建议您通过默认的沟通渠道(例如,GitHub discussions)与社区联系。

控件未在 MDX 文档页面内的 story 中更新

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

使用的 React 版本不符合预期

对于大多数项目,Storybook 的 addon-docs 会使用您项目依赖项中列出的 React 版本。如果找不到,它将使用 React 18.2.0。对此有两个例外:

  • Preact 项目将始终使用 React 17。
  • Next.js 项目将始终使用 Next.js 版本安装的 canary 版本,而不管项目中依赖项中列出的 React 版本是什么。

如果您在使用 React 版本时遇到问题,您可能需要重新创建项目的 node_modules 文件夹以确保使用正确的版本。

详细了解 Storybook 文档

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