跳到主要内容

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),超出时最旧的先退场。

top-left
top-center
top-right
bottom-left
bottom-center
bottom-right

本站在根部挂的是默认位置的 Toaster,所以这一页的通知都出现在右上角。一个应用里只挂一个 Toaster;挂多个的话每条通知会在每个出口各显示一次。

App.tsxtsx
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) 的选项

属性类型默认值说明
titleReactNode—标题。toast('文本') 等同于 toast({ title: '文本' })。
descriptionReactNode—标题下的说明。
tone'neutral' | 'accent' | 'success' | 'warning' | 'danger' | 'info'—状态色。neutral 和 accent 用默认图标。
iconReactNode | false—自定义图标;false 不要图标。
durationnumberToaster 的 duration多少毫秒后自动消失;0 表示一直留着。
action{ label: ReactNode; onClick?: () => void; dismiss?: boolean }—操作按钮。dismiss 默认 true:点了之后关掉这条通知。
closableboolean—带一个关闭按钮。默认只有不会自动消失的通知才带。
idstring—自己指定 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'停靠位置。窄屏一律横向撑满,只分上下。
maxnumber4同时最多显示几条,超出时最旧的先退场。
durationnumber4200默认的自动消失时间(ms);0 表示不自动消失。
pauseOnHoverbooleantrue指针停在通知上时暂停计时。键盘焦点在通知里时总是暂停。
offsetnumber20(窄屏 12)到视口边缘的距离(px)。
labelstring'通知'这块区域的读屏名称。
closeLabelstring'关闭'关闭按钮的读屏名称。
containerHTMLElement | null—渲染到哪个容器,默认 body。

无障碍

  • Toaster 是一个有名字的 region(默认“通知”),读屏用户可以从地标列表直接跳过去。
  • 每条通知是一个 live region:默认 role="status"(polite,等读屏空闲再读);danger 是 role="alert"(assertive,立即打断)。可以用 live 覆盖。标题和说明作为一个整体读出(aria-atomic)。
  • 通知出现时不会抢走焦点。操作按钮和关闭按钮可以 Tab 到;焦点在通知里时计时暂停,不会读到一半消失。
  • 焦点在通知里时按 Esc 关掉这一条。
  • 会自动消失的通知,读屏和键盘用户很可能来不及操作。所以不要把唯一的入口(比如唯一的“撤销”)只放在 Toast 里;重要的、需要操作的通知用 duration: 0 常驻。
  • 状态除了颜色还有各自的图标形状,但图标对读屏隐藏——文字本身要说清是成功还是失败。
  • 减弱动效时进退场和让位都直接完成。