Toast
提示条分两半:toast() 是模块级单例,请求拦截器、插件这类组件外的代码也能调;XToaster 是宿主,整页挂一个,负责画出来。本站在布局里挂了一个,下面的 demo 都复用它。
vue
<!-- 宿主根组件或布局里挂一次 -->
<XToaster position="top-center" />
ts
import { toast } from '@xwink/ui'
toast('已复制链接')
toast.success('已保存')
toast.error('保存失败', { description: '网络连接中断,稍后重试' })
toast.warning('会话已过期,请重新登录', { id: 'auth-unauthenticated' })
调用形态与 vue-sonner 的常用子集相同(四种类型加 id / description / duration),从 sonner 换过来调用点不用改。没挂 XToaster 时开发环境警告一次;服务端调用是空操作(模块级单例在服务端会被所有请求共用)。
类型
success / info / warning / error 各带图标与色调,配色全走 --ui-* 令牌,暗色自动跟随。error 用 role="alert" 立即播报,其余 role="status" 等读屏空闲再念。
四种类型与描述
时长、去重与操作
- 时长:缺省 4 秒,
error6 秒(要读完原因),loading常驻;duration显式给毫秒,Infinity常驻。悬停、键盘聚焦到提示条、切走页面时整组暂停,恢复后按剩余时间接着走,不重新计。 - 同 id 改写:传了
id的调用改写同 id 的那一条并重新计时,正在离场的也留下来。「加载中 → 完成」用同一个 id 原地换。 - 自动合并:没传
id时,与还没收起的某条类型、文案、描述都相同就并成一条,请求连着失败不刷屏。 - 排队:同时最多显示 3 条,多的排队,前面一条开始离场就补上。
- 操作:
action: { label, onClick }在条上加一个按钮(如「撤销」),点了执行并收起。toast.dismiss(id)收起一条,不给 id 收起全部。
聚焦到某条时按 Esc 收起;触屏上横向滑走。
撤销、加载中原地换成完成、连点合并
剩余:草稿 A、草稿 B、草稿 C
逻辑层
状态机与队列是不依赖 Vue 的纯 TS(createToastQueue),时钟可注入,可以拿假时钟单测;整页共用的那一份就是 toast() 背后的队列。单条状态 queued → entering → visible ⇄ paused → leaving → removed,进出场由 XToaster 在过渡结束时报回,没报回(减弱动效、没挂宿主)时按兜底时长自己推进。
API
Props
| 名称 | 类型 | 默认值 | 说明 |
|---|---|---|---|
position | ToasterPosition | undefined | "top-center" | 提示条出现的位置,缺省顶部居中 |