跳转到内容

Button 按钮 ​

用于触发即时操作。

用法 ​

触发一次操作

组件结构 ​

加粗的是必需部件。

data-scope="button":root · label · indicator · prefix · suffix

示例 ​

变体 ​

设置按钮外观

尺寸 ​

小、中、大三档

图标 ​

在文字前后放置图标

仅图标 ​

紧凑的图标操作

加载 ​

保留按钮标签并阻止重复操作

异步操作 ​

点击后显示加载状态

全宽 ​

占满容器宽度

禁用 ​

暂时不可执行的操作

链接 ​

保留原生导航能力

设计指引 ​

何时使用 ​

  • 提交表单或执行命令。
  • 打开菜单、对话框等浮层。
  • 需要明确主次关系的一组操作。

何时不用 ​

特性 ​

  • 支持四种变体、六种颜色和三种尺寸。
  • 缺省变体是品牌实心 solid,这是按钮独有的缺省;其余触发器缺省中性。
  • 支持文字、图标、图标加文字与全宽按钮。
  • loading 保留焦点并阻止重复操作。
  • as="a" 保留原生链接能力。
  • 应用设为 data-material="liquid" 时,实心按钮在细指针悬停的一刻有一道光沿描边扫过一次;光只走描边、不进面,文字对比不受影响。粗指针、减弱动效与强制色下不播。

组合 ​

  • 使用 prefix 与 suffix 放置图标。
  • 使用 indicator 提供加载图形。
  • 使用按钮组组合相关操作。

最佳实践 ​

  • 每个视图只保留一个主要操作。
  • 图标按钮必须提供 aria-label。
  • 加载时保留原有标签,避免按钮宽度变化。

反模式 ​

  • 不要使用按钮模拟普通链接。
  • 不要在按钮中嵌套可聚焦元素。

API 参考 ​

产物 ​

层值
自定义元素<xh-button>
Vue 组件XhButton XhButtonIndicator XhButtonLabel XhButtonPrefix XhButtonSuffix
状态机buttonMachine
皮肤@xihan-ui/styles/button.css

Props ​

属性类型必填说明
type'button' | 'submit' | 'reset'
disabledboolean
loadingboolean加载态:用 aria-disabled + 拦截事件表达,保留焦点。
variantActionVariant变体:solid / subtle / outline / ghost,默认 solid——只有 Button 缺省品牌实心,其余触发器缺省中性。
toneTone颜色:brand / neutral / success / warning / danger / info。
sizeSize
iconOnlyboolean仅图标:左右内边距清零、宽高相等。宽度跟随当前尺寸档的高度, 不必把档位写进行内样式。图标按钮没有可见文字,作者须自行提供可及名。
ariaLabelstring作者写在根节点上的可及名(aria-label / aria-labelledby)。 宿主只把它们转告连接层,用于判断图标按钮是否有名字;属性本身仍由宿主写入根节点。
ariaLabelledbystring
fullWidthboolean撑满行宽:表单末尾的提交按钮与移动端常用。
asButtonElement渲染的标签,默认 button。 写为 a 时不再产出 type 与原生 disabled(两者在链接上无效),禁用改由 aria-disabled 表达, 点击仍被拦截。href 由作者自行提供。

React 适配器 props ​

只列各组件自己声明的那些:继承自 ComponentPropsWithRef 的 DOM 属性不在其中,根组件上与上面 Props 表同名的也不重复列。Vue 的对应物是上面的插槽表。

React 组件属性类型必填说明
XhButtonhrefComponentPropsWithRef<'a'>['href']
XhButtontargetComponentPropsWithRef<'a'>['target']
XhButtonrelComponentPropsWithRef<'a'>['rel']

状态 ​

以下名称仅用于内部状态机。

状态:idle

事件:PRESS.START · PRESS.END

判据:canPress

connect API ​

getXxxProps() 返回对应部件的宿主属性。

成员类型说明
disabledboolean
loadingboolean
getRootProps() => T['button']
getLabelProps() => T['element']
getIndicatorProps() => T['element']
getPrefixProps() => T['element']
getSuffixProps() => T['element']

无障碍 ​

键盘 ​

规格出处:W3C APG

按键生效条件行为
Enter / Spacefocus in root, interactive激活按钮(原生行为)
Enter / Spaceheld in root, interactive按住期间投影 data-pressed,与指针 :active 同一副按压面;抬起或失焦撤下

ARIA ​

以下属性由 connect 生成。

部件属性值
rootaria-busy'true' | undefined
rootaria-disabled'true' | undefined
indicatoraria-hidden'true'
prefixaria-hidden'true'
suffixaria-hidden'true'

样式参考 ​

皮肤 ​

@xihan-ui/styles/button.css 使用 [data-scope="button"][data-part="root"] 部件选择器,位于 xihan.components 层。覆盖样式使用 xihan.overrides。

forced-colors: active 下另有一套规则:颜色交给系统,边框与状态标记改用系统色关键字。

数据属性 ​

由 connect 生成;条件不成立时不输出无值属性。

部件属性值
rootdata-disabled''(条件成立时才出现)
rootdata-full-width''(条件成立时才出现)
rootdata-icon-only''(条件成立时才出现)
rootdata-loading''(条件成立时才出现)
rootdata-pressed''(条件成立时才出现)
rootdata-sizeprops.size
rootdata-toneprops.tone
rootdata-variantprops.variant
rootdata-xh-action-control''
rootdata-xh-action-display'always'
rootdata-xh-action-profile'icon' | 'text'
rootdata-xh-action-sizeprops.size
rootdata-xh-action-variantprops.variant
rootdata-xh-ink-surface''(条件成立时才出现)

CSS 变量 ​

本组件公开覆盖槽由独立皮肤的实际消费位生成;默认来源、作用部件和状态均与 CSS 同源。

变量部件CSS 属性状态默认来源说明
--xh-button-bgroot--xh-ink-surface
background-color
default
focus-visible
loading
xh-ink-surface
--xh-_action-variant-bg-focus-visible
--xh-_action-variant-bg-loading
--xh-_action-variant-bg-rest
button 的 root 部件 --xh-ink-surface、background-color 覆盖槽。
--xh-button-bg-activerootbackground-colordisabled
is(:active, [data-pressed])
loading
not([data-disabled])
not([data-loading])
pressed
--xh-_action-variant-bg-pressedbutton 的 root 部件 background-color 覆盖槽。
--xh-button-bg-hoverrootbackground-colordisabled
hover
loading
not([data-disabled])
not([data-loading])
--xh-_action-variant-bg-hoverbutton 的 root 部件 background-color 覆盖槽。
--xh-button-fgrootcolordefault
disabled
focus-visible
hover
is(:active, [data-pressed])
loading
not([data-disabled])
not([data-loading])
pressed
--xh-_action-variant-fg-focus-visible
--xh-_action-variant-fg-hover
--xh-_action-variant-fg-loading
--xh-_action-variant-fg-pressed
--xh-_action-variant-fg-rest
button 的 root 部件 color 覆盖槽。
--xh-button-font-sizerootfont-sizedefault--xh-_button-group-font-sizebutton 的 root 部件 font-size 覆盖槽。
--xh-button-font-weightrootfont-weightdefault--xh-text-label-weightbutton 的 root 部件 font-weight 覆盖槽。
--xh-button-gaprootgapdefault--xh-_button-group-gapbutton 的 root 部件 gap 覆盖槽。
--xh-button-glint-durationrootanimation@media (hover: hover) and (pointer: fine) and (forced-colors: none)
disabled
hover
loading
material=liquid
not([data-disabled])
not([data-loading])
where([data-material='liquid'])
xh-action-variant=solid
--xh-motion-duration-glintbutton 的 root 部件 animation 覆盖槽。
--xh-button-hrootblock-size
inline-size
default
xh-action-profile=icon
--xh-_button-group-hbutton 的 root 部件 block-size、inline-size 覆盖槽。
--xh-button-icon-sizeroot--xh-icon-sizedefault--xh-_action-profile-glyph-sizebutton 的 root 部件 --xh-icon-size 覆盖槽。
--xh-button-pxrootpadding-inlinedefault--xh-_button-group-pxbutton 的 root 部件 padding-inline 覆盖槽。
--xh-button-radiusrootborder-radiusdefault--xh-_button-radiusbutton 的 root 部件 border-radius 覆盖槽。
--xh-button-shadowrootbox-shadowdefaultnonebutton 的 root 部件 box-shadow 覆盖槽。
--xh-button-shadow-hoverrootbox-shadowdisabled
hover
loading
not([data-disabled])
not([data-loading])
nonebutton 的 root 部件 box-shadow 覆盖槽。
--xh-button-spin-durationindicator
root
animationloading--xh-motion-loop-spinbutton 的 indicator、root 部件 animation 覆盖槽。

动效 ​

动效角色:按压 · 状态 · 循环(见动效规范)。

可覆盖的动效槽:--xh-button-glint-duration · --xh-button-spin-duration。

共享关键帧 xh-spin 由 family/motion.css 提供,皮肤 @import 它,单独引入仍成立。时长与缓动读动效令牌,改令牌即改全局节奏。

prefers-reduced-motion: reduce 下本组件另有降级规则。

响应式 ​

皮肤另按输入能力分档:hover: hover:同一份皮肤在触屏与带指针的设备上不一样,与视口宽度无关。

RTL ​

皮肤用逻辑属性排布(inline-start 一族),dir="rtl" 下自动镜像;另有按 dir 分支的规则。

Released under The MIT License