react-component-documentation
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseComponent Documentation (MDX Stories)
组件文档(MDX Stories)
Create a file for a Sentry component following the conventions in .
.mdxstatic/app/components/core/按照 目录下的规范为Sentry组件创建 文件。
static/app/components/core/.mdxStep 0: Gather Editorial Content
第0步:收集编辑内容
Before writing, collect the information that makes documentation useful beyond mechanical structure. Ask the user these questions — or, if they aren't available, search existing usages in the codebase ( for the component name across ) to infer answers.
Grepstatic/app/views/| Question | Where it surfaces in the docs |
|---|---|
| When should a developer reach for this component? | Introduction or a |
| When should they NOT use it — and what should they use instead? | |
| What does each variant/priority mean semantically? | Description in each variant's section (e.g., " |
| What do developers commonly get wrong? | |
| Does this component require a specific parent, peer, or provider to work correctly? | Noted in the introduction or a |
| Are there related components that overlap in purpose? | |
| Which props and variants are worth documenting with a demo? | See prop triage below |
You don't need answers to all questions for every component. Skip ones that don't apply. The goal is to not write docs that only describe how to use the API — write docs that tell developers when and why.
开始编写前,请先收集让文档不止于机械结构的有用信息。向用户询问以下问题——如果联系不到用户,可以在代码库中搜索现有使用案例(在 目录下 组件名称)来推断答案。
static/app/views/Grep| 问题 | 展示在文档的位置 |
|---|---|
| 开发者什么时候应该使用这个组件? | 介绍部分或 |
| 什么时候不应该使用它——应该用什么替代? | |
| 每个variant/优先级的语义含义是什么? | 每个variant章节的描述(例如:" |
| 开发者常见的使用误区有哪些? | |
| 该组件是否需要特定的父组件、同级组件或provider才能正常运行? | 介绍部分标注或 |
| 是否有功能重叠的相关组件? | |
| 哪些prop和variant值得通过demo演示? | 参考下文的prop分级规则 |
不是每个组件都需要所有问题的答案,跳过不适用的问题即可。我们的目标不是只写描述「如何使用API」的文档,而是要告诉开发者「什么时候用、为什么用」。
Prop triage
Prop分级规则
Not every prop needs a demo section. Ask the user: "Which props should I document, and are there any variants or values with specific intended uses?"
If the user isn't available, read the component's TypeScript props and classify each:
| Tier | Document how | Examples |
|---|---|---|
| Core — defines the component's primary behavior or appearance | Full | |
| Modifier — adjusts a single aspect; values are self-explanatory | Brief mention with a demo, or a single combined demo with other modifiers | |
| Structural — controls layout or composition | Demo showing the before/after or compound usage | |
| Internal / pass-through — not user-facing | Skip entirely | |
For enum props specifically, always ask: "Does each value have a distinct intended meaning, or are they purely visual?" If distinct (e.g., means destructive, not just red), document the semantics — not just the visual difference.
danger不是每个prop都需要单独的演示章节。询问用户:「我应该记录哪些prop?有没有存在特定使用意图的variant或取值?」
如果联系不到用户,阅读组件的TypeScript prop定义并给每个prop分级:
| 分级 | 记录方式 | 示例 |
|---|---|---|
| 核心级 — 定义组件的核心行为或外观 | 完整的 | |
| 修饰级 — 调整单一方面,取值不言自明 | 简短提及加演示,或和其他修饰级prop合并为一个演示 | |
| 结构级 — 控制布局或组合 | 演示使用前后的效果或组合用法 | |
| 内部/透传级 — 不面向用户开放 | 完全跳过 | |
针对枚举类型prop,请务必确认:「每个取值是否有明确的预期含义,还是仅为视觉差异?」如果有明确语义(例如代表破坏性操作,而不只是红色),请记录语义含义,而不仅是视觉差异。
dangerStep 1: Locate the Component
第1步:定位组件
Find the component source file:
static/app/components/core/<category>/<component>/index.tsx
static/app/components/core/<category>/<component>/<component>.tsxRead the component file to understand:
- Props and their types
- Exported named variants and sub-components (e.g., ,
Component.SubComponent)export {TabList, TabPanels} - Available values for enum/union props
- Default prop values
The MDX file goes next to the component: .
<component-dir>/<component>.mdxIf the file already exists, read it first and update rather than overwrite.
Determining the import path:
- Components in are published as
static/app/components/core/@sentry/scraps/<name> - All other components use the sentry-internal path:
sentry/components/<path>
To confirm the exact package name and type-loader path, check an existing import in the component directory or a neighboring file — the type-loader path can be or depending on the package structure.
@sentry/scraps.mdx@sentry/scraps/<name>@sentry/scraps/<name>/<name>找到组件的源文件:
static/app/components/core/<category>/<component>/index.tsx
static/app/components/core/<category>/<component>/<component>.tsx阅读组件文件了解以下信息:
- Prop及其类型
- 导出的命名variant和子组件(例如:,
Component.SubComponent)export {TabList, TabPanels} - 枚举/联合类型prop的可用取值
- Prop默认值
MDX文件放在组件同级目录:。
<component-dir>/<component>.mdx如果文件已经存在,请先阅读现有内容再更新,不要直接覆盖。
确定导入路径:
- 目录下的组件发布为
static/app/components/core/@sentry/scraps/<name> - 其他所有组件使用Sentry内部路径:
sentry/components/<path>
要确认准确的 包名和type-loader路径,请查看组件目录下的现有导入或相邻的 文件——type-loader路径可能是 或 ,取决于包结构。
@sentry/scraps.mdx@sentry/scraps/<name>@sentry/scraps/<name>/<name>Step 2: Determine Frontmatter
第2步:配置Frontmatter
yaml
---
title: <ComponentName>
description: <One sentence describing what it is and its primary purpose.>
category: <category> # See category table below; omit for principle docs
source: '@sentry/scraps/<component>' # or 'sentry/<path>' for product components
resources:
figma: <figma-url> # Include if known
js: https://github.com/getsentry/sentry/blob/master/static/app/components/core/<path>
a11y: # Include for interactive components
WCAG 1.4.3: https://www.w3.org/TR/WCAG22/#contrast-minimum
WAI-ARIA <Pattern> Practices: https://www.w3.org/WAI/ARIA/apg/patterns/<pattern>/
---Category values:
| Category | Components |
|---|---|
| Button, ButtonBar, LinkButton |
| Input, Select, Checkbox, Radio, Slider, Switch |
| Tabs, SegmentedControl, Disclosure |
| Alert, Badge, Tag, Toast |
| Flex, Grid, Stack, Container, Surface |
| Text, Heading, Prose |
| design patterns, principles |
For principle/pattern docs (no interactive component), use instead of , and replace with under resources.
layout: documentcategorya11y:reference:yaml
---
title: <ComponentName>
description: <一句话描述组件是什么以及核心用途。>
category: <category> # 参考下方分类表;原则类文档省略此字段
source: '@sentry/scraps/<component>' # 业务组件填写 'sentry/<path>'
resources:
figma: <figma-url> # 已知的话请包含
js: https://github.com/getsentry/sentry/blob/master/static/app/components/core/<path>
a11y: # 交互组件请包含
WCAG 1.4.3: https://www.w3.org/TR/WCAG22/#contrast-minimum
WAI-ARIA <Pattern> Practices: https://www.w3.org/WAI/ARIA/apg/patterns/<pattern>/
---分类取值:
| 分类 | 对应组件 |
|---|---|
| Button, ButtonBar, LinkButton |
| Input, Select, Checkbox, Radio, Slider, Switch |
| Tabs, SegmentedControl, Disclosure |
| Alert, Badge, Tag, Toast |
| Flex, Grid, Stack, Container, Surface |
| Text, Heading, Prose |
| 设计模式、设计原则 |
对于原则/模式类文档(无交互组件),使用 替代 ,并把resources下的 替换为 。
layout: documentcategorya11y:reference:Step 3: Write Imports
第3步:编写导入语句
Follow this import order exactly:
jsx
// 1. External packages (react, etc.) — only if needed for examples
import {useState} from 'react';
// 5. Type-loader for auto-generated API docs (@sentry/scraps components only)
import documentation from '!!type-loader!@sentry/scraps/<component>';
// 3. @sentry/scraps component(s)
import {ComponentName} from '@sentry/scraps/<component>';
// 2. Sentry internals used in examples (icons, utils)
import {IconAdd, IconEdit} from 'sentry/icons';
// 4. Stories namespace (always last before type-loader)
import * as Storybook from 'sentry/stories';
export {documentation};Omit any group that isn't needed. For product components (not in ), omit the type-loader lines and document props manually in a table (see Step 5).
@sentry/scrapsComplex export: If the component exports need filtering (e.g., to hide internal exports), use the explicit form instead of :
export {documentation}jsx
import RawDocumentation from '!!type-loader!@sentry/scraps/<component>';
export const documentation = {
exports: RawDocumentation.exports,
props: {
...RawDocumentation?.props,
// Remove internal props if needed
},
};严格遵循以下导入顺序:
jsx
// 1. 外部包(react等)——仅示例需要时导入
import {useState} from 'react';
// 5. 自动生成API文档的type-loader(仅@sentry/scraps组件需要)
import documentation from '!!type-loader!@sentry/scraps/<component>';
// 3. @sentry/scraps组件
import {ComponentName} from '@sentry/scraps/<component>';
// 2. 示例中使用的Sentry内部资源(图标、工具函数)
import {IconAdd, IconEdit} from 'sentry/icons';
// 4. Stories命名空间(始终放在type-loader之前的最后一位)
import * as Storybook from 'sentry/stories';
export {documentation};省略不需要的分组。对于业务组件(不在 中),省略type-loader相关行,手动在表格中记录prop(参考第5步)。
@sentry/scraps复杂导出场景: 如果需要过滤组件导出内容(例如隐藏内部导出),请使用显式写法替代 :
export {documentation}jsx
import RawDocumentation from '!!type-loader!@sentry/scraps/<component>';
export const documentation = {
exports: RawDocumentation.exports,
props: {
...RawDocumentation?.props,
// 按需移除内部prop
},
};Step 4: Write Content
第4步:编写内容
Section structure
章节结构
Organize content by feature or user-facing variant, not by prop name:
- Introduction — 1-2 sentences, then a minimal usage code block (no demo wrapper)
- When to use (if the component has meaningful alternatives or misuse risk) — prose guidance, optionally a do/don't
<Storybook.SideBySide> - Feature sections — one per major feature:
##,## Sizes,## Priorities,## States## Composition - Accessibility — WCAG claims and developer responsibilities
- See Also — links to related components with one-line guidance (optional)
Prefer titles like , , over .
## Sizes## Variants## States## The size propWhen to use / See Also patterns:
mdx
undefined按功能或面向用户的variant组织内容,不要按prop名称组织:
- 介绍 — 1-2句话,然后是最简使用代码块(无demo包裹)
- 适用场景 (如果组件存在有意义的替代方案或误用风险) — 文字指引,可选搭配对错对比
<Storybook.SideBySide> - 功能章节 — 每个核心功能对应一个 章节:
##,## 尺寸,## 优先级,## 状态## 组合用法 - 无障碍 — WCAG合规说明和开发者责任
- 相关推荐 — 相关组件链接和简短适用指引(可选)
优先使用 、、 这类标题,不要用 这类标题。
## 尺寸## 变体## 状态## size prop适用场景/相关推荐写法示例:
mdx
undefinedWhen to use
适用场景
Use for inline feedback within a page. For application-level banners that span the full viewport, use the prop or reach for if the message is transient.
<Alert>system<Toast>[!WARNING] Do not usefor confirmation dialogs. Use a modal instead.<Alert variant="danger">
```mdx页面内的行内反馈请使用 。如果是占满整个视口的应用级横幅,请使用 prop;如果是临时提示消息,请使用 。
<Alert>system<Toast>[!WARNING] 确认对话框不要使用,请使用模态框替代。<Alert variant="danger">
```mdxSee Also
相关推荐
- LinkButton — use when the action navigates to a new URL
- Link — use for inline text navigation, not standalone CTAs
undefined- LinkButton — 动作是跳转到新URL时使用
- Link — 用于行内文本导航,不要用作独立CTA
undefinedIntroduction pattern
介绍写法示例
mdx
To create a basic <component>, wrap content in `<ComponentName>`.
```jsx
<ComponentName prop="value">Content</ComponentName>
```undefinedmdx
要创建基础的<component>,把内容包裹在 `<ComponentName>` 中即可。
```jsx
<ComponentName prop="value">Content</ComponentName>
```undefinedSub-components
子组件
When a component exposes sub-components, show the full compound usage early:
mdx
`<Tabs>` is a compound component. Use `<TabList>` and `<TabPanels>` together:
```jsx
<Tabs>
<TabList>
<TabList.Item key="tab1">Tab 1</TabList.Item>
</TabList>
<TabPanels>
<TabPanels.Item key="tab1">Content 1</TabPanels.Item>
</TabPanels>
</Tabs>undefined如果组件暴露了子组件,请尽早展示完整的组合用法:
mdx
`<Tabs>` 是组合组件,需要配合 `<TabList>` 和 `<TabPanels>` 一起使用:
```jsx
<Tabs>
<TabList>
<TabList.Item key="tab1">Tab 1</TabList.Item>
</TabList>
<TabPanels>
<TabPanels.Item key="tab1">Content 1</TabPanels.Item>
</TabPanels>
</Tabs>undefinedDemo pattern
Demo写法示例
Every feature section must have a followed immediately by the matching code block:
<Storybook.Demo>mdx
undefined每个功能章节必须包含一个 ,紧接着是对应的代码块:
<Storybook.Demo>mdx
undefinedSizes
尺寸
<brief description>
<Storybook.Demo>
<Component size="sm">Small</Component>
<Component size="md">Medium</Component>
<Component size="lg">Large</Component>
</Storybook.Demo>
jsx
<Component size="sm">Small</Component>
<Component size="md">Medium</Component>
<Component size="lg">Large</Component>
**Demo layout helpers:**
| Component | Use when |
|-----------|----------|
| `<Storybook.Demo>` | Default; horizontally arranges examples |
| `<Storybook.Grid>` | Grid layout for many variants |
| `<Storybook.SideBySide>` | Two-column comparisons (do/don't) |
| `<Storybook.TokenReference>` | Displaying design tokens (spacing, color, etc.) |
| `<Storybook.ColorReference>` | Displaying color tokens specifically |<简短说明>
<Storybook.Demo>
<Component size="sm">Small</Component>
<Component size="md">Medium</Component>
<Component size="lg">Large</Component>
</Storybook.Demo>
jsx
<Component size="sm">Small</Component>
<Component size="md">Medium</Component>
<Component size="lg">Large</Component>
**Demo布局辅助组件:**
| 组件 | 适用场景 |
|-----------|----------|
| `<Storybook.Demo>` | 默认;水平排列示例 |
| `<Storybook.Grid>` | 大量variant的网格布局 |
| `<Storybook.SideBySide>` | 两列对比(对错示例) |
| `<Storybook.TokenReference>` | 展示设计token(间距、颜色等) |
| `<Storybook.ColorReference>` | 专门展示颜色token |Accessibility section
无障碍章节
mdx
undefinedmdx
undefinedAccessibility
无障碍
This component meets WCAG 2.2 AA standards:
- Color contrast: Meets 4.5:1 ratio (WCAG 1.4.3)
- Keyboard navigation: <what interactions are supported>
- Screen reader support: <ARIA role and labeling behavior>
本组件符合 WCAG 2.2 AA 标准:
- 色彩对比度:符合4.5:1对比度要求(WCAG 1.4.3)
- 键盘导航:<支持的交互操作说明>
- 屏幕阅读器支持:<ARIA role和标记行为说明>
Developer responsibilities
开发者责任
- Always provide <required accessible prop> (e.g., or visible label text)
aria-label - <other requirement>
undefined- 始终提供<必填无障碍prop>(例如:或可见的标签文本)
aria-label - <其他要求>
undefinedCallout syntax
提示框语法
mdx
> [!TIP]
> Use the `<prop>` prop when you need <use case>.
> [!WARNING]
> Avoid <pattern> because <reason>.
> [!NOTE]
>
> <Additional context.>mdx
> [!TIP]
> 当你需要<使用场景>时,可以使用 `<prop>` prop。
> [!WARNING]
> 避免<模式>,因为<原因>。
> [!NOTE]
>
> <额外上下文说明。>Step 5: Props Table (product components only)
第5步:Prop表格(仅业务组件需要)
For components not in , list props manually instead of using the type-loader:
@sentry/scrapsmdx
undefined对于不在 中的组件,手动列出prop,不要使用type-loader:
@sentry/scrapsmdx
undefinedProps
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| | | Controls the visual style |
| | | Controls the size |
undefined| Prop | Type | Default | Description |
|---|---|---|---|
| | | 控制视觉样式 |
| | | 控制尺寸 |
undefinedComplete Example
完整示例
mdx
---
title: Alert
description: Alerts provide contextual feedback messages with different severity levels.
category: status
source: '@sentry/scraps/alert'
resources:
js: https://github.com/getsentry/sentry/blob/master/static/app/components/core/alert/index.tsx
a11y:
WCAG 1.4.3: https://www.w3.org/TR/WCAG22/#contrast-minimum
WCAG 2.1.1: https://www.w3.org/TR/WCAG22/#keyboard
WAI-ARIA Alert Pattern: https://www.w3.org/WAI/ARIA/apg/patterns/alert/
---
import {Alert} from '@sentry/scraps/alert';
import * as Storybook from 'sentry/stories';
import documentation from '!!type-loader!@sentry/scraps/alert';
export {documentation};
To create a basic alert, wrap a message in `<Alert>` and specify the appropriate type.
```jsx
<Alert variant="info">This is an informational message</Alert>
```mdx
---
title: Alert
description: Alert提供不同 severity 级别的上下文反馈消息。
category: status
source: '@sentry/scraps/alert'
resources:
js: https://github.com/getsentry/sentry/blob/master/static/app/components/core/alert/index.tsx
a11y:
WCAG 1.4.3: https://www.w3.org/TR/WCAG22/#contrast-minimum
WCAG 2.1.1: https://www.w3.org/TR/WCAG22/#keyboard
WAI-ARIA Alert Pattern: https://www.w3.org/WAI/ARIA/apg/patterns/alert/
---
import {Alert} from '@sentry/scraps/alert';
import * as Storybook from 'sentry/stories';
import documentation from '!!type-loader!@sentry/scraps/alert';
export {documentation};
要创建基础的alert,把消息包裹在 `<Alert>` 中并指定对应类型即可。
```jsx
<Alert variant="info">This is an informational message</Alert>
```Types
类型
Alerts come in five types: , , , , and .
mutedinfowarningsuccessdanger<Storybook.Demo>
<Alert.Container>
<Alert variant="muted">Muted</Alert>
<Alert variant="info">Info</Alert>
<Alert variant="warning">Warning</Alert>
<Alert variant="success">Success</Alert>
<Alert variant="danger">Danger</Alert>
</Alert.Container>
</Storybook.Demo>
jsx
<Alert.Container>
<Alert variant="muted">Muted</Alert>
<Alert variant="info">Info</Alert>
<Alert variant="warning">Warning</Alert>
<Alert variant="success">Success</Alert>
<Alert variant="danger">Danger</Alert>
</Alert.Container>Alert有五种类型:、、、 和 。
mutedinfowarningsuccessdanger<Storybook.Demo>
<Alert.Container>
<Alert variant="muted">Muted</Alert>
<Alert variant="info">Info</Alert>
<Alert variant="warning">Warning</Alert>
<Alert variant="success">Success</Alert>
<Alert variant="danger">Danger</Alert>
</Alert.Container>
</Storybook.Demo>
jsx
<Alert.Container>
<Alert variant="muted">Muted</Alert>
<Alert variant="info">Info</Alert>
<Alert variant="warning">Warning</Alert>
<Alert variant="success">Success</Alert>
<Alert variant="danger">Danger</Alert>
</Alert.Container>Accessibility
无障碍
This component meets WCAG 2.2 AA standards:
- Color contrast: All variants meet 4.5:1 ratio (WCAG 1.4.3)
- Keyboard accessible: Fully operable via keyboard (WCAG 2.1.1)
undefinedChecklist
检查清单
Before completing, verify:
- MDX file is colocated next to the component source file (named )
<component>.mdx - Frontmatter has ,
title, anddescriptionsource - Imports follow the correct order (external → icons/utils → @sentry/scraps → Storybook → type-loader)
- Type-loader import is included for components
@sentry/scraps - Every is immediately followed by a matching code block
<Storybook.Demo> - Sections are organized by feature/variant, not by prop name
- Sub-components are documented with compound usage examples
- Accessibility section covers WCAG compliance and developer responsibilities
- No raw tags (use
<img>), no inline SVGs, no styled components<Image>
完成前请确认:
- MDX文件和组件源文件放在同一目录(命名为 )
<component>.mdx - Frontmatter包含 、
title和descriptionsource - 导入语句遵循正确顺序(外部包 → 图标/工具函数 → @sentry/scraps → Storybook → type-loader)
- 组件包含了type-loader导入
@sentry/scraps - 每个 后面紧接着对应的代码块
<Storybook.Demo> - 章节按功能/variant组织,而非按prop名称组织
- 子组件配有组合用法示例
- 无障碍章节包含WCAG合规说明和开发者责任
- 没有原生 标签(使用
<img>)、没有内联SVG、没有styled components<Image>