Skip to content

ToggleGroup 切换按钮组 ​

一排 Toggle 切换按钮,由组统一管理谁按下。用在「对齐方式」「视图切换」这类几个选项里选一个, 或「加粗 / 斜体 / 下划线」这类可以同时按下几个的工具栏分组。选项要随表单提交时用 RadioGroup 单选组。

单选

默认 type="single":同一时间最多按下一项,点另一项时原来那项弹起;再点已按下的那项取消选择(value 变为空串)。

<pt-toggle-group variant="outline" value="center" aria-label="对齐方式">
  <pt-toggle value="left">左对齐</pt-toggle>
  <pt-toggle value="center">居中</pt-toggle>
  <pt-toggle value="right">右对齐</pt-toggle>
</pt-toggle-group>
多选与尺寸

type="multiple" 时各项独立按下,value 是字符串数组(HTML 里写成逗号分隔)。组上的 size / variant 回写到每一项。

<pt-toggle-group type="multiple" size="sm" value="bold,underline" aria-label="文字样式">
  <pt-toggle value="bold">加粗</pt-toggle>
  <pt-toggle value="italic">斜体</pt-toggle>
  <pt-toggle value="underline">下划线</pt-toggle>
</pt-toggle-group>
纵向与禁用

orientation="vertical" 时竖排、↑ ↓ 移动焦点。禁用的项不可点,方向键跳过它;组上的 disabled 禁用全部项。

<pt-toggle-group orientation="vertical" variant="outline" value="list" aria-label="视图">
  <pt-toggle value="list">列表</pt-toggle>
  <pt-toggle value="grid" disabled>网格</pt-toggle>
  <pt-toggle value="board">看板视图</pt-toggle>
</pt-toggle-group>

结构 ​

pt-toggle-group 里直接放若干 pt-toggle,每一项都写上 value —— 组的 value 靠它对应,缺了 value 的项不能被选中。 项必须是组的直接子元素:隔了一层容器的 pt-toggle 不归组管,照常自己切换。

组上写了 variant / size 时回写到每一项,覆盖项自己写的(组级优先,之后再改项上的同名属性也会被组改回去); 组上没写时各项用自己的,可以逐项设置。组上的 disabled 禁用全部项, 但不改写项自己的 disabled,解除后各项回到自己的状态。

受控值 ​

受控属性是 value,事件是 ptChange:

typevalue 的形状一个都没按下时
single(默认)字符串:按下那一项的 value''
multiple字符串数组:按下的各项的 value[]
  • Vue:<PtToggleGroup v-model="align">
  • Angular:<pt-toggle-group [(ngModel)]="align">,standalone 组件要在 imports 里加上 TextValueAccessor
  • React:<PtToggleGroup value={align} onPtChange={e => setAlign(e.detail)}>

数组只能用 JS / 框架绑定赋值;在 HTML 里写 multiple 的初始值时用逗号分隔:value="bold,underline" (各段去掉首尾空白)。因此 multiple 下项的 value 本身不要含逗号。

ptChange 只在用户点击时发;外部直接改 value 只改状态,不发事件。组的 value 是按下态的唯一来源: 直接改组内某项的 pressed(业务代码或框架绑定)会被组按 value 改回去,要改按下态请改组的 value。multiple 下组件写回的总是一个新数组。 组内的 pt-toggle 不发它自己的 ptChange,ptChange 照常冒泡,外层容器可以做事件委托。

single 下再点已按下的那项会取消选择(与 Radix ToggleGroup 一致)。需要「总有一项选中」时用 Tabs 标签页 的 segmented 变体或 RadioGroup 单选组。

键盘操作 ​

整组只占一个 Tab 停靠点:有按下的项停在第一个按下的项上,否则停在第一个可用项。

按键行为
← →(horizontal,默认)在各项之间移动焦点,RTL 下对调;不改变按下态
↑ ↓(vertical)同上
Home / End移到第一项 / 最后一项
Space / Enter切换当前聚焦的项

禁用项被跳过。loop(默认开)决定到头时是否回到另一端,原生 HTML 里关掉写 loop="false"。

无障碍 ​

  • single 与 multiple 语义一致:组是 role="group",各项内部按钮是切换按钮(aria-pressed)。
  • single 不用 radiogroup / radio(Radix ToggleGroup 用了,这里有意不跟):WAI-ARIA 的单选组要求 「选中后不能靠再次激活取消」「方向键移焦点的同时选中」,而切换按钮组恰好相反 —— 再点已按下项会取消选择, 方向键只移焦点、要按 Space / Enter 才切换。读屏若宣布成「单选按钮」,用户会按单选组的习惯操作而得到意外结果。 需要真正的单选语义(总有一项选中、方向键即选中、可随表单提交)时用 RadioGroup 单选组。
  • 页面上没有可见的组标题时给组写 aria-label(包装层里是 ariaLabelText);纯图标的项同样要各自写 aria-label。

API ​

属性

属性Attribute类型默认值说明
ariaLabelTextaria-labelstring | undefined—无障碍名称:原生 HTML 里写 aria-label,React / Vue / Angular 包装层里属性名是 ariaLabelText。 页面上没有可见的组标题时必须给 —— 读屏进入这一组时先念它。
disableddisabledbooleanfalse禁用整组:全部项不可点、不可聚焦。不改写各项自己的 `disabled`,解除后各项回到自己的状态
inheritedDisabledinherited-disabledbooleanfalse外层 pt-field-set 下发的禁用。内部继承通道:由它以 attribute 维护,不建议使用方直接写。 有效禁用是 `disabled` 与它的并集;父元素只写这一条、不碰 `disabled`,读 `el.disabled` 得到的始终是使用方自己写的值
looploopbooleantrue方向键到头后是否回到另一端。默认为真:原生 HTML 里关掉它写 `loop="false"`
orientationorientation"horizontal" | "vertical"'horizontal'排列方向,同时决定方向键:horizontal 横排、← →(默认);vertical 竖排、↑ ↓
sizesize"lg" | "md" | "sm" | undefined—尺寸档位,三档对应 24 / 32 / 40 的控件刻度。回写规则同 `variant`:写了组级优先,不写时各项用自己的(默认 md)
typetype"multiple" | "single"'single'选择方式: - `single`:同一时间最多按下一项,按下另一项时原来那项弹起;再点已按下的那项会取消选择(`value` 变为空串); - `multiple`:各项独立按下 / 弹起。
valuevaluestring | string[]''按下着的项的 `value`。 - `single`:字符串,空串表示一个都没按下; - `multiple`:字符串数组。数组只能用 JS / 框架绑定赋值;写成 HTML attribute 时用**逗号分隔** (`value="bold,italic"`,各段去掉首尾空白),因此 multiple 下项的 `value` 本身不要含逗号。 用户点击时组件自己改写它(multiple 下总是写回一个新数组)并发 `ptChange`;外部直接赋值不发事件。
variantvariant"default" | "outline" | undefined—视觉变体:default 透明底;outline 带 1px 描边。写了就回写到每一项(组级优先,覆盖项自己写的 variant, 项之后再改也会被改回去);不写时各项用自己的 variant(默认 default)。写过再撤掉时各项保留最后一次回写的值

事件

事件detail 类型说明
ptChangestring | string[]用户点击某一项改变了按下态后触发,detail 是新的 `value`(`single` 为字符串、取消选择时为空串; `multiple` 为字符串数组)。Vue 的 v-model 与 Angular 的 ngModel 绑在它上面。外部直接改 `value` 不触发。 冒泡(组件默认):切换按钮组不会自我嵌套,组内的 `pt-toggle` 也不发自己的 `ptChange`,冒泡不会串到别的绑定上。

方法

方法说明
refresh() => Promise<void>重新按 `value` 同步各项的按下态与 Tab 停靠点。子项增删、改 value / disabled,或组内某项的 `pressed` 被外部改写时 组件自己会调,一般不需要手动调用

插槽

名称说明
(默认)若干 `pt-toggle`,每个都要写 `value`(缺了 `value` 的项不能被选中)

可定制的内部元素(::part())

part说明
base排布各项的容器

Apache-2.0 协议开源