Tree
Tree
Basic Tree
src
components
utils
index.ts
docs
Controlled Expansion
Expanded: src, components
src
components
Button.tsx
Input.tsx
Modal.tsx
utils
index.ts
docs
With Actions
src
components
utils
index.ts
docs
Built from Flat Data
Using buildTree() utility
Animals
Mammals
Dog
Cat
Birds
Eagle
Plants
Trees
Empty State
No files found
import { Tree, type TreeNode } from "@f0rbit/ui";
const nodes: TreeNode[] = [ { id: "src", label: "src", children: [ { id: "index", label: "index.ts" }, { id: "utils", label: "utils.ts" }, ], },];
<Tree nodes={nodes} />| Prop | Type | Default | Description |
|---|---|---|---|
nodes | TreeNode[] | TreeNode | — | Tree node(s) to render |
renderNode | (node: TreeNode, depth: number) => JSX.Element | — | Custom node label rendering |
renderActions | (node: TreeNode, depth: number) => JSX.Element | — | Render action buttons for each node |
showGuides | boolean | true | Show tree guide lines |
defaultExpanded | boolean | string[] | true | Initial expansion state (uncontrolled) |
expanded | string[] | — | Controlled expansion state (node IDs) |
onExpandedChange | (expanded: string[]) => void | — | Callback when expansion changes |
emptyMessage | string | "No items" | Message when tree is empty |
Building from Flat Data
Section titled “Building from Flat Data”Use the buildTree utility to convert flat data with parentId references:
import { Tree, buildTree, type FlatTreeItem } from "@f0rbit/ui";
const items: FlatTreeItem[] = [ { id: "1", label: "Root", parentId: null }, { id: "2", label: "Child", parentId: "1" }, { id: "3", label: "Grandchild", parentId: "2" },];
<Tree nodes={buildTree(items)} />Default Expansion
Section titled “Default Expansion”Control initial expansion state with defaultExpanded:
// All collapsed<Tree nodes={nodes} defaultExpanded={false} />
// All expanded<Tree nodes={nodes} defaultExpanded />
// Specific nodes expanded<Tree nodes={nodes} defaultExpanded={["src", "components"]} />Controlled Expansion
Section titled “Controlled Expansion”For controlled expansion, use expanded and onExpandedChange:
const [expanded, setExpanded] = createSignal<string[]>(["src"]);
<Tree nodes={nodes} expanded={expanded()} onExpandedChange={setExpanded}/>Custom Node Rendering
Section titled “Custom Node Rendering”Customize how nodes are rendered with renderNode:
<Tree nodes={nodes} renderNode={(node, depth) => ( <span style={{ color: depth === 0 ? "blue" : "inherit" }}> {node.label} </span> )}/>Node Actions
Section titled “Node Actions”Add action buttons to nodes with renderActions:
<Tree nodes={nodes} renderActions={(node) => ( <Button size="sm" variant="ghost" onClick={() => handleSelect(node)}> Select </Button> )}/>Guides
Section titled “Guides”Tree guides are shown by default. Disable with showGuides={false}:
<Tree nodes={nodes} showGuides={false} />Empty State
Section titled “Empty State”Customize the empty state message:
<Tree nodes={[]} emptyMessage="No files found" />Common Use Cases
Section titled “Common Use Cases”File Browser
Section titled “File Browser”<Tree nodes={fileSystem} defaultExpanded={["src"]} renderNode={(node) => ( <span> {node.children?.length ? "folder" : "file"} {node.label} </span> )}/>Organization Chart
Section titled “Organization Chart”const orgChart = buildTree(employees);
<Tree nodes={orgChart} defaultExpanded renderActions={(node) => ( <Button size="sm" onClick={() => viewEmployee(node.data)}> View </Button> )}/>Category Navigation
Section titled “Category Navigation”<Tree nodes={categories} expanded={expanded()} onExpandedChange={setExpanded} renderNode={(node) => ( <a href={`/category/${node.id}`}>{node.label}</a> )}/>