一个 React 通知堆栈,采用 Liquid Glass 风格,支持操作、Promise 状态与四个角落位置。
ToastProvider 负责提供 toast manager。在它内部渲染 Toast 来绘制 Portal、Viewport 和 Liquid Glass toast 栈;在 Provider 内任意位置调用 useToast() 即可添加、更新、关闭或跟踪通知。
建议在应用根部渲染一个 ToastProvider,并把 Toast 放在应用内容之后。每个 Provider 拥有独立的 Viewport;如果还需要在 React 外创建通知,请把同一个 toastManager 传给它。
add 接收标题、描述和可选的类型。Toast 默认在 timeout(5000 ms)后自动关闭,Viewport 被悬停或聚焦时计时会暂停。
type 会选择内置状态图标:info、success、warning、error 或 loading。未知类型仍会渲染,只是不显示图标。priority: "high" 会使用更紧急的无障碍播报。
loading 通常由 toast.promise 自动生成,不需要直接创建。
actionProps 会在 Toast 内渲染操作按钮。操作按钮会透传 children 和原生 button 属性;操作完成后需要在 onClick 中自行关闭 Toast。
Nothing archived yet.
toast.promise 会先显示 loading Toast,并在 Promise 完成或失败时把同一个 Toast 更新为 success 或 error。
The toast updates when the promise resolves.
position 会把通知栈固定在某个角落:top-left、top-right、bottom-left 或 bottom-right。Toast 会朝远离上下边缘的方向堆叠,滑动关闭方向也会跟随所在角落变化。
Current position: bottom-right
update 会替换已有 Toast 的字段;close 关闭指定 Toast,省略 ID 时关闭全部。示例会保留 add 返回的 ID,把 loading Toast 逐步更新为成功状态。
No upload in progress.
ToastProvider 支持 limit 与 timeout。timeout 为 0 时 Toast 不会自动关闭,需要代码或用户主动关闭。下面的示例会保持两条常驻通知。
createToastManager 会创建一个可被任意模块调用的管理器。把该实例通过 toastManager 传给 ToastProvider,Viewport 就会渲染它创建的通知。
viewport 是实时区域。高优先级通知使用 alertdialog 角色,其余使用 dialog 角色;标题与描述通过 aria-labelledby 与 aria-describedby 关联。
通知堆栈支持 F6 进入焦点与滑动关闭,viewport 被悬停或聚焦时计时器会暂停。替换默认关闭按钮时,请为自定义 close 控件提供可访问名称。播报规范见可访问性指南。
ToastProvider
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
children | ReactNode | — | 可以调用 useToast() 的应用内容。 |
timeout | number | 5000 | 默认自动关闭延时(毫秒);0 表示不自动关闭。 |
limit | number | 3 | 最多同时显示的 Toast 数量;超出的旧 Toast 仍保留在 DOM 中,并带上 data-limited。 |
toastManager | ToastManager | — | 由 createToastManager 创建的全局管理器。 |
Toast
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
position | "top-left" | "top-right" | "bottom-left" | "bottom-right" | "bottom-right" | 通知栈固定的角落。 |
close | ReactNode | 内置关闭按钮 | 替换默认关闭按钮的自定义内容。 |
className | string | — | 合并到每条 Toast 的 Tailwind 类名。 |
style | CSSProperties | — | 内联样式,合并到与 className 相同的元素。 |
ui | { viewport?: ClassValue; root?: ClassValue; glass?: ClassValue; overlay?: ClassValue; content?: ClassValue; icon?: ClassValue; text?: ClassValue; title?: ClassValue; description?: ClassValue; actions?: ClassValue; action?: ClassValue; close?: ClassValue } | — | 按 data-slot 组织的内部槽位类名。 |
render | ReactElement | ((props, state) => ReactElement) | — | 替换每条 Toast 的根元素。 |
ref | Ref<HTMLDivElement> | — | 转发到每条 Toast 根元素的 ref。 |
useToast
| 方法 | 说明 |
|---|---|
add(options) | 添加一个 Toast,并返回它的 ID。 |
update(id, options) | 更新已有的 Toast。 |
close(id?) | 关闭指定 Toast;省略 id 时关闭全部。 |
promise(promise, options) | 跟踪 Promise,并在 loading、success、error 之间更新。 |
toasts | 当前 Toast 对象列表。 |
Toast 选项
add 支持以下字段;update 接收 ToastUpdateOptions,即不带 id 的部分版本;promise 的 loading、success 与 error 也使用同一组 update 字段。下表中,ToastOptions 指 add 选项,ToastUpdateOptions 等价于 Partial<Omit<ToastOptions, "id">>。
| 选项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
id | string | 自动生成 | add 的稳定标识。使用已存在的 ID 会原地更新该 Toast;update 与 promise 不接受 id。 |
title | ReactNode | — | Toast 标题。 |
description | ReactNode | — | 标题下方的说明文字。 |
type | string | — | 状态图标:info、success、warning、error 或 loading。 |
timeout | number | 5000 | 自动关闭延时(毫秒);0 表示保持打开。 |
priority | "low" | "high" | "low" | 普通播报或更紧急的播报。 |
actionProps | ComponentPropsWithoutRef<"button"> | — | 操作按钮属性,包括 children 与 onClick。 |
onClose | () => void | — | Toast 关闭时调用。 |
onRemove | () => void | — | Toast 从列表中移除后调用。 |
data | object | — | 附加到 Toast 对象上的自定义数据。 |
Promise 选项
| 选项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
loading | string | ToastUpdateOptions | — | Promise 进行中显示的内容。 |
success | string | ToastUpdateOptions | ((value) => string | ToastUpdateOptions) | — | Promise 成功时显示的内容。 |
error | string | ToastUpdateOptions | ((error) => string | ToastUpdateOptions) | — | Promise 失败时显示的内容。 |
createToastManager
createToastManager() 返回的管理器提供与 useToast() 相同的 add、update、close 与 promise 方法,但不暴露当前 toasts 列表;需要在 React 内读取该列表时使用 useToast()。需要在 React 之外创建通知时使用管理器,并通过 toastManager 把实例传给 ToastProvider。
Toast 属性
| 属性 | 说明 |
|---|---|
data-expanded | Toast 在视口中展开时存在。 |
data-limited | Toast 因超出数量限制而被标记时存在。 |
data-type | 表示 Toast 类型(info、success、warning、error 或 loading)。 |
data-swiping | Toast 正在滑动时存在。 |
data-swipe-direction | 表示滑动方向(up、down、left 或 right)。 |
data-starting-style | Toast 开始进入动画时存在。 |
data-ending-style | Toast 正在退出动画时存在。 |
data-behind | Toast 位于栈中非最前位置时存在。 |
data-position | 在视口上表示固定的角落。 |
data-icon | 在图标槽位上表示状态图标类型。 |
data-slot | 标记内部部件(viewport、root、glass、overlay、content、icon、text、title、description、actions、action、close),用于样式选择。 |
玻璃表面、堆叠几何和动效由各槽位共享。使用 ui.root、ui.glass、ui.overlay 与 ui.content 调整单个槽位;ui.viewport 控制堆叠定位,className 与 style 都会合并到每条 Toast 的根元素。请优先通过共享的 --ui-glass-* token 调整材质。