ComponentsData display

Tree view

Display and navigate hierarchies — a CMS page tree, category tree, media folders, a department tree, file explorer panes. A flat WAI-ARIA tree (level, set size and position on every row) with single, multiple or tri-state checkbox selection, lazy children with retry, filtering that keeps ancestors, hover actions, indent guides and virtualisation for thousands of nodes. The useTree hook underneath is exported for custom trees.

WAI-ARIA treeview + @tanstack/react-virtual components/tree-view.tsx, lib/use-tree.tstheme · material · accent · density · font
Home
Services
Web design
SEO audits
Google Ads managementDraft
Company
About
Careers
Frontend engineer
Project manager
Contact

Double-click or press Enter to open a page.

Installation

$ pnpm add @vamos-ui/react

The whole kit as one package — get updates by bumping the version. Add the styles to globals.css: @import "@vamos-ui/react/styles.css";

Usage

import { TreeView, type TreeNode } from "@vamos-ui/react";

<TreeView aria-label="Pages" data={pages} defaultExpanded={["company"]} onAction={(node) => openPage(node.id)} />

Keyboard: ↑ ↓ move, → opens or enters a branch, ← closes or goes to the parent (swapped in RTL), Home / End, * opens all siblings, type-ahead (folded: “ist” finds “İstanbul”), Space toggles the check or selection, Enter runs onAction.

Drag-to-move comes from Sortable tree (Editors & drag-and-drop), which reuses useTree.

Examples

Tri-state checkboxes

selectionMode="checkbox" cascades to descendants and shows mixed parents. checkValueMode="leaf" keeps only leaf ids (permission keys). Disabled nodes keep their state.

Content
View posts
Create and edit posts
Publish posts
Manage media library
CRM
View contacts
Export contacts
Manage deals
Edit deals
Delete deals

3 permissions granted · “Change plan” is owner-only

Lazy folders

hasChildren + loadChildren: a spinner replaces the chevron while loading (aria-busy). A failed load shows Retry in the row.

Filter keeps ancestors

filter keeps matches and their ancestors, opens the path and highlights the match. The match count is announced.

1 match
Office of the CEO
Engineering
Platform
Data infrastructure

5,550 nodes (virtual)

virtual renders only the rows in view; keyboard focus scrolls rows into view first. Set a height.

API

TreeView

PropTypeDefault
data
{ id, label, children?, hasChildren?, disabled?, icon?, badge?, description?, keywords? }.
TreeNode[]—
aria-label
Accessible name of the tree (required unless labelled by a heading).
string—
selectionMode
checkbox = tri-state checks.
"none" | "single" | "multiple" | "checkbox""single"
selected / defaultSelected
Selected ids (checked ids in checkbox mode).
string[]—
onSelectedChange
Called with the new selection.
(ids) => void—
expanded / defaultExpanded
Open branches (controlled / initial).
string[]—
onExpandedChange
Called when a branch opens or closes.
(ids) => void—
cascade
Checkbox mode: parents check descendants.
booleantrue
checkValueMode
Checkbox mode: shape of the value.
"all" | "parent" | "leaf""all"
isSelectable
Which rows can be selected.
(node, hasChildren) => boolean—
loadChildren
Lazy children.
(node, signal) => Promise<TreeNode[]>—
filter
Locale-folded filter; keeps ancestors.
string—
onAction
Enter or double click.
(node) => void—
renderActions
Trailing buttons, revealed on hover and focus.
(node) => ReactNode—
renderLabel
Replace a row's label.
(item) => ReactNode—
virtual
Render only visible rows.
booleanfalse
height
Scroll height.
number | string360 when virtual
indent
Indent per level (px, logical start).
number16
guides
Indent guide lines.
booleantrue
variant
sidebar: accent current row.
"default" | "sidebar""default"
size
Row height (follows density).
"sm" | "md""md"
emptyState
Shown when data is empty.
ReactNode—
labels
Built-in strings (namespace treeView).
Partial<TreeViewLabels>—

useTree(options)

PropTypeDefault
returns items
Flattened visible rows with level, posinset, setsize, expanded, checked, loading, error, guides.
TreeItemState[]—
getTreeProps / getItemProps
Spread on the tree element and each row: roles, roving tabindex, ARIA state, full keyboard.
() => props—
toggleExpanded / toggleChecked / select / focusItem / reload
Imperative helpers.
(id) => void—
getPath / getNode / getChildren
Lookups (paths for breadcrumbs and triggers).
…—