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与适当的文档插件