跳转到内容

Toast 轻提示 ​

一条会自动消失的短反馈:状态字形、标题与可选的一行补充说明。

用法 ​

默认由状态图标、文本列和悬停显示的关闭按钮组成;duration 设为 0 即不自动消失

草稿已保存

组件结构 ​

加粗的是必需部件。

data-scope="toast":root · indicator · content · title · description · action-trigger · progress · close-trigger · group

示例 ​

颜色 ​

卡片保持中性,tone 只改变标题与状态字形;danger 使用 assertive 实时区,loading 另有一档,显示加载且不自动消失

草稿已保存
发布成功
配额即将用尽
同步失败,稍后自动重试
正在上传

计时与暂停 ​

duration 结束后自动退场;指针停在提示条上或焦点进入提示条内都会暂停计时,离开后继续剩余部分

6 秒后自动收走
状态:visible · 计时在走

操作按钮 ​

action-trigger 按下时先发 action 事件,再使该条进入退场;closable 决定是否保留关闭按钮

已删除 1 个文件
(还没点)

补充说明 ​

description 提供一行简短上下文;需要长时间阅读的内容改用 Notification

文件已上传
可在项目资源中继续查看

全局服务 ​

轻提示没有容器组件,堆叠区由 createToastService 渲染;模块作用域随处可调用(请求拦截器、store)

设计指引 ​

何时使用 ​

  • 一次操作的结果:“已保存”“已复制”“发送失败”。
  • 反馈重要但不需要打断用户。

何时不用 ​

  • 用户必须知道并处理时,使用警告提示常驻,或使用对话框阻断。
  • 内容较长、需要持续阅读,或不是由用户操作触发时,使用通知。

特性 ​

  • duration 默认 4000ms;指针悬停或焦点进入时暂停计时,全局服务还会在页面转入后台时暂停。
  • 可以带一个操作按钮(撤销、查看详情)。
  • tone 只改变标题与状态字形,卡片始终使用中性浮层;loading 单独一档,字形换为旋转指示器且不自动消失。
  • closable 默认开启;悬停或焦点进入卡片时显示关闭按钮。
  • 全局服务默认将最新一条置于最前,后两层按 12px 偏移与 0.05 比例收拢;鼠标或焦点进入后按真实高度展开。

组合 ​

  • 没有容器组件:全局服务在底部渲染队列,默认最多显示 3 条、间距 12px。
  • content 是必需的文本列,内部组合 title 与可选的 description。

最佳实践 ​

  • 破坏性操作配“撤销”按钮,体验优于事前确认对话框。
  • 错误类提示停留更久,或不自动消失。

反模式 ​

  • 把错误详情放进轻提示,用户尚未读完就消失。
  • 同一个动作连续发出多条。

API 参考 ​

产物 ​

层值
自定义元素<xh-toast>
Vue 组件XhToastActionTrigger XhToastCloseTrigger XhToastContent XhToastDescription XhToastIndicator XhToastProgress XhToastRoot XhToastTitle
组合式函数useToast
状态机toastMachine
皮肤@xihan-ui/styles/toast.css

Props ​

属性类型必填说明
idstring队列身份。服务档用它作为 create / update / dismiss 的寻址键。
titlestring标题文本;作者未在 title 部件中写内容时由适配器填入。
descriptionstring可选的补充说明;应保持简短,需要持续阅读的长内容改用 notification。
toneToastTone语气,默认 info。danger 使用 alert + assertive。
loadingboolean事情尚未完成:行首换为转圈,且不自动消失(duration 不再生效),完成后改写为其他语气收尾。
durationnumber停留毫秒,默认 4000。<=0 或非有限数即不自动消失。
closableboolean是否显示可用的关闭按钮,默认 true。
pauseOnPageIdleboolean页面切到后台时暂停计时,默认 false;全局服务默认开启。
pausedboolean由宿主暂停计时,默认 false。整组一起暂停经此路径: 置真时登记 'service' 暂停来源,置假时移除它,与指针、焦点等来源并存。
translationsPartial<ToastTranslations>
onStatusChange(details: ToastStatusChangeDetails) => void生命周期落定时通知:dismissing 与 unmounted 各一次。宿主据此把条目移出队列。
onAction(details: ToastActionDetails) => void操作按钮被按下。

事件 ​

自定义元素将载荷放在 detail;Vue 使用同名 emit。

事件载荷说明
status-changeToastStatusChangeDetails生命周期落定;detail 为 { id: string, status: 'dismissing'|'unmounted' }
actionToastActionDetails操作按钮被按下;detail 为 { id: string }

插槽 ​

仅列出带载荷的插槽。

Vue 组件插槽载荷说明
XhToastRootdefaultToastRootSlotProps

React 适配器 props ​

只列各组件自己声明的那些:继承自 ComponentPropsWithRef 的 DOM 属性不在其中,根组件上与上面 Props 表同名的也不重复列。Vue 的对应物是上面的插槽表。

React 组件属性类型必填说明
XhToastRootchildrenSlotChildren<ToastRootSlotProps>

状态 ​

公开状态写入 data-state。

部件取值
roottoStatus(state.get())
progresstoStatus(state.get())

以下名称仅用于内部状态机。

状态:visible · visible.running · visible.paused · dismissing · unmounted

事件:TOAST.DISMISS · TOAST.ACTION · TOAST.PAUSE · TOAST.RESUME · TOAST.RESET · after.duration · EXIT.COMPLETE · PRESS.START · PRESS.END

判据:isLastPauseSource · canPress

connect API ​

getXxxProps() 返回对应部件的宿主属性。

成员类型说明
idstring
statusToastStatus
toneToastTone
loadingboolean
titlestring | undefined
descriptionstring | undefined
pausedboolean计时暂停中。倒计时的可见反馈由使用者自行渲染,该标记是留给使用者的钩子:自带皮肤不绘制。
closableboolean
remainingnumber剩余毫秒;不自动消失时为 Infinity。
dismiss() => void
pause() => void
resume() => void
durationnumber停留总时长(毫秒);不自动消失时为 Infinity。
getRootProps() => T['element']
getIndicatorProps() => T['element']语气指示符:作者放入自己的图形,未放入时由皮肤按语气绘制兜底字形,加载中换为转圈。
getContentProps() => T['element']标题与说明的文本列。
getTitleProps() => T['element']
getDescriptionProps() => T['element']
getActionTriggerProps() => T['button']
getProgressProps() => T['element']倒计时条:不自动消失时收起。
getCloseTriggerProps() => T['button']

无障碍 ​

键盘 ​

规格出处:W3C APG

按键生效条件行为
Enter / Spacefocus 在 close-trigger 上且 closable立即进入 dismissing,退场动画播完后转 unmounted
Enter / Spacefocus 在 action-trigger 上触发 onAction 并进入 dismissing
Enter / Spaceheld in close-trigger / action-trigger(close-trigger 须 closable)按住期间该按钮投影 data-pressed,与指针 :active 同一副按压面;抬起、失焦或进入退场撤下。notification 的卡片按钮同此

ARIA ​

以下属性由 connect 生成。

部件属性值
rootaria-atomic'true'
rootaria-describedbydescription 部件的 id | undefined
rootaria-labelledbytitle 部件的 id
rootaria-live'assertive' | 'polite'
rootrole'alert' | 'status'
indicatoraria-hidden'true'
progressaria-hidden'true'
close-triggeraria-labelprops.translations.close

样式参考 ​

皮肤 ​

@xihan-ui/styles/toast.css 使用 [data-scope="toast"][data-part="root"] 部件选择器,位于 xihan.components 与 xihan.motion 层。覆盖样式使用 xihan.overrides。

数据属性 ​

由 connect 生成;条件不成立时不输出无值属性。

部件属性值
rootdata-loading''(条件成立时才出现)
rootdata-paused''(条件成立时才出现)
rootdata-statetoStatus(state.get())
rootdata-toneprops.tone
indicatordata-loading''(条件成立时才出现)
action-triggerdata-pressed''(条件成立时才出现)
action-triggerdata-xh-action-control''
action-triggerdata-xh-action-display'always'
action-triggerdata-xh-action-profile'text'
action-triggerdata-xh-action-size'sm'
action-triggerdata-xh-action-variant'outline'
progressdata-statetoStatus(state.get())
close-triggerdata-disabled''(条件成立时才出现)
close-triggerdata-pressed''(条件成立时才出现)
close-triggerdata-xh-action-control''
close-triggerdata-xh-action-display'always'
close-triggerdata-xh-action-profile'icon'
close-triggerdata-xh-action-size'xs'
close-triggerdata-xh-action-variant'ghost'

CSS 变量 ​

本组件公开覆盖槽由独立皮肤的实际消费位生成;默认来源、作用部件和状态均与 CSS 同源。

变量部件CSS 属性状态默认来源说明
--xh-toast-action-bgaction-trigger--xh-ink-surface
background-color
default
xh-ink-surface
transparenttoast 的 action-trigger 部件 --xh-ink-surface、background-color 覆盖槽。
--xh-toast-action-bg-activeaction-triggerbackground-colordisabled
is(:active, [data-pressed])
loading
not([data-disabled])
not([data-loading])
pressed
--xh-bg-subtle-hovertoast 的 action-trigger 部件 background-color 覆盖槽。
--xh-toast-action-bg-hoveraction-triggerbackground-colordisabled
hover
loading
not([data-disabled])
not([data-loading])
--xh-bg-subtletoast 的 action-trigger 部件 background-color 覆盖槽。
--xh-toast-action-borderaction-triggerborder
border-color
default
disabled
hover
is(:active, [data-pressed])
loading
not([data-disabled])
not([data-loading])
pressed
--xh-border-control
--xh-border-control-hover
toast 的 action-trigger 部件 border、border-color 覆盖槽。
--xh-toast-action-fgaction-triggercolordefault
disabled
hover
is(:active, [data-pressed])
loading
not([data-disabled])
not([data-loading])
pressed
--xh-fg-defaulttoast 的 action-trigger 部件 color 覆盖槽。
--xh-toast-action-font-weightaction-triggerfont-weightdefault--xh-font-weight-mediumtoast 的 action-trigger 部件 font-weight 覆盖槽。
--xh-toast-action-haction-triggerblock-size
inline-size
default
xh-action-profile=icon
--xh-_action-profile-visual-sizetoast 的 action-trigger 部件 block-size、inline-size 覆盖槽。
--xh-toast-action-pxaction-triggerpadding-inlinedefault--xh-_action-profile-padding-inlinetoast 的 action-trigger 部件 padding-inline 覆盖槽。
--xh-toast-action-radiusaction-triggerborder-radiusdefault--xh-shape-controltoast 的 action-trigger 部件 border-radius 覆盖槽。
--xh-toast-bgrootbackgrounddefault--xh-material-elevated-bgtoast 的 root 部件 background 覆盖槽。
--xh-toast-borderrootborderdefault--xh-material-elevated-bordertoast 的 root 部件 border 覆盖槽。
--xh-toast-close-bgclose-trigger--xh-ink-surface
background-color
default
xh-ink-surface
--xh-_action-variant-bg-resttoast 的 close-trigger 部件 --xh-ink-surface、background-color 覆盖槽。
--xh-toast-close-bg-activeclose-triggerbackground-colordisabled
is(:active, [data-pressed])
loading
not([data-disabled])
not([data-loading])
pressed
--xh-_action-variant-bg-pressedtoast 的 close-trigger 部件 background-color 覆盖槽。
--xh-toast-close-bg-hoverclose-triggerbackground-colordisabled
hover
loading
not([data-disabled])
not([data-loading])
--xh-_action-variant-bg-hovertoast 的 close-trigger 部件 background-color 覆盖槽。
--xh-toast-close-borderclose-triggerborderdefault--xh-_action-variant-border-resttoast 的 close-trigger 部件 border 覆盖槽。
--xh-toast-close-fgclose-triggercolordefault--xh-fg-mutedtoast 的 close-trigger 部件 color 覆盖槽。
--xh-toast-close-fg-hoverclose-triggercolordisabled
hover
is(:active, [data-pressed])
loading
not([data-disabled])
not([data-loading])
pressed
--xh-fg-defaulttoast 的 close-trigger 部件 color 覆盖槽。
--xh-toast-close-radiusclose-triggerborder-radiusdefault--xh-shape-controltoast 的 close-trigger 部件 border-radius 覆盖槽。
--xh-toast-close-sizeclose-triggerblock-size
inline-size
min-inline-size
default
xh-action-profile=icon
--xh-_action-profile-visual-sizetoast 的 close-trigger 部件 block-size、inline-size、min-inline-size 覆盖槽。
--xh-toast-description-fgdescriptioncolordefault--xh-fg-mutedtoast 的 description 部件 color 覆盖槽。
--xh-toast-description-font-sizedescriptionfont-sizedefault--xh-text-secondary-sizetoast 的 description 部件 font-size 覆盖槽。
--xh-toast-description-leadingdescriptionline-heightdefault--xh-leading-normaltoast 的 description 部件 line-height 覆盖槽。
--xh-toast-dir*
root
translate@keyframes xh-toast-in
@keyframes xh-toast-out
default
1toast 的 *、root 部件 translate 覆盖槽。
--xh-toast-fgrootcolordefault--xh-material-elevated-fgtoast 的 root 部件 color 覆盖槽。
--xh-toast-font-sizerootfont-sizedefault--xh-text-label-sizetoast 的 root 部件 font-size 覆盖槽。
--xh-toast-front-heightrootblock-sizeexpanded
frontmost
not([data-expanded])
not([data-frontmost])
stack-index
autotoast 的 root 部件 block-size 覆盖槽。
--xh-toast-gaprootgapdefault--xh-space-1_5toast 的 root 部件 gap 覆盖槽。
--xh-toast-heightrootblock-sizeexpandedautotoast 的 root 部件 block-size 覆盖槽。
--xh-toast-icon-fgindicator
root
background-color
color
default--xh-_tone-fgtoast 的 indicator、root 部件 background-color、color 覆盖槽。
--xh-toast-icon-sizeclose-trigger
root
--xh-icon-sizedefault--xh-_action-profile-glyph-size
--xh-glyph-size-md
toast 的 close-trigger、root 部件 --xh-icon-size 覆盖槽。
--xh-toast-indicator-pindicatorpaddingdefault--xh-space-1toast 的 indicator 部件 padding 覆盖槽。
--xh-toast-inline-sizegroup
root
inline-sizedefault28.75remtoast 的 group、root 部件 inline-size 覆盖槽。
--xh-toast-insetgroupinset-block-end
inset-block-start
inset-inline-end
inset-inline-start
placement=-end
placement=-start
placement=bottom
placement=top
--xh-space-4toast 的 group 部件 inset-block-end、inset-block-start、inset-inline-end、inset-inline-start 覆盖槽。
--xh-toast-layergroupz-indexdefault--xh-layer-toasttoast 的 group 部件 z-index 覆盖槽。
--xh-toast-leadingrootline-heightdefault--xh-text-body-leadingtoast 的 root 部件 line-height 覆盖槽。
--xh-toast-offset-collapsed*
root
--xh-toast-y
translate
@keyframes xh-toast-in
default
0pxtoast 的 *、root 部件 --xh-toast-y、translate 覆盖槽。
--xh-toast-offset-expandedroot--xh-toast-yexpanded0pxtoast 的 root 部件 --xh-toast-y 覆盖槽。
--xh-toast-progress-bgprogressbackgrounddefault--xh-_tone-softtoast 的 progress 部件 background 覆盖槽。
--xh-toast-progress-durationprogressanimationdefault--xh-motion-duration-slidetoast 的 progress 部件 animation 覆盖槽。
--xh-toast-progress-thicknessprogressblock-sizedefault--xh-space-0_5toast 的 progress 部件 block-size 覆盖槽。
--xh-toast-pxrootpadding-inlinedefault--xh-space-4toast 的 root 部件 padding-inline 覆盖槽。
--xh-toast-pyrootpadding-blockdefault--xh-space-3toast 的 root 部件 padding-block 覆盖槽。
--xh-toast-radiusrootborder-radiusdefault--xh-shape-overlaytoast 的 root 部件 border-radius 覆盖槽。
--xh-toast-scale*scale@keyframes xh-toast-out1toast 的 * 部件 scale 覆盖槽。
--xh-toast-scale-collapsed*
root
--xh-toast-scale
scale
@keyframes xh-toast-in
default
--xh-_toast-stack-scaletoast 的 *、root 部件 --xh-toast-scale、scale 覆盖槽。
--xh-toast-shadowrootbox-shadowdefault--xh-material-elevated-shadowtoast 的 root 部件 box-shadow 覆盖槽。
--xh-toast-title-fgtitlecolordefault--xh-_tone-fgtoast 的 title 部件 color 覆盖槽。
--xh-toast-title-font-sizetitlefont-sizedefault--xh-text-label-sizetoast 的 title 部件 font-size 覆盖槽。
--xh-toast-title-font-weighttitlefont-weightdefault--xh-font-weight-semiboldtoast 的 title 部件 font-weight 覆盖槽。
--xh-toast-title-leadingtitleline-heightdefault--xh-text-body-leadingtoast 的 title 部件 line-height 覆盖槽。
--xh-toast-y*translate@keyframes xh-toast-out0pxtoast 的 * 部件 translate 覆盖槽。

动效 ​

动效角色:按压 · 状态 · 指示与换位 · 出现 · 导航 · 数值 · 循环(见动效规范)。

可覆盖的动效槽:--xh-toast-progress-duration。

关键帧 xh-toast-in · xh-toast-out 随皮肤自带,不引用别处文件里的名字;共享关键帧 xh-countdown · xh-spin 由 family/motion.css 提供,皮肤 @import 它,单独引入仍成立;block-size · opacity · scale · translate 走 transition 过渡。时长与缓动读动效令牌,改令牌即改全局节奏。

皮肤之外还有一段:退场由适配器的退场闸门把关,动画播完才真收起。

prefers-reduced-motion: reduce 下本组件另有降级规则。

响应式 ​

皮肤另按输入能力分档:hover: hover:同一份皮肤在触屏与带指针的设备上不一样,与视口宽度无关。

RTL ​

皮肤用逻辑属性排布(inline-start 一族),dir="rtl" 下自动镜像;另有按 dir 分支的规则。

Released under The MIT License