Toast 轻提示
非阻塞反馈——3 秒后自动消失,居中或底部出现。
实时预览
下方渲染的就是 src/components/ui/Toast/ToastHost.tsx 本体(reanimated 4 worklet 驱动 fade + slide),通过 react-native-web 翻译成浏览器节点。点按钮触发。
视觉规范
来源:src/components/ui/Toast/styles.ts、ToastHost.tsx、toast.ts。
| 元素 | 规则 |
|---|---|
| 形态 | 圆角 8(radius.md)c.inverseSurface 底(亮色 #1C1C1E),c.inverseOnSurface 白字 |
| 内边距 | 横向 14(space[6])/ 纵向 10(space[4]) |
| 宽度 | max-width 85%,水平居中;距底部 32px(space[10]) |
| 字号 | 14px(type.sm)/ 500 |
| 出现 | 200ms(motion.base)fade + 8px slide-up |
| 停留 | 默认 3000ms(duration 可覆盖) |
| 退出 | 200ms fade + 下滑 8px |
| 层级 | host position: absolute + zIndex: 200 + pointerEvents: none |
状态变体
kind 仅决定文本左侧 6×6 圆点的颜色(来源:dotColorFor):
✓ success · c.success 绿点(亮色 #52C41A)
✕ error · c.error 红点(亮色 #F4511E)
ℹ info · 无圆点(默认)
用法
import { toast, ToastHost } from '@unif/react-native-design';
// 在应用根放一次 ToastHost
<ToastHost />
// 任意位置触发
toast('已保存');
toast.success('订单提交成功');
toast.error('网络异常,请重试');
toast.info('已切换到日报模式');
// 自定义时长
toast({ message: '正在同步…', duration: 5000 });
API
来源:src/components/ui/Toast/toast.ts、types.ts、ToastHost.tsx。
命令式函数 toast(不是组件):
| 调用 | 签名 | 说明 |
|---|---|---|
toast(input) | (input: ToastInput) => void | 默认 kind: 'info' |
toast.info(input) | (input: ToastInput) => void | info 提示 |
toast.success(input) | (input: ToastInput) => void | success 提示(绿点) |
toast.error(input) | (input: ToastInput) => void | error 提示(红点) |
ToastInput = string(简写,走默认 kind + 3000ms)| 对象:
| 字段 | 类型 | 默认 | 说明 |
|---|---|---|---|
message | string | — | 消息文本(必填) |
kind | 'info' | 'success' | 'error' | 'info' | 类型(决定圆点颜色) |
duration | number? | 3000 | 自动消失毫秒数 |
position | 'top' | 'bottom' | 'center' | 'bottom' | 显示位置(top/center 自动避让 safe-area) |
<ToastHost /> 组件 props(ToastHostProps,在 app 根附近挂一次):
| Prop | 类型 | 默认 | 说明 |
|---|---|---|---|
testID | string? | — | 容器 testID;文本节点派生 ${testID}-text |
全局只需一个
<ToastHost />;同一时间只显示一条,新调用替换旧的。
无障碍(a11y)
来源:src/components/ui/Toast/ToastHost.tsx、ToastHost.web.tsx、toast.ts、types.ts。
- 默认
accessibilityRole:无。Toast 由<ToastHost>渲染为<View>+<Text>(native 与 web 两份实现一致),源码未设置accessibilityRole。 - 朗读 / live region:
<ToastHost>在每条 toast 出现时调用AccessibilityInfo.announceForAccessibility(message)(native 与 web 两端一致,web 经 RN-Web 注入 aria-live region),screen reader 会主动播报 message 文本。host 容器仍pointerEvents="none"(不抢焦点)。需要用户停留确认的关键操作(而非一次性通知)仍应改用会获得焦点的模态对话框。 - a11y props:命令式
toast(...)入参(ToastInput:message/kind/duration)与ToastHostProps(仅testID)均不含 a11y 字段;kind(success/error/info)只决定圆点颜色,不带语义角色。 - 无受控状态(
checked/selected/disabled均不适用)。
现状如实记录:Toast 出现时主动播报 message(SR 可感知),但仍是非阻塞提示(不抢焦点、自动消失);需要用户停留确认的关键操作请用模态对话框。
- ❌ 不要在 Toast 里放按钮——需要交互的反馈用内联 Confirmation 或模态对话框
- ❌ 不要堆叠多个 Toast——同一时间最多 1 条,新的把旧的替换
- ❌ 不要超过 50 字——超过就用模态对话框承载