ui · Primitive
TreeView / TreeItem
@devalok/shilp-sutra/ui/tree-viewView in Storybook Hand-curated previews ship in rolling waves. See it live in Storybook →
Reference
Props
TreeView
items: TreeNode[] (data-driven mode) — { id, label, icon?, disabled?, children? }
defaultExpanded: string[]
defaultSelected: string[]
multiSelect: boolean
checkboxes: boolean
onSelect: (ids: string[]) => void
onExpand: (ids: string[]) => void
children: ReactNode (declarative mode)
TreeItem
itemId: string (REQUIRED)
label: ReactNode
secondaryLabel: ReactNode
icon: ReactNode
actions: ReactNode
disabled: boolean
depth: number
children: ReactNode (nested TreeItems)
Hook
useTree({ defaultExpanded, defaultSelected, multiSelect, onSelect, onExpand })
Example (data-driven)
<TreeView
items={[
{ id: '1', label: 'Folder', children: [
{ id: '1.1', label: 'File A' },
{ id: '1.2', label: 'File B' },
]},
]}
defaultExpanded={['1']}
onSelect={(ids) => console.log(ids)}
/>
Example (declarative)
<TreeView>
<TreeItem itemId="1" label="Folder">
<TreeItem itemId="1.1" label="File A" />
</TreeItem>
</TreeView>
Composability
- Two rendering modes:
- Data-driven: Pass
items: TreeNode[]with nestedchildren. Good for server-fetched or programmatic trees. - Declarative: Use
<TreeItem>children directly. Good for hardcoded nav, readable JSX. - Don't mix — pick one per TreeView instance.
- Data-driven: Pass
- useTree hook lets you drive TreeView state externally (e.g. sync with URL, persist expanded state, drive from Redux). Pass
defaultExpanded/defaultSelectedinitially OR manage state via the hook's return value. - TreeItem composability: Each TreeItem has
icon,label,secondaryLabel, andactionsslots — rich rows without custom render props.actionsreveals on row hover (same pattern as Message.Actions). - multiSelect + checkboxes: Set both to turn TreeView into a file-picker style tree with checkboxes instead of single-select highlighting.
- Keyboard navigation: Full
role="tree"spec — Arrow Up/Down to move, Right to expand/descend, Left to collapse/ascend, Enter to select. Pre-wired; no manual key handling needed.
Gotchas
- Supports both data-driven (items prop) and declarative (children) modes
- Don't mix data-driven and declarative in the same TreeView — pick one
- For a simple flat checkbox list, use RadioGroup/Checkbox + Stack — TreeView is overkill for non-hierarchical data
Changes
v0.4.2
- Added TreeItem now accepts
classNameprop
v0.3.0
- Added Per-component export:
./ui/tree-view
v0.1.0
- Added Initial release