跳转到内容

Notification 通知

主动推送给用户的一条消息:有标题、有正文,可以带操作按钮。

用法

create 入队并返回 id,队列中的每条由作者渲染为一条通知;退场窗口结束后只收起不删除,宿主在 status-change 中把它移出队列

队列:0 条

组件结构

加粗的是必需部件。

data-scope="notification"root · group · item · item-indicator · item-title · item-description · item-action-trigger · item-progress · item-close-trigger

示例

落位

placement 决定该堆叠贴视口的哪个角,更换的只是 group 上的 data-placement,队列本身不变

就地改写

同一个 id 再次 create 是原地改写而不是新弹出一条,位置不变;loading 不自动消失,换为 success 后才开始倒计时

上限与清空

max 限制每个位置同时显示几条,超出时移除最旧的;dismissAll 直接清空队列,不经退场窗口

队列:0 条(上限 3)

手动关闭

create 返回的就是队列身份 id,保存后可随时 dismiss 该条;dismiss 直接移出队列,不经退场窗口

队列:0 条 · 记下的 id:(无)

逐条落位

单条通知自带 placement 即覆盖 notification 的默认落位;placements 报告当前有条目的位置,一个位置一个堆叠

眼下有条目的位置:(无)

设计指引

何时使用

  • 系统或他人发起的消息:新评论、审批到达、任务完成。
  • 后台完成的长任务,用户当时可能在做其他事。
  • 一句话说不完,需要标题加正文两层信息。

何时不用

  • 用户刚点击按钮、只需要一句结果反馈时,使用轻提示
  • 用户必须处理才能继续时,使用对话框阻断。
  • 页面内某块区域的常驻状态说明使用警告提示

特性

  • 九宫格落位,placement 决定整摞的位置,也可以逐条指定。
  • max 限制每个位置同时显示的条数,默认 5,超出时先挤出低优先级,同级中挤出最旧的;设为 Infinity 即不限制。
  • 同一个 id 再次发出即就地改写,位置不变,用于“处理中 → 已完成”。
  • 每条自带计时与暂停:指针停在卡片上或焦点进入时暂停计时。
  • duration 为 0 时常驻不消失,适合需要用户处理的消息。

组合

  • 卡片可以放一个操作按钮(查看详情、撤销),按下即退场。
  • 队列的增删改由根插槽统一给出,业务代码不需要自行维护数组。

最佳实践

  • 整个应用只挂一个队列,挂在最外层。
  • 落位避开固定的操作条与移动端手势区。
  • 重要的消息把 duration 设为 0,由用户自行关闭。

反模式

  • 用它做操作反馈:一次点击弹出一张两层文本的大卡片,喧宾夺主。
  • 每个页面各挂一个队列,多摞互相遮盖。
  • max 过大,一屏被通知占满。

API 参考

产物

自定义元素<xh-notification>
Vue 组件XhNotificationGroup XhNotificationItem XhNotificationItemActionTrigger XhNotificationItemCloseTrigger XhNotificationItemDescription XhNotificationItemIndicator XhNotificationItemProgress XhNotificationItemTitle XhNotificationRoot
组合式函数useNotification
状态机notificationMachine
皮肤@xihan-ui/styles/notification.css

Props

属性类型必填说明
itemsNotificationRecord[]受控队列:提供后由宿主决定,内部写入只发 onItemsChange。
defaultItemsNotificationRecord[]
placementNotificationPlacement默认落位,默认 bottom-end。
maxnumber每个位置最多同时保留几条,超出时先移除低优先级、同级中移除最旧的。默认 5;提供 Infinity 即不限。
dedupeNotificationDedupe重复的处理方式,默认 'id'。
gapnumber同一组内的间距(px),默认 16。
durationnumber单条未写 duration 时的默认停留毫秒。
removeDelaynumber单条未写 removeDelay 时的默认退场窗口毫秒。
pauseOnPageIdleboolean页面切到后台时暂停计时,逐条下发给 toast。
translationsPartial<NotificationTranslations>
onItemsChange(details: NotificationItemsChangeDetails) => void

事件

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

事件载荷说明
items-changeNotificationItemsChangeDetails队列变化;detail 为 { items: NotificationRecord[] }

插槽

仅列出带载荷的插槽。

Vue 组件插槽载荷说明
XhNotificationGroupdefaultNotificationGroupSlotProps
XhNotificationItemdefault{ item: NotificationItemApi }
XhNotificationRootdefaultNotificationRootSlotProps

状态

公开状态写入 data-state

部件取值
itemtoStatus(state.get())
item-progresstoStatus(state.get())

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

状态idle

事件ITEMS.CREATE · ITEMS.UPDATE · ITEMS.DISMISS · ITEMS.DISMISS_ALL

connect API

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

成员类型说明
visibleNotificationsResolvedNotification[]max 之内、按加入先后排列的可见条目,已补齐默认值。
placementsNotificationPlacement[]当前有条目的位置,按九宫格固定顺序。作者据此决定渲染哪几个 group。
countnumber
getItemsByPlacement(placement: NotificationPlacement) => ResolvedNotification[]
create(options?: NotificationOptions) => string入队并返回 id;同 id 已存在则就地改写,位置不变。
update(id: string, options: Partial<NotificationOptions>) => void
dismiss(id: string) => void
dismissAll() => void
getRootProps() => T['element']
getGroupProps(props?: NotificationGroupProps) => T['element']

无障碍

键盘

规格出处:W3C APG

无键盘交互(不接收焦点,或焦点行为完全由原生元素提供)。

ARIA

以下属性由 connect 生成。

部件属性
grouparia-labelprops.translations.region
grouprole'region'
itemaria-atomic'true'
itemaria-describedbydescription 部件的 id
itemaria-labelledbytitle 部件的 id
itemaria-live'assertive' | 'polite'
itemrole'alert' | 'status'
item-indicatoraria-hidden'true'
item-progressaria-hidden'true'
item-close-triggeraria-labelprops.translations.close

样式参考

皮肤

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

数据属性

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

部件属性
rootdata-countlist.length
rootdata-empty''(条件成立时才出现)
groupdata-countgroup.length
groupdata-empty''(条件成立时才出现)
groupdata-placementprops.placement
itemdata-loading''(条件成立时才出现)
itemdata-paused''(条件成立时才出现)
itemdata-statetoStatus(state.get())
itemdata-toneprops.tone
item-action-triggerdata-pressed''(条件成立时才出现)
item-action-triggerdata-xh-action-control''
item-action-triggerdata-xh-action-display'always'
item-action-triggerdata-xh-action-profile'text'
item-action-triggerdata-xh-action-size'sm'
item-action-triggerdata-xh-action-variant'outline'
item-progressdata-statetoStatus(state.get())
item-close-triggerdata-disabled''(条件成立时才出现)
item-close-triggerdata-pressed''(条件成立时才出现)
item-close-triggerdata-xh-action-control''
item-close-triggerdata-xh-action-display'always'
item-close-triggerdata-xh-action-profile'icon'
item-close-triggerdata-xh-action-size'sm'
item-close-triggerdata-xh-action-variant'ghost'

CSS 变量

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

变量部件CSS 属性状态默认来源说明
--xh-notification-action-bgitem-action-triggerbackground-colordefaulttransparentnotification 的 item-action-trigger 部件 background-color 覆盖槽。
--xh-notification-action-bg-activeitem-action-triggerbackground-colordisabled
is(:active, [data-pressed])
loading
not([data-disabled])
not([data-loading])
pressed
--xh-bg-subtle-hovernotification 的 item-action-trigger 部件 background-color 覆盖槽。
--xh-notification-action-bg-hoveritem-action-triggerbackground-colordisabled
hover
loading
not([data-disabled])
not([data-loading])
--xh-bg-subtlenotification 的 item-action-trigger 部件 background-color 覆盖槽。
--xh-notification-action-borderitem-action-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
notification 的 item-action-trigger 部件 border、border-color 覆盖槽。
--xh-notification-action-fgitem-action-triggercolordefault
disabled
hover
is(:active, [data-pressed])
loading
not([data-disabled])
not([data-loading])
pressed
--xh-fg-defaultnotification 的 item-action-trigger 部件 color 覆盖槽。
--xh-notification-action-font-weightitem-action-triggerfont-weightdefault--xh-font-weight-mediumnotification 的 item-action-trigger 部件 font-weight 覆盖槽。
--xh-notification-action-hitem-action-triggerblock-size
inline-size
default
xh-action-profile=icon
--xh-_action-profile-visual-sizenotification 的 item-action-trigger 部件 block-size、inline-size 覆盖槽。
--xh-notification-action-pxitem-action-triggerpadding-inlinedefault--xh-_action-profile-padding-inlinenotification 的 item-action-trigger 部件 padding-inline 覆盖槽。
--xh-notification-action-radiusitem-action-triggerborder-radiusdefault--xh-shape-controlnotification 的 item-action-trigger 部件 border-radius 覆盖槽。
--xh-notification-close-bg-activeitem-close-triggerbackground-colordisabled
is(:active, [data-pressed])
loading
not([data-disabled])
not([data-loading])
pressed
--xh-_action-variant-bg-pressednotification 的 item-close-trigger 部件 background-color 覆盖槽。
--xh-notification-close-bg-hoveritem-close-triggerbackground-colordisabled
hover
loading
not([data-disabled])
not([data-loading])
--xh-_action-variant-bg-hovernotification 的 item-close-trigger 部件 background-color 覆盖槽。
--xh-notification-close-fgitem-close-triggercolordefault--xh-fg-mutednotification 的 item-close-trigger 部件 color 覆盖槽。
--xh-notification-close-fg-hoveritem-close-triggercolordisabled
hover
is(:active, [data-pressed])
loading
not([data-disabled])
not([data-loading])
pressed
--xh-fg-defaultnotification 的 item-close-trigger 部件 color 覆盖槽。
--xh-notification-close-insetitem
item-close-trigger
item-title
inset-block-start
inset-inline-end
padding-inline-end
default
has([data-part='item-close-trigger'])
--xh-surface-action-insetnotification 的 item、item-close-trigger、item-title 部件 inset-block-start、inset-inline-end、padding-inline-end 覆盖槽。
--xh-notification-close-radiusitem-close-triggerborder-radiusdefault--xh-shape-controlnotification 的 item-close-trigger 部件 border-radius 覆盖槽。
--xh-notification-close-sizeitem
item-close-trigger
item-title
block-size
inline-size
min-inline-size
padding-inline-end
default
has([data-part='item-close-trigger'])
xh-action-profile=icon
--xh-_action-profile-visual-size
--xh-control-h-sm
notification 的 item、item-close-trigger、item-title 部件 block-size、inline-size、min-inline-size、padding-inline-end 覆盖槽。
--xh-notification-description-fgitem-descriptioncolordefault--xh-fg-mutednotification 的 item-description 部件 color 覆盖槽。
--xh-notification-description-font-sizeitem-descriptionfont-sizedefault--xh-text-secondary-sizenotification 的 item-description 部件 font-size 覆盖槽。
--xh-notification-icon-sizeitem
item-action-trigger
item-close-trigger
--xh-icon-sizedefault--xh-_action-profile-glyph-size
--xh-glyph-size-md
notification 的 item、item-action-trigger、item-close-trigger 部件 --xh-icon-size 覆盖槽。
--xh-notification-indicator-fgitem-indicatorcolordefault--xh-_tone-fgnotification 的 item-indicator 部件 color 覆盖槽。
--xh-notification-indicator-sizeitem-indicator--xh-icon-size
inline-size
default--xh-glyph-size-mdnotification 的 item-indicator 部件 --xh-icon-size、inline-size 覆盖槽。
--xh-notification-insetgrouppadding-block-end
padding-block-start
padding-inline
default--xh-space-6notification 的 group 部件 padding-block-end、padding-block-start、padding-inline 覆盖槽。
--xh-notification-item-bgitembackgrounddefault--xh-material-elevated-bgnotification 的 item 部件 background 覆盖槽。
--xh-notification-item-borderitemborderdefault--xh-material-elevated-bordernotification 的 item 部件 border 覆盖槽。
--xh-notification-item-fgitemcolordefault--xh-material-elevated-fgnotification 的 item 部件 color 覆盖槽。
--xh-notification-item-font-sizeitemfont-sizedefault--xh-text-body-sizenotification 的 item 部件 font-size 覆盖槽。
--xh-notification-item-gapitemcolumn-gapdefault--xh-space-3notification 的 item 部件 column-gap 覆盖槽。
--xh-notification-item-leadingitemline-heightdefault--xh-text-body-leadingnotification 的 item 部件 line-height 覆盖槽。
--xh-notification-item-pxitempadding-inlinedefault--xh-surface-pad-lgnotification 的 item 部件 padding-inline 覆盖槽。
--xh-notification-item-pyitempadding-blockdefault--xh-surface-pad-lgnotification 的 item 部件 padding-block 覆盖槽。
--xh-notification-item-radiusitemborder-radiusdefault--xh-shape-overlaynotification 的 item 部件 border-radius 覆盖槽。
--xh-notification-item-row-gapitemrow-gapdefault--xh-space-2notification 的 item 部件 row-gap 覆盖槽。
--xh-notification-item-shadowitembox-shadowdefault--xh-material-elevated-shadownotification 的 item 部件 box-shadow 覆盖槽。
--xh-notification-item-witeminline-sizedefault--xh-overlay-max-w-lgnotification 的 item 部件 inline-size 覆盖槽。
--xh-notification-layergroupz-indexdefault--xh-layer-toastnotification 的 group 部件 z-index 覆盖槽。
--xh-notification-progress-bgitem-progressbackgrounddefault--xh-_tone-softnotification 的 item-progress 部件 background 覆盖槽。
--xh-notification-progress-durationitem-progressanimationdefault--xh-motion-duration-slidenotification 的 item-progress 部件 animation 覆盖槽。
--xh-notification-progress-radiusitem-progressborder-radiusdefault--xh-shape-pillnotification 的 item-progress 部件 border-radius 覆盖槽。
--xh-notification-progress-thicknessitem-progressblock-sizedefault--xh-space-0_5notification 的 item-progress 部件 block-size 覆盖槽。
--xh-notification-title-fgitem-titlecolordefault--xh-fg-defaultnotification 的 item-title 部件 color 覆盖槽。
--xh-notification-title-font-sizeitem-indicator
item-title
block-size
font-size
default--xh-text-label-sizenotification 的 item-indicator、item-title 部件 block-size、font-size 覆盖槽。
--xh-notification-title-font-weightitem-titlefont-weightdefault--xh-font-weight-semiboldnotification 的 item-title 部件 font-weight 覆盖槽。
--xh-notification-title-leadingitem-titleline-heightdefault--xh-leading-tightnotification 的 item-title 部件 line-height 覆盖槽。

动效

关键帧 xh-countdown · xh-notification-in · xh-notification-out · xh-notification-spin 随皮肤自带,不引用别处文件里的名字。时长与缓动读动效令牌,改令牌即改全局节奏。

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

RTL

皮肤用逻辑属性排布(inline-start 一族),dir="rtl" 下自动镜像。

Released under The MIT License