TreeView
Hierarchical explorer (account trees, resource groups, file paths) with disclosure carets and single selection.
Component behavior
TreeView renders nested nodes with expansion controls, icons, and optional right-aligned metadata. It manages expansion and optional selection and reports node selection to the application.
- Nested resources such as folders, organizational units, or accounts.
- Hierarchy navigation controlling an adjacent detail pane.
- Hierarchies with one metadata value per node.
TreeTable: nodes need several aligned data columns.
List: rows are flat and need media, descriptions, or actions.
DataGrid: records need sorting, multiple selection, or cell editing.
VirtualList: row counts require virtualization; TreeView renders every expanded node.
Sidebar: the hierarchy is the application’s primary navigation.
Accordion: the content consists of independent collapsible panels.
Props
TreeNode contains id, label, and optional icon, meta, and children. Nonempty children make a node expandable. IDs must be unique across the tree. Indentation is 14 pixels per level; leaves retain the caret column.
| Prop | Type | Default | Description |
|---|---|---|---|
nodes | TreeNode[] | — | Root-level nodes. Children nest inside each node. |
defaultExpandedIds | string[] | [] | Initially expanded IDs. Read once at mount; later changes are ignored. |
selectedId | string | — | Controlled selected ID. Selection styling changes when this value changes. |
defaultSelectedId | string | — | Initial uncontrolled selected ID. Defaults to an empty string. |
onSelect | (id: string) => void | — | Fires on every row click, including a parent being expanded and including a re-click of the already-selected row. |
renderNode | (node: TreeNode, state: { depth: number; expanded: boolean; selected: boolean; hasChildren: boolean }) => ReactNode | — | Custom node content. Retains row-button semantics, indentation, expansion, and selection styling. |
className | string | — | Class applied to the tree container. Set height and overflow on this container or a wrapper to enable scrolling. |
| Prop | Type | Default | Description |
|---|---|---|---|
id | string | — | Unique node ID used for expansion and selection. |
label | ReactNode | — | Row label. Truncates with an ellipsis on one line rather than wrapping. |
icon | ReactNode | — | Icon before the label. The application supplies dimensions; 14px matches the row height. |
meta | ReactNode | — | Right-aligned mono value, pushed to the far edge. Rendered whenever it is not undefined, so an empty string still reserves the slot. |
children | TreeNode[] | — | Child nodes. A non-empty array turns the caret on; an empty array is treated as a leaf. |
Examples
Icons, meta, and seeded expansion
defaultExpandedIds identifies initially expanded branches. To reveal a nested leaf, include every ancestor ID.
Controlled selection
selectedId controls the highlighted row. Expansion remains internal and has no controlled prop.
Numbers in the meta slot
meta renders monospaced and right-aligned. Parent totals must be supplied in the data; they are not calculated. Without defaultExpandedIds, all branches start collapsed.
import { TreeView } from "@solarius/onset";
import type { TreeNode } from "@solarius/onset";
import { IconFolder, IconFile } from "@tabler/icons-react";
<TreeView
nodes={nodes}
defaultExpandedIds={["src"]}
selectedId={selected}
onSelect={setSelected}
/>;