6.8 KiB
6.8 KiB
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/process/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_treepage_treefile_tree
最小字段基线:
row_idnode_idparent_node_idnode_typeprojection_kinddepthpositiontitlecapabilitiesresource_meta
文件树扩展字段:
resource_kindasset_kindicon_hintexpandableexpanded_by_default
5.2 Command 合同
命令面至少要为后续产品交互预留稳定口径:
tree.node.createtree.node.renametree.subtree.movetree.node.archivetree.node.restoretree.asset.attachtree.asset.detach
5.3 本地 UI 状态合同
以下状态不应回流为结构真相,只能留在 UI 本地状态层:
expandedselectedhoverfocusdraggingdrop 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/task113smoke 与组件/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 不再依赖协议裂缝或壳内临时拼装来维持主路径