# 统一模态窗口设计 2026-04-25 ## 背景 当前前端已有两套稳定视觉资产: - 平台侧:`platform-overlay`、`platform-modal-shell`、`platform-auth-card` 等主题变量。 - RPG 运行时:`pixel-nine-slice`、`pixel-modal-shell` 与 `UI_CHROME.modalPanel` 九宫格边框。 但弹窗结构仍分散在业务组件内,常见重复包括遮罩层、点击遮罩关闭、`role="dialog"`、`aria-modal`、移动端底部贴边、桌面居中、最大高度、滚动区域和关闭按钮。新增弹窗时容易出现 z-index、无障碍属性、移动端高度和视觉边界不一致。 ## 目标 新增统一组件 `UnifiedModal`,只负责弹窗外壳和交互边界,不接管业务内容: - 统一遮罩、面板、标题区、内容区、底部区结构。 - 支持平台风与像素风两种外观,不混用两套视觉资产。 - 默认移动端优先,平台风移动端底部弹出、桌面居中;像素风保持游戏内居中弹窗。 - 默认提供 `role="dialog"`、`aria-modal`、标题关联、Escape 关闭和遮罩点击关闭。 - 支持禁用关闭,用于生成中、保存中等不可打断流程。 - 支持 Portal 渲染到 `document.body`,避免被父层 `overflow` 裁剪。 ## 非目标 - 不一次性迁移所有旧弹窗,避免运行时大面积回归。 - 不把业务按钮、表单、状态文案放进通用组件。 - 不改变现有主题变量、九宫格素材、平台和 RPG 的视觉风格。 - 不新增第三方弹窗库。 ## 组件接口 `UnifiedModal` 核心参数: | 参数 | 说明 | | --- | --- | | `open` | 是否显示。为 `false` 时返回 `null`。 | | `variant` | `platform` 或 `pixel`。默认 `platform`。 | | `title` | 标题,同时作为默认 `aria-label` 来源。 | | `description` | 可选副标题,显示在标题下方。 | | `children` | 主内容区。 | | `footer` | 可选底部操作区。 | | `onClose` | 关闭回调。 | | `closeDisabled` | 禁止遮罩、Escape 和关闭按钮触发关闭。 | | `closeOnBackdrop` | 是否允许点击遮罩关闭,默认允许。 | | `showCloseButton` | 是否显示右上关闭按钮,默认显示。 | | `size` | `sm`、`md`、`lg`、`xl`、`fullscreen`。 | | `zIndexClassName` | z-index class,默认 `z-[90]`。 | | `panelClassName` / `bodyClassName` / `footerClassName` | 局部样式扩展。 | | `portal` | 是否渲染到 `document.body`,默认开启。 | ## 使用边界 ### 平台风弹窗 用于平台首页、登录注册、作品结果、创作工作台等非 RPG 运行时界面。 要求: - 使用 `variant="platform"`。 - 面板使用 `platform-modal-shell` 主题变量。 - 移动端优先底部贴边,大屏居中。 - 不在弹窗内放功能说明式长文案,只放任务所需信息。 ### 像素风弹窗 用于 RPG 运行时、地图、背包、角色详情、NPC 交易等游戏内面板。 要求: - 使用 `variant="pixel"`。 - 面板使用 `pixel-nine-slice pixel-modal-shell`。 - 默认使用 `getNineSliceStyle(UI_CHROME.modalPanel)`。 - 标题、内容和底部仍由业务方控制,避免通用组件内写入玩法解释。 ## 首批迁移 首批只迁移平台入口创作类型弹窗: - 文件:`src/components/platform-entry/PlatformEntryCreationTypeModal.tsx` - 目的:验证平台风布局、关闭禁用、标题区、内容区与错误区都可由统一组件承载。 后续可按风险由低到高迁移: 1. 结果页小弹窗:`PuzzleResultView`、`BigFishResultView`。 2. 平台创作页编辑器弹窗:`RpgCreationEntityEditorShared` 内局部 `ModalShell`。 3. RPG 运行时像素风弹窗:`RpgAdventurePanelOverlays`、`AdventureEntityModal`、`NpcModals`。 ## 验收标准 - 新增弹窗优先使用 `UnifiedModal`,不再手写完整 overlay + panel 结构。 - 迁移后的弹窗保留原有移动端和桌面布局。 - 关闭按钮、遮罩关闭、Escape 行为一致,`closeDisabled` 时都不会关闭。 - 类型检查、编码检查通过。