DirectSurface UIDirectSurface UI
开始使用
文档/核心概念

Popup 与 Overlay

Popup 和 Overlay 用于显示脱离正常布局流的内容,例如下拉框、日期选择、右键菜单、通知、抽屉和模态框。

典型场景

  • RenderComboBox 的下拉选项。
  • RenderDatePicker 的日期面板。
  • RenderColorPicker 的颜色面板。
  • ContextMenuManager 的右键菜单。
  • NotificationManager 的 toast 通知。
  • RenderModal 的模态框。
  • RenderDrawer 的抽屉。

PopupManager

PopupManager 负责管理当前弹层上下文、绘制请求和关闭流程。业务通常不直接操作底层 Popup,而是使用具体组件。

自定义弹层需要明确:

  • 锚点是谁。
  • 如何计算弹层位置。
  • 点击外部是否关闭。
  • Escape 是否关闭。
  • 焦点如何进入和恢复。
  • 关闭时如何释放资源。

局部 OverlayHost

RenderOverlayHost 是布局组件,不通过 PopupManager 挂到全局弹层。它把底层内容和覆盖层内容都放在同一棵 render tree 中,适合当前工作区内的应用中心、局部选择器、局部阻断面板。

选择边界:

  • 浮层需要跟随某个输入控件或右键位置时,使用 popup / popover / context menu。
  • 浮层只属于当前布局区域,且希望遮罩限制在这个区域内时,使用 RenderOverlayHost
  • 浮层需要全局模态、通知层级或跨工作区显示时,使用 modal / notification / drawer 等组件。
  • 浮层属于开发者工具、请求日志、布局检查器这类宿主工具区,并且不应被业务 modal/loading 遮挡时,使用 AppOverlayService.showDockWindow()

宿主停靠窗口

AppOverlayService.showDockWindow() 会把 RenderWindow 作为 runtime 级 root 停靠在主内容区左侧、右侧或底部。停靠窗口不属于主窗口的 owned windows;主内容 viewport 会被停靠区域挤压,普通 popup、modal、loading 只覆盖主内容区。停靠窗口标题栏提供左侧/右侧/底部/浮动切换,并且相邻主内容的边缘可以拖拽调整尺寸。同一 side 上的多个停靠窗口会共享该 side 的厚度,并沿垂直或水平方向分段显示,避免互相覆盖。

宿主停靠窗口适合:

  • Layout Inspector。
  • Runtime Diagnostics。
  • 请求日志、网络面板、状态监控面板。

它不适合业务流程中的详情抽屉、选择弹窗或表单弹窗;这些仍应使用 Drawer、Modal、Popover、Popup 或局部 RenderOverlayHost

锚点定位

锚点弹层需要跟随触发控件移动。当页面滚动、布局变化或窗口尺寸变化时,弹层位置必须重新计算。

下拉、日期选择、颜色选择和查询选择都属于锚点弹层。

Overlay 层级

不同弹层有不同层级:

  • 普通 popup。
  • modal overlay。
  • tooltip。
  • notification。

层级设计要避免 tooltip 被 modal 遮挡关系弄乱,也要避免非交互层拦截底层事件。

生命周期

弹层关闭后应释放:

  • 子组件。
  • 输入会话。
  • 定时器。
  • 事件订阅。
  • 临时上下文。

如果弹层内容很重,不应在未显示时长期持有完整组件树。

性能原则

  • 大列表下拉应限制最大高度或虚拟化。
  • popup 重定位应基于锚点矩形,不应全量布局页面。
  • 通知高频出现时要合并或限流。
  • 关闭弹层必须断开引用,避免内存泄露。