Tree View
Navigate and select items in a keyboard-accessible hierarchy.
Import
import { TreeView, type TreeViewItem } from "@puzzle-ui/ui";Hierarchy and selection
Each item needs a stable unique ID. Supply textValue for rich labels so typeahead can find them. Every tree requires an accessible name.
Multiple selection and navigation
selectionMode="none" is useful for navigation trees. Link items can report route state with getItemActive. Use multiple selection for independent file-like choices.
API
| Prop | Type | Default | Description |
|---|---|---|---|
items | TreeViewItem<TData>[] | Required | Hierarchical data. |
aria-label or aria-labelledby | string | Required | Accessible tree name. |
selectionMode | "none" | "single" | "multiple" | "single" | Selection behavior. |
expandedIds, defaultExpandedIds | string[] | [] | Controlled/initial expansion. |
onExpandedChange | (ids: string[]) => void | - | Expansion changes. |
selectedIds, defaultSelectedIds | string[] | [] | Controlled/initial selection. |
onSelectionChange | (ids: string[]) => void | - | Selection changes. |
defaultFocusedId | string | Selected or first root item | Initial focus target. |
onFocusedChange | (id: string) => void | - | Focus changes. |
loadChildren | (item) => Promise<TreeViewItem<TData>[]> | - | Load children of a hasChildren item. |
onLoadChildrenError | (item, error: unknown) => void | - | Handle load failures. |
onItemActivate | (item) => void | - | Enter activation. |
getItemActive | (item) => boolean | - | Current-route predicate. |
renderItem, renderIcon, renderLabel | (item, state) => ReactNode | Built-in renderer | Non-interactive custom content. |
expandOnItemClick | boolean | false | Toggle branches on label click. |
size | "sm" | "md" | "md" | Density. |
indentation | string | number | Theme spacing | Hierarchy indentation. |
typeahead | boolean | true | Character-based navigation. |
loadingLabel, loadErrorLabel | string | Built-in messages | Loading/error feedback. |
itemClassName | string | - | Class on each item. |
Items require id and label; optional fields are href, textValue, icon, endAdornment, children, hasChildren, disabled, selectable, and data. Disabled branches can still expand. Rendering state contains expanded, selected, focused, loading, disabled, and hasChildren.
Arrow keys move through the hierarchy; Home/End reach boundaries, Enter activates, and Space selects. Re-collapse and re-expand a failed lazy branch to retry. Keep nested buttons and links out of custom row content.