Tree View

About this component

Tree View

A file explorer tree built on the full WAI-ARIA tree pattern: folders open and close with a height animation and a spring on the chevron, indent guides run under every open folder and the branch holding the focus lights up, and each file gets an icon from its extension. Arrow keys walk the tree, Right and Left open, close and climb, Home and End jump, `*` opens every sibling folder and typing a name jumps to it. Single or multiple selection with Shift ranges and Cmd or Ctrl toggles, controlled or uncontrolled expansion and selection, and optional actions at the end of each row.

Usage

The import and the props worth knowing about, in one place.

import { TreeView } from "@/components/beste/component/tree-view";

<TreeView
  aria-label="Project files"
  items={[
    { id: "app", name: "app", children: [{ id: "app/page.tsx", name: "page.tsx" }] },
    { id: "package.json", name: "package.json" },
  ]}
  defaultExpanded={["app"]}
/>

// Multiple selection, controlled, with an action on Enter or double click
<TreeView
  items={items}
  selectionMode="multiple"      // "single" (default) | "multiple" | "none"
  selected={selected}
  onSelectedChange={setSelected}
  onAction={(item) => console.log("Open", item.name)}
  renderActions={(item) => <button type="button" onClick={() => console.log("Rename", item.name)}>Rename</button>}
  tone="outline"                 // "ghost" (default) | "muted" | "outline"
  size="sm"                      // "sm" | "default" | "lg"
/>

Keyboard and gestures

Every one of these is in the component already. They are listed because a props table cannot mention a gesture, so nothing else on this page can tell you they exist.

Arrow Up / DownMove between visible items; the tree is one tab stop.
Arrow RightOpen a closed folder, or step into an open one.
Arrow LeftClose an open folder, or climb to the parent.
Home / EndJump to the first or last visible item.
*Open every folder at the focused item's level.
Type a nameJump to the next item starting with the letters typed.
Enter / Double-clickSelect the item and run onAction; without one, a folder opens or closes.
SpaceSelect the item; in multiple mode it toggles, with Shift it selects a range.
Shift + Arrow / ClickExtend a range in multiple mode.
Cmd or Ctrl + ClickToggle one item in multiple mode.
Cmd or Ctrl + ASelect every visible item in multiple mode.

Props

Read from the component's own type, so this cannot drift from what it accepts.

PropTypeDefaultDescription
items*TreeViewItem[]—
selectionMode"single" | "multiple" | "none"—"single" (default), "multiple" (Shift for ranges, Cmd or Ctrl to toggle) or "none".
selectedstring[]—
defaultSelectedstring[]—
onSelectedChange(ids: string[]) => void—
expandedstring[]—
defaultExpandedstring[]—
onExpandedChange(ids: string[]) => void—
onAction(item: TreeViewItem) => void—Enter or a double click on an item.
renderActions(item: TreeViewItem) => React.ReactNode—Controls at the end of a row, shown on hover, focus and selection.
expandOnClickboolean—Clicking a folder row also opens or closes it.
guidesboolean—Vertical guides under each open folder; the branch holding the focus lights up.
iconsboolean—File and folder icons.
tone"muted" | "outline" | "ghost"—
size"sm" | "default" | "lg"—
classNamestring—
aria-labelstring—

More Tree components

View all Tree
  • data: {10 keys}
    • artist: "Joni Mitchell"
    • tour: "Blue, Revisited"
    • year: 2026
    • onSale: true
    • support: null
    • manager: {3 keys}
      • name: "Elliot Roberts"
      • email: "hello@beste.co"
      • phone: "+1 310 555 0142"
    • dates: [4 items]
    • setlist: [12 items]
      • 0: "All I Want"
      • 1: "My Old Man"
      • 2: "Little Green"
      • 3: "Carey"
      • 4: "Blue"
      • 5: "California"
      • Show 6 more (6 left)
    • band: [3 items]
    • rider: {2 keys}
      • piano: "Steinway D"