Button Skills
本说明给 AI 使用目标是快速判断该用哪个按钮、参数怎么传、哪些样式可以通过 className 定制、哪些属于组件内强约束
设计原则
- 优先使用现有按钮组件, 不要为业务页面随手新造按钮
- 按钮差异优先通过
variant、className、宽度、图标、文案表达 GradientButton偏 CTA 和链接XButton偏业务动作和下拉动作XToggleButton偏单选切换, 不负责渲染切换后的内容面板- 图标优先使用全局 icon;图标沉淀见 global-icon skills
- 文案必须表达真实动作, 不要全部写成
Submit或Confirm
组件选择
| 需求 | 推荐组件 |
|---|---|
| 单个业务操作按钮 | XButton type="single" |
| 主操作 + 更多操作 | XButton type="split" |
| 页面 CTA、跳转按钮、营销按钮 | GradientButton |
| 看起来像按钮的链接 | GradientButton with href |
| 单选切换、计费周期、视图模式切换 | XToggleButton |
| 胶囊选择、筛选、多选、token 输入 | 见 select.skills.md |
什么时候不要用 GB / XB
GradientButton 和 XButton 是页面级操作按钮, 不是所有可点击元素都要套它们
下面场景应该优先写原生 button, 并按局部 UI 自己控制样式:
- 弹窗内部按钮: 使用弹窗组件自带按钮语义, 不在弹窗 footer 里再套
GradientButton或XButton - 表格行内小操作: 例如行内编辑、展开、更多、删除图标按钮
- 工具栏里的纯 icon 控件: 例如加粗、撤销、关闭、排序、折叠
- 自定义组合控件内部: 例如 slider handle、tab item、segmented item、menu item、dropdown item
- 很小的局部交互: 例如卡片右上角关闭、清除输入、移除 token
- 需要完全贴合父组件尺寸和状态机的按钮: 例如复杂表单控件、canvas 工具、编辑器工具
判断标准:
- 如果它是页面上的独立业务动作, 用
XButton或GradientButton - 如果它是某个组件内部结构的一部分, 用原生
button - 如果它的尺寸、焦点、hover、disabled、aria 状态必须和父组件强绑定, 用原生
button - 如果它只是图标级控制, 不要为了统一而强行套完整按钮组件
原生按钮也必须满足:
- 有明确
type="button" - 有可访问名称, 纯 icon 按钮必须有
aria-label或 tooltip - 有
focus-visible样式 - disabled 态不能只靠颜色表达
- 点击区域不能过小
共同视觉规则
- 默认使用圆角胶囊
- 默认按钮应保持清晰点击目标, 不要把核心操作做得过小
- 一组按钮中只允许一个主视觉重点, 其他按钮用
soft或subtle - 危险操作不要用主题渐变伪装成普通主按钮;应使用红色边框、红色文本或弹窗危险语义
- 如果按钮文字较长, 设置稳定
minWidth/maxWidth, 不要让布局因为状态变化跳动
GradientButton
适用场景:
- Landing 或页面 CTA
- 强调型链接
- 需要默认箭头图标或 loading 防重复点击
- 想要主题渐变、主题 soft、浅色 subtle 三种层级
核心参数:
title: 按钮文字href: 有跳转时传onClick: 有点击逻辑时传variant:'default' | 'soft' | 'subtle'icon: 覆盖默认图标iconForcePosition: 强制图标左右位置preventDoubleClick: 默认开启, 点击后会进入 loading, 避免重复点击pressFeedback: 需要按压反馈时使用, 常见值为solid或关闭反馈
使用指导:
- 有
href且不需要复杂业务动作时, 用它做链接按钮 - 有
onClick且需要防重复点击时, 也可以使用它 - 普通后台操作更推荐
XButton, 不要所有按钮都做成渐变 CTA className可以覆盖宽度、边框、颜色、hover、圆角、字号
<GradientButton
title="Start Now"
href="/pricing"
variant="default"
/><GradientButton
title="Create"
variant="soft"
icon={<SparklesIcon />}
onClick={handleCreate}
/>XButton Single
适用场景:
- 页面里的普通业务操作
- 工具栏按钮
- 图标 + 文案按钮
- subtle/soft 层级按钮
核心参数:
type="single"button.icon: 按钮图标button.text: 按钮文字button.onClick: 点击回调button.disabled: 禁用态variant:'default' | 'soft' | 'subtle'minWidth: 稳定最小宽度className: 按钮本体样式pressFeedback: 按压反馈
使用指导:
- 业务操作默认从
XButton single开始 - 如果只是低强调操作, 使用
variant="subtle" - 如果按钮需要更安静但仍有主题感, 使用
variant="soft" - 多个并排按钮时, 设置
minWidth="min-w-0"或稳定宽度, 避免过宽 - 图标按钮也优先用
XButton single, 传短文本或空文本前先确认可访问性
<XButton
type="single"
variant="subtle"
minWidth="min-w-0"
button={{
icon: <DownloadIcon />,
text: 'Export',
onClick: handleExport,
}}
/>XButton Split
适用场景:
- 左侧是主动作, 右侧是更多动作
- 同一对象有多个相关操作
- 需要把低频操作收进菜单
核心参数:
type="split"mainButton: 主按钮配置menuItems: 下拉菜单项menuWidth: 下拉菜单宽度mainButtonClassName: 左侧按钮样式dropdownButtonClassName: 右侧触发按钮样式pressFeedback: 主按钮和 dropdown trigger 的按压反馈
菜单项支持:
icontextonClickdisabledtagsplitTopBorder
使用指导:
- 主动作必须是最常用、最安全、最明确的动作
- 危险或低频动作放在菜单里, 并可用
splitTopBorder做分隔 - 如果菜单项需要复杂样式或二级菜单, 当前
XButton split不适合, 应该评估新组件或扩展源码 - 不要把 split 当普通双按钮使用;它表达的是“主动作 + 更多操作”
<XButton
type="split"
mainButton={{
icon: <RocketIcon />,
text: 'Publish',
onClick: handlePublish,
}}
menuItems={[
{ icon: <ClockIcon />, text: 'Schedule', onClick: handleSchedule },
{ icon: <ArchiveIcon />, text: 'Archive', onClick: handleArchive, splitTopBorder: true },
]}
/>XToggleButton
适用场景:
- 计费周期切换
- 视图模式切换
- tabs-like 单选切换
- 状态密度不高的一组选项
核心参数:
options: 切换项数组value/defaultValue: 受控或非受控选中值onChange: 切换回调size:'default' | 'compact'fullWidth: 整组铺满ariaLabel: 没有可见 label 时应传mobileIcon: 移动端显示图标badge: 选中项可显示 floating badge
使用指导:
XToggleButton只做单选, 不做多选- 下方内容由业务根据
value自己渲染 - 文本长时配置
minItemWidthClassName、maxItemWidthClassName、itemTextClassName - 移动端空间紧张时, 用
mobileIcon, 同时收紧 padding 和宽度 - 不要用它替代真正的表单 select 或多选筛选
<XToggleButton
value={billingCycle}
onChange={setBillingCycle}
ariaLabel="Billing cycle"
options={[
{ value: 'monthly', label: 'Monthly' },
{ value: 'yearly', label: 'Yearly', badge: 'Save 20%' },
]}
/><XToggleButton
value={viewMode}
onChange={setViewMode}
size="compact"
itemPaddingClassName="px-1.5 py-1 sm:px-3 sm:py-2"
minItemWidthClassName="min-w-[48px] sm:min-w-[100px]"
maxItemWidthClassName="max-w-[60px] sm:max-w-[160px]"
options={[
{ value: 'grid', label: 'Grid', mobileIcon: <GridIcon className="h-4 w-4" /> },
{ value: 'list', label: 'List', mobileIcon: <ListIcon className="h-4 w-4" /> },
]}
/>AI 判断 Checklist
- 是单个业务动作吗?优先
XButton single - 是页面主 CTA 或链接吗?优先
GradientButton - 是主动作加更多动作吗?用
XButton split - 是单选切换吗?用
XToggleButton - 是筛选、表单胶囊、多选或 token 输入吗?去看
select.skills.md - 只是换颜色、宽度、hover、边框吗?先用 props/className, 不要改源码
- 交互结构变了、菜单项需要复杂内容、需要多选 toggle 时, 才考虑扩展组件