REAL SHOWCASE SOURCEpopup-stack-lifecycle

1 个文件 · 86 行 · TypeScript

// ===== showcase/src/examples/components/popup_stack.ts ===== import {  PopupManager,  RenderBorder,  RenderButton,  RenderPageHeader,  RenderPopover,  RenderStackPanel,  RenderText,  RenderWrapPanel,} from 'ds-ui'import type { ShowcaseExample } from '../../showcase_example' export function createPopupStackExample(): ShowcaseExample {  const manager = PopupManager.instance  const status = new RenderText('当前没有打开的浮层。', { role: 'secondary' })   const updateStatus = (message: string): void => {    status.text = `${message} · Popup 栈 ${manager.stack.length} 层 · ${manager.hasOpen ? '存在交互浮层' : '无交互浮层'}`  }   const patientContent = new RenderStackPanel({ orientation: 'vertical', spacing: 8, crossAxisAlignment: 'stretch' })  patientContent.addChild(new RenderText('患者摘要', { role: 'title', weight: 'semibold' }))  patientContent.addChild(new RenderText('李安然 · 女 · 42 岁'))  patientContent.addChild(new RenderText('门诊号:OP-20260717-018', { role: 'secondary' }))  patientContent.addChild(new RenderText('点击外部或按 Escape 关闭当前浮层。', { role: 'secondary' }))   const taskContent = new RenderStackPanel({ orientation: 'vertical', spacing: 8, crossAxisAlignment: 'stretch' })  taskContent.addChild(new RenderText('待办任务', { role: 'title', weight: 'semibold' }))  taskContent.addChild(new RenderText('• 复核过敏史'))  taskContent.addChild(new RenderText('• 确认检查申请'))  taskContent.addChild(new RenderText('• 完成本次病历签名'))   const patientPopover = new RenderPopover({    label: '患者摘要',    content: patientContent,    placement: 'bottom-start',    popoverWidth: 280,    onOpenChange: open => updateStatus(open ? '已打开患者摘要' : '已关闭患者摘要'),  })  const taskPopover = new RenderPopover({    label: '待办任务',    content: taskContent,    placement: 'bottom-end',    popoverWidth: 260,    onOpenChange: open => updateStatus(open ? '已打开待办任务' : '已关闭待办任务'),  })   const triggers = new RenderWrapPanel({ spacing: 10, runSpacing: 10 })  triggers.addChild(patientPopover)  triggers.addChild(taskPopover)  triggers.addChild(new RenderButton({    label: '关闭栈顶',    onClick: () => {      const closed = manager.closeTop()      updateStatus(closed ? '已关闭最上层交互浮层' : '没有可关闭的交互浮层')    },  }))  triggers.addChild(new RenderButton({    label: '关闭全部',    onClick: () => {      manager.closeAll()      updateStatus('已清空 Popup 栈')    },  }))   const explanation = new RenderStackPanel({ orientation: 'vertical', spacing: 8, crossAxisAlignment: 'stretch' })  explanation.addChild(new RenderText('PopupManager 负责什么?', { role: 'title', weight: 'semibold' }))  explanation.addChild(new RenderText('所有弹出层共享同一个栈:最新的交互浮层接收键盘和指针事件,Escape 与外部点击按层关闭。'))  explanation.addChild(new RenderText('业务页面通常使用 Popover、ContextMenu、Modal 等上层组件;只有实现新的通用浮层时才直接操作 Popup 协议。', { role: 'secondary' }))   const panel = new RenderStackPanel({ orientation: 'vertical', spacing: 18, crossAxisAlignment: 'stretch' })  panel.addChild(new RenderPageHeader({    title: 'Popup 浮层栈与生命周期',    description: '用两个真实锚点浮层观察 PopupManager 的栈、当前交互层和统一关闭行为。',  }))  panel.addChild(triggers)  panel.addChild(new RenderBorder({ background: 'muted', padding: 16, child: explanation }))  panel.addChild(status)  panel.padding = 24  return {    content: panel,    afterMount: () => patientPopover.openPopover(),  }}