2.5 KiB
2.5 KiB
4-7 [done] Tree Shell UI State Boundary v1
更新时间:2026-04-18
目的:明确哪些状态属于 projection,哪些状态只能留在 tree shell / renderer 本地。
1. 结论
树域必须严格区分:
- projection truth
- local UI state
否则 Rust projection、Leptos tree shell、Next 挂载切流会继续把状态缠回旧前端壳。
2. 属于 projection 的状态
这些状态必须来自上游 projection 或 command 结果,而不是由 UI 自行猜测:
nodeIdparentNodeIdprojectionKindnodeTypetitledepthpositionchildCountexpandableexpandedByDefaultcapabilitiesresourceMetaiconHint
说明:
- projection 只描述“结构真相”和“允许做什么”
- projection 不承载 hover、selected、dragging 等临时交互态
3. 只能留在 UI 本地的状态
这些状态只能存在于 tree shell / renderer 本地:
expandedselectedhoverfocusdraggingdrop targetcontext menu openkeyboard navigation anchor
说明:
expandedByDefault是 projection 建议值expanded是本地会话态,不直接回写 projection
4. 边界规则
4.1 expanded
- 初始值可由
expandedByDefault推导 - 运行期展开/折叠必须只保留在本地状态
- 不能把
expanded反向写回 projection item
4.2 selected
selected属于当前用户当前会话的局部状态- 不能作为 projection 的共享字段
4.3 focus
focus属于 keyboard / accessibility 层本地状态- 不能参与结构真相
4.4 dragging / drop target
dragging与drop target是瞬时状态- 只能存在于 DnD 状态机
- drop 成功后,真正持久化的是
tree.subtree.move等命令结果
5. Rust 与前端共识
Rust 负责:
- 输出 projection
- 接收 command
- 返回 command result / resync snapshot
前端或 Leptos shell 负责:
expandedselectedhoverfocusdraggingdrop target
6. 对 page_tree / file_tree / picker 的影响
page_tree、file_tree、picker 必须共用同一套本地状态边界- picker 只是交互能力更窄,不是另一套状态模型
keyboard、selection、focus、dragging的命名与语义必须一致
7. 完成判定
当以下条件同时成立时,视为状态边界冻结完成:
- 文档明确列出 projection 与本地状态
- Rust 和前端都不再把
expanded/selected/focus/dragging/drop target写进 projection - 后续 Leptos shell 与 Next consumer 使用同一份边界说明