一个 React 开关,采用 Liquid Glass 滑块、标签、描述与黑白主题。
Switch 渲染带 Liquid Glass 轨道与滑块的两种状态控件。它适合立即生效的设置;需要保持按下状态的单一操作请使用 Toggle。
下面的开关来自真实组件,可以直接点击切换。
开关根元素就是最外层元素。视觉轨道是内部的 base 槽位,整行(包括标签和描述)都可以点击。label 会通过 aria-labelledby 成为可访问名称;当控件有标签或显式名称时,description 会通过 aria-describedby 关联。显式传入的 aria-label 或 aria-labelledby 优先决定名称,显式传入的 aria-describedby 会与描述合并。只有 description 的控件会把描述作为名称,不再添加 aria-describedby。
支持 xs / sm / md / lg / xl,默认 md。轨道与文字会随 size 缩放。
checked 与 onCheckedChange 让开关状态完全由外部状态控制:
不传 checked 时,Switch 自己维护状态,defaultChecked 只作为初始值:
Switch 会把 name 与 value 用于表单,并在提交时通过隐藏的 checkbox input 发送当前值:
Switch 渲染带 role="switch" 与 aria-checked 的可聚焦元素(默认是 <span>)。可见的 label 为其命名,description 通过 aria-describedby 关联;显式 ARIA 名称优先。
Space 切换当前控件。隐藏复选框携带 name 与 value 用于表单提交,readOnly 会阻止修改但保留焦点。表单模式见可访问性指南。
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
label | ReactNode | — | 可见标签;未提供 aria-label 或 aria-labelledby 时会成为可访问名称。 |
description | ReactNode | — | 辅助说明;控件有名称时会通过 aria-describedby 关联。 |
size | "xs" | "sm" | "md" | "lg" | "xl" | "md" | 控制开关尺寸与文字大小。 |
checked | boolean | — | 受控选中状态。 |
defaultChecked | boolean | false | 非受控初始状态。 |
onCheckedChange | (checked: boolean, details) => void | — | 选中状态变化时调用。 |
disabled | boolean | false | 禁用开关。 |
readOnly | boolean | false | 只读,不允许切换,但仍可聚焦。 |
required | boolean | false | 表单提交前必须开启。 |
name | string | — | 表单字段名。 |
form | string | — | 拥有隐藏输入框的表单 ID。 |
value | string | — | 开启时随表单提交的值。 |
uncheckedValue | string | — | 关闭时随表单提交的值。 |
id | string | — | 隐藏输入框的 ID;当 nativeButton 为 true 时改为根元素的 ID。 |
inputRef | Ref<HTMLInputElement> | — | 指向隐藏原生输入框的 ref。 |
nativeButton | boolean | false | 是否渲染原生 <button>。 |
render | ReactElement | ((props, state) => ReactElement) | — | 替换根元素。 |
ref | Ref<HTMLElement> | — | 转发到根元素的 ref。 |
className | string | — | Tailwind 类名,合并到 switch root。 |
style | CSSProperties | — | 内联样式,合并到与 className 相同的元素。 |
ui | { root?: ClassValue; container?: ClassValue; base?: ClassValue; thumb?: ClassValue; wrapper?: ClassValue; label?: ClassValue; description?: ClassValue } | — | 按 data-slot 组织的内部槽位类名。 |
| 属性 | 说明 |
|---|---|
data-checked | 开关开启时存在。 |
data-unchecked | 开关关闭时存在。 |
data-disabled | 开关禁用时存在。 |
data-readonly | 开关只读时存在。 |
data-required | 开关必填时存在。 |
data-valid | 开关包裹在 Field 中且有效时存在。 |
data-invalid | 开关包裹在 Field 中且无效时存在。 |
data-touched | 开关包裹在 Field 中并被触碰后存在。 |
data-dirty | 开关包裹在 Field 中且值变化后存在。 |
data-filled | 开关包裹在 Field 中且开启时存在。 |
data-focused | 开关包裹在 Field 中且聚焦时存在。 |
data-animating | thumb 过渡动画运行时存在。 |
data-slot | 标记内部部件(root、container、base、thumb、wrapper、label、description),用于样式选择。 |
轨道和 thumb 使用 --ui-ink 与 --ui-surface;组件级几何数值位于 src/theme/switch.ts,包括 --ui-switch-width、--ui-switch-height、--ui-switch-inset、--ui-switch-thumb-size 和 --ui-switch-travel。可以在 Switch 上通过 style 覆盖这些变量,用 className 控制布局,并通过 ui 按 data-slot 调整内部槽位。Token 分层与预设见主题指南。