Toast 轻提示toast() · Toaster
操作之后一闪而过的反馈:“已保存”“已复制”“发送失败”。它不打断人,几秒后自己消失,所以只放看不看都行的信息;必须被看到的内容用 Alert 或 Dialog。
基本用法
在任何地方(组件里、事件回调里、请求的 then 里)直接调用 toast(),不需要 hook。页面根部要挂一个 <Toaster />(本站已挂)。传字符串只有标题;传对象可以带说明。返回值是这条通知的 id。
状态
toast.success / warning / danger / info 是带状态色的简写(toast.error 是 danger 的别名),也可以在对象里写 tone。每种状态有自己的图标:圆底先弹出来,符号再描线画出。
带操作
action 在通知右侧放一个按钮,最常见的是“撤销”。点了之后默认关掉这条通知;action.dismiss 设为 false 则保留。带操作的通知建议把时间放长一些,给人够得着的机会。
时长与常驻
默认 4.2 秒后消失;指针停在通知上、或键盘焦点在通知里时暂停计时。duration 单独指定时长(毫秒),0 表示一直留着——常驻的通知自动带关闭按钮。也可以用 closable 给会自动消失的通知加上关闭按钮。点通知本身的任意位置也会关掉它。
原地更新
给通知一个固定的 id:同一个 id 再次调用会原地更新内容并重新计时,而不是新增一条。适合“进行中 → 完成 / 失败”。
手动关闭
toast.dismiss(id) 关掉某一条,不传 id 则全部关掉。onDismiss 在通知消失之后回调。
自定义图标、不要图标、消失后的回调
位置
位置是 <Toaster /> 的属性,整个应用统一设置一次,不是每条通知各自决定。一共六个位置,默认 top-right;靠下的位置里最新的一条贴着底边,旧的往上让。窄于 520px 时一律横向撑满,只分上下。同时最多显示 max 条(默认 4),超出时最旧的先退场。
本站在根部挂的是默认位置的 Toaster,所以这一页的通知都出现在右上角。一个应用里只挂一个 Toaster;挂多个的话每条通知会在每个出口各显示一次。
import { Toaster } from 'oink-ui';
export function App() {
return (
<>
<Routes />
{/* 应用根部挂一次 */}
<Toaster position="bottom-center" max={3} duration={5000} offset={24} />
</>
);
}规格
- 卡片
- 宽 360 · 圆角 20 · 内边距 16 · 不透明底,无阴影
- 进场
- 下落 32px + scale 0.84 → 1 · bouncy
- 图标
- 圆底弹出 → 符号描线
- 让位
- FLIP · spring
- 退场
- 朝停靠的一侧滑出 56px · 170ms ease-in
- 时长
- 默认 4.2s · 悬停或聚焦时暂停
接口
toast(options) 的选项
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
title | ReactNode | — | 标题。toast('文本') 等同于 toast({ title: '文本' })。 |
description | ReactNode | — | 标题下的说明。 |
tone | 'neutral' | 'accent' | 'success' | 'warning' | 'danger' | 'info' | — | 状态色。neutral 和 accent 用默认图标。 |
icon | ReactNode | false | — | 自定义图标;false 不要图标。 |
duration | number | Toaster 的 duration | 多少毫秒后自动消失;0 表示一直留着。 |
action | { label: ReactNode; onClick?: () => void; dismiss?: boolean } | — | 操作按钮。dismiss 默认 true:点了之后关掉这条通知。 |
closable | boolean | — | 带一个关闭按钮。默认只有不会自动消失的通知才带。 |
id | string | — | 自己指定 id:同一个 id 再次调用会原地更新。 |
live | 'polite' | 'assertive' | — | 读屏播报的方式。默认 danger 用 assertive,其余 polite。 |
onDismiss | () => void | — | 这条通知消失之后。 |
toast 上的方法
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
toast(options | string) | => string | — | 发一条通知,返回它的 id。 |
toast.success / warning / danger / info | (options | string) => string | — | 带状态色的简写。 |
toast.error | (options | string) => string | — | danger 的别名。 |
toast.dismiss | (id?: string) => void | — | 关掉某一条;不传 id 则全部关掉。 |
Toaster
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
position | 'top-right' | 'top-left' | 'top-center' | 'bottom-right' | 'bottom-left' | 'bottom-center' | 'top-right' | 停靠位置。窄屏一律横向撑满,只分上下。 |
max | number | 4 | 同时最多显示几条,超出时最旧的先退场。 |
duration | number | 4200 | 默认的自动消失时间(ms);0 表示不自动消失。 |
pauseOnHover | boolean | true | 指针停在通知上时暂停计时。键盘焦点在通知里时总是暂停。 |
offset | number | 20(窄屏 12) | 到视口边缘的距离(px)。 |
label | string | '通知' | 这块区域的读屏名称。 |
closeLabel | string | '关闭' | 关闭按钮的读屏名称。 |
container | HTMLElement | null | — | 渲染到哪个容器,默认 body。 |
无障碍
- Toaster 是一个有名字的
region(默认“通知”),读屏用户可以从地标列表直接跳过去。 - 每条通知是一个 live region:默认
role="status"(polite,等读屏空闲再读);danger 是role="alert"(assertive,立即打断)。可以用live覆盖。标题和说明作为一个整体读出(aria-atomic)。 - 通知出现时不会抢走焦点。操作按钮和关闭按钮可以 Tab 到;焦点在通知里时计时暂停,不会读到一半消失。
- 焦点在通知里时按 Esc 关掉这一条。
- 会自动消失的通知,读屏和键盘用户很可能来不及操作。所以不要把唯一的入口(比如唯一的“撤销”)只放在 Toast 里;重要的、需要操作的通知用 duration: 0 常驻。
- 状态除了颜色还有各自的图标形状,但图标对读屏隐藏——文字本身要说清是成功还是失败。
- 减弱动效时进退场和让位都直接完成。