Switch 开关
布尔开关——32×20 轨道 + 16×16 圆形 thumb,关时灰底 thumb 在左,开时主橙底 thumb 在右,200ms 动画。
实时预览
下方渲染的就是 src/components/ui/Switch/Switch.tsx 本体,通过 react-native-web 翻译成浏览器节点(reanimated 4 worklet 驱动动画)。
关
开
禁用
拜访提醒
按计划自动推送提醒
同步给团队
拜访完成后通知主管
语音输入
长按说话输入消息
状态
来源:src/components/ui/Switch/styles.ts、Switch.tsx。
| 状态 | 视觉 |
|---|---|
| 关 | 32×20 灰底 c.surfaceContainerHighest(亮色 #E0E0E0),16×16 白圆 thumb(c.onPrimary)在左 |
| 开 | 32×20 主橙底 c.primary(#EB6E00),16×16 白圆 thumb 在右 |
| 禁用 | 整体 opacity: 0.5 |
切换动画:thumb 水平移动 12px(off x=2 → on x=14),背景颜色插值,200ms(motion.base)。native 走 reanimated 4 worklet,web 走 CSS transition(见 Switch.web.tsx)。
用法
import { Switch, Cell, List } from '@unif/react-native-design';
{/* 独立使用 */}
<Switch value={enabled} onChange={setEnabled} />
{/* 设置场景 — 配 Cell 使用,Switch 作为 extra */}
<List>
<Cell
title="拜访提醒"
desc="按计划自动推送提醒"
extra={<Switch value={notify} onChange={setNotify} />}
/>
<Cell
title="语音输入"
desc="长按说话输入消息"
extra={<Switch value={voice} onChange={setVoice} />}
/>
</List>
API
来源:src/components/ui/Switch/types.ts、Switch.tsx。
| Prop | Type | 默认 | 说明 |
|---|---|---|---|
value | boolean | — | 当前状态(受控,必填) |
onChange | (value: boolean) => void | — | 切换回调(必填) |
disabled | boolean? | — | 禁用(不可点 + opacity: 0.5) |
accessibilityLabel | string? | — | 无障碍朗读文案(独立使用时建议传) |
testID | string? | — | E2E / 测试定位 |
无障碍(a11y)
来源:src/components/ui/Switch/Switch.tsx、Switch.web.tsx、types.ts(native 与 web 两份实现 a11y 完全一致)。
- 默认
accessibilityRole:包裹的<Pressable>上硬编码'switch'。 - a11y props:
accessibilityLabel在types.ts中是可选的(accessibilityLabel?)——Switch 本身不带可见 label(设计上 label 交给左侧 Cell),所以独立使用时不传accessibilityLabel则无朗读文案,应由承载它的 Cell / 上下文提供语义。 - 状态语义:
accessibilityState={{ checked: value, disabled: !!disabled }}——checked直接映射必填的value,disabled映射disabledprop。
// 独立使用时显式给 accessibilityLabel;checked 由 value 自动上报
<Switch value={enabled} onChange={setEnabled} accessibilityLabel="拜访提醒" />