3.9 KiB
3.9 KiB
统一模态窗口设计 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 - 目的:验证平台风布局、关闭禁用、标题区、内容区与错误区都可由统一组件承载。
后续可按风险由低到高迁移:
- 结果页小弹窗:
PuzzleResultView、BigFishResultView。 - 平台创作页编辑器弹窗:
RpgCreationEntityEditorShared内局部ModalShell。 - RPG 运行时像素风弹窗:
RpgAdventurePanelOverlays、AdventureEntityModal、NpcModals。
验收标准
- 新增弹窗优先使用
UnifiedModal,不再手写完整 overlay + panel 结构。 - 迁移后的弹窗保留原有移动端和桌面布局。
- 关闭按钮、遮罩关闭、Escape 行为一致,
closeDisabled时都不会关闭。 - 类型检查、编码检查通过。