Vesture
Get started

Data

TreeView

A virtualized, keyboard-navigable tree with optional cascading checkbox selection and lazy-loaded children — the hierarchical counterpart to DataGrid, reusing its exact scrollTop virtualization math against a flattened, expansion-aware node list.

TreeView

Preview

src
components
Button.tsx
TreeView.tsx
index.ts
package.json
src
components
Button.tsx
TreeView.tsx
index.ts
package.json

Usage

tsx
import { TreeView } from "@vesture/react";
import type { TreeNode } from "@vesture/react";

const nodes: TreeNode[] = [
  {
    id: "src",
    label: "src",
    children: [
      { id: "components", label: "components", children: [
        { id: "button", label: "Button.tsx" },
      ] },
    ],
  },
];

<TreeView
  nodes={nodes}
  selectable="multi"
  selected={selected}
  onSelectedChange={setSelected}
  onLoadChildren={(node) => fetchChildren(node.id)}
/>

Behavior

  • Row virtualization is a flatten-then-slice of nodes by expanded state, computed the same way as DataGrid's rows (scrollTop / rowHeight / overscan) — a node only appears in the flat list if every ancestor is expanded.
  • selectable="multi" cascades: selecting a parent selects every currently-loaded descendant, and a parent with some-but-not-all descendants selected renders indeterminate (Checkbox's indeterminate prop) rather than checked.
  • onLoadChildren fetches a lazy node's children on first expand and caches the result on the node — collapsing and re-expanding never re-fetches. A Spinner replaces the chevron while a fetch is in flight.
  • Full ARIA tree keyboard model with roving tabindex: ArrowUp/Down move across visible rows, ArrowRight expands (or descends into an already-expanded node), ArrowLeft collapses (or moves to the parent), Home/End jump to the first/last visible row, Space toggles selection without changing expansion.

Props

TreeNode<T>

PropTypeDefaultDescription
idstringStable identity, used for expanded/selected sets and React keys.
labelReactNodeRow content.
childrenTreeNode<T>[]Loaded child nodes. Omit (leave undefined) for a lazy node.
hasChildrenbooleanMarks a lazy node as expandable before its children have been fetched.
dataTArbitrary payload for your own render/selection logic.

TreeView<T>

PropTypeDefaultDescription
nodesTreeNode<T>[]Root nodes.
expanded / defaultExpanded / onExpandedChangeSet<string>Controlled or uncontrolled expansion, keyed by node id.
selected / defaultSelected / onSelectedChangeSet<string>Controlled or uncontrolled selection, keyed by node id.
selectable"none" | "single" | "multi""none""multi" enables cascading checkboxes; "single" highlights one row at a time with no checkbox.
onLoadChildren(node: TreeNode<T>) => Promise<TreeNode<T>[]>Called once per lazy node, on first expand; the result is cached on the node.
height / rowHeightnumber320 / 32Virtualization sizing, same idea as DataGrid.