File manager folder tree should live in the shared nav column (width + collapse parity with page tree) #109

Closed
opened 2026-07-18 13:06:04 +02:00 by dominik.polakovics · 0 comments

The media module's folder tree is a copy-paste mirror of the shell's page tree column, not a reuse of it: it declares `tree: false` in the module registry and renders its own `.media-tree-column` inside the module body, with duplicated resize logic, its own `deckle:media-tree-width` sessionStorage key, mirrored CSS classes, and no collapse at all. Consequences visible to users: the file tree does not share the page tree's width (they drift independently) and cannot be collapsed from the module rail.

Agreed design (grilled + resolved):

  1. Shell-owned nav slot. Generalize `TreeColumn` into a generic nav column owned by the shell: it keeps width, resize handle, and collapse; the pane content comes from the active module.
  2. Registry API. Replace `ModuleDef.tree: boolean` with `nav?: Component<{ ctx: ModuleContext }>`. page/list/view/edit point at a shared `PageTreeNav` (renders `TreePane` from ctx state — the tree data stays shell-owned since `App.tsx` also uses it for `hasPage`/`findPageTitle`/`refetchAfterMutation`); media points at `MediaFolderNav`; no `nav` = no column and the rail toggle is hidden (current `treeAvailable()` behavior).
  3. One shared width. Single `deckle:tree-width` key (180–560px clamp) for whichever nav is active; `deckle:media-tree-width` is dropped (sessionStorage, no migration needed).
  4. One shared collapse flag. Existing `deckle:tree-collapsed` + rail toggle now govern the media nav too.
  5. Folder tree parity: node expand/collapse. `FolderRow` currently always renders all descendants. Give it expand/collapse with a persisted expanded-set (own key, mirroring `deckle:tree-expanded` semantics), first-load default = root open / rest closed (page-tree parity), and auto-expand ancestors of the URL-selected folder so the selection is never hidden.
  6. Media grid↔tree drag-drop (`dragRef`/`dropFolder`) moves to a module-scoped store (file-level signals) since nav and module body become sibling render subtrees.

Duplicated CSS (`.media-tree-column*`) and resize logic are deleted in the process.

The media module's folder tree is a copy-paste mirror of the shell's page tree column, not a reuse of it: it declares \`tree: false\` in the module registry and renders its own \`.media-tree-column\` inside the module body, with duplicated resize logic, its own \`deckle:media-tree-width\` sessionStorage key, mirrored CSS classes, and no collapse at all. Consequences visible to users: the file tree does not share the page tree's width (they drift independently) and cannot be collapsed from the module rail. Agreed design (grilled + resolved): 1. **Shell-owned nav slot.** Generalize \`TreeColumn\` into a generic nav column owned by the shell: it keeps width, resize handle, and collapse; the pane content comes from the active module. 2. **Registry API.** Replace \`ModuleDef.tree: boolean\` with \`nav?: Component<{ ctx: ModuleContext }>\`. page/list/view/edit point at a shared \`PageTreeNav\` (renders \`TreePane\` from ctx state — the tree *data* stays shell-owned since \`App.tsx\` also uses it for \`hasPage\`/\`findPageTitle\`/\`refetchAfterMutation\`); media points at \`MediaFolderNav\`; no \`nav\` = no column and the rail toggle is hidden (current \`treeAvailable()\` behavior). 3. **One shared width.** Single \`deckle:tree-width\` key (180–560px clamp) for whichever nav is active; \`deckle:media-tree-width\` is dropped (sessionStorage, no migration needed). 4. **One shared collapse flag.** Existing \`deckle:tree-collapsed\` + rail toggle now govern the media nav too. 5. **Folder tree parity: node expand/collapse.** \`FolderRow\` currently always renders all descendants. Give it expand/collapse with a persisted expanded-set (own key, mirroring \`deckle:tree-expanded\` semantics), first-load default = root open / rest closed (page-tree parity), and auto-expand ancestors of the URL-selected folder so the selection is never hidden. 6. **Media grid↔tree drag-drop** (\`dragRef\`/\`dropFolder\`) moves to a module-scoped store (file-level signals) since nav and module body become sibling render subtrees. Duplicated CSS (\`.media-tree-column*\`) and resize logic are deleted in the process.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
Cloonar/deckle#109
No description provided.