From 3d72fc0dcbac884bec464a7058c83ebaa1d0b815 Mon Sep 17 00:00:00 2001 From: Tevin <tingquanren@163.com> Date: Mon, 13 Apr 2026 12:22:48 +0800 Subject: [PATCH] chore: 完成 implement-c-side-menu 归档的目录移动 --- openspec/docs/old-refactors/side-menu/prod.md | 142 +++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 142 insertions(+), 0 deletions(-) diff --git a/openspec/docs/old-refactors/side-menu/prod.md b/openspec/docs/old-refactors/side-menu/prod.md new file mode 100644 index 0000000..c2a4978 --- /dev/null +++ b/openspec/docs/old-refactors/side-menu/prod.md @@ -0,0 +1,142 @@ +> **本文档集顺序**:① [prod.md](./prod.md)(产品与决策)→ ② [spec.md](./spec.md)(规格)→ ③ [task.md](./task.md)(验收)。编写与修订亦建议按此顺序。 + +# 侧栏导航(Side Menu)— 产品说明 + +## 1. 业务职能与要解决的问题 + +本组件是**管理后台壳层**的**左侧主导航**:在固定宽度侧栏内展示按业务模块分组的菜单树,并与「已打开的子页签」状态联动,使用户在多模块、多层级入口之间快速跳转;在视口变窄时仍以折叠 / 全宽覆盖等方式保持可用。 + +要解决的核心问题: + +- **树状模块结构**(含多级入口):保持当前位置可辨识(选中、父级高亮、已打开页签提示)。 +- **菜单可能超高**:仍能完整浏览(纵向滚动;在满足宽屏媒体条件时用与侧栏风格一致的自绘滚动条,避免原生条割裂视觉)。 +- **大屏与窄屏**:展开/收拢侧栏与点击打开子页的时序一致,避免动画未完成就切页。 + +**非目标**:子页内容、路由注册、权限与数据请求;本组件只消费宿主传入的树与状态。 + +主要使用者:登录后使用后台的运营/管理员等。 + +信息结构(便于与 spec 对齐): + +- **一级**:业务分组,由 antd `Menu.SubMenu` 承载(分组标题即模块名)。 +- **分组以内**:节点若仍有子列表,则由**自研子菜单层**递归展开(解决部分环境下嵌套 `SubMenu` 展示异常的问题);无子列表则为叶子,点击打开页。 + +--- + +## 2. 用户感知(人如何理解这个组件) + +### 可见状态 + +- **整体**:深色竖向导航;顶区为站点/产品标题;下方为可滚动菜单树。 +- **一级分组**:分组标题;若子树中有当前页,分组须有「子树选中」可辨样式。 +- **分组内仍含下级**:由自研子菜单层呈现,可展开/收起,箭头随展开在「V 形」与「展开」之间变化;选中落在本节点与选中落在子级时标题强调程度不同(本节点选中时更接近「当前页」色块)。 +- **叶子项**:类型图标与文案;若对应窗格已在「已打开」列表中,须有与未打开可区分的样式(如右侧小箭头仅在「已打开」时明显出现)。 +- **窄屏**:侧栏可变为盖住主内容的固定层;展开时可占满可视宽度;可配半透明遮罩,点遮罩收起(拖拽自绘滑块时遮罩语义见 spec §5)。 +- **菜单超高**:在宽屏媒体下,右侧出现细轨 + 滑块(非系统默认宽条外观);拖拽滑块时整壳层级与遮罩反馈与平时不同。 + +### 断点与「固定 / 覆盖」(补充详述) + +- **大屏**:主导航是左侧固定宽度竖条,主内容在右,菜单不「浮」在整页上。 +- **屏变窄**:侧栏进入固定覆盖语义;仅当用户展开时才以全宽抽屉压在主内容之上,收起后主内容再占满。 + +### 自定义滚动条(宽屏,与 `lg` 断点同量级 992px)(补充详述) + +- 一屏装不下时,在满足宽屏媒体且判定需要滚动后,右侧出现与深色侧栏一致的细条,而非突兀的系统条。 +- 指针移入可滚菜单区时滑块先略提亮,再移到滑块热区则变宽、变亮(两级 hover 可感知差异)。 +- 拖拽时列表跟手,滑块颜色立刻到位(关闭颜色过渡以免迟滞);若同时存在遮罩层,则近透明且不应误触关闭逻辑。 +- 不溢出时右侧无可点死区(轨不接收指针)。 + +### 表现行为 + +- 分组与自研子菜单的展开/收起有过渡(收起与展开时长可略有不同,约 0.2s~0.3s 量级);侧栏与内容区过渡与现网一致(约 0.3s 量级)。 +- 自绘轨在需要时渐入(可带 delay);拖拽时关闭颜色过渡以保证跟手。 + +### 交互反馈 + +- **点叶子**:大屏立即打开页;窄屏固定覆盖模式下先收侧栏,短延迟后再打开页。 +- **点遮罩**(非拖拽滚动条、且遮罩为可见半透明时):收起侧栏。 +- **拖拽自绘滑块**:内容与滑块联动;拖拽中遮罩与层级语义见 [spec.md](./spec.md) §5。 +- **resize**:重算是否需滚动条与滑块比例。 + +### 交互反馈阶梯(自绘滚动条,白话) + +从「离滚动条较远」到「正在拖拽」,用户应能感到至少三档:① 菜单区可滚但未对准轨/柄;② 对准轨或滑块热区,轨与滑块明显可交互;③ 按下拖拽,高对比、过渡关闭。详见 spec §5 表格化谓词,便于验收对齐。 + +--- + +## 3. 操作时序与流程 + +### 主路径(打开某叶子功能) + +1. 在树中找到目标叶子并点击。 +2. **大屏**(非固定覆盖):宿主立即收到「打开页」。 +3. **窄屏固定覆盖态**:先收起侧栏 → 约 300ms 后宿主收到「打开页」。 + +### 分支 + +- 手风琴:同一父级下新开一侧同级则收起其他同级展开(antd 一级 `SubMenu` 与自研子菜单层两条更新路径写入同一套 `openKeys` 语义须一致)。 +- 只收起不导航:点遮罩等 → 不收新页。 +- resize:可能在「要/不要自绘滚动条」「是否进入窄屏固定覆盖」间切换。 + +### 顺序约束 + +- 窄屏下须先收侧栏再打开页(延迟与动画对齐)。 +- 展开导致高度变化后,须在动画稍后再检测是否需滚动(避免算错高度);一级菜单与自研层回调后的延迟可略有不同,但均须完成一次可靠检测。 + +### 断点与覆盖(典型时序) + +1. 由宽变窄 → 宿主与内部态随 `breakpoint` 同步,常呈现收起、主区全宽。 +2. 用户展开菜单 → 固定覆盖 + 可配遮罩;点遮罩收起。 +3. 再拉宽 → 恢复左侧固定条与主内容并排。 + +### 自定义滚动条(典型时序) + +1. 列表超高 → 判定需滚动后,轨与滑块延时淡入。 +2. 移入菜单滚动区 → 滑块先中间强调色。 +3. 移到滑块热区 → 加宽、高亮。 +4. 拖拽 → 联动滚动;遮罩按 spec §5;滑块关闭颜色 transition。 +5. 松开 → 恢复 hover 与过渡。 +6. 不再溢出 → 轨隐藏且不挡指针,内边距恢复。 + +--- + +## 4. 产品决策与架构(逻辑与决策一体) + +### 为何需要自研子菜单层(分组内「仍有子列表」) + +- **上下文**:antd `Menu.SubMenu` 嵌套在部分移动端/窄视口下曾有多级展示异常。 +- **决策**:分组内凡仍有 `items` 的节点用自研子菜单层(外层列表项 + 内嵌 `Menu`);一级分组仍用 antd `SubMenu`。 +- **后果**:`openKeys` 同时服务两套展开来源;迁移 antd v6 须回归多级与触摸。 + +### 手风琴式同级展开 + +- **上下文**:纵向空间有限。 +- **决策**:新展开一项时,从展开集合中移除同级其他 key(基于树结构求同级)。 +- **后果**:非 antd 默认的「多同级全开记忆」;迁移勿擅自改成全开除非产品要求。 + +### 自绘纵向滚动条(宽屏媒体下且内容溢出) + +- **上下文**:原生条与深色侧栏不协调,且需与箭头、内边距对齐。 +- **决策**:在宽屏媒体且内容超出可视区(含容差阈值)时自绘轨与滑块,transform 移滑块并与 `scrollTop` 比例同步;不满足媒体条件时不依赖自绘轨(由布局内滚动或抽屉承担)。 +- **后果**:resize 与展开后须重算;拖拽与遮罩、z-index 协同见 spec §5。 + +### 遮罩 + +- **上下文**:窄屏覆盖需提示「壳外」并可点关;拖拽滚动条时不应误关。 +- **决策**:窄屏展开时半透明遮罩;拖拽滚动条时遮罩可仍占位但近透明,侧栏容器抬升 z-index 以免挡拖拽。 + +### 宿主侧「按页名找页」与深层树(已知边界) + +若宿主存在仅在分组下浅层扫描的辅助逻辑,而真实菜单深于两层,可能找不到叶子——须由宿主与数据层保证一致;详见 [adr.md](./adr.md) 相应条。 + +--- + +## 5. 对 spec 与 task 的指向 + +| 内容 | 落点 | +|------|------| +| 树字段、展开/选中/点击顺序 | [spec.md](./spec.md) §2–§4 | +| 根容器语义、断点、`Sider`、布尔组合 | spec §3 | +| 遮罩、自绘滚动条、子菜单动效 | spec §5 | +| 可测条目 | [task.md](./task.md) | +| 历史 ADR 式条目(可选对照) | [adr.md](./adr.md) | -- Gitblit v1.9.1