Semi Design Toast 提示组件完全指南:静态方法、堆叠样式与源码实现剖析
前端UI组件设计系统【免费下载链接】semi-designA modern, comprehensive, flexible design system and React UI library, AI-friendly built-in.Provide 3000 Design Tokens, easy to build your design system. Make Semi Design to Any Design.‍ Design to Code in one click项目地址https://gitcode.com/gh_mirrors/se/semi-design点击查看免费下载Toast 是 Semi Designdouyinfe/semi-ui反馈类组件中用于对用户操作给出及时反馈的轻量级提示它由用户操作触发反馈信息可以是操作的结果状态成功、失败、出错、警告等。本篇以官方文档 content/feedback/toast/index.md 为主体骨架结合仓库内 packages/semi-ui/toast 与 packages/semi-foundation/toast 的源码实现系统讲解 Toast 的引入方式、全部静态方法、Options/Config 参数、堆叠模式、Hook 消费 Context、自定义配置工厂以及 ARIA 无障碍与文案规范帮助你从“会调用”进阶到“懂原理”。如何引入Toast 采用命令式imperative调用方式无需在 JSX 中挂载组件直接从组件库导入即可import { Toast } from douyinfe/semi-ui;文档中所有演示代码均可直接运行点击按钮后Toast 会在屏幕顶部默认位置以浮动层形式出现并在duration默认 3 秒后自动关闭。普通提示静态方法的基础用法调用Toast的静态方法即可弹出提示。最基本的用法是传入一个字符串Toast.info(Hi, Bytedance dance dance);也可以传入一个options对象配置内容、展示时长、堆叠行为等import React from react; import { throttle } from lodash-es; import { Toast, Button } from douyinfe/semi-ui; function Demo() { 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, { trailing: false }); return ( div Button onClick{() Toast.info(opts)}Display Toast/Button br / br / Button onClick{throttled}Throttled Toast/Button /div ); }推荐使用 stack 堆叠模式文档特别建议推荐设置stack属性应用堆叠样式到同屏多个 ToastHover 可展开这能有效防止一次性弹出多个并列 Toast 对用户造成干扰。该 API 在v2.42.0之后支持。从源码 packages/semi-ui/toast/toast.tsx 可以看到堆叠模式的实现当stack为true时每个 Toast 外层会包裹一个semi-toast-zero-height-wrapper其高度在未展开时为 0通过 3D 变换transform: translate3d(0, 0, ${reservedIndex * -10}px)见 toast.tsx按索引在 Z 轴方向层叠鼠标悬停onMouseEnter时调用clearCloseTimer暂停关闭计时并展开堆叠区域展示全部内容。对应的层叠过渡动画定义在样式文件 packages/semi-foundation/toast/toast.scss 中使用transition: all $animation_duration-toast-stack $animation_function-toast-stack完成展开/收起。其他提示类型Success / Warning / ErrorToast 共提供四种操作结果反馈类型对应四个静态方法。下面的例子演示了成功、警告、错误三种提示Toast.success可直接传入字符串import React from react; import { Toast, Button } from douyinfe/semi-ui; function Demo() { 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 typewarning onClick{() Toast.warning(opts)} Warning /Button br / br / Button typedanger onClick{() Toast.error(opts)} Error /Button / ); }四种类型的图标映射在 packages/semi-ui/toast/toast.tsx 的renderIcon()中定义warning对应IconAlertTriangle、success对应IconTickCircle、info对应IconInfoCircle、error对应IconAlertCircle。如果你传入自定义iconSemi 图标会被自动放大为large尺寸非 Semi 图标则原样渲染。多色样式theme 浅色填充默认情况下 Toast 使用白色卡片normal模式。通过theme: light可以启用浅色填充样式为不同类型赋予语义背景色提高与界面的对比度import React from react; import { Toast, Button } from douyinfe/semi-ui; function Demo() { let opts { content: Hi, Bytedance dance dance, duration: 3, theme: light, }; 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 typewarning onClick{() Toast.warning(opts)} Warning /Button br / br / Button typedanger onClick{() Toast.error(opts)} Error /Button / ); }theme的可选值在 packages/semi-foundation/toast/constants.ts 中定义为[normal, light]默认值为normalv2.54.0起支持。从源码看light主题通过 toast.scss 中的-light样式为每种类型设置了语义背景色、边框与图标颜色例如成功态使用$color-toast_success_light-bg背景与$color-toast_success_light-border边框。链接文本配合 Typography 自定义内容Toast 的content接受任意ReactNode因此可以配合Typography组件如Text link渲染带链接的文本适用于“查看详情”“稍后处理”等复合操作场景import React from react; import { Toast, Typography, Button } from douyinfe/semi-ui; function Demo() { const { Text } Typography; let opts { content: ( span TextHi, Bytedance dance dance/Text Text link style{{ marginLeft: 12 }} 更多 /Text /span ), duration: 3, }; let multiLineOpts { content: ( divHi, 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 / ); }在渲染层面content会被放入semi-toast-content-text容器见 toast.tsx该容器设置了textMaxWidth对应的maxWidth以及word-wrap: break-word自动换行见 toast.scss因此多行、长文本均能良好展示。修改延时duration 自动关闭duration控制 Toast 自动关闭的延时单位为秒默认值为 3。下面的例子将其设置为 10 秒import React from react; import { Toast, Button } from douyinfe/semi-ui; function Demo() { let opts { content: Hi, Bytedance dance dance, duration: 10, }; return Button onClick{() Toast.info(opts)}Close After 10s/Button; }底层计时逻辑位于 packages/semi-foundation/toast/toastFoundation.tsstartCloseTimer_()读取duration当其为合法数字时通过setTimeout(..., duration * 1000)触发关闭。默认值3定义在 constants.ts 的numbers.duration中。值得注意的细节是Toast 内容区域.semi-toast-content设置了pointer-events: alltoast.scss并且 Toast 本身监听了onMouseEnter/onMouseLeavetoast.tsx鼠标悬停时会暂停关闭计时、移出后恢复避免用户还没读完内容就消失。手动关闭duration 为 0 与 Toast.close(toastId)当duration设置为0时Toast 不会自动关闭此时必须通过手动方式关闭。每次调用Toast.info()等静态方法会返回一个toastId用它即可精确关闭对应 Toastimport React, { useState } from react; import { Toast, Button } from douyinfe/semi-ui; function Demo() { const [toastId, setToastId] useState(); function show() { if (toastId) { return; } let id Toast.info(opts); setToastId(id); } function hide() { Toast.close(toastId); destroy(); } function destroy() { setToastId(null); } let opts { content: Not auto close, duration: 0, onClose: destroy, }; return ( Button typeprimary onClick{show} Show Toast /Button br / br / Button typeprimary onClick{hide} Hide Toast /Button / ); }这里演示了“显示后记住toastId→ 点击按钮通过Toast.close(toastId)关闭”的完整闭环同时通过onClose回调把本地 state 复位防止重复弹出。源码层面Toast.close(id)最终调用ToastListFoundation.removeToast(id)见 packages/semi-foundation/toast/toastListFoundation.ts它先把目标 Toast 从list中摘除并放入removedItems随后由 React 侧的CSSAnimation播放离场动画动画结束后才真正卸载节点并清理计时器见 packages/semi-ui/toast/index.tsx保证关闭过程平滑且无内存残留。更新消息内容通过唯一 id当你需要改变一条已存在 Toast 的内容时例如从“上传中”变为“上传成功”无需关闭重建直接传入相同的id即可触发更新import React, { useState } from react; import { Toast, Button } from douyinfe/semi-ui; function Demo() { 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 typeprimary onClick{show} Update Content By Id /Button ); }更新流程在 packages/semi-ui/toast/index.tsx 中实现静态create方法会先通过ToastList.ref.has(id)判断该 id 是否已存在若存在则走update(id, opts)分支调用ToastListFoundation.updateToasttoastListFoundation.ts以浅合并方式替换该条 Toast 的配置并记录到updatedItems渲染阶段通过 ref 回调检测到更新项后会调用restartCloseTimer()重新计时index.tsx避免内容刚更新就被旧计时器关闭。销毁所有Toast.destroyAll()需要一次性清空屏幕上所有 Toast 时使用全局销毁方法Toast.destroyAll()从源码看destroyAll()会先调用ToastListFoundation.destroyAll()把所有 Toast 移入removedItems播放离场动画随后reactUnmount(wrapper)卸载整个 ToastList 实例并移除挂载容器、重置静态引用packages/semi-ui/toast/index.tsx。消费 ContextToast.useToast()命令式 API 的 Toast 默认渲染在document.body下无法读取组件树中的 Context。若希望 Toast 内容能消费到业务 Context可以使用Toast.useToast()创建contextHolder将其插入组件树的任意位置此时通过 hooks 创建的 Toast 会渲染在contextHolder所在节点处并拿到该位置的全部上下文import React from react; import { Toast, Button } from douyinfe/semi-ui; const ReachableContext React.createContext(); function Demo(props {}) { const [toast, contextHolder] Toast.useToast(); const config { duration: 0, title: This is a success message, content: ReachableContext.Consumer{name ReachableContext: ${name}}/ReachableContext.Consumer, }; return ( ReachableContext.Provider valueLight div Button onClick{() { toast.success(config); }} Hook Toast /Button /div {contextHolder} /ReachableContext.Provider ); }hook 返回的 toast 对象拥有以下方法info、success、warning、error、close。其实现位于 packages/semi-ui/toast/useToast/index.tsxuseToast内部通过usePatchElement维护一个 elements 数组addToast为每次调用生成semi_toast_前缀的 uuid并渲染一个 HookToast 到 contextHolder 中close(id)则通过 ref Map 找到对应实例执行关闭。注意由于 toast 渲染位置变化hook 模式的 Toast 与命令式 Toast 在 DOM 挂载节点、以及能否读取 Context 上存在差异需要根据场景二选一。创建不同配置 ToastToastFactory.create(config)如果应用的不同区域需要差异化的 Toast 默认配置比如把 Toast 渲染到指定容器可以使用ToastFactory.create(config)创建新的 Toast 实例 1.23版本支持import React from react; import { Button, ToastFactory } from douyinfe/semi-ui; function Demo() { const ToastInCustomContainer ToastFactory.create({ getPopupContainer: () document.getElementById(custom-toast-container), }); 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 idcustom-toast-containercustom container/div /div ); }ToastFactory.create(config)的实现见 packages/semi-ui/toast/index.tsx它调用createBaseToast()生成一个全新的 ToastList 类并对其调用config(config)应用独立配置因此两个实例互不干扰——Toast与ToastInCustomContainer拥有各自的默认配置、挂载容器与内部状态。文档中提示该模式常用于覆盖全局配置。API 参考静态方法总览Toast 组件提供的静态方法使用方式与参数如下。展示时可直接传入options对象或string全局配置在调用前提前配置全局一次生效Toast.config(config)直接展示 ToastToast.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); // 手动关闭config方法对全局默认值的写入逻辑在 packages/semi-ui/toast/index.tsxtop/left/bottom/right直接写入defaultOptstheme需命中strings.themes白名单zIndex、duration需为数字getPopupContainer需为函数。此外四个展示方法在内部都会合并全局覆盖配置semiGlobal.config.overrideDefaultProps.Toast优先级为opts 全局配置 defaultOpts见 index.tsx这也是ToastFactory.create之外的另一种全局定制入口。Options 参数说明Toast Options 支持以下 API同时也支持 Config 中的全部 API属性说明类型默认值版本content提示内容ReactNode-icon自定义图标ReactNode--showClose是否展示关闭按钮booleantrue-textMaxWidth内容的最大宽度number | string450-onClosetoast 关闭的回调函数() void--stack是否堆叠 Toastbooleanfalse2.42.0id自定义 ToastIdnumber--这些默认值在 packages/semi-ui/toast/toast.tsx 的defaultProps中均有对应定义showClose默认为true、textMaxWidth默认为450、stack默认为false、theme默认为normal。showClose为true时会在内容右侧渲染一个borderless主题、small尺寸的关闭按钮toast.tsx点击后调用foundation.close(e)关闭并停止事件冒泡。Config 全局配置参数说明以下 API 支持全局配置用于更改当前 Toast 的默认配置属性说明类型默认值版本bottom弹出位置 bottomnumber | string--left弹出位置 leftnumber | string--right弹出位置 rightnumber | string--top弹出位置 topnumber | string--zIndex弹层 z-index 值number1010-theme填充样式支持light、normalstringnormal2.54.0duration自动关闭的延时单位 s设为 0 时不自动关闭number3-getPopupContainer指定父级 DOM弹层将会渲染至该 DOM 中。自定义时需要设置 container 和内部的.semi-toast-wrapper为position: relative。这会改变浮层 DOM 树位置但不会改变视图渲染位置。() HTMLElement | null() document.body-位置与 z-index 的应用逻辑位于 packages/semi-ui/toast/index.tsx首次创建 Toast 时系统会动态生成一个semi-toast-wrapper容器挂载到document.body或getPopupContainer指定的节点将top/left/bottom/right写入容器的内联样式数字类型自动拼接px并把zIndex作为容器的层级。容器本身是position: fixed的见 toast.scss默认位于屏幕顶部中央。Accessibility 无障碍ARIAToast 的role为alert。实现上Toast 根元素渲染了rolealert以及aria-label${type} typepackages/semi-ui/toast/toast.tsx使屏幕阅读器能够及时播报操作结果符合反馈类组件的无障碍要求。文案规范Toast 作为高频出现的轻量反馈文案质量直接影响产品体验。Semi 官方给出以下规范保持简洁句尾不使用句号使用「名词 动词」的格式进行说明✅ 推荐用法❌ 不推荐用法Language addedNew language has been added successfullyTicket transfer failedCant transfer ticket提供动作的提示消息只提供一个动作不使用类似于「已读」类的动作例如 OK、Got it、Dismiss、Cancel✅ 推荐用法❌ 不推荐用法Ticket transfer failed Retry重试动作Ticket transfer failed Dismiss已读类动作设计变量Toast 组件的全部设计变量Design Tokens可在文档页下方通过DesignToken/查看涵盖背景色、边框色、图标色、圆角、间距、动画时长与缓动函数等对应样式变量定义见 packages/semi-foundation/toast/variables.scss 与 animation.scss支持通过 Semi 的主题定制能力统一调整。这些变量同时服务于normal与light两种主题是自定义品牌外观的入口。小结Toast 是 Semi Design 中最常用的轻量反馈组件之一其核心要点可归纳为命令式 APIToast.info/success/warning/error四类静态方法参数支持字符串或 options 对象返回toastId供Toast.close手动关闭全局配置Toast.config()一次性修改默认行为位置、zIndex、theme、duration、挂载容器ToastFactory.create()可创建互相独立的配置实例进阶能力stack堆叠v2.42.0、theme: light彩色样式v2.54.0、按id更新内容、useToast消费 Context、destroyAll全量销毁工程细节默认 3 秒自动关闭、鼠标悬停暂停计时、rolealert无障碍支持以及源码中 Foundation/组件双层架构与removedItems CSSAnimation的平滑离场机制。掌握这些 API 与底层行为后你可以在任何 React 应用中快速构建专业、可访问、体验统一的 Toast 反馈体系。赞分享前端UI组件设计系统【免费下载链接】semi-designA modern, comprehensive, flexible design system and React UI library, AI-friendly built-in.Provide 3000 Design Tokens, easy to build your design system. Make Semi Design to Any Design.‍ Design to Code in one click项目地址https://gitcode.com/gh_mirrors/se/semi-design点击查看免费下载相关推荐Semi Design Toast 轻提示组件完全指南静态方法、Hook 与源码实现解析Semi Design Toast 轻提示组件完全指南静态方法、Hook 与源码实现解析 Toast 是 Semi Design 反馈类Feedback组前端UI组件设计系统Semi Design Notification 通知组件完全指南静态方法、Hooks 用法与源码级原理剖析Semi Design Notification 通知组件完全指南静态方法、Hooks 用法与源码级原理剖析 Notification 是 Semi Desi前端UI组件设计系统Ant Design Message 组件完全指南全局消息提示的静态方法、Hooks 用法与源码级原理剖析Ant Design Message 组件完全指南全局消息提示的静态方法、Hooks 用法与源码级原理剖析 Message 是 Ant Design 中面向全前端UI组件设计系统上一篇RapidOCR与LangChain集成构建智能文档处理系统的终极指南下一篇SyncTrayzor注册表设置修改默认行为的高级技巧创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考