跳转到内容

Toggle 切换按钮 ​

在按下和未按下状态之间切换的按钮。

用法 ​

切换点赞状态

组件结构 ​

加粗的是必需部件。

data-scope="toggle":root

示例 ​

变体 ​

默认与幽灵外观

仅图标 ​

为每个图标按钮提供可访问名称

尺寸 ​

提供三种尺寸

禁用 ​

保留禁用前的状态

受控状态 ​

由外部状态控制按下值

设计指引 ​

何时使用 ​

  • 切换立即生效的格式、视图或工具状态。
  • 操作需要保留当前状态时。

何时不用 ​

特性 ​

  • 使用 aria-pressed 表达当前状态。
  • 支持受控和非受控状态。
  • 支持变体、颜色、尺寸、仅图标和全宽外观;缺省变体是中性淡底 subtle。
  • 按下态是品牌淡底配淡底前景,悬停与按压在同一淡底上加深;只有 solid 变体在按下时才是品牌实心,未按下时按 ghost 取面。
  • 禁用后保留当前按下状态。

组合 ​

最佳实践 ​

  • 标签应说明切换后影响的功能。
  • 仅图标按钮必须提供 aria-label。
  • 按下状态不能只依赖颜色区分。

反模式 ​

  • 不要用切换按钮表示当前标签页。
  • 不要将切换按钮作为表单开关使用。

API 参考 ​

产物 ​

层值
自定义元素<xh-toggle>
Vue 组件XhToggle
组合式函数useToggle
状态机toggleMachine
皮肤@xihan-ui/styles/toggle.css

Props ​

属性类型必填说明
pressedboolean
defaultPressedboolean
disabledboolean
variantActionVariant变体:solid / subtle / outline / ghost,默认 subtle(缺省中性淡底)。 solid 只在按下(on)时才是品牌实心,未按下时按 ghost 取面;其余三档按下时一律品牌淡底。
toneTone颜色:brand / neutral / success / warning / danger / info。
sizeSize尺寸:sm / md / lg
iconOnlyboolean仅图标:左右内边距清零、宽高相等。宽度跟随当前尺寸档的高度, 不必把档位写进行内样式。图标按钮没有可见文字,作者须自行提供可及名。
fullWidthboolean撑满行宽:工具条中的一列开关常用。
onPressedChange(details: TogglePressedChangeDetails) => voidpressed 变化意图回调;受控时是唯一出口,非受控时随内部转移一并通知。

事件 ​

自定义元素将载荷放在 detail;Vue 使用同名 emit。

事件载荷说明
pressed-changeTogglePressedChangeDetailspressed 状态变化;detail 为 { pressed: boolean }

React 适配器 props ​

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

React 组件属性类型必填说明
XhTogglechildrenReactNode

状态 ​

公开状态写入 data-state。

部件取值
root'on' | 'off'

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

状态:off · on

事件:TOGGLE · CONTROLLED.ON · CONTROLLED.OFF · PRESS.START · PRESS.END

判据:isPressedControlled · canPress

connect API ​

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

成员类型说明
pressedboolean
setPressed(next: boolean) => void
getRootProps() => T['button']

无障碍 ​

键盘 ​

规格出处:W3C APG

按键生效条件行为
Space / Enterfocus in root, not disabled切换 pressed 状态
Space / Enterheld in root, not disabled按住期间投影 data-pressed,与指针 :active 同一副按压面;抬起或失焦撤下

ARIA ​

以下属性由 connect 生成。

部件属性值
rootaria-pressed'true' | 'false'

样式参考 ​

皮肤 ​

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

数据属性 ​

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

部件属性值
rootdata-disabled''(条件成立时才出现)
rootdata-full-width''(条件成立时才出现)
rootdata-icon-only''(条件成立时才出现)
rootdata-pressed''(条件成立时才出现)
rootdata-sizeprops.size
rootdata-state'on' | 'off'
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-variant'solid' | 'ghost' | props.variant
rootdata-xh-ink-surface''(条件成立时才出现)

CSS 变量 ​

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

变量部件CSS 属性状态默认来源说明
--xh-toggle-bgroot--xh-ink-surface
background-color
default
focus-visible
xh-ink-surface
--xh-_action-variant-bg-focus-visible
--xh-_action-variant-bg-rest
toggle 的 root 部件 --xh-ink-surface、background-color 覆盖槽。
--xh-toggle-bg-activerootbackground-colordisabled
is(:active, [data-pressed])
loading
not([data-disabled])
not([data-loading])
pressed
--xh-_action-variant-bg-pressedtoggle 的 root 部件 background-color 覆盖槽。
--xh-toggle-bg-disabledroot--xh-ink-surface
background-color
disabled
xh-ink-surface
--xh-_action-variant-bg-disabledtoggle 的 root 部件 --xh-ink-surface、background-color 覆盖槽。
--xh-toggle-bg-hoverrootbackground-colordisabled
hover
loading
not([data-disabled])
not([data-loading])
--xh-_action-variant-bg-hovertoggle 的 root 部件 background-color 覆盖槽。
--xh-toggle-bg-onroot--xh-ink-surface
background-color
disabled
focus-visible
not([data-variant='solid'])
state=on
variant=solid
xh-ink-surface
--xh-_tone-subtletoggle 的 root 部件 --xh-ink-surface、background-color 覆盖槽。
--xh-toggle-bg-on-activerootbackground-colordisabled
is(:active, [data-pressed])
loading
not([data-disabled])
not([data-loading])
not([data-variant='solid'])
pressed
state=on
variant=solid
--xh-_tone-subtle-activetoggle 的 root 部件 background-color 覆盖槽。
--xh-toggle-bg-on-disabledroot--xh-ink-surface
background-color
disabled
not([data-variant='solid'])
state=on
variant=solid
xh-ink-surface
--xh-_action-variant-bg-rest
--xh-_toggle-bg-on
toggle 的 root 部件 --xh-ink-surface、background-color 覆盖槽。
--xh-toggle-bg-on-hoverrootbackground-colordisabled
hover
loading
not([data-disabled])
not([data-loading])
not([data-variant='solid'])
state=on
variant=solid
--xh-_tone-subtle-hovertoggle 的 root 部件 background-color 覆盖槽。
--xh-toggle-borderrootborder
border-color
default
disabled
focus-visible
hover
is(:active, [data-pressed])
loading
not([data-disabled])
not([data-loading])
pressed
--xh-_action-variant-border-focus-visible
--xh-_action-variant-border-hover
--xh-_action-variant-border-pressed
--xh-_action-variant-border-rest
toggle 的 root 部件 border、border-color 覆盖槽。
--xh-toggle-border-disabledrootborder-colordisabled--xh-_action-variant-border-disabledtoggle 的 root 部件 border-color 覆盖槽。
--xh-toggle-border-onrootborder
border-color
disabled
focus-visible
hover
is(:active, [data-pressed])
loading
not([data-disabled])
not([data-loading])
not([data-variant='solid'])
pressed
state=on
variant=outline
variant=solid
--xh-_tone-border-control
transparent
toggle 的 root 部件 border、border-color 覆盖槽。
--xh-toggle-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-pressed
--xh-_action-variant-fg-rest
toggle 的 root 部件 color 覆盖槽。
--xh-toggle-fg-disabledrootcolordisabled--xh-_action-variant-fg-disabledtoggle 的 root 部件 color 覆盖槽。
--xh-toggle-fg-onrootcolordisabled
focus-visible
hover
is(:active, [data-pressed])
loading
not([data-disabled])
not([data-loading])
not([data-variant='solid'])
pressed
state=on
variant=solid
--xh-_tone-fgtoggle 的 root 部件 color 覆盖槽。
--xh-toggle-fg-on-disabledrootcolordisabled
not([data-variant='solid'])
state=on
variant=solid
--xh-_action-variant-fg-rest
--xh-_toggle-fg-on
toggle 的 root 部件 color 覆盖槽。
--xh-toggle-font-sizerootfont-sizedefault--xh-_action-profile-font-sizetoggle 的 root 部件 font-size 覆盖槽。
--xh-toggle-font-weightrootfont-weightdefault--xh-text-label-weighttoggle 的 root 部件 font-weight 覆盖槽。
--xh-toggle-gaprootgapdefault--xh-_action-profile-gaptoggle 的 root 部件 gap 覆盖槽。
--xh-toggle-hrootblock-size
inline-size
default
xh-action-profile=icon
--xh-_action-profile-visual-sizetoggle 的 root 部件 block-size、inline-size 覆盖槽。
--xh-toggle-icon-size*
root
--xh-icon-size
block-size
inline-size
default--xh-_action-profile-glyph-sizetoggle 的 *、root 部件 --xh-icon-size、block-size、inline-size 覆盖槽。
--xh-toggle-pxrootpadding-inlinedefault--xh-_action-profile-padding-inlinetoggle 的 root 部件 padding-inline 覆盖槽。
--xh-toggle-radiusrootborder-radiusdefault--xh-shape-controltoggle 的 root 部件 border-radius 覆盖槽。
--xh-toggle-shadowrootbox-shadowdisabled
focus-visible
hover
is(:active, [data-pressed])
loading
not([data-disabled])
not([data-loading])
pressed
state=on
nonetoggle 的 root 部件 box-shadow 覆盖槽。

动效 ​

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

本组件皮肤不含过渡与关键帧,也没有脚本驱动的动效:状态一变,外观立即到位。

RTL ​

皮肤用逻辑属性排布(inline-start 一族),dir="rtl" 下自动镜像。

Released under The MIT License