Storybook组件文档编写Skill storybook-component-documentation

这个技能专注于使用Storybook创建和改进组件文档,通过autodocs、MDX和JSDoc实现自动化文档生成,提高前端开发效率。关键词:Storybook, 组件文档, 前端开发, 自动文档, MDX, JSDoc, SEO优化

前端开发 0 次安装 0 次浏览 更新于 3/25/2026

name: storybook-component-documentation user-invocable: false description: 用于在Storybook中创建或改进组件文档。帮助使用MDX、autodocs和JSDoc注释生成全面的文档。 allowed-tools:

  • Read
  • Write
  • Edit
  • Bash
  • Grep
  • Glob

Storybook - 组件文档

使用Storybook的autodocs功能、MDX页面和JSDoc注释,创建全面的、自动生成的组件文档。

关键概念

Autodocs

从故事自动生成文档页面:

const meta = {
  title: 'Components/Button',
  component: Button,
  tags: ['autodocs'],  // 启用自动文档生成
  parameters: {
    docs: {
      description: {
        component: '一个多功能按钮组件,具有多种变体和尺寸。',
      },
    },
  },
} satisfies Meta<typeof Button>;

MDX文档

创建自定义文档页面,具有完全控制:

import { Meta, Canvas, Story, Controls } from '@storybook/blocks';
import * as ButtonStories from './Button.stories';

<Meta of={ButtonStories} />

# 按钮组件

一个用于用户交互的多功能按钮组件。

## 用法

<Canvas of={ButtonStories.Primary} />

## 属性

<Controls of={ButtonStories.Primary} />

JSDoc注释

为自动提取记录组件属性:

interface ButtonProps {
  /**
   * 按钮标签文本
   */
  label: string;

  /**
   * 这是主要操作吗?
   * @default false
   */
  primary?: boolean;

  /**
   * 按钮尺寸变体
   * @default 'medium'
   */
  size?: 'small' | 'medium' | 'large';
}

最佳实践

1. 启用Autodocs

添加autodocs标签以自动生成文档:

const meta = {
  component: Button,
  tags: ['autodocs'],
  parameters: {
    docs: {
      description: {
        component: '具有主次变体的按钮组件。',
      },
    },
  },
} satisfies Meta<typeof Button>;

2. 文档组件描述

提供清晰、简洁的组件描述:

const meta = {
  component: Tooltip,
  tags: ['autodocs'],
  parameters: {
    docs: {
      description: {
        component: `
Tooltip在用户悬停元素时显示有用信息。
支持多个放置位置,可通过悬停、点击或焦点触发。

## 特性
- 多种放置选项
- 可自定义延迟
- 可访问性(符合ARIA标准)
- 键盘导航支持
        `.trim(),
      },
    },
  },
} satisfies Meta<typeof Tooltip>;

3. 文档故事变体

为单个故事添加描述:

export const WithIcon: Story = {
  args: {
    label: '下载',
    icon: 'download',
  },
  parameters: {
    docs: {
      description: {
        story: '按钮可以包含图标以增强视觉传达。',
      },
    },
  },
};

export const Loading: Story = {
  args: {
    loading: true,
    label: '处理中...',
  },
  parameters: {
    docs: {
      description: {
        story: '加载状态禁用交互并显示旋转器。',
      },
    },
  },
};

4. 使用JSDoc进行类型文档

使用JSDoc记录属性以获得丰富的文档:

interface CardProps {
  /**
   * 显示在顶部的卡片标题
   */
  title: string;

  /**
   * 标题下方的可选子标题
   */
  subtitle?: string;

  /**
   * 影响视觉样式的卡片变体
   * @default 'default'
   */
  variant?: 'default' | 'outlined' | 'elevated';

  /**
   * 卡片内容
   */
  children: React.ReactNode;

  /**
   * 当卡片被点击时调用
   * @param event - 点击事件
   */
  onClick?: (event: React.MouseEvent) => void;

  /**
   * 提升级别(阴影深度)
   * @minimum 0
   * @maximum 5
   * @default 1
   */
  elevation?: number;
}

5. 创建用法示例

在MDX中展示现实的用法示例:

import { Meta, Canvas, Story } from '@storybook/blocks';
import * as FormStories from './Form.stories';

<Meta of={FormStories} />

# 表单组件

## 基本用法

<Canvas of={FormStories.Default} />

## 带验证

<Canvas of={FormStories.WithValidation} />

```tsx
import { Form } from './Form';

function MyForm() {
  return (
    <Form
      onSubmit={(data) => console.log(data)}
      validationSchema={schema}
    >
      <Input name="email" label="邮箱" />
      <Button type="submit">提交</Button>
    </Form>
  );
}

## 常见模式

### 组件概述页面

```mdx
import { Meta, Canvas, Controls } from '@storybook/blocks';
import * as ButtonStories from './Button.stories';

<Meta of={ButtonStories} />

# 按钮

按钮在整个应用程序中触发操作和事件。

## 变体

### 主按钮

使用主按钮作为主要操作。

<Canvas of={ButtonStories.Primary} />

### 次按钮

使用次按钮进行次要操作。

<Canvas of={ButtonStories.Secondary} />

## 属性

<Controls of={ButtonStories.Primary} />

## 可访问性

- 键盘可访问(Enter/Space激活)
- 屏幕阅读器友好
- 焦点可见指示器
- 适当的ARIA标签

## 最佳实践

- 使用清晰、面向操作的标签
- 提供足够的点击目标大小(最小44×44px)
- 每个部分不要使用超过一个主按钮
- 为异步操作包含加载状态

API文档

const meta = {
  component: DataGrid,
  tags: ['autodocs'],
  parameters: {
    docs: {
      description: {
        component: '高级数据网格,具有排序、过滤和分页功能。',
      },
    },
  },
  argTypes: {
    data: {
      description: '要显示的数据对象数组',
      table: {
        type: { summary: 'Array<Record<string, any>>' },
      },
    },
    columns: {
      description: '列配置',
      table: {
        type: { summary: 'ColumnDef[]' },
      },
    },
    onRowClick: {
      description: '当行被点击时触发的回调',
      table: {
        type: { summary: '(row: any, index: number) => void' },
      },
    },
  },
} satisfies Meta<typeof DataGrid>;

迁移指南

import { Meta } from '@storybook/blocks';

<Meta title="Guides/Migration/v2 to v3" />

# 迁移指南: v2 → v3

## 破坏性更改

### 按钮组件

**之前(v2):**
```tsx
<Button type="primary">点击我</Button>

之后(v3):

<Button variant="primary">点击我</Button>

type属性已重命名为variant以保持一致性。

输入组件

之前(v2):

<Input error="无效邮箱" />

之后(v3):

<Input error={{ message: "无效邮箱" }} />

错误处理现在使用对象以支持额外的元数据。

新功能

图标支持

按钮现在支持图标:

<Button variant="primary" icon="check">
  保存
</Button>

### 设计令牌

记录设计令牌和主题:

```mdx
import { Meta, ColorPalette, ColorItem, Typeset } from '@storybook/blocks';

<Meta title="Design System/Colors" />

# 颜色调色板

## 主颜色

<ColorPalette>
  <ColorItem
    title="主色"
    subtitle="主品牌颜色"
    colors={{ Primary: '#007bff' }}
  />
  <ColorItem
    title="次色"
    subtitle="辅助颜色"
    colors={{ Secondary: '#6c757d' }}
  />
</ColorPalette>

## 排版

<Typeset
  fontSizes={[12, 14, 16, 20, 24, 32, 40, 48]}
  fontWeight={400}
  sampleText="The quick brown fox jumps over the lazy dog"
/>

高级模式

MDX中的内联故事

import { Meta, Story } from '@storybook/blocks';
import { Button } from './Button';

<Meta title="Components/Button/Examples" component={Button} />

# 按钮示例

## 内联故事

<Story name="自定义">
  {() => {
    const [count, setCount] = React.useState(0);
    return (
      <Button onClick={() => setCount(count + 1)}>
        点击了 {count} 次
      </Button>
    );
  }}
</Story>

代码片段

import { Source } from '@storybook/blocks';

<Meta title="Guides/Setup" />

# 安装

安装组件库:

<Source
  language="bash"
  code={`
npm install @company/ui-components
# 或
yarn add @company/ui-components
  `}
/>

然后导入组件:

<Source
  language="tsx"
  code={`
import { Button, Input, Form } from '@company/ui-components';

function App() {
  return (
    <Form>
      <Input label="邮箱" />
      <Button>提交</Button>
    </Form>
  );
}
  `}
/>

反模式

❌ 不要跳过组件描述

// 坏
const meta = {
  component: Button,
  tags: ['autodocs'],
} satisfies Meta<typeof Button>;
// 好
const meta = {
  component: Button,
  tags: ['autodocs'],
  parameters: {
    docs: {
      description: {
        component: '用户操作的主要UI组件。',
      },
    },
  },
} satisfies Meta<typeof Button>;

❌ 不要使用通用的JSDoc注释

// 坏
interface ButtonProps {
  /** 标签 */
  label: string;
  /** 尺寸 */
  size?: string;
}
// 好
interface ButtonProps {
  /** 显示在按钮上的文本 */
  label: string;
  /**
   * 按钮的视觉尺寸
   * @default 'medium'
   */
  size?: 'small' | 'medium' | 'large';
}

❌ 不要忘记故事描述

// 坏
export const Disabled: Story = {
  args: { disabled: true },
};
// 好
export const Disabled: Story = {
  args: { disabled: true },
  parameters: {
    docs: {
      description: {
        story: '禁用状态防止用户交互并使按钮视觉上变暗。',
      },
    },
  },
};

相关技能

  • storybook-story-writing: 创建结构良好的故事
  • storybook-args-controls: 为属性配置交互式控件
  • storybook-configuration: 设置Storybook与适当的文档插件