Tree View
Navigate nested folders and structured content with expandable branches, smooth blur transitions, and keyboard navigation.
Installation
You can add the tree view using our CLI or manually:
Dark mode ready - this component follows BoardUI semantic tokens automatically. Set up theme switching.
The CLI copies the component source (with its internal dependencies) into your project and installs any required npm packages.
npx boardui@latest add tree-viewUsing a shared UI package or custom import aliases? Configure your installation paths before running the CLI. Copy-paste examples use the default imports.
Controlled and data-driven
Keep expansion and selection in your own state with expandedKeys and selectedKeys. Use TreeViewCollection to recursively render nested data. Every item needs a unique, stable id.
Branches expand and collapse with a smooth height, fade, and blur transition. Exiting rows leave keyboard navigation immediately, and reduced motion disables the animation.
import { useState } from "react";import type { Key, Selection } from "react-aria-components";import { TreeView, TreeViewCollection, TreeViewItem } from "@/components/base/tree-view/tree-view";
interface FileNode { id: string; name: string; children?: FileNode[];}
const files: FileNode[] = [ { id: "design", name: "Design", children: [ { id: "logo", name: "Logo.svg" }, { id: "colors", name: "Colors.fig" }, ] }, { id: "notes", name: "Project notes.md" },];
function renderFile(item: FileNode) { return ( <TreeViewItem id={item.id} label={item.name}> <TreeViewCollection items={item.children ?? []}>{renderFile}</TreeViewCollection> </TreeViewItem> );}
export function Example() { const [expandedKeys, setExpandedKeys] = useState<Set<Key>>(new Set(["design"])); const [selectedKeys, setSelectedKeys] = useState<Selection>(new Set(["logo"]));
return ( <TreeView aria-label="Workspace files" items={files} expandedKeys={expandedKeys} onExpandedChange={setExpandedKeys} selectedKeys={selectedKeys} onSelectionChange={setSelectedKeys} > {renderFile} </TreeView> );}Multiple selection
Set selectionMode="multiple" to toggle items independently. Hold Shift to select a range with the keyboard. Single selection is the default; use selectionMode="none" with onAction for an action-only tree.
<TreeView aria-label="Documents to share" selectionMode="multiple" defaultExpandedKeys={["documents"]} defaultSelectedKeys={["overview", "guidelines"]}> <TreeViewItem id="documents" label="Documents" trailingContent="3 files"> <TreeViewItem id="overview" label="Overview.md" /> <TreeViewItem id="guidelines" label="Guidelines.md" /> <TreeViewItem id="changelog" label="Changelog.md" /> </TreeViewItem></TreeView>Sizes, icons, and states
Use size="sm" for compact rows and showGuides={false} to hide guide lines. Branches get folder icons automatically; pass a Remix Icon component to icon or expandedIcon to customize them. Disabled items prevent interaction, and renderEmptyState supplies an empty message.
import { RiFolder3Line } from "@remixicon/react";
<TreeView aria-label="Repository files" size="sm" showGuides={false}> <TreeViewItem id="index" label="index.tsx" /> <TreeViewItem id="private" label="Private files" isDisabled trailingContent="Restricted" /> <TreeViewItem id="archive" label="Archive" icon={RiFolder3Line} trailingContent="Empty" /></TreeView>
<TreeView aria-label="Search results" renderEmptyState={() => "No matching files."}> {[]}</TreeView>Right-to-left
Set the locale with DirectionProvider. Indentation, guide lines, disclosure icons, and horizontal keyboard navigation follow the reading direction.
import { DirectionProvider } from "@/components/foundations/direction/direction";import { TreeView, TreeViewItem } from "@/components/base/tree-view/tree-view";
<DirectionProvider locale="ar"> <TreeView aria-label="ملفات المشروع" defaultExpandedKeys={["project"]}> <TreeViewItem id="project" label="المشروع"> <TreeViewItem id="design" label="التصميم"> <TreeViewItem id="logo" label="الشعار.svg" /> </TreeViewItem> <TreeViewItem id="notes" label="الملاحظات.md" /> </TreeViewItem> </TreeView></DirectionProvider>Keyboard navigation
Tab into the tree, then use Up and Down to move through visible items. Right expands a branch or moves to its first child; Left collapses it or returns to its parent. Home and End jump to the first and last visible items. Type a label to find it, and press Space to select.
Give every tree an aria-label or aria-labelledby. Wrap RTL regions in BoardUI's DirectionProvider with the appropriate locale; disclosure icons, indentation, and horizontal keys follow the direction automatically.