按钮

按钮就是人点下去让某件事发生的那个东西。button() 渲染的是真正的 <button>,并带上 type="button",所以把它放进表单里也不会误触提交。

基础按钮

默认是实心、primary、中等尺寸。子元素就是文字,其余都是属性。

stack({ direction: 'row', gap: 'md' },
  button('一'),
  button('二'),
  button('三'),
)

变体

五个强调级别,从页面上唯一的行动号召,一路降到读起来像链接的那种。

stack({ direction: 'row', gap: 'md', wrap: true },
  button({ variant: 'solid' }, 'Solid'),
  button({ variant: 'soft' }, 'Soft'),
  button({ variant: 'outline' }, 'Outline'),
  button({ variant: 'ghost' }, 'Ghost'),
  button({ variant: 'link' }, 'Link'),
)

颜色

所有带主题的组件都取自同样的五套配色,所以 color: 'danger' 的按钮和 color: 'danger' 的提示天然一致,彼此并不需要知道对方的存在。

stack({ direction: 'row', gap: 'md', wrap: true },
  button({ color: 'primary' }, 'Primary'),
  button({ color: 'neutral' }, 'Neutral'),
  button({ color: 'success' }, 'Success'),
  button({ color: 'warning' }, 'Warning'),
  button({ color: 'danger' }, 'Danger'),
)
stack({ direction: 'row', gap: 'md', wrap: true },
  button({ variant: 'soft', color: 'primary' }, 'Primary'),
  button({ variant: 'soft', color: 'neutral' }, 'Neutral'),
  button({ variant: 'soft', color: 'success' }, 'Success'),
  button({ variant: 'soft', color: 'warning' }, 'Warning'),
  button({ variant: 'soft', color: 'danger' }, 'Danger'),
)

尺寸

stack({ direction: 'row', gap: 'md', align: 'center', wrap: true },
  button({ size: 'sm' }, '小'),
  button({ size: 'md' }, '中'),
  button({ size: 'lg' }, '大'),
)

图标

把任意 SVG 标记传给 startIcon 或 endIcon。图标按 em 定尺寸,所以跟着按钮一起缩放,不必单独设定大小。

stack({ direction: 'row', gap: 'md', wrap: true },
  button({
    startIcon: icon('plus'),
  }, '新建页面'),
  button({
    variant: 'outline',
    endIcon: icon('arrow-right'),
  }, '继续'),
)

图标按钮

iconButton() 是只放一个图标的方形按钮。它的 label 是必填的——它既是图标本身给不了的无障碍名称,也是悬停时的提示。

stack({ direction: 'row', gap: 'md' },
  iconButton({ label: '添加', icon: icon('plus') }),
  iconButton({ label: '编辑', variant: 'soft', icon: icon('edit') }),
  iconButton({ label: '删除', variant: 'ghost', color: 'danger', icon: icon('trash') }),
)

加载中与禁用

loading 会换上一个加载转圈并设置 aria-busy,同时保留文字,这样按钮不会在操作途中改变宽度。

stack({ direction: 'row', gap: 'md', wrap: true },
  button({ loading: true }, '保存中'),
  button({ variant: 'outline', loading: true }, '检查中'),
  button({ disabled: true }, '已禁用'),
  button({ variant: 'soft', disabled: true }, '已禁用'),
)

链接

给按钮一个 href,它就会改渲染成 <a>——跳转本就该用这个元素。锚点没有禁用状态,所以 disabled 会变成 aria-disabled,并把它移出 Tab 顺序。

stack({ direction: 'row', gap: 'md', wrap: true },
  button({ href: '/zh/docs' }, '阅读文档'),
  button({ href: '/zh/docs/ui', variant: 'outline' }, '组件'),
  button({ href: '/zh/docs', variant: 'link' }, '普通链接'),
)

通栏宽度

button({ block: true, size: 'lg' }, '部署站点')

属性

这里没列出的一切都会作为属性落到渲染出的元素上——id、data-*、onclick、popovertarget 等等。

属性类型默认值说明
variant'solid' | 'soft' | 'outline' | 'ghost' | 'link''solid'按钮的强调程度。
color'primary' | 'neutral' | 'success' | 'warning' | 'danger''primary'取用哪一套配色。
size'sm' | 'md' | 'lg''md'高度、内边距和文字大小。
hrefstring—渲染 <a> 而不是 <button>。
startIconstring—放在文字前面的标记。
endIconstring—放在文字后面的标记。
loadingbooleanfalse显示加载转圈并设置 aria-busy。
disabledbooleanfalse禁用按钮,或把链接标记为 aria-disabled。
blockbooleanfalse撑满容器宽度。
type'button' | 'submit' | 'reset''button'仅对 <button> 形态有效。

iconButton() 接受同样的属性,外加必填的 label 和一个 icon。