Tree
Tree displays hierarchical data with expandable branches.
Source
LLM docs
Package
Examples
7
Properties
73
Hooks
1
Playground
Basics
Render a hierarchical dataset with collapsing branches. Use
indent to control how far each level is inset.Loading demo…
import { Tree } from '@plocks/ui';
import { TREE_DATA } from './data';
export function Demo() {
return <Tree data={TREE_DATA} collapsible indent={20} />;
}Tree with Checkboxes
Enable
checkboxes with cascadeCheck to keep parent and child nodes synchronized while tracking checked ids.Loading demo…
import { useState } from 'react';
import { Tree } from '@plocks/ui';
import { TREE_DATA } from './data';
export function Demo() {
const [checkedIds, setCheckedIds] = useState<string[]>(['react', 'css']);
return (
<Tree
data={TREE_DATA}
checkboxes
cascadeCheck
checkedIds={checkedIds}
onCheckedChange={setCheckedIds}
expandAll
/>
);
}Tree Selection
Set
selectionMode to single or multiple and drive selectedIds from state. In multiple mode, shift-click captures a range and Cmd/Ctrl-click toggles one row.Loading demo…
import { useState } from 'react';
import { Block, Text, Tree } from '@plocks/ui';
import { TREE_DATA } from './data';
export function Demo() {
const [selectedIds, setSelectedIds] = useState<string[]>([]);
return (
<Block fullWidth>
<Tree
data={TREE_DATA}
selectionMode="multiple"
selectedIds={selectedIds}
onSelectionChange={setSelectedIds}
expandAll
/>
<Text size="xs" c="secondary">
{selectedIds.length === 0
? 'Click a row, shift-click for a range, or Cmd/Ctrl-click to toggle.'
: `${selectedIds.length} selected`}
</Text>
</Block>
);
}Tree Filtering
Provide
filterQuery with hideFiltered to search the tree. A highlight renderer and noResultsFallback are also available for custom match styling and empty states.Loading demo…
import { useState } from 'react';
import { Block, Input, Tree } from '@plocks/ui';
import { TREE_DATA } from './data';
export function Demo() {
const [filterQuery, setFilterQuery] = useState('');
return (
<Block fullWidth>
<Input
label="Search technologies"
value={filterQuery}
onChangeText={setFilterQuery}
placeholder="Type to filter the tree"
/>
<Tree
data={TREE_DATA}
filterQuery={filterQuery}
hideFiltered
expandAll={!!filterQuery}
/>
</Block>
);
}Lazy Loading
Mark a node with
hasChildren and supply loadChildren to fetch a branch the first time it opens. The disclosure control shows a loader while the promise is in flight.Loading demo…
import { Tree, type TreeNode } from '@plocks/ui';
import { TREE_DATA, fetchInstances, fetchVolumes } from './data';
export function Demo() {
const loadChildren = (node: TreeNode) =>
node.id.includes('-web') ? fetchVolumes(node.id) : fetchInstances(node.id);
return <Tree data={TREE_DATA} loadChildren={loadChildren} selectionMode="single" showGuides />;
}Custom Tree Rendering
Pass
renderLabel to build custom rows with icons and badges while keeping the tree interactions intact.Loading demo…
import { Badge, Icon, Row, Text, Tree, type TreeNode } from '@plocks/ui';
import { STATUS_BADGES, TREE_DATA, TYPE_ICONS, type CustomNodeData } from './data';
export function Demo() {
const renderCustomLabel = (node: TreeNode) => {
const data = node.data as CustomNodeData;
const status = STATUS_BADGES[data.status];
return (
<Row gap="sm" align="center" style={{ flex: 1 }}>
<Icon name={TYPE_ICONS[data.type]} size="sm" />
<Text size="sm" style={{ flex: 1 }}>
{node.label}
</Text>
<Badge variant="outline" c={status.color}>
{status.label}
</Badge>
</Row>
);
};
return <Tree data={TREE_DATA} renderLabel={renderCustomLabel} selectionMode="single" expandAll />;
}Virtualized Tree
Pass
virtualized with an h to render only the rows in view. Expansion animation is skipped in this mode; filtering, selection and keyboard navigation all still operate on the full row list.Loading demo…
import { Tree } from '@plocks/ui';
import { TREE_DATA } from './data';
export function Demo() {
return <Tree data={TREE_DATA} virtualized h={320} size="sm" striped showGuides />;
}React Native design for iOS, Android, and Web.
Quick Links
Resources