DirectSurface UIDirectSurface UI
开始使用
组件/浮层和反馈组件

浮层和反馈组件 / COMPONENT

Notification

NotificationManager 用于展示非阻塞 toast 通知。通知显示在 viewport 右上角,按时间自动关闭,多条通知垂直堆叠,并带滑入和淡出动画。

文档 READY示例 1
PUBLIC APINotificationManager

FUNCTION EXPLORER

可运行示例与完整源码。

这里始终保留组件的主运行入口;文档中的示例用于补充具体功能说明。

LIVE EXAMPLE OVERLAY
全屏
正在启动 DirectSurface UI 运行时…

Notification 通知

与统一布局属性的关系NotificationManager 管理独立 overlay 卡片,不使用 RenderBox.margin 或 alignment;本页的 margin 是通知堆栈与 viewport 边缘距离。详见组件通用布局属性

LIVE CANVAS可运行组件示例
ON-DEMAND RUNTIME交互式示例将在进入视区时启动避免文档首屏同时初始化多个 Canvas Runtime

NotificationManager 用于展示非阻塞 toast 通知。通知显示在 viewport 右上角,按时间自动关闭,多条通知垂直堆叠,并带滑入和淡出动画。

Notification 基于 Popup 管理器注册为非交互 overlay:它不抢占焦点,不参与 popup 当前交互对象,也不会阻断底层鼠标和键盘。

API 总览

import {  AppOverlayService,  NotificationManager,  type NotificationType,} from 'ds-ui'
API 类型 用途
NotificationManager class 非阻塞 toast 管理器,负责通知堆叠、自动关闭、动画和 popup 注册。
NotificationType type 通知类型:infosuccesswarningerror
AppOverlayService class 应用级通知推荐入口,统一复用 manager 并在服务释放时清理通知。

最小装配顺序是:应用层复用一个 NotificationManagerAppOverlayService,调用 show()/showNotification() 显示通知。不要为每条通知创建新的 manager。

何时使用

使用 Notification:

  • 保存成功、提交成功、后台任务完成。
  • 非阻塞警告或错误提示。
  • 用户不需要立即决策的信息。
  • 操作结果需要短暂反馈,但不应该打断当前流程。

不要使用:

  • 需要用户确认/取消的流程,使用 Modal
  • 任务进行中的阻塞等待,使用 Loading
  • 表单字段校验错误,优先在字段附近展示。
  • 高频状态变化,例如每次输入、每行滚动、每个后台心跳。

最小示例

const notificationManager = new NotificationManager() notificationManager.show(  'success',  '保存成功',  '病历内容已保存。',)

show() 返回通知 id,可用于后续程序化关闭:

const notificationManager = new NotificationManager()const id = notificationManager.show('warning', '网络较慢', '正在重试...', 0) notificationManager.close(id)

duration0 时不会自动关闭,需要调用 close(id)close()

AppOverlayService 示例

业务页面通常通过应用 overlay 服务显示通知:

const overlayService = new AppOverlayService() overlayService.showNotification(  'error',  '保存失败',  '请检查网络后重试。',  5000,)

关闭单条或全部通知:

const overlayService = new AppOverlayService()const id = overlayService.showNotification('info', '正在同步') overlayService.closeNotification(id)overlayService.closeNotification()

构造参数

new NotificationManager() 不接收 options。通知类型、标题、消息和自动关闭时间通过 show(type, title, message?, duration?) 传入。

AppOverlayService.showNotification(type, title, message?, duration?) 使用同一组 show 参数。应用层通常只创建一个 NotificationManager 或一个 AppOverlayService,不要为每条通知创建 manager。详细参数见下方 show 参数

NotificationType

type NotificationType = 'info' | 'success' | 'warning' | 'error'
类型 语义 当前图标 强调色
info 普通信息 蓝色
success 成功反馈 绿色
warning 警告提醒 黄色
error 错误反馈 红色

图标和强调色由组件内部常量定义,目前不是公开配置项。整体卡片背景、边框、阴影、字号和间距来自主题派生 token。

NotificationManager API

API 类型 说明
overlayLayer 'tooltip' popup 绘制层。
cardWidth number 当前主题下卡片宽度。默认 280。
cardHeight number 当前主题下卡片高度。
cardSpacing number 多条通知之间的垂直间距。
margin number 与 viewport 顶部/右侧的距离。
hasItems boolean 当前是否有通知。
show(type, title, message?, duration?) number 显示通知并返回 id。默认 duration 为 3000ms。
close(id) void 关闭指定通知,启动淡出动画。
close() void 立即关闭所有通知并注销 popup。
hitTest(point, context?) boolean 始终返回 false,通知不拦截鼠标。
paint(context, offset) void 绘制所有通知卡片。
dispose() void 关闭所有通知并清理计时器、动画资源。

AppOverlayService 对应入口:

API 说明
showNotification(type, title, message?, duration?) 转发到内部 NotificationManager.show()
closeNotification(id?) 未传 id 时关闭全部;传 id 时关闭指定通知。

show 参数

show(
  type: NotificationType,
  title: string,
  message = '',
  duration = 3000,
): number
参数 类型 默认值 说明
type NotificationType 必填 通知类型。
title string 必填 主标题。
message string '' 副文本。为空时标题垂直居中。
duration number 3000 自动关闭延迟,单位 ms。0 或负数表示不自动关闭。

通知关闭分两步:

  1. 到达 duration 或调用 close(id) 后进入 closing 状态,启动 300ms 淡出动画。
  2. 约 320ms 后移除该项,dispose 对应动画和计时器。

重复关闭同一个 id 是安全的:已经 closing 或不存在的通知会被忽略。

堆叠和定位

通知从右上角向下排列:

x = viewport.width - margin - cardWidth + slideX
y = margin + index * (cardHeight + cardSpacing)

打开动画期间,slideX 会让通知从右侧滑入。关闭动画期间,透明度会从当前值淡出。

当前实现没有最大显示数量限制,也不会自动合并相同通知。高频业务事件应在业务层合并、节流或替换为状态栏/任务中心,避免通知堆满屏幕。

交互行为

行为 说明
鼠标点击 不拦截。hitTest() 始终为 false
键盘焦点 不获取焦点。
Popup 当前对象 openPopup({ interactive: false }),因此 PopupManager.current 仍为 null 或其他交互 popup。
自动关闭 duration > 0 时通过内部 disposable timer 自动关闭。
手动关闭 只能通过 close(id)close() 程序化关闭。当前没有可点击关闭按钮。
与 Modal/Loading 共存 通知作为被动 overlay,不会主动关闭 Modal、Loading、Popover 等交互 popup。

因为通知不阻断交互,它适合作为结果反馈,不适合承载必须阅读或必须处理的信息。

绘制和主题

通知绘制顺序:

  1. 卡片阴影。
  2. 卡片背景。
  3. 左侧类型强调色条。
  4. 卡片边框。
  5. 类型图标。
  6. 标题。
  7. 可选 message。

主题 token 来自 deriveNotificationStyle(theme)

Token 说明
cardWidthcardHeightcardSpacingmargin 尺寸和堆叠间距。
accentWidth 左侧强调色条宽度。
bgColorborderColorborderWidthborderRadius 卡片背景和边框。
shadowColorshadowBlurshadowOffsetX/Y 阴影。
titleTextmessageText 标题和消息文本颜色。
fontSizemessageFontSizeiconFontSizefontFamily 字体。
padding 卡片内部间距。

cardHeightcardSpacingmargin 会随主题字号、间距和窗口 padding 派生;切换主题后下一次读取和绘制会使用新值。

生命周期

创建方式通常有两种:

const notificationManager = new NotificationManager()notificationManager.show('info', '已连接') notificationManager.dispose()

或者由 AppOverlayService 统一持有:

const overlayService = new AppOverlayService()overlayService.showNotification('success', '完成') overlayService.dispose()

dispose() 会:

  • 关闭所有通知。
  • dispose 每条通知的 enter/exit 动画。
  • 清理自动关闭 timer 和移除 timer。
  • 注销 popup overlay。

不要为每次通知都创建新的 manager。应用层应复用同一个 NotificationManager 或使用 AppOverlayService

性能边界

  • 每条通知都有 enter 和 exit 动画,会在动画期间请求 overlay 重绘。
  • 自动关闭依赖 timer;大量通知会产生大量 timer 和动画对象。
  • 当前没有内置队列上限和去重策略。业务应避免把高频事件直接映射为通知。
  • 长标题/长 message 当前不会自动换行,绘制会被卡片宽度视觉约束限制不足。通知文案应短而明确。

常见问题

为什么点不到通知?

当前通知是被动 toast,不是交互卡片。hitTest() 始终返回 false,鼠标会继续命中底层内容。

如何让通知不自动消失?

duration 传为 0 或负数,然后保存 show() 返回的 id,后续调用 close(id)

为什么关闭后不是立即消失?

close(id) 会启动淡出动画,约 320ms 后从列表移除。close() 不传 id 时会立即清空全部通知。

是否有关闭按钮?

没有。当前 UI 不绘制关闭按钮,也不处理通知点击。需要用户必须处理的信息应使用 Modal 或业务自定义浮层。

多条通知会不会自动限制数量?

不会。通知会持续向下堆叠。复杂业务系统应在业务层做合并、限流或替换为任务中心。

相关文档