Skip to main content
Version: Next

Tree

A hierarchical tree view for file explorers, navigation menus, and nested data structures. Supports keyboard navigation, roving focus, expand/collapse, and typeahead.

Import

// Subpath (recommended)
import { Tree } from '@editora/ui-react/Tree';

// Barrel
import { Tree } from '@editora/ui-react';

Composition

ComponentRendersPurpose
Tree<ui-tree>Root — manages selection and keyboard navigation
Tree.Item<ui-tree-item>Individual node — supports nesting, prefix/suffix slots

Basic Usage

import { Tree } from '@editora/ui-react/Tree';

function FileExplorer() {
const [value, setValue] = React.useState('button');

return (
<Tree
value={value}
onSelect={(detail) => setValue(detail.value)}
>
<Tree.Item value="src" label="src" expanded>
<Tree.Item value="components" label="components" expanded>
<Tree.Item value="button" label="button.tsx" />
<Tree.Item value="dialog" label="dialog.tsx" />
</Tree.Item>
</Tree.Item>
<Tree.Item value="docs" label="docs" expanded>
<Tree.Item value="changelog" label="changelog.md" />
</Tree.Item>
</Tree>
);
}

Prefix and Suffix Slots

<Tree>
<Tree.Item
value="alerts"
label="Alerts"
prefix={<span>🔔</span>}
suffix={<span style={{ fontSize: 11, color: '#64748b' }}>3</span>}
/>
<Tree.Item
value="settings"
label="Settings"
prefix={<span>⚙️</span>}
/>
</Tree>

Disabled Items

<Tree value="active">
<Tree.Item value="active" label="Active Node" />
<Tree.Item value="locked" label="Locked Node" disabled />
</Tree>

Controlled Expand/Collapse

function ControlledTree() {
const [selected, setSelected] = React.useState('');

return (
<Tree
value={selected}
onSelect={(detail) => setSelected(detail.value)}
onExpandedChange={(detail) => console.log(detail.value, detail.expanded)}
>
<Tree.Item value="group-a" label="Group A" expanded>
<Tree.Item value="item-1" label="Item 1" />
<Tree.Item value="item-2" label="Item 2" />
</Tree.Item>
<Tree.Item value="group-b" label="Group B">
<Tree.Item value="item-3" label="Item 3" />
</Tree.Item>
</Tree>
);
}

Tree Props

PropTypeDefaultDescription
valuestringControlled selected node value
indentSizestring'16px'CSS value for per-level indentation
onSelect(detail: TreeSelectDetail) => voidFires when a node is selected
onExpandedChange(detail: TreeExpandedChangeDetail) => voidFires when a node is expanded or collapsed

Tree.Item Props

PropTypeDefaultDescription
valuestringUnique identifier for this node (required)
labelReactNodeNode label rendered in the label slot
expandedbooleanfalseWhether this node's children are visible
selectedbooleanfalseMarks node as selected (managed by root)
disabledbooleanfalsePrevents interaction and dims the node
prefixReactNodeContent rendered before the label (icon, avatar, etc.)
suffixReactNodeContent rendered after the label (badge, count, etc.)
childrenReactNodeNested Tree.Item nodes

Event Detail Types

type TreeSelectDetail = {
value: string;
label: string;
};

type TreeExpandedChangeDetail = {
value: string;
expanded: boolean;
};

Keyboard Navigation

KeyAction
ArrowDownMove focus to next visible node
ArrowUpMove focus to previous visible node
ArrowRightExpand focused node (or move to first child if already expanded)
ArrowLeftCollapse focused node (or move to parent if already collapsed)
HomeMove focus to first node
EndMove focus to last visible node
Enter / SpaceSelect focused node
Printable characterTypeahead — jump to next node starting with that character