组件

Toast

一个简短的消息,会暂时显示。

import * as React from 'react';
import * as Toast from '@radix-ui/react-toast';
import './styles.css';
const ToastDemo = () => {
const [open, setOpen] = React.useState(false);
const eventDateRef = React.useRef(new Date());
const timerRef = React.useRef(0);
React.useEffect(() => {
return () => clearTimeout(timerRef.current);
}, []);
return (
<Toast.Provider swipeDirection="right">
<button className="Button large violet" onClick={() => { setOpen(false); window.clearTimeout(timerRef.current); timerRef.current = window.setTimeout(() => { eventDateRef.current = oneWeekAway(); setOpen(true); }, 100); }} >
Add to calendar
</button>
<Toast.Root className="ToastRoot" open={open} onOpenChange={setOpen}>
<Toast.Title className="ToastTitle">Scheduled: Catch up</Toast.Title>
<Toast.Description asChild>
<time className="ToastDescription" dateTime={eventDateRef.current.toISOString()}>
{prettyDate(eventDateRef.current)}
</time>
</Toast.Description>
<Toast.Action className="ToastAction" asChild altText="Goto schedule to undo">
<button className="Button small green">Undo</button>
</Toast.Action>
</Toast.Root>
<Toast.Viewport className="ToastViewport" />
</Toast.Provider>
);
};
function oneWeekAway(date) {
const now = new Date();
const inOneWeek = now.setDate(now.getDate() + 7);
return new Date(inOneWeek);
}
function prettyDate(date) {
return new Intl.DateTimeFormat('en-US', { dateStyle: 'full', timeStyle: 'short' }).format(date);
}
export default ToastDemo;

功能

    自动关闭。

    在悬停、聚焦和窗口模糊时暂停关闭。

    支持热键跳转到 toast 视窗。

    支持通过滑动手势关闭。

    公开用于滑动手势动画的 CSS 变量。

    可以是受控的或不受控的。

安装

从命令行安装组件。

npm install @radix-ui/react-toast

解剖

导入组件。

import * as Toast from '@radix-ui/react-toast';
export default () => (
<Toast.Provider>
<Toast.Root>
<Toast.Title />
<Toast.Description />
<Toast.Action />
<Toast.Close />
</Toast.Root>
<Toast.Viewport />
</Toast.Provider>
);

API 引用

提供者

包裹你的 toasts 和 toast 视窗的提供者。 它通常包裹应用程序。

属性类型默认值
duration
number
5000
label*
string
"通知"
swipeDirection
enum
"right"
swipeThreshold
number
50

视窗

toasts 出现的位置。 用户可以通过按热键跳转到视窗。 由你负责确保键盘用户的热键可发现性。

属性类型默认值
asChild
boolean
false
hotkey
string[]
["F8"]
label
string
"通知 ({hotkey})"

自动关闭的 toast。 它不应该被保留打开以获取用户响应

属性类型默认值
asChild
boolean
false
type
enum
"foreground"
duration
number
没有默认值
defaultOpen
boolean
true
open
boolean
没有默认值
onOpenChange
function
没有默认值
onEscapeKeyDown
function
没有默认值
onPause
function
没有默认值
onResume
function
没有默认值
onSwipeStart
function
没有默认值
onSwipeMove
function
没有默认值
onSwipeEnd
function
没有默认值
onSwipeCancel
function
没有默认值
forceMount
boolean
没有默认值
数据属性
[data-state]"open" |"closed"
[data-swipe]"start" |"move" |"cancel" |"end"
[data-swipe-direction]"up" |"down" |"left" |"right"
CSS 变量描述
--radix-toast-swipe-move-x水平滑动时 toast 的偏移位置
--radix-toast-swipe-move-y垂直滑动时 toast 的偏移位置
--radix-toast-swipe-end-x水平滑动后 toast 的偏移结束位置
--radix-toast-swipe-end-y垂直滑动后 toast 的偏移结束位置

标题

可选的 toast 标题。

属性类型默认值
asChild
boolean
false

描述

toast 消息。

属性类型默认值
asChild
boolean
false

操作

为了确保用户不会因为时间限制而产生的意外副作用来完成任务,可以忽略此操作。

当需要获取用户响应时,请在视窗中弹出AlertDialog,并将其样式设置为吐司。

属性类型默认值
asChild
boolean
false
altText*
string
没有默认值

关闭

一个按钮,允许用户在吐司的持续时间结束之前将其关闭。

属性类型默认值
asChild
boolean
false

示例

自定义热键

使用event.code值覆盖默认热键,该值来自keycode.info中的每个键。

<Toast.Provider>
{/* ... */}
<Toast.Viewport hotkey={['altKey', 'KeyT']} />
</Toast.Provider>

自定义持续时间

自定义吐司的持续时间以覆盖提供者值。

<Toast.Root duration={3000}>
<Toast.Description>Saved!</Toast.Description>
</Toast.Root>

重复的吐司

当吐司必须在用户每次点击按钮时出现时,请使用状态渲染多个相同吐司的实例(见下文)。或者,您可以抽象出各个部分以创建您自己的命令式 API

export default () => {
const [savedCount, setSavedCount] = React.useState(0);
return (
<div>
<form onSubmit={() => setSavedCount((count) => count + 1)}>
{/* ... */}
<button>save</button>
</form>
{Array.from({ length: savedCount }).map((_, index) => (
<Toast.Root key={index}>
<Toast.Description>Saved!</Toast.Description>
</Toast.Root>
))}
</div>
);
};

动画滑动手势

--radix-toast-swipe-move-[x|y]--radix-toast-swipe-end-[x|y] CSS 变量与data-swipe="[start|move|cancel|end]"属性结合起来,以动画化滑动关闭手势。以下是一个示例

// index.jsx
import * as Toast from '@radix-ui/react-toast';
import './styles.css';
export default () => (
<Toast.Provider swipeDirection="right">
<Toast.Root className="ToastRoot">...</Toast.Root>
<Toast.Viewport />
</Toast.Provider>
);
/* styles.css */
.ToastRoot[data-swipe='move'] {
transform: translateX(var(--radix-toast-swipe-move-x));
}
.ToastRoot[data-swipe='cancel'] {
transform: translateX(0);
transition: transform 200ms ease-out;
}
.ToastRoot[data-swipe='end'] {
animation: slideRight 100ms ease-out;
}
@keyframes slideRight {
from {
transform: translateX(var(--radix-toast-swipe-end-x));
}
to {
transform: translateX(100%);
}
}

无障碍性

符合aria-live 要求

敏感度

使用type道具控制吐司对屏幕阅读器的敏感度。

对于由用户操作产生的吐司,请选择foreground。从后台任务生成的吐司应使用background

前台

前台吐司会立即宣布。辅助技术可能会选择在出现前台吐司时清除以前排队的消息。尽量避免同时堆叠不同的前台吐司。

背景

背景吐司会在下一个合适的时机宣布,例如,当屏幕阅读器完成当前句子的朗读时。它们不会清除排队的消息,因此在响应用户交互时过度使用它们会导致屏幕阅读器用户体验到滞后的体验。

<Toast.Root type="foreground">
<Toast.Description>File removed successfully.</Toast.Description>
<Toast.Close>Dismiss</Toast.Close>
</Toast.Root>
<Toast.Root type="background">
<Toast.Description>We've just released Radix 1.0.</Toast.Description>
<Toast.Close>Dismiss</Toast.Close>
</Toast.Root>

备用操作

使用Action上的altText道具为屏幕阅读器用户指示执行吐司的备用操作方法。

您可以将用户引导到应用程序中可以执行操作的永久位置,或者实现您自己的自定义热键逻辑。如果实现后者,请使用foreground类型以立即宣布并延长持续时间,以便用户有充足的时间。

<Toast.Root type="background">
<Toast.Title>Upgrade Available!</Toast.Title>
<Toast.Description>We've just released Radix 1.0.</Toast.Description>
<Toast.Action altText="Goto account settings to upgrade">
Upgrade
</Toast.Action>
<Toast.Close>Dismiss</Toast.Close>
</Toast.Root>
<Toast.Root type="foreground" duration={10000}>
<Toast.Description>File removed successfully.</Toast.Description>
<Toast.Action altText="Undo (Alt+U)">
Undo <kbd>Alt</kbd>+<kbd>U</kbd>
</Toast.Action>
<Toast.Close>Dismiss</Toast.Close>
</Toast.Root>

关闭图标按钮

当提供图标(或字体图标)时,请记住为屏幕阅读器用户正确地标记它。

<Toast.Root type="foreground">
<Toast.Description>Saved!</Toast.Description>
<Toast.Close aria-label="Close">
<span aria-hidden>×</span>
</Toast.Close>
</Toast.Root>

键盘交互

描述
F8
将焦点定位到吐司视窗。
Tab
将焦点移动到下一个可聚焦元素。
Shift + Tab
将焦点移动到上一个可聚焦元素。
空格
当焦点位于Toast.Action Toast.Close上时,关闭吐司。
Enter
当焦点位于Toast.Action Toast.Close上时,关闭吐司。
Esc
当焦点位于Toast上时,关闭吐司。

自定义 API

抽象部分

通过将基本部分抽象到您自己的组件中来创建您自己的 API。

用法

import { Toast } from './your-toast';
export default () => (
<Toast title="Upgrade available" content="We've just released Radix 3.0!">
<button onClick={handleUpgrade}>Upgrade</button>
</Toast>
);

实现

// your-toast.jsx
import * as ToastPrimitive from '@radix-ui/react-toast';
export const Toast = ({ title, content, children, ...props }) => {
return (
<ToastPrimitive.Root {...props}>
{title && <ToastPrimitive.Title>{title}</ToastPrimitive.Title>}
<ToastPrimitive.Description>{content}</ToastPrimitive.Description>
{children && (
<ToastPrimitive.Action asChild>{children}</ToastPrimitive.Action>
)}
<ToastPrimitive.Close aria-label="Close">
<span aria-hidden>×</span>
</ToastPrimitive.Close>
</ToastPrimitive.Root>
);
};

命令式 API

创建您自己的命令式 API,以允许吐司重复(如果需要)。

用法

import { Toast } from './your-toast';
export default () => {
const savedRef = React.useRef();
return (
<div>
<form onSubmit={() => savedRef.current.publish()}>
{/* ... */}
<button>Save</button>
</form>
<Toast ref={savedRef}>Saved successfully!</Toast>
</div>
);
};

实现

// your-toast.jsx
import React from 'react';
import * as ToastPrimitive from '@radix-ui/react-toast';
export const Toast = React.forwardRef((props, forwardedRef) => {
const { children, ...toastProps } = props;
const [count, setCount] = React.useState(0);
React.useImperativeHandle(forwardedRef, () => ({
publish: () => setCount((count) => count + 1),
}));
return (
<>
{Array.from({ length: count }).map((_, index) => (
<ToastPrimitive.Root key={index} {...toastProps}>
<ToastPrimitive.Description>{children}</ToastPrimitive.Description>
<ToastPrimitive.Close>Dismiss</ToastPrimitive.Close>
</ToastPrimitive.Root>
))}
</>
);
});
上一个标签
下一个切换