--- name: modal-drawer-components overview: 在 fms-vue 组件库中新增 Modal 模态框与 Drawer 抽屉两个弹层组件:参考 antdv-next 与 shadcn 的 dialog 设计,按本项目规范做轻量化实现——Teleport 渲染、遮罩/点击遮罩关闭/Esc 关闭、body 滚动锁定、焦点陷阱与焦点还原、mask fade + 面板 zoom/slide 过渡、受控/非受控双模式,并在 App.vue 反馈分类新增演示。 design: architecture: framework: vue styleKeywords: - 简洁 - 中性色 - 主色强调 - 清晰层次 fontSystem: fontFamily: PingFang SC heading: size: 16px weight: 600 subheading: size: 14px weight: 500 body: size: 14px weight: 400 colorSystem: primary: - "#0f172b" - "#ffffff" background: - "#ffffff" - "#f5f6f8" - "#f1f5f9" - "#000000" text: - "#1f2329" - "#86909c" - "#ffffff" functional: - "#e5e6eb" - "#c9cdd4" - "#f2f3f5" - rgba(0,0,0,0.45) todos: - id: create-shared-utils content: 使用 [skill:ui-ux-pro-max] 核对对话框/抽屉可访问性规范后,创建 utils/focus.js 焦点陷阱与 utils/scroll.js 滚动锁 status: completed - id: build-modal content: 创建 modal/modal.vue 与 modal/index.scss:受控 open、mask fade + panel zoom、标题/关闭/确定取消/footer 插槽、ARIA 与焦点滚动接入 status: completed dependencies: - create-shared-utils - id: build-drawer content: 创建 drawer/drawer.vue 与 drawer/index.scss:四方向滑入、header/extra/body/footer 三段式、ARIA 与焦点滚动接入 status: completed dependencies: - create-shared-utils - id: wire-tokens-demo content: tokens.css 新增 mask/z-index token;App.vue 反馈分类新增 Modal/Drawer 导航与演示 section;静态检查后汇报 status: completed dependencies: - build-modal - build-drawer --- ## 产品概述 在 fms-vue 组件库中新增 Modal 对话框与 Drawer 抽屉两个浮层组件:参考 antdv-next 的 Modal/Drawer 与 shadcn dialog 的设计,两者共享遮罩、焦点陷阱、滚动锁、关闭动画等基础能力,按本项目开发规范做轻量化实现,并在演示站 App.vue 反馈分类中新增展示。 ## 核心功能 ### Modal 对话框 - 受控开关 `v-model:open`,遮罩点击、右上角关闭按钮、Esc 键均可关闭 - 标题区(title 属性或 #title 插槽)、内容区(默认插槽)、底部操作区(默认"取消/确定"按钮,支持 #footer 自定义、footer=false 隐藏) - 确定按钮加载态(confirmLoading)、宽度可配置(默认 520)、居中显示(centered) - destroyOnClose 销毁内容、afterOpenChange 动画完成回调 ### Drawer 抽屉 - 受控开关 `v-model:open`,支持四方向滑出(placement: right/left/top/bottom,默认 right) - 尺寸可配置(默认 378,左右取宽、上下取高) - 三段式结构:header(标题 + 关闭按钮 + #extra 附加区)、body(内容滚动区)、footer(纯插槽,无默认按钮,与 Modal 不同) - 遮罩点击、关闭按钮、Esc 键关闭 ### 共同能力 - 打开时锁定 body 滚动(滚动条宽度补偿,避免布局跳动),支持多个弹层嵌套计数 - 焦点管理:打开聚焦面板、Tab 焦点陷阱循环、关闭后焦点还原到触发元素 - 关闭动画(mask 淡出 + panel 缩放/滑出)后再真正卸载;prefers-reduced-motion 下关闭动画 - ARIA:role=dialog、aria-modal、aria-labelledby 关联标题、关闭按钮 aria-label - 非受控模式:open 未传时组件内部维护(参照 Popover 先例) ## 视觉效果 - Modal:居中卡片,默认宽 520px,圆角 6px(--fms-control-radius),阴影 --fms-popover-shadow,深色半透明遮罩(0.45 透明度),打开 mask 淡入 + 面板轻微缩放 - Drawer:从边缘滑入(±100% 位移),面板白底,header 下边框、body 独立滚动、footer 上边框,阴影加深 - 全部复用 --fms-* token,深色模式自动适配 ## 技术栈 - Vue 3 `