Files
opsxsql/.zcode/plans/plan-sess_bc7da99a-6d01-4954-8e96-069e6ebb2857.md
Logan.Li 48c8fddbe9 refactor(ui): unify all dialogs on radix base per guide ch.6/7
- base dialog: z raised to 300/301 (was below sidebar z-200 - dialogs
  appeared sunken under navigation), overlay bg-black/45 + 2px blur,
  unified close button with hover/focus-visible states, footer pt-4
- FormDialog normalized: width presets sm/md/lg/xl + optional
  description, single scrollable body (header/footer fixed), unified
  top-right close from base
- ModalOverlay rewritten on radix kernel, same props (+title/noScroll):
  portal/focus trap/scroll lock/ESC with proper nesting (fixes
  chain-close when ticket detail opens quick-review), 200ms animation,
  z-300 layering - was a bare div with no a11y, no animation, ESC
  via document listener that leaked to nested dialogs
- killed box-in-box: all 14 ModalOverlay callers stripped their inner
  card wrapper (double border/shadow/radius/padding gone) and duplicate
  scroll containers; EditInstanceDialog (4th standalone system) migrated
  to ModalOverlay, gains ESC/animation/portal
- visual unification per guide: dialog title text-base semibold
  (was 4 sizes), close button one form (was 5), footer buttons on
  dg-btn system (secondary/primary/danger, was 4 systems), primary
  color var(--dg-blue) everywhere (yellow/emerald/blue-500/600 mixed
  before), widths 4 presets (was 7 arbitrary values)
- dead code removed: 3 orphaned LDAP dialog components, leftover
  create-OU state/handler in BatchImportModal, unused icon imports

verified in browser: users create dialog shows single card (0 inner
cards), 12px radius, z-301/300, overlay blur, sidebar correctly
covered; tsc/build/audit gates green
2026-10-27 16:35:32 +08:00

3.0 KiB

统一全部弹框(对照指南 06/07 章)

探索结论:「奇特」的可解释根因——① ModalOverlay 系 14 处全部「弹窗里再套一张卡片」(双边框/双阴影/双圆角/双倍内边距);② 双滚动条;③ 侧栏/顶栏 z-200 浮在弹窗 z-100 之上(弹窗像陷进布局里、导航不被遮罩仍可点);④ 关闭钮 5 种形态、footer 按钮 4 套体系、主色 5 种、标题字号 4 档、宽度 7 档;⑤ ModalOverlay 系无动画/无 ESC 之外的可达性;⑥ TicketDetailDialog 内嵌弹窗 ESC 会连锁关闭外框;⑦ EditInstanceDialog 独立第四体系(无 ESC/动画/portal);⑧ LDAP 三弹窗疑似孤儿 + BatchImportModal 残留死代码。

1. 基座统一(改 3 个基础组件,全站生效)

  • ui/dialog.tsx:遮罩/面板 z-index 提到 300/301(压过侧栏 200,指南 modal=300 档);遮罩 bg-black/45 + backdrop-blur-[2px];保留 fade+zoom 200ms 动画
  • FormDialog 规范化:统一头(标题 text-base font-semibold + 可选描述)+ 右上角统一关闭钮(absolute X 16px,替换现在 5 种形态)、内容区单滚动(flex-col,header/footer 固定,max-h-85vh)、footer 右对齐 gap-2 pt-4;类名用 cn() 合并
  • ConfirmDialog:标题加 font-semibold,与 FormDialog 对齐(shadcn Button 保留)

2. ModalOverlay 重写为 Radix 内核(同 props,14 处零改调用签名)

open/onClose/width/className 接口不变,内部改渲染 Radix Dialog → 免费获得 portal/焦点陷阱/滚动锁定/ESC(含嵌套正确分层,修复连锁关闭)/200ms 动画/z-300;面板策略改「header 固定 + 内容区滚动」。修 ESC 连锁关闭 bug

3. 消灭「框中框」与双滚动(14 + 1 处调用点机械清理)

  • 各 ModalOverlay 调用点删除内层 bg/border/rounded/shadow/p-6 卡片包装,内容直挂(保留各自布局)
  • 删除内层第二个 max-h/overflow-y-auto(BatchImportModal/TicketDetailDialog/InstanceGroupPage/UserDetailModal)→ 单滚动条
  • EditInstanceDialog 迁到 ModalOverlay(同体系,获得 ESC/动画/portal)

4. 视觉统一(按指南 06 数值层)

  • 弹窗圆角统一 rounded-xl(12px);阴影单层 shadow-2xl、去边框(描边/阴影二选一)
  • 标题统一 text-base font-semibold;关闭钮统一形态
  • footer 按钮统一 dg-btn 体系(dg-btn-sm dg-btn-secondary 取消 / dg-btn-primary 主操作 / dg-btn-danger 危险),替换裸 button 四种写法;主色统一 var(--dg-blue)(ResetPasswordModal 的 yellow-500、LDAP 弹窗的 emerald-500 一并收敛);宽度归档 sm/md/lg/xl 四档(内容宽度语义保留,消除随意值)

5. 死代码清理

  • 验证 LdapCreateOuDialog/LdapAddUserDialog/LdapAccountTestDialog 无引用后删除;BatchImportModal 残留的建 OU 嵌套状态/函数清除

6. 验证

  • tsc/build/audit:pages 全绿
  • 浏览器实测 6 类弹框:用户新建/编辑(rbac)、批量导入、实例编辑(EditInstanceDialog)、工单详情+内嵌快捷审批(验证 ESC 不再连锁、z-index 压过侧栏)、Redis 行编辑、各页删除确认——确认单卡片/单滚动/统一关闭钮与按钮/动画一致
  • 提交并推送远程