Button
- 组件说明:Primary 按钮用于页面的单一主要操作,独立使用,不与其他按钮并列。
- 尺寸基线:Small=32px、Medium=40px、Large=48px、Icon Only=28px。
- 实现约定:
ui/button只保留结构骨架,design 层统一接管全部视觉 token。 - Figma 规范
变体
8 种视觉变体,适配不同语义层级。
结果
Loading...
实时编辑器
<div style={{ display: 'flex', gap: 12, flexWrap: 'wrap', alignItems: 'center' }}> <Button variant="primary">Primary</Button> <Button variant="secondary">Secondary</Button> <Button variant="tertiary">Tertiary</Button> <Button variant="quaternary">Quaternary</Button> <Button variant="destructive">Destructive</Button> <Button variant="destructive-outline">Destructive Outline</Button> <Button variant="link-color">Link Color</Button> <Button variant="link-gray">Link Gray</Button> </div>
| 样式 | 说明 |
|---|---|
| Primary | 实心深色背景 + 反白文字,强调主操作 |
| Secondary | 白色背景带边框,次于 Primary |
| Tertiary | 透明无边框,hover 显示次级背景色 |
| Quaternary | 透明无边框,hover 显示 tinted 灰色背景,视觉最轻 |
| Destructive | 错误色实心背景,强调危险操作 |
| Destructive Outline | 错误色描边 + 错误色文字,危险操作的弱强调态 |
| Link Color | 品牌色文本链接样式 |
| Link Gray | 灰色文本链接样式,hover 变为主色 |
状态
5 种交互状态:Default / Hover / Clicked / Loading / Disabled。
结果
Loading...
实时编辑器
<div style={{ display: 'flex', gap: 16, flexWrap: 'wrap', alignItems: 'center' }}> <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 8 }}> <span style={{ fontSize: 12, color: '#999' }}>Default</span> <Button>Button</Button> </div> <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 8 }}> <span style={{ fontSize: 12, color: '#999' }}>Hover</span> <Button className="bg-[var(--Labels-Secondary)]">Button</Button> </div> <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 8 }}> <span style={{ fontSize: 12, color: '#999' }}>Clicked</span> <Button className="bg-[var(--Labels-Secondary)]">Button</Button> </div> <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 8 }}> <span style={{ fontSize: 12, color: '#999' }}>Loading</span> <Button loading>Button</Button> </div> <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 8 }}> <span style={{ fontSize: 12, color: '#999' }}>Disabled</span> <Button disabled>Button</Button> </div> </div>
Loading 状态
loading 属性会自动禁用按钮并显示内置 Spinner。所有变体均支持。
结果
Loading...
实时编辑器
<div style={{ display: 'flex', gap: 12, flexWrap: 'wrap', alignItems: 'center' }}> <Button variant="primary" loading> Primary </Button> <Button variant="secondary" loading> Secondary </Button> <Button variant="tertiary" loading> Tertiary </Button> <Button variant="quaternary" loading> Quaternary </Button> <Button variant="destructive" loading> Destructive </Button> <Button variant="destructive-outline" loading> Outline </Button> <Button variant="link-color" loading> Link Color </Button> <Button variant="link-gray" loading> Link Gray </Button> </div>
图标按钮
size="icon" 时渲染为 28×28 方形,必须设置 aria-label 以保证无障碍。
结果
Loading...
实时编辑器
<div style={{ display: 'flex', gap: 12, alignItems: 'center', flexWrap: 'wrap' }}> <Button size="icon" variant="primary" aria-label="Add"> <Plus size={16} /> </Button> <Button size="icon" variant="secondary" aria-label="Add"> <Plus size={16} /> </Button> <Button size="icon" variant="tertiary" aria-label="Add"> <Plus size={16} /> </Button> <Button size="icon" variant="quaternary" aria-label="Add"> <Plus size={16} /> </Button> <Button size="icon" variant="destructive" aria-label="Add"> <Plus size={16} /> </Button> <Button size="icon" variant="destructive-outline" aria-label="Add"> <Plus size={16} /> </Button> <Button size="icon" variant="link-color" aria-label="Add"> <Plus size={16} /> </Button> <Button size="icon" variant="link-gray" aria-label="Add"> <Plus size={16} /> </Button> </div>
Icon Only 的 Tertiary / Quaternary 交互反馈与文字按钮不同:
- Tertiary:Hover / Clicked 背景使用 Tinted 系列(
Grays/Tinted/Default、Grays/Tinted/Emphasized),而非文字按钮的 Gray 系列。 - Quaternary:移除背景反馈,仅通过 icon 颜色变化体现交互——Default
Labels/Tertiary→ HoverLabels/Primary→ ClickedLabels/Secondary。
尺寸规范
结果
Loading...
实时编辑器
<div style={{ display: 'flex', alignItems: 'flex-end', gap: 24 }}> <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 8 }}> <Button variant="secondary" size="lg"> Large </Button> <span style={{ fontSize: 12, color: '#999' }}>48px</span> </div> <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 8 }}> <Button variant="secondary" size="default"> Medium </Button> <span style={{ fontSize: 12, color: '#999' }}>40px</span> </div> <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 8 }}> <Button variant="secondary" size="sm"> Small </Button> <span style={{ fontSize: 12, color: '#999' }}>32px</span> </div> <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 8 }}> <Button variant="secondary" size="icon" aria-label="Add"> <Plus size={16} /> </Button> <span style={{ fontSize: 12, color: '#999' }}>28px</span> </div> </div>
| 维度 | Large | Medium | Small | Icon Only |
|---|---|---|---|---|
| 高度 | 48px | 40px | 32px | 28px |
| 最小宽度 | 100px | 100px | 70px | 28px |
| 水平内边距 | 24px | 24px | 16px | 0 |
| 圆角 | 5px | 5px | 5px | 5px |
Props
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
children | ReactNode | - | 按钮内容 |
variant | 'primary' | 'secondary' | 'tertiary' | 'quaternary' | 'destructive' | 'destructive-outline' | 'link-color' | 'link-gray' | 'primary' | 视觉变体 |
size | 'default' | 'sm' | 'lg' | 'icon' | 'default' | 尺寸:sm=32px、default=40px、lg=48px、icon=28px |
loading | boolean | false | 加载状态,显示 Spinner 并禁用交互 |
disabled | boolean | false | 禁用状态 |
onClick | MouseEventHandler | - | 点击回调 |
aria-label | string | - | 无障碍标签,size="icon" 时必填 |