Tree view component
components specs/components/tree-view.kmd
Hierarchical, expandable/collapsible list for nested data — file explorers, settings navigation, nested categories, org structures — with optional tri-state cascading checkboxes, lazy child loading, and full keyboard + ARIA tree semantics. Modeled after Fluent 2 TreeView (and the WAI-ARIA tree pattern). Distinct from a flat list and from a data table.
Quando esta spec se aplica
Triggers primários
- Build a tree view in a Koder surface
Todos os triggers
- Display nested/hierarchical data with expand/collapse
- Add a file-explorer or nested-settings navigation
- Select a subtree with cascading (tri-state) checkboxes
Corpo da especificação
Component — Tree view
Status: v0.1.0 — Draft. Promoted from the Microsoft Fluent 2 parity scan (meta/docs/stack #081). Sources: https://fluent2.microsoft.design/ (TreeView) + WAI-ARIA tree pattern.
R1 — When to use
Use a tree view for data with a parent→child hierarchy the user navigates by expanding nodes (files/folders, nested settings, categories). Do NOT use it for:
- flat, same-level items →
specs/components/lists.kmd; - tabular/columnar records →
specs/components/data-table.kmd; - transient command lists →
specs/components/menus.kmd.
R2 — Anatomy
Each node row: an expand/collapse twisty (only when it has children), depth indentation, an optional checkbox (R4), an optional icon, and the label. Leaf nodes align with their siblings (no orphan twisty).
R3 — Expand / collapse
- Children may load lazily on first expand (show a
specs/components/skeleton.kmdplaceholder while loading). - Expansion state persists across re-render within a session; expand-all / collapse-all are optional bulk controls.
- A node with zero children after load shows no twisty.
R4 — Cascading checkboxes (tri-state)
When selection-by-inclusion is enabled, checkboxes are tri-state:
- checking a node checks all descendants;
- unchecking clears all descendants;
- a node whose descendants are mixed renders indeterminate
(
aria-checked="mixed"); - a node becomes checked iff all its children are checked (state propagates up as well as down). The checked set is derived from leaves; never store a parent "checked" that contradicts its children.
R5 — Selection vs check (distinct)
- Focus/selection = the active node (single, keyboard-navigable).
- Check = membership in an inclusion set (R4), independent of focus.
Both can coexist (you can move focus without changing checks). For pure
multi-select without hierarchy semantics, see
specs/interaction/selection.kmd.
R6 — Keyboard
- ↑/↓ move focus across visible nodes; → expands (or moves to first child), ← collapses (or moves to parent); Home/End jump to first/last; type-ahead matches labels.
- Space toggles the focused node's checkbox; Enter activates the node's primary action.
- Exactly one node is in the tab order (roving tabindex); arrows move within.
R7 — Scale
Virtualize rendering for large/deep trees (only expanded, on-screen nodes in the DOM). Any truncated/lazy-unloaded branch is disclosed, never silently capped.
R8 — Accessibility
role="tree"on the container;role="treeitem"per node; child lists wrapped inrole="group".- Each item carries
aria-expanded(when expandable),aria-selected,aria-checked(true|false|mixedfor R4), andaria-level/aria-setsize/aria-posinset. - Indentation/twisty are not the sole structure signal — the ARIA level + group convey hierarchy to assistive tech.
Não-escopo
- Drag-to-reorder / drag-between-nodes (separate enhancement).
- Columnar tree-grid (a
data-tablevariant, not this). - The backing data model / lazy-load transport.
Referências
specs/components/lists.kmdspecs/interaction/selection.kmdspecs/components/skeleton.kmdspecs/i18n/contract.kmd