跳到主要内容

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/DefaultGrays/Tinted/Emphasized),而非文字按钮的 Gray 系列。
  • Quaternary:移除背景反馈,仅通过 icon 颜色变化体现交互——Default Labels/Tertiary → Hover Labels/Primary → Clicked Labels/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>
维度LargeMediumSmallIcon Only
高度48px40px32px28px
最小宽度100px100px70px28px
水平内边距24px24px16px0
圆角5px5px5px5px

Props

属性类型默认值说明
childrenReactNode-按钮内容
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
loadingbooleanfalse加载状态,显示 Spinner 并禁用交互
disabledbooleanfalse禁用状态
onClickMouseEventHandler-点击回调
aria-labelstring-无障碍标签,size="icon" 时必填