Button 按钮
Button 把操作的语义类型和视觉层级分开。同一套 API 在 Brutal 和 Elegant 主题下行为完全一致,只是外观不同。ButtonGroup 把相关的操作连成一组,可以统一尺寸,但不改变每个按钮的语义类型。
演示
每种行为都是单独的 TSX 示例和预览,看某一节的源码时不用翻一整页无关的代码。
类型与层级
对比八种语义类型在 solid、secondary、tertiary、quaternary 四个层级下的样子。
尺寸与形状
tiny、small、medium、large 严格对应 22 / 28 / 34 / 40px 的高度。round 和 circle 是独立的形状控制。
外观
ghost、dashed、text、borderless、strong 和 block 共用同一套语义类型 API。多个层级开关同时设置时,按固定的优先级决定最终外观。
图标
可以传 React 节点或渲染函数,图标放左边或右边,也可以做只有图标的按钮。
发送操作
type="accent" 是操作色,也就是 rUI 的粉色,用在一个界面就是为它而存在的那个操作上,比如发送消息。在输入框里按回车即可发送。
加载与禁用
加载状态使用 Raft UI 的 Spinner,保留文字和焦点,同时阻止鼠标和键盘触发,但不设置原生的 disabled 属性。计数器可以直接看到输入被拦下。
自定义颜色
为个别产品需求覆盖语义填充色和文字色。
标签、焦点与键盘
渲染成原生链接或自定义元素,控制是否参与 Tab 导航和键盘触发,兼容 Safari 点击后的焦点,并显式指定原生表单类型。
按钮组
按钮组把相邻的操作连在一起,提供统一尺寸,支持横向和竖向排列,但不接管语义类型。
Props
Button
| 名称 | 类型 | 默认值 | 说明 | 版本 |
|---|---|---|---|---|
type | default | tertiary | primary | accent | info | success | warning | error | default | 设置语义意图和对应的颜色。这里的 tertiary 是中性的语义类型,不是层级 prop。 | 未发布 |
secondary | boolean | false | 使用该语义颜色的浅色底。 | 未发布 |
tertiary | boolean | false | 使用安静的中性底,文字保留语义颜色。 | 未发布 |
quaternary | boolean | false | 常态不显示容器,保留悬停和聚焦反馈。 | 未发布 |
ghost | boolean | false | 透明底,带语义颜色的边框。 | 未发布 |
dashed | boolean | false | ghost 的样式,边框改为虚线。 | 未发布 |
text | boolean | false | 去掉按钮外框,只留文字。 | 未发布 |
bordered | boolean | true | 当前外观是否显示边框。没有边框的按钮是平的,没有阴影。 | 未发布 |
color | string | undefined | 覆盖语义颜色,并由它推导悬停、按下、浅色底和波纹颜色。浅色的十六进制或 rgb() 颜色在实心填充上用深色文字,保证文字满足 AA 对比度。 | 未发布 |
textColor | string | undefined | 覆盖所有状态下的文字和图标颜色。 | 未发布 |
size | tiny | small | medium | large | medium | 设置高度、内边距、字号、图标尺寸和圆角。高度为 22 / 28 / 34 / 40px。 | 未发布 |
loading | boolean | false | 保持可聚焦、文字可见,把图标位置换成 Spinner,标记为忙碌,并阻止鼠标和键盘触发。 | 未发布 |
loadingLabel | string | 语言包里的“加载中” | Spinner 的无障碍名称。不传时取 ConfigProvider 当前语言包里的文案。 | 未发布 |
spinProps | Omit<SpinnerProps, "aria-label" | "role"> | undefined | 转发给 Spinner 的选项,比如 size、variant 和原生 span 属性;加载状态的无障碍名称仍由 Button 负责。 | 未发布 |
disabled | boolean | false | 禁止聚焦和触发。换成其他标签时使用等价的 ARIA 和事件处理。 | 未发布 |
focusable | boolean | true | 是否参与焦点导航。 | 未发布 |
keyboard | boolean | true | 是否响应 Enter 和空格触发,鼠标点击不受影响。 | 未发布 |
nativeFocusBehavior | boolean | 取决于浏览器 | 浏览器支持时使用原生的点击聚焦,否则用兼容 Safari 且不滚动页面的方式聚焦。 | 未发布 |
tag | React.ElementType | button | 渲染成其他元素(比如链接),并保留对应的原生 props 和 ref。 | 未发布 |
block | boolean | false | 占满可用宽度。 | 未发布 |
icon | ReactNode | undefined | 装饰性图标。只有图标的按钮要加 aria-label。 | 未发布 |
renderIcon | () => ReactNode | undefined | 渲染函数。和 icon 同时传时优先;加载时图标位置归 Spinner,不会调用它。 | 未发布 |
iconPlacement | left | right | left | 图标放在文字前面还是后面。 | 未发布 |
round | boolean | false | 胶囊形。 | 未发布 |
circle | boolean | false | 正圆形,用于只有图标的操作。 | 未发布 |
strong | boolean | false | 使用主题的加粗字重:Brutal 700、Elegant 500,默认分别是 500 和 400。 | 未发布 |
attrType | button | submit | reset | button | 原生 button 的 type 属性。 | 未发布 |
secondary、tertiary、quaternary、ghost、dashed、text 都是独立的布尔值。同时设置多个时按这个顺序生效:text → dashed → ghost → secondary → tertiary → quaternary → solid。原生属性、事件和 ref 的类型由 tag 推导;原生表单行为用 attrType。Button 和 ButtonGroup 的全部公开类型都在组件的 public-types.ts 里。加载状态使用公开的 Spinner:Brutal 是硬边的圆环,Elegant 是两层圆的 SVG 弧线,Button 负责保留文字并阻止触发。点击波纹只属于 Elegant,Brutal 里刻意没有;secondary、tertiary、quaternary 这些安静的外观也不显示波纹。
ButtonGroup
| 名称 | 类型 | 默认值 | 说明 | 版本 |
|---|---|---|---|---|
size | tiny | small | medium | large | undefined | 统一尺寸,覆盖组内按钮自己的尺寸。 | 未发布 |
vertical | boolean | false | 竖向排列。 | 未发布 |
ButtonGroup 支持原生 div 属性和 ref。请用 aria-label 或 aria-labelledby 给每个按钮组一个无障碍名称。