From 50b8de6c31de9876576a0f2f169d8207490d5fa0 Mon Sep 17 00:00:00 2001
From: Tevin <tingquanren@163.com>
Date: Wed, 08 Apr 2026 15:51:24 +0800
Subject: [PATCH] config: 更新 Claude Code 本地设置

---
 openspec/changes/implement-c-side-menu/design.md |  111 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 111 insertions(+), 0 deletions(-)

diff --git a/openspec/changes/implement-c-side-menu/design.md b/openspec/changes/implement-c-side-menu/design.md
new file mode 100644
index 0000000..0746b03
--- /dev/null
+++ b/openspec/changes/implement-c-side-menu/design.md
@@ -0,0 +1,111 @@
+## Context
+
+admin2-components 是管理后台组件库,位于 `src/framework/sideMenu/`。组件需要:
+
+- 基于 antd@6 Menu 实现三级菜单(antd 原生支持内嵌三级)
+- 实现全局手风琴展开(最多同时展开一个分支,避免滚动条过长)
+- 响应式固定模式(窄屏下覆盖式抽屉 + 遮罩,仅移动端生效)
+- 受控组件模式,菜单数据由外部注入
+
+详细行为规范见 `openspec/docs/old-refactors/side-menu/` 下的 spec.md、adr.md、task.md。
+
+## Goals / Non-Goals
+
+**Goals:**
+- 实现 P0:基础三级菜单 + 全局手风琴展开
+- 实现 P1:响应式固定模式 + 遮罩
+
+**Non-Goals:**
+- P2 自定义滚动条、P3 动效细节留作后续迭代
+- 不实现菜单数据请求(由宿主提供已合并的树结构)
+- PC 端不启用覆盖模式(固定模式仅移动端生效)
+
+## Decisions
+
+### 1. 三级菜单采用 antd 原生实现
+
+**决定**:利用 antd@6 Menu 的 `items` + `children` 嵌套结构,支持 `key > label > children > key > label > children` 三级结构。
+
+**原因**:antd@6 已原生支持多级菜单展开,自定义第三级增加了不必要的复杂度。
+
+### 2. 手风琴逻辑为全局互斥
+
+**决定**:在 `onOpenChange` 中实现全局互斥——当用户展开一个新分支时,关闭之前展开的分支。
+
+**原因**:避免多分支同时展开导致滚动条过长,影响导航效率。
+
+**实现**:维护单一 `openKeys` 数组,展开时用新 key 替换数组。
+
+### 3. 响应式固定模式仅移动端生效,使用样式自定义覆盖
+
+**决定**:
+- 移动端(断点 `< lg`):侧边栏以 `position: fixed` 悬浮覆盖在内容之上,配合半透明遮罩
+- PC 端:侧边栏固定在内容左侧,不覆盖
+
+**原因**:使用 Drawer 组件会增加复杂性,且 PC 端不需要覆盖效果。
+
+**实现**:使用 antd Layout.Sider 的 `breakpoint` 检测断点,配合 CSS 媒体查询控制覆盖样式。
+
+### 4. 组件 Props 设计
+
+```typescript
+interface CSideMenuProps {
+  title: string;                          // 顶区标题
+  tree: MenuTree;                         // 合并后的菜单树
+  collapsed: boolean;                      // 是否收起
+  curActivePaneKey?: string | number;    // 当前选中键
+  panesOnShelf?: Array<{ key: string }>; // 已打开页签列表
+  onClickMenuItem: (item: MenuItem) => void;
+  onSetMenuCollapse: (collapsed: boolean | void) => void;
+}
+```
+
+### 5. 统一组件导出入口
+
+**决定**:创建 `src/index.ts` 作为组件库的统一导出入口。
+
+**结构**:
+```typescript
+export { CSideMenu } from './framework/sideMenu/CSideMenu';
+// 后续组件陆续添加
+```
+
+### 6. example 极简结构
+
+**决定**:example 保持极简,仅作为组件演示用途。
+
+**结构**:
+```
+example/
+├── App.tsx          # 组件列表页
+├── main.tsx         # 入口
+├── index.css       # 全局样式
+└── pages/
+    └── side-menu/
+        └── SideMenuPage.tsx  # 组件示例页
+```
+
+**原因**:极简结构减少维护成本,重点在组件本身,Playwright 测试也依赖此示例。
+
+### 7. vitest 测试文件放在 test 文件夹
+
+**决定**:组件的 vitest 测试文件放在 `test/unit/` 目录。
+
+**结构**:
+```
+test/
+├── setup.ts
+└── unit/
+    └── CSideMenu.test.tsx
+```
+
+## Risks / Trade-offs
+
+| Risk | Mitigation |
+|------|------------|
+| 全局手风琴限制了多分支展开的灵活性 | 当前业务场景以导航效率优先,后续可扩展为可配置 |
+| 移动端覆盖模式可能影响内容区交互 | 遮罩层 `z-index` 正确设置,确保点击遮罩可关闭侧栏 |
+
+## Open Questions
+
+无。所有决策已确认。

--
Gitblit v1.9.1