Files
mnote/design/04-tree-domain/done/4-2-sidebar-pagetree-filetree-product-interaction-contract-v1.md
T
lix-2026 5f97800489 chore: align local-first control plane and editor fixes
- wire SQLite control-plane access/session paths into Rust web local-folder routes

- preserve local Markdown attachment semantics across upload, reload, and secondary-pane resource tabs

- refresh design governance docs, Reasonix task templates, and bug records

- retire root .mcp.json local MCP config
2026-05-23 23:38:42 +08:00

236 lines
6.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 4-2 [done] Sidebar / 页面树 / 文件树 产品交互合同 v1
> 更新时间:2026-04-17
>
> 关联文档:
> - `/mnt/Data1T/mnote/design/04-tree-domain/done/4-sidebar-pagetree-filetree-rust-web-rebuild-v1.md`
> - `/mnt/Data1T/mnote/design/old/04-tree-domain/process/4-1-sidebar-pagetree-filetree-product-gap-analysis-v1.md`
> - `/mnt/Data1T/mnote/design/01-tree-first-graph-kernel/reference/1-tree-first-graph-kernel-v1.md`
## 1. 文档目的
这份文档不是继续讨论“是否要做 Rust tree shell”。
这份文档要冻结的是:
- 页面树对标 Wolai / Notion 的最小产品交互合同
- 文件树对标 VS Code Explorer 的最小产品交互合同
- 当前旧树已经具备的能力基线
- 新 Rust tree shell 必须补齐的能力矩阵
- 后续 `projection / command / row model / selection model / focus model / keyboard / DnD / context menu` 的最低验收口径
也就是说,这份文档是下一阶段多人并行推进时的共同合同,而不是描述性分析。
---
## 2. 基本原则
- 页面树 / 文件树都不是事实源,它们都只是 `tree-first graph kernel` 的 projection。
- Sidebar 是壳,不是树真相。
- 新实现不能以“能显示树结构”作为完成标准,而要以“不比旧交互与 UI 差”作为最低标准。
- 文件树与页面树允许在 UI 上不同,但必须共享同一套 projection 与 command 主骨架。
- 所有新增能力都应优先落到可测试的 `row model / selection model / focus model / keyboard / DnD` 层,而不是先堆散落 UI 事件。
---
## 3. 页面树合同
### 3.1 对标目标
- 功能对标:Wolai / Notion 页面树
- 视觉与节奏对标:轻量、低干扰、hover 才显动作、不是调试面板
### 3.2 页面树必须具备的最低能力
- 稳定的页面层级展开 / 折叠
- 当前页高亮与祖先自动展开
- 行级 hover 动作区
- 新建子页面
- 重命名
- 页面移动
- 上下文菜单入口
- 焦点与键盘导航
- 基础拖拽排序
- 搜索过滤后仍保持树层级可理解
### 3.3 页面树必须保留的旧能力基线
- 右键菜单不是只有重命名/删除,而应保留工作区级高频动作入口
- 页面树不能退化成纯按钮列表
- 大树场景不能因切流而失去稳定滚动体验
- 主树 consumer 不能重新持有第二套结构真相
---
## 4. 文件树合同
### 4.1 对标目标
- 功能对标:VS Code Explorer
- 视觉密度对标:资源管理器,而不是文档树换皮
### 4.2 文件树必须具备的最低能力
- 文件树专用 row model
- 页面、`index.md`、附件、mindmap 文件夹、导图子附件的复合资源层级
- 单选
- 多选
- Shift 范围选
- 右键菜单入口
- 双击打开资源
- 基础键盘导航
- 目录拖拽骨架
- 外部文件拖入上传骨架
- 资源图标语义
- 资源类型菜单分支
### 4.3 文件树必须保留的旧能力基线
- 不能退化成“页面树加附件列表”
- 不能丢掉多选与范围选
- 不能丢掉资产级操作入口
- 不能丢掉内部拖拽/复制与外部文件拖入的扩展空间
- mindmap 相关资源不能被拍平成普通附件列表
---
## 5. 统一协议合同
### 5.1 Projection 合同
所有树 consumer 必须能明确声明自己消费哪一种 projection
- `sidebar_tree`
- `page_tree`
- `file_tree`
最小字段基线:
- `row_id`
- `node_id`
- `parent_node_id`
- `node_type`
- `projection_kind`
- `depth`
- `position`
- `title`
- `capabilities`
- `resource_meta`
文件树扩展字段:
- `resource_kind`
- `asset_kind`
- `icon_hint`
- `expandable`
- `expanded_by_default`
### 5.2 Command 合同
命令面至少要为后续产品交互预留稳定口径:
- `tree.node.create`
- `tree.node.rename`
- `tree.subtree.move`
- `tree.node.archive`
- `tree.node.restore`
- `tree.asset.attach`
- `tree.asset.detach`
### 5.3 本地 UI 状态合同
以下状态不应回流为结构真相,只能留在 UI 本地状态层:
- `expanded`
- `selected`
- `hover`
- `focus`
- `dragging`
- `drop target`
---
## 6. 状态骨架合同
### 6.1 row model
必须单独存在,不能散落在 renderer 中。
最低要求:
- 页面树与文件树都能从 projection 映射到稳定 row model
- row model 可以独立测试
- row model 不再重新定义结构真相
### 6.2 selection model
最低要求:
- 单选
- 多选
- Shift 范围选
- 右键选中
- 可见行变化后的选择归一化
### 6.3 focus model
最低要求:
- 当前焦点行稳定可追踪
- 焦点与选中不完全等价
- 页面树与文件树都能共享焦点层定义
### 6.4 keyboard
最低要求:
- 上下导航
- 左右展开/折叠
- Enter 打开
- 文件树预留 copy / paste / delete 的按键入口
### 6.5 DnD
最低要求:
- 页面树支持基础排序/移动
- 文件树支持目录拖放骨架
- 文件树支持外部文件拖入的扩展点
- 非法投放校验必须可测试
### 6.6 context menu
最低要求:
- 页面树与文件树都有统一的 context menu 入口模型
- 菜单本身可按资源类型分支
- shell 与宿主之间要有稳定动作协议,而不是只靠壳内 `prompt/alert`
---
## 7. 当前判定
截至 2026-04-28 final DOM shell 收口后:
- `page_tree`:默认主路径已进入 `rust_wasm_dom_shell_host + dom_wasm`,展开/折叠、当前页高亮、祖先展开、行级动作、重命名、移动、上下文菜单、键盘与基础拖拽均由 Rust runtime contract 驱动或回放。
- `picker`:轻量选择器已复用同一 renderer state family,键盘高亮、Enter 选中、根节点与排除项逻辑已进入默认 DOM host。
- `file_tree`:默认主路径已进入 `rust_wasm_dom_shell_host + dom_wasm`,页面、`index.md`、附件、`mindmap` 文件夹、资源图标、单选/多选/范围选、右键、双击打开、内部拖放与外部文件拖入均保留。
本合同的产品交互最低门槛已由 `4-11``4-18` 收口;剩余 `normalizedMove` fallback、`document.snapshot.saved` 独立事件、`tree.node.embed pageReference` 等属于后续 Page Aggregate / runtime 深层收口,不再阻塞本文。
- `filetree` 模式闭环已由 Rust projection、runtime state family、preflight 与默认 DOM host 共同承接。
- 页面树 / 文件树正式交互合同已固定,并由 `task112/task113` smoke 与组件/Rust 测试覆盖。
- row model / selection model / focus model / keyboard / DnD / context menu 骨架已进入 renderer state family 与 runtime facade。
---
## 8. 完成判定
只有同时满足下面几条,才可以宣称“新树不比旧交互与 UI 差”:
- 页面树满足本合同第 3 节最低能力
- 文件树满足本合同第 4 节最低能力
- projection / command 合同不再漂移
- `row model / selection model / focus model / keyboard / DnD / context menu` 有独立实现与测试
- filetree 不再依赖协议裂缝或壳内临时拼装来维持主路径