Tree A compound tree component with single-select and checkbox modes, search, keyboard navigation, cascade checking, and ARIA tree semantics.
npx vayu-ui-cli@latest add tree
Preview Code
const data : TreeNode [] = [
{
id: "src" ,
label: "src" ,
children: [
{ id: "app.tsx" , label: "app.tsx" },
{ id: "index.tsx" , label: "index.tsx" },
],
},
{ id: "package.json" , label: "package.json" },
]
< Tree data = {data} aria-label = "Project files" >
< Tree.Search searchQuery = {query} onSearchChange = {setQuery} />
< Tree.Actions onExpandAll = {expandAll} onCollapseAll = {collapseAll} />
< Tree.Container >
< Tree.Nodes nodes = {data} />
</ Tree.Container >
</ Tree >
< Tree data = {data} mode = "checkbox" onCheck = {( keys ) => setChecked (keys)}>
< Tree.Container >
< Tree.Nodes nodes = {data} />
</ Tree.Container >
</ Tree >
import { Tree } from 'vayu-ui' ;
import type { TreeNode } from 'vayu-ui' ;
const data : TreeNode [] = [
{ id: 'root' , label: 'Root' , children: [{ id: 'child' , label: 'Child' }] },
];
< Tree data = {data} aria-label = "My tree" >
< Tree.Search searchQuery = {query} onSearchChange = {setQuery} />
< Tree.Actions onExpandAll = {handleExpandAll} onCollapseAll = {handleCollapseAll} />
< Tree.Container >
< Tree.Nodes nodes = {data} />
</ Tree.Container >
</ Tree >;
Tree — Root provider that manages expand, select, and check state. Wraps all sub-components.
Tree.Search — Controlled search input for filtering nodes. Requires searchQuery and onSearchChange.
Tree.Actions — Toolbar with Expand All and Collapse All buttons.
Tree.Container — Bordered container with a built-in empty state fallback.
Tree.Nodes — Renders an array of TreeNode objects. Typically receives the filtered data array.
Tree.Node — Renders a single node with optional children. Used internally by Tree.Nodes or manually for custom layouts.
Keyboard Support :
ArrowDown — Move focus to the next visible node.
ArrowUp — Move focus to the previous visible node.
ArrowRight — Expand a collapsed node, or move focus to the first child of an expanded node.
ArrowLeft — Collapse an expanded node, or move focus to the parent of a collapsed node.
Home — Move focus to the first visible node.
End — Move focus to the last visible node.
Enter — Toggle expand/collapse on parent nodes, select in normal mode, or toggle checkbox in checkbox mode.
Space — Select a node in normal mode, or toggle checkbox in checkbox mode.
ARIA Attributes :
Root has role="tree" with aria-label or aria-labelledby.
aria-multiselectable is set to true when mode="checkbox".
Each node has role="treeitem" with aria-expanded, aria-selected, aria-disabled, and aria-level.
Child groups use role="group" with aria-label describing the parent.
Checkboxes use role="checkbox" with aria-checked (true, false, or "mixed" for indeterminate).
Search input uses role="searchbox" with aria-label="Search tree".
Action buttons use role="toolbar" with aria-label="Tree actions".
Focus Behavior :
Only the focused node has tabIndex={0}; all others have tabIndex={-1}.
Focus ring is shown via ring-2 ring-inset ring-focus.
Arrow key navigation cycles through visible nodes only, skipping collapsed children.
When a user navigates to a tree node, the screen reader announces the node label, its nesting level (via aria-level), and its expanded or collapsed state (via aria-expanded). In checkbox mode, the checked state is announced as checked, unchecked, or indeterminate (via aria-checked). When a node is expanded or collapsed, the screen reader announces the state change. Parent nodes are announced with their child count via the role="group" container. Disabled nodes are announced as disabled (via aria-disabled). Users can navigate between nodes using arrow keys, and the screen reader announces each node as it receives focus. The search input is announced as a search box, and toolbar buttons are announced with their respective labels.
Tree/
├── Tree.tsx # Root component with context provider and state management
├── TreeNode.tsx # Individual node rendering with expand, select, and checkbox
├── TreeContainer.tsx # Bordered container with empty state fallback
├── TreeActions.tsx # Expand All / Collapse All toolbar
├── TreeSearch.tsx # Controlled search input with clear button
├── hooks.ts # useTree hook for accessing tree context
├── utils.ts # Tree traversal utilities (flatten, find, filter)
├── types.ts # TypeScript type definitions
└── index.ts # Re-exports all components, hook, and types
Prop Type Default Description dataTreeNode[]— Tree data structure. Required. mode'normal' | 'checkbox''normal'Selection mode. variant'default' | 'filled' | 'bordered' | 'minimal''default'Visual style variant. size'sm' | 'md' | 'lg''md'Component size. showLinesbooleantrueShow connecting lines between nodes. showIconsbooleantrueShow file/folder icons on nodes. defaultExpandAllbooleanfalseExpand all nodes on mount. defaultExpandedKeys(string | number)[][]Initially expanded node keys. expandedKeys(string | number)[]— Controlled expanded state. onExpandedChange(keys: (string | number)[]) => void— Fired when expand state changes. selectedKeystring | number | null— Controlled selected node (normal mode). defaultSelectedKeystring | number— Initially selected node. onSelect(key, node) => void— Fired when a node is selected. checkedKeys(string | number)[]— Controlled checked nodes (checkbox mode). defaultCheckedKeys(string | number)[][]Initially checked node keys. onCheck(keys, nodes) => void— Fired when checkboxes change. checkStrictlybooleanfalseDisable parent-child checkbox cascade. disabledbooleanfalseDisable the entire tree. onNodeClick(node: TreeNode) => void— Fired on any node click. renderActions(node: TreeNode) => ReactNode— Render action buttons per node. aria-labelstring'Tree'Accessible label for the tree. aria-labelledbystring— ID of the element labeling the tree. classNamestring— Additional CSS classes.
Prop Type Default Description searchQuerystring— Current search query. Required. onSearchChange(query: string) => void— Callback when query changes. Required. placeholderstring'Search tree…'Input placeholder text. classNamestring— Additional CSS classes.
Prop Type Default Description onExpandAll() => void— Expand all nodes callback. Required. onCollapseAll() => void— Collapse all nodes callback. Required. classNamestring— Additional CSS classes.
Prop Type Default Description childrenReactNode— Tree content. Required. emptyReactNode— Custom empty state fallback. classNamestring— Additional CSS classes.
Prop Type Default Description nodesTreeNode[]— Array of tree nodes to render. Required.
Prop Type Default Description nodeTreeNode— Single tree node object. Required. levelnumber0Nesting depth (0-based).
Prop Type Default Description idstring | number— Unique identifier. Required. labelstring— Display text. Required. iconReactNode— Custom icon override. childrenTreeNode[]— Nested child nodes. disabledbooleanfalseDisable this node. selectablebooleantrueAllow selection on this node. metadataRecord<string, unknown>— Arbitrary metadata.