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

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/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-114-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 不再依赖协议裂缝或壳内临时拼装来维持主路径