一个 React 切换组,采用 Liquid Glass 选中状态,支持单选、多选以及水平或垂直布局。
ToggleGroup 在一整块玻璃表面上组合一组相关的开关按钮。它适合视图切换与格式控制,支持单选与多选。
下面的视图切换使用真实 Toggle Group。选中项会显示 Liquid Glass 选中态,并把当前值同步到下方文字。
选项通过 items 数组传入,每个条目的 value 对应 group 的选中值。
请通过 aria-label 或 aria-labelledby 为分组提供可访问名称。只渲染图标的条目需要自己的 aria-label。
Current view: Grid
支持 xs / sm / md / lg / xl,默认 md。
使用 multiple 允许多个 item 同时选中,默认是单选。
使用 orientation="vertical" 切换为纵向布局:
value 与 onValueChange 让选中值完全由外部状态控制。下面的示例在清空后仍然保持受控:
在 group 上设置 disabled 会禁用所有 item;在单个 item 上设置 disabled 只会禁用该选项。
ToggleGroup 渲染 group,其中的条目是带 aria-pressed 的开关按钮。请用 aria-label 或 aria-labelledby 为分组命名;纯图标条目需要自己的名称。
方向键在分组内移动焦点,Home 与 End 跳到首尾,Space 或 Enter 切换当前条目。单选模式下,分组值就是唯一数据源;选择不能被清空时,请使用受控用法。键盘细节见可访问性指南。
ToggleGroup
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
value | readonly string[] | — | 受控的选中值。 |
defaultValue | readonly string[] | [] | 非受控时的初始选中值。 |
onValueChange | (value: string[], details) => void | — | 选中值变化时调用。 |
multiple | boolean | false | 是否允许多选。 |
orientation | "horizontal" | "vertical" | "horizontal" | 布局与键盘方向。 |
loopFocus | boolean | true | 键盘焦点到达末尾后回到第一项。 |
disabled | boolean | false | 禁用所有 item。 |
size | "xs" | "sm" | "md" | "lg" | "xl" | "md" | 控制 item 高度、内边距、文字和图标尺寸。 |
items | readonly ToggleGroupItemProps[] | — | 渲染在 group 内部的选项。 |
aria-label | string | — | 分组的无障碍名称。 |
aria-labelledby | string | — | 用外部元素命名分组。 |
render | ReactElement | ((props, state) => ReactElement) | — | 替换 group 元素。 |
ref | Ref<HTMLDivElement> | — | 转发到 group 元素的 ref。 |
className | string | — | Tailwind 类名,合并到 group root。 |
style | CSSProperties | — | 内联样式,合并到与 className 相同的元素。 |
ui | { root?: ClassValue; glass?: ClassValue; rim?: ClassValue; item?: ClassValue; content?: ClassValue; icon?: ClassValue; label?: ClassValue } | — | 按 data-slot 组织的内部槽位类名。 |
ToggleGroupItemProps
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
value | string | — | 必填,group value 使用的标识。 |
label | ReactNode | — | item 内的可见文字。 |
icon | ReactNode | — | 文字前的装饰性图标。 |
onPressedChange | (pressed, details) => void | — | 该 item 的按下状态变化时调用。 |
disabled | boolean | false | 禁用该项。 |
aria-label | string | — | 仅图标时使用的无障碍名称。 |
aria-labelledby | string | — | 用外部元素命名仅图标 item。 |
nativeButton | boolean | true | item 是否渲染原生 <button>。 |
render | ReactElement | ((props, state) => ReactElement) | — | 替换 item 元素。 |
ref | Ref<HTMLButtonElement> | — | 转发到 item 元素的 ref。 |
className | string | — | 合并到 item root。 |
style | CSSProperties | — | 内联样式,合并到与 className 相同的元素。 |
ui | { item?: ClassValue; content?: ClassValue; icon?: ClassValue; label?: ClassValue } | — | 按 data-slot 组织的该 item 内部槽位类名。 |
item 不接收 pressed 或 defaultPressed;选中状态以 group 的 value / defaultValue 为唯一数据源。根 ui 会先合并到每个 item,再合并该 item 的 ui,最后合并 item 的 className。
| 属性 | 说明 |
|---|---|
data-disabled | group 或 item 禁用时存在。 |
data-orientation | 表示方向(horizontal 或 vertical)。 |
data-multiple | group 允许多选时存在。 |
data-pressed | item 处于按下状态时存在。 |
data-slot | 标记内部部件(root、glass、rim、item、content、icon、label)。 |
组件使用共享玻璃材质。可以在父级调整 --ui-glass-* token,用 className 控制布局,并通过 ui 按 data-slot 调整内部槽位。组件级数值位于 src/theme/toggle-group.ts。Token 分层与预设见主题指南。