代码演示
如何引入
import { Toast } from '@fibrous/semi-ui-react';
普通提示
通过调用 Toast的相关 method 可以实现弹出提示。推荐设置 stack 属性应用堆叠样式到同屏多个 Toast,Hover 展开,可有效防止一次性弹出多个并列 Toast 对用户造成干扰。
代码
import { throttle } from 'es-toolkit';
import { Toast, Button } from '@fibrous/semi-ui-react';
export default function ToastDemo() {
const opts = {
content: 'Hi, Bytedance dance dance',
duration: 3,
stack: true,
};
const handleClose = () => {
throttled.cancel();
};
const throttleOpts = {
content: 'Hi, Bytedance dance dance',
duration: 10,
onClose: handleClose,
stack: true,
};
const throttled = throttle(() => Toast.info(throttleOpts), 10000, { edges: ['leading'] });
return (
<div>
<Button onClick={() => Toast.info(opts)}>Display Toast</Button>
<br />
<br />
<Button onClick={throttled}>Throttled Toast</Button>
</div>
);
}其他提示类型
包括成功、失败、警告
代码
import { Toast, Button } from '@fibrous/semi-ui-react';
export default function ToastDemo() {
let opts = {
content: 'Hi, Bytedance dance dance',
duration: 3,
};
return (
<>
<Button style={{ color: `var(--semi-color-success)` }} onClick={() => Toast.success('Hi,Bytedance dance dance')}>
Success
</Button>
<br />
<br />
<Button type="warning" onClick={() => Toast.warning(opts)}>
Warning
</Button>
<br />
<br />
<Button type="danger" onClick={() => Toast.error(opts)}>
Error
</Button>
</>
);
}多色样式
可以使用 theme 设置浅色填充样式提高与界面的对比,默认为 'normal' 的白色模式。
代码
import { Toast, Button } from '@fibrous/semi-ui-react';
export default function ToastDemo() {
let opts = {
content: 'Hi, Bytedance dance dance',
duration: 3,
theme: 'light',
} as const;
return (
<>
<Button onClick={() => Toast.info(opts)}>Info</Button>
<br />
<br />
<Button style={{ color: `var(--semi-color-success)` }} onClick={() => Toast.success(opts)}>
Success
</Button>
<br />
<br />
<Button type="warning" onClick={() => Toast.warning(opts)}>
Warning
</Button>
<br />
<br />
<Button type="danger" onClick={() => Toast.error(opts)}>
Error
</Button>
</>
);
}堆叠样式
设置 stack 后,同屏 Toast 超过阈值时堆叠展示,Hover 展开。true 的阈值为 3,传数字可自定义阈值;堆叠时只显示最前面的 3 层。
代码
import { Toast, Button } from '@fibrous/semi-ui-react';
export default function ToastDemo() {
const opts = {
content: 'Hi, Bytedance dance dance',
duration: 10,
stack: true,
};
return (
<Button
onClick={() => {
Toast.info(opts);
}}
>
多次点击
</Button>
);
}链接文本
配合 Typography 可以自定义链接文本,用来配合更复杂的场景的使用。
代码
import { Toast, Typography, Button } from '@fibrous/semi-ui-react';
export default function ToastDemo() {
const { Text } = Typography;
let opts = {
content: (
<span>
<Text>Hi, Bytedance dance dance</Text>
<Text link style={{ marginLeft: 12 }}>
更多
</Text>
</span>
),
duration: 3,
};
let multiLineOpts = {
content: (
<>
<div>Hi, Bytedance dance dance</div>
<div style={{ marginTop: 8 }}>
<Text link>查看详情</Text>
<Text link style={{ marginLeft: 20 }}>
一会再看
</Text>
</div>
</>
),
duration: 3,
};
return (
<>
<Button onClick={() => Toast.info(opts)}>Display Toast</Button>
<br />
<br />
<Button onClick={() => Toast.info(multiLineOpts)}>Display Multi-line Toast</Button>
</>
);
}修改延时
自定义时长 10s,默认时长为 3s
代码
import { Toast, Button } from '@fibrous/semi-ui-react';
export default function ToastDemo() {
let opts = {
content: 'Hi, Bytedance dance dance',
duration: 10,
};
return <Button onClick={() => Toast.info(opts)}>Close After 10s</Button>;
}手动关闭
当 duration 设置为 0 时,toast 不会自动关闭,此时必须通过手动关闭。
代码
import { useState } from 'react';
import { Toast, Button } from '@fibrous/semi-ui-react';
export default function ToastDemo() {
const [toastId, setToastId] = useState<string | null>(null);
function show() {
if (toastId) {
return;
}
let id = Toast.info(opts);
setToastId(id);
}
function hide() {
if (toastId) {
Toast.close(toastId);
}
destroy();
}
function destroy() {
setToastId(null);
}
let opts = {
content: 'Not auto close',
duration: 0,
onClose: destroy,
};
return (
<>
<Button type="primary" onClick={show}>
Show Toast
</Button>
<br />
<br />
<Button type="primary" onClick={hide}>
Hide Toast
</Button>
</>
);
}更新消息内容
可以通过唯一的 id 来更新内容。
代码
import { Toast, Button } from '@fibrous/semi-ui-react';
export default function ToastDemo() {
function show() {
const id = 'toastid';
Toast.info({ content: 'Update Content By Id', id });
setTimeout(() => {
Toast.success({ content: 'Id By Content Update', id });
}, 1000);
}
return (
<Button type="primary" onClick={show}>
Update Content By Id
</Button>
);
}销毁所有
全局销毁:
Toast.destroyAll()
消费 Context
通过 Toast.useToast 创建支持读取 context 的 contextHolder。此时的 toast 会渲染在 contextHolder 所在的节点处。
Toast.useToast() 返回元组 [toast, contextHolder]:toast 对象的 info、success、warning、error、open 接收不含 type、id、zIndex、getPopupContainer 的 Options,返回 toastId;close(toastId) 手动关闭。
代码
import React from 'react';
import { Toast, Button } from '@fibrous/semi-ui-react';
const ReachableContext = React.createContext<string | undefined>(undefined);
export default function ToastDemo() {
const [toast, contextHolder] = Toast.useToast();
const config = {
duration: 0,
content: <ReachableContext.Consumer>{(name) => `ReachableContext: ${name}`}</ReachableContext.Consumer>,
};
return (
<ReachableContext.Provider value="Light">
<div>
<Button
onClick={() => {
toast.success(config);
}}
>
Hook Toast
</Button>
</div>
{contextHolder}
</ReachableContext.Provider>
);
}创建不同配置 Toast
ToastFactory.create(config) => Toast
如果您的应用中需要使用不同 config 的 Toast,可以使用 ToastFactory.create(config)创建新的 Toast:
代码
import { useEffect } from 'react';
import { Button, ToastFactory, Toast } from '@fibrous/semi-ui-react';
const ToastInCustomContainer = ToastFactory.create({
getPopupContainer: () => document.getElementById('custom-toast-container') as HTMLElement,
});
export default function ToastDemo() {
useEffect(() => () => ToastInCustomContainer.destroyAll(), []);
return (
<div>
<Button onClick={() => Toast.info('Toast')}>Default Toast</Button>
<br />
<br />
<Button onClick={() => ToastInCustomContainer.info('Toast in some container')}>Toast in custom container</Button>
<div id="custom-toast-container">custom container</div>
</div>
);
}API 参考
组件提供的静态方法,使用方式和参数如下:展示:可以直接传入 options 对象或 string:
全局配置, 在调用前提前配置,全局一次生效
Toast.config(config)Toast.resetConfig()将全局配置恢复为默认值,只影响之后弹出的 Toast。ToastFactory.create(config)创建的实例恢复为创建时传入的config
直接展示 Toast
Toast.info(options || string)Toast.error(options || string)Toast.warning(options || string)Toast.success(options || string)
info error warning success 返回值为toastId, 可用于手动关闭
const toastId = Toast.info({ /*...options*/ })
Toast.close(toastId)手动关闭
Options
Toast Options 支持以下 API 及 Config 中的 API
| 属性 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| content | 提示内容 | ReactNode | '' |
| icon | 自定义图标 | ReactNode | |
| showClose | 是否展示关闭按钮 | boolean | true |
| textMaxWidth | 内容的最大宽度 | number | string | 450 |
| onClose | toast 关闭的回调函数 | () => void | |
| stack | 同屏 Toast 超过多少条时堆叠展示,true 为 3,false 不堆叠 | boolean | number | false |
| id | 自定义 ToastId | string | |
| motion | 是否开启进出场动画 | boolean | true |
| className | 类名 | string | |
| style | 样式 | CSSProperties |
className、style 与未声明的选项(如 data-*)落在 .semi-toast 上,堆叠模式下同样如此。
Config
以下 API 支持全局配置,用于更改当前 Toast 的默认配置
| 属性 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| bottom | 弹出位置 bottom | number | string | - |
| left | 弹出位置 left | number | string | - |
| right | 弹出位置 right | number | string | - |
| top | 弹出位置 top | number | string | - |
| zIndex | 弹层 z-index 值 | number | 1010 |
| theme | 填充样式,支持 light, normal | string | normal |
| duration | 自动关闭的延时,单位 s,设为 0 时不自动关闭 | number | 3 |
| getPopupContainer | 指定父级 DOM,弹层将会渲染至该 DOM 中,自定义需要设置 container 和 内部的 .semi-toast-wrapper position: relative, 这会改变浮层 DOM 树位置,但不会改变视图渲染位置。 | () => HTMLElement | () => document.body |
Accessibility
ARIA
- Toast 的 role 按类型区分:
warning、error为alert,info、success与没有type的为status status类 Toast 由列表常驻的aria-live="polite"播报区朗读,Toast 自身为aria-live="off",只播报content的文本;warning、error仍由alert自行播报
键盘和焦点
- 关闭按钮是原生
button,可以用Tab聚焦,Enter或Space触发关闭 - Toast 出现时不会抢走焦点
- 指针或键盘焦点进入 Toast 时暂停自动关闭的计时,并展开堆叠;移出后恢复计时
文案规范
- 保持简洁
- 句尾不使用句号
- 使用 名词 + 动词 的格式进行说明
| ✅ 推荐用法 | ❌ 不推荐用法 |
|---|---|
| Language added | New language has been added successfully |
| Ticket transfer failed | Can't transfer ticket |
- 提供动作的提示消息
- 只提供一个动作
- 不使用类似于「已读」类的动作,例如 OK, Got it, Dismiss, Cancel
| ✅ 推荐用法 | ❌ 不推荐用法 |
|---|---|
Ticket transfer failed Retry | Ticket transfer failed Dismiss |
设计变量
| Sass 变量 | 值 | 用法 |
|---|---|---|
| $animation_duration-toast-show | 300ms | |
| $animation_duration-toast-hide | 300ms | |
| $animation_function-toast-show | cubic-bezier(0.22, 0.57, 0.02, 1.2) | |
| $animation_function-toast-hide | cubic-bezier(0.22, 0.57, 0.02, 1.2) | |
| $animation_delay-toast-show | 0s | |
| $animation_delay-toast-hide | 0s | |
| $animation_opacity-toast-show | 0 | |
| $animation_opacity-toast-hide | 0 | |
| $animation_transform_translateY-toast-show | -100% | |
| $animation_transform_translateY-toast-hide | -100% | |
| $animation_duration-toast-stack | 300ms | |
| $animation_function-toast-stack | cubic-bezier(0.22, 0.57, 0.02, 1.2) | |
| $color-toast-bg-default | var(--semi-color-bg-3) | 提示背景颜色 - 默认 |
| $color-toast-text-default | var(--semi-color-text-0) | 提示文字颜色 - 默认 |
| $color-toast_warning-icon | var(--semi-color-warning) | 警告提示图标颜色 |
| $color-toast_success-icon | var(--semi-color-success) | 成功提示图标颜色 |
| $color-toast_info-icon | var(--semi-color-info) | 通知提示图标颜色 |
| $color-toast_danger-icon | var(--semi-color-danger) | 错误提示图标颜色 |
| $color-toast_warning_light-bg | var(--semi-color-warning-light-default) | 多色样式 警告提示背景颜色 |
| $color-toast_warning_light-icon | $color-toast_warning-icon | 多色样式 警告提示图标颜色 |
| $color-toast_warning_light-border | var(--semi-color-warning) | 多色样式 警告提示描边颜色 |
| $color-toast_success_light-bg | var(--semi-color-success-light-default) | 多色样式 成功提示背景颜色 |
| $color-toast_success_light-icon | $color-toast_success-icon | 多色样式 成功提示图标颜色 |
| $color-toast_success_light-border | var(--semi-color-success) | 多色样式 成功提示描边颜色 |
| $color-toast_info_light-bg | var(--semi-color-info-light-default) | 多色样式 通知提示背景颜色 |
| $color-toast_info_light-icon | $color-toast_info-icon | 多色样式 通知提示图标颜色 |
| $color-toast_info_light-border | var(--semi-color-info) | 多色样式 通知提示描边颜色 |
| $color-toast_danger_light-bg | var(--semi-color-danger-light-default) | 多色样式 错误提示背景颜色 |
| $color-toast_danger_light-icon | $color-toast_danger-icon | 多色样式 错误提示图标颜色 |
| $color-toast_danger_light-border | var(--semi-color-danger) | 多色样式 错误提示描边颜色 |
| $spacing-toast_wrapper-top | 0 | 通知容器顶部位置 |
| $spacing-toast_content-paddingY | $spacing-base-tight | 通知内容垂直内边距 |
| $spacing-toast_content-paddingX | $spacing-tight | 通知内容水平内边距 |
| $spacing-toast_content-paddingTop | $spacing-toast_content-paddingY | 通知内容 top 内边距 |
| $spacing-toast_content-paddingBottom | $spacing-toast_content-paddingY | 通知内容 bottom 内边距 |
| $spacing-toast_content-paddingLeft | $spacing-toast_content-paddingX | 通知内容 left 内边距 |
| $spacing-toast_content-paddingRight | $spacing-toast_content-paddingX | 通知内容 right 内边距 |
| $spacing-toast_content-margin | $spacing-base-tight | 通知内容外边距 |
| $spacing-toast_content_close_btn-marginTop | -2px | 通知关闭按钮顶部外边距 |
| $spacing-toast_content_text-marginLeft | $spacing-base-tight | 通知文本左侧外边距 |
| $spacing-toast_content_text-marginRight | $spacing-base-tight | 通知文本右侧外边距 |
| $spacing-toast-perspective-originY | 280px | 通知透视原点 Y 轴位置 |
| $spacing-toast-perspective | 280px | 通知透视距离 |
| $width-toast_wrapper | 100% | 通知容器整体宽度 |
| $width-toast_light-border | 1px | 多色样式 通知描边宽度 |
| $radius-toast_content | var(--semi-border-radius-medium) | 通知圆角 |
| $font-toast_content-fontWeight | $font-weight-bold | 通知文本字重 |