storybook-component-documentation

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Storybook - Component Documentation

Storybook - 组件文档

Create comprehensive, auto-generated component documentation using Storybook's autodocs feature, MDX pages, and JSDoc comments.
利用Storybook的autodocs功能、MDX页面和JSDoc注释,创建全面的自动生成组件文档。

Key Concepts

核心概念

Autodocs

Autodocs

Automatically generate documentation pages from stories:
typescript
const meta = {
  title: 'Components/Button',
  component: Button,
  tags: ['autodocs'],  // Enable auto-documentation
  parameters: {
    docs: {
      description: {
        component: 'A versatile button component with multiple variants and sizes.',
      },
    },
  },
} satisfies Meta<typeof Button>;
从stories自动生成文档页面:
typescript
const meta = {
  title: 'Components/Button',
  component: Button,
  tags: ['autodocs'],  // Enable auto-documentation
  parameters: {
    docs: {
      description: {
        component: 'A versatile button component with multiple variants and sizes.',
      },
    },
  },
} satisfies Meta<typeof Button>;

MDX Documentation

MDX文档

Create custom documentation pages with full control:
mdx
import { Meta, Canvas, Story, Controls } from '@storybook/blocks';
import * as ButtonStories from './Button.stories';

<Meta of={ButtonStories} />
完全自定义文档页面:
mdx
import { Meta, Canvas, Story, Controls } from '@storybook/blocks';
import * as ButtonStories from './Button.stories';

<Meta of={ButtonStories} />

Button Component

Button Component

A versatile button component for user interactions.
A versatile button component for user interactions.

Usage

Usage

<Canvas of={ButtonStories.Primary} />
<Canvas of={ButtonStories.Primary} />

Props

Props

<Controls of={ButtonStories.Primary} /> ```
<Controls of={ButtonStories.Primary} /> ```

JSDoc Comments

JSDoc注释

Document component props for auto-extraction:
typescript
interface ButtonProps {
  /**
   * The button label text
   */
  label: string;

  /**
   * Is this the principal call to action?
   * @default false
   */
  primary?: boolean;

  /**
   * Button size variant
   * @default 'medium'
   */
  size?: 'small' | 'medium' | 'large';
}
为组件属性添加注释以支持自动提取:
typescript
interface ButtonProps {
  /**
   * The button label text
   */
  label: string;

  /**
   * Is this the principal call to action?
   * @default false
   */
  primary?: boolean;

  /**
   * Button size variant
   * @default 'medium'
   */
  size?: 'small' | 'medium' | 'large';
}

Best Practices

最佳实践

1. Enable Autodocs

1. 启用Autodocs

Add the
autodocs
tag to generate documentation automatically:
typescript
const meta = {
  component: Button,
  tags: ['autodocs'],
  parameters: {
    docs: {
      description: {
        component: 'Button component with primary and secondary variants.',
      },
    },
  },
} satisfies Meta<typeof Button>;
添加
autodocs
标签以自动生成文档:
typescript
const meta = {
  component: Button,
  tags: ['autodocs'],
  parameters: {
    docs: {
      description: {
        component: 'Button component with primary and secondary variants.',
      },
    },
  },
} satisfies Meta<typeof Button>;

2. Document Component Descriptions

2. 编写组件描述

Provide clear, concise component descriptions:
typescript
const meta = {
  component: Tooltip,
  tags: ['autodocs'],
  parameters: {
    docs: {
      description: {
        component: `
Tooltip displays helpful information when users hover over an element.
Supports multiple placements and can be triggered by hover, click, or focus.
提供清晰、简洁的组件描述:
typescript
const meta = {
  component: Tooltip,
  tags: ['autodocs'],
  parameters: {
    docs: {
      description: {
        component: `
Tooltip displays helpful information when users hover over an element.
Supports multiple placements and can be triggered by hover, click, or focus.

Features

Features

  • Multiple placement options
  • Customizable delay
  • Accessible (ARIA compliant)
  • Keyboard navigation support `.trim(), }, }, }, } satisfies Meta<typeof Tooltip>;
undefined
  • Multiple placement options
  • Customizable delay
  • Accessible (ARIA compliant)
  • Keyboard navigation support `.trim(), }, }, }, } satisfies Meta<typeof Tooltip>;
undefined

3. Document Story Variations

3. 编写Story变体描述

Add descriptions to individual stories:
typescript
export const WithIcon: Story = {
  args: {
    label: 'Download',
    icon: 'download',
  },
  parameters: {
    docs: {
      description: {
        story: 'Buttons can include icons to enhance visual communication.',
      },
    },
  },
};

export const Loading: Story = {
  args: {
    loading: true,
    label: 'Processing...',
  },
  parameters: {
    docs: {
      description: {
        story: 'Loading state disables interaction and shows a spinner.',
      },
    },
  },
};
为单个stories添加描述:
typescript
export const WithIcon: Story = {
  args: {
    label: 'Download',
    icon: 'download',
  },
  parameters: {
    docs: {
      description: {
        story: 'Buttons can include icons to enhance visual communication.',
      },
    },
  },
};

export const Loading: Story = {
  args: {
    loading: true,
    label: 'Processing...',
  },
  parameters: {
    docs: {
      description: {
        story: 'Loading state disables interaction and shows a spinner.',
      },
    },
  },
};

4. Use JSDoc for Type Documentation

4. 用JSDoc编写类型文档

Document props with JSDoc for rich documentation:
typescript
interface CardProps {
  /**
   * Card title displayed at the top
   */
  title: string;

  /**
   * Optional subtitle below the title
   */
  subtitle?: string;

  /**
   * Card variant affecting visual style
   * @default 'default'
   */
  variant?: 'default' | 'outlined' | 'elevated';

  /**
   * Card content
   */
  children: React.ReactNode;

  /**
   * Called when card is clicked
   * @param event - The click event
   */
  onClick?: (event: React.MouseEvent) => void;

  /**
   * Elevation level (shadow depth)
   * @minimum 0
   * @maximum 5
   * @default 1
   */
  elevation?: number;
}
使用JSDoc为属性添加注释,生成丰富的文档:
typescript
interface CardProps {
  /**
   * Card title displayed at the top
   */
  title: string;

  /**
   * Optional subtitle below the title
   */
  subtitle?: string;

  /**
   * Card variant affecting visual style
   * @default 'default'
   */
  variant?: 'default' | 'outlined' | 'elevated';

  /**
   * Card content
   */
  children: React.ReactNode;

  /**
   * Called when card is clicked
   * @param event - The click event
   */
  onClick?: (event: React.MouseEvent) => void;

  /**
   * Elevation level (shadow depth)
   * @minimum 0
   * @maximum 5
   * @default 1
   */
  elevation?: number;
}

5. Create Usage Examples

5. 创建使用示例

Show realistic usage examples in MDX:
mdx
import { Meta, Canvas, Story } from '@storybook/blocks';
import * as FormStories from './Form.stories';

<Meta of={FormStories} />
在MDX中展示真实的使用示例:
mdx
import { Meta, Canvas, Story } from '@storybook/blocks';
import * as FormStories from './Form.stories';

<Meta of={FormStories} />

Form Component

Form Component

Basic Usage

Basic Usage

<Canvas of={FormStories.Default} />
<Canvas of={FormStories.Default} />

With Validation

With Validation

<Canvas of={FormStories.WithValidation} />
tsx
import { Form } from './Form';

function MyForm() {
  return (
    <Form
      onSubmit={(data) => console.log(data)}
      validationSchema={schema}
    >
      <Input name="email" label="Email" />
      <Button type="submit">Submit</Button>
    </Form>
  );
}
undefined
<Canvas of={FormStories.WithValidation} />
tsx
import { Form } from './Form';

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

Common Patterns

常见模式

Component Overview Page

组件概览页面

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

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

<Meta of={ButtonStories} />

Button

Button

Buttons trigger actions and events throughout the application.
Buttons trigger actions and events throughout the application.

Variants

Variants

Primary

Primary

Use primary buttons for the main call-to-action.
<Canvas of={ButtonStories.Primary} />
Use primary buttons for the main call-to-action.
<Canvas of={ButtonStories.Primary} />

Secondary

Secondary

Use secondary buttons for less important actions.
<Canvas of={ButtonStories.Secondary} />
Use secondary buttons for less important actions.
<Canvas of={ButtonStories.Secondary} />

Props

Props

<Controls of={ButtonStories.Primary} />
<Controls of={ButtonStories.Primary} />

Accessibility

无障碍访问

  • Keyboard accessible (Enter/Space to activate)
  • Screen reader friendly
  • Focus visible indicator
  • Proper ARIA labels
  • 支持键盘操作(按Enter/Space激活)
  • 适配屏幕阅读器
  • 可见的焦点指示器
  • 正确的ARIA标签

Best Practices

最佳实践

  • Use clear, action-oriented labels
  • Provide sufficient click target size (min 44×44px)
  • Don't use more than one primary button per section
  • Include loading states for async actions
undefined
  • 使用清晰、面向动作的标签
  • 提供足够的点击目标尺寸(最小44×44px)
  • 每个区域不要使用多个primary按钮
  • 异步操作需包含加载状态
undefined

API Documentation

API文档

typescript
const meta = {
  component: DataGrid,
  tags: ['autodocs'],
  parameters: {
    docs: {
      description: {
        component: 'Advanced data grid with sorting, filtering, and pagination.',
      },
    },
  },
  argTypes: {
    data: {
      description: 'Array of data objects to display',
      table: {
        type: { summary: 'Array<Record<string, any>>' },
      },
    },
    columns: {
      description: 'Column configuration',
      table: {
        type: { summary: 'ColumnDef[]' },
      },
    },
    onRowClick: {
      description: 'Callback fired when a row is clicked',
      table: {
        type: { summary: '(row: any, index: number) => void' },
      },
    },
  },
} satisfies Meta<typeof DataGrid>;
typescript
const meta = {
  component: DataGrid,
  tags: ['autodocs'],
  parameters: {
    docs: {
      description: {
        component: 'Advanced data grid with sorting, filtering, and pagination.',
      },
    },
  },
  argTypes: {
    data: {
      description: 'Array of data objects to display',
      table: {
        type: { summary: 'Array<Record<string, any>>' },
      },
    },
    columns: {
      description: 'Column configuration',
      table: {
        type: { summary: 'ColumnDef[]' },
      },
    },
    onRowClick: {
      description: 'Callback fired when a row is clicked',
      table: {
        type: { summary: '(row: any, index: number) => void' },
      },
    },
  },
} satisfies Meta<typeof DataGrid>;

Migration Guides

迁移指南

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

<Meta title="Guides/Migration/v2 to v3" />
mdx
import { Meta } from '@storybook/blocks';

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

Migration Guide: v2 → v3

迁移指南:v2 → v3

Breaking Changes

破坏性变更

Button Component

Button组件

Before (v2):
tsx
<Button type="primary">Click me</Button>
After (v3):
tsx
<Button variant="primary">Click me</Button>
The
type
prop has been renamed to
variant
for consistency.
之前(v2):
tsx
<Button type="primary">Click me</Button>
之后(v3):
tsx
<Button variant="primary">Click me</Button>
type
属性已重命名为
variant
以保持一致性。

Input Component

Input组件

Before (v2):
tsx
<Input error="Invalid email" />
After (v3):
tsx
<Input error={{ message: "Invalid email" }} />
Error handling now uses an object to support additional metadata.
之前(v2):
tsx
<Input error="Invalid email" />
之后(v3):
tsx
<Input error={{ message: "Invalid email" }} />
错误处理现在使用对象格式,以支持额外的元数据。

New Features

新功能

Icon Support

图标支持

Buttons now support icons:
tsx
<Button variant="primary" icon="check">
  Save
</Button>
undefined
按钮现在支持图标:
tsx
<Button variant="primary" icon="check">
  Save
</Button>
undefined

Design Tokens

设计令牌

Document design tokens and theming:
mdx
import { Meta, ColorPalette, ColorItem, Typeset } from '@storybook/blocks';

<Meta title="Design System/Colors" />
编写设计令牌和主题文档:
mdx
import { Meta, ColorPalette, ColorItem, Typeset } from '@storybook/blocks';

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

Color Palette

调色板

Primary Colors

主色调

<ColorPalette> <ColorItem title="Primary" subtitle="Main brand color" colors={{ Primary: '#007bff' }} /> <ColorItem title="Secondary" subtitle="Supporting color" colors={{ Secondary: '#6c757d' }} /> </ColorPalette>
<ColorPalette> <ColorItem title="Primary" subtitle="Main brand color" colors={{ Primary: '#007bff' }} /> <ColorItem title="Secondary" subtitle="Supporting color" colors={{ Secondary: '#6c757d' }} /> </ColorPalette>

Typography

排版

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

Advanced Patterns

高级模式

Inline Stories in MDX

MDX中的内联Stories

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

<Meta title="Components/Button/Examples" component={Button} />
mdx
import { Meta, Story } from '@storybook/blocks';
import { Button } from './Button';

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

Button Examples

Button示例

Inline Story

内联Story

<Story name="Custom"> {() => { const [count, setCount] = React.useState(0); return ( <Button onClick={() => setCount(count + 1)}> Clicked {count} times </Button> ); }} </Story> ```
<Story name="Custom"> {() => { const [count, setCount] = React.useState(0); return ( <Button onClick={() => setCount(count + 1)}> Clicked {count} times </Button> ); }} </Story> ```

Code Snippets

代码片段

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

<Meta title="Guides/Setup" />
mdx
import { Source } from '@storybook/blocks';

<Meta title="Guides/Setup" />

Installation

安装

Install the component library:
<Source language="bash" code={` npm install @company/ui-components
安装组件库:
<Source language="bash" code={` npm install @company/ui-components

or

or

yarn add @company/ui-components `} />
Then import components:
<Source language="tsx" code={` import { Button, Input, Form } from '@company/ui-components';
function App() { return ( <Form> <Input label="Email" /> <Button>Submit</Button> </Form> ); } `} />
undefined
yarn add @company/ui-components `} />
然后导入组件:
<Source language="tsx" code={` import { Button, Input, Form } from '@company/ui-components';
function App() { return ( <Form> <Input label="Email" /> <Button>Submit</Button> </Form> ); } `} />
undefined

Anti-Patterns

反模式

❌ Don't Skip Component Descriptions

❌ 不要跳过组件描述

typescript
// Bad
const meta = {
  component: Button,
  tags: ['autodocs'],
} satisfies Meta<typeof Button>;
typescript
// Good
const meta = {
  component: Button,
  tags: ['autodocs'],
  parameters: {
    docs: {
      description: {
        component: 'Primary UI component for user actions.',
      },
    },
  },
} satisfies Meta<typeof Button>;
typescript
// 错误示例
const meta = {
  component: Button,
  tags: ['autodocs'],
} satisfies Meta<typeof Button>;
typescript
// 正确示例
const meta = {
  component: Button,
  tags: ['autodocs'],
  parameters: {
    docs: {
      description: {
        component: 'Primary UI component for user actions.',
      },
    },
  },
} satisfies Meta<typeof Button>;

❌ Don't Use Generic JSDoc Comments

❌ 不要使用通用的JSDoc注释

typescript
// Bad
interface ButtonProps {
  /** The label */
  label: string;
  /** The size */
  size?: string;
}
typescript
// Good
interface ButtonProps {
  /** Text displayed on the button */
  label: string;
  /**
   * Visual size of the button
   * @default 'medium'
   */
  size?: 'small' | 'medium' | 'large';
}
typescript
// 错误示例
interface ButtonProps {
  /** The label */
  label: string;
  /** The size */
  size?: string;
}
typescript
// 正确示例
interface ButtonProps {
  /** Text displayed on the button */
  label: string;
  /**
   * Visual size of the button
   * @default 'medium'
   */
  size?: 'small' | 'medium' | 'large';
}

❌ Don't Forget Story Descriptions

❌ 不要忘记Story描述

typescript
// Bad
export const Disabled: Story = {
  args: { disabled: true },
};
typescript
// Good
export const Disabled: Story = {
  args: { disabled: true },
  parameters: {
    docs: {
      description: {
        story: 'Disabled state prevents user interaction and dims the button visually.',
      },
    },
  },
};
typescript
// 错误示例
export const Disabled: Story = {
  args: { disabled: true },
};
typescript
// 正确示例
export const Disabled: Story = {
  args: { disabled: true },
  parameters: {
    docs: {
      description: {
        story: 'Disabled state prevents user interaction and dims the button visually.',
      },
    },
  },
};

Related Skills

相关技能

  • storybook-story-writing: Creating well-structured stories
  • storybook-args-controls: Configuring interactive controls for props
  • storybook-configuration: Setting up Storybook with proper documentation addons
  • storybook-story-writing: 创建结构清晰的stories
  • storybook-args-controls: 为属性配置交互式控件
  • storybook-configuration: 使用合适的文档插件配置Storybook