跳到主要内容

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.tsSwitch.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.tsSwitch.tsx

PropType默认说明
valueboolean当前状态(受控,必填)
onChange(value: boolean) => void切换回调(必填)
disabledboolean?禁用(不可点 + opacity: 0.5
accessibilityLabelstring?无障碍朗读文案(独立使用时建议传)
testIDstring?E2E / 测试定位

无障碍(a11y)

来源:src/components/ui/Switch/Switch.tsxSwitch.web.tsxtypes.ts(native 与 web 两份实现 a11y 完全一致)。

  • 默认 accessibilityRole:包裹的 <Pressable> 上硬编码 'switch'
  • a11y props:accessibilityLabeltypes.ts 中是可选的(accessibilityLabel?)——Switch 本身不带可见 label(设计上 label 交给左侧 Cell),所以独立使用时不传 accessibilityLabel 则无朗读文案,应由承载它的 Cell / 上下文提供语义。
  • 状态语义:accessibilityState={{ checked: value, disabled: !!disabled }}——checked 直接映射必填的 valuedisabled 映射 disabled prop。
// 独立使用时显式给 accessibilityLabel;checked 由 value 自动上报
<Switch value={enabled} onChange={setEnabled} accessibilityLabel="拜访提醒" />

不要

  • ❌ 不要换其它颜色——开必须是主橙(这是品牌一致性)
  • ❌ 不要在 Switch 上加 label——配 Cell 把 label 放左侧、Switch 放 extra slot
  • ❌ 不要做"中间态"——Switch 只有开/关,三态用 Radio