Tree

A nesting tree view for file explorers, category browsers and any hierarchy. Built on Radix Collapsible, with single selection, full keyboard navigation and CSS guide rails that trace every level.

  • src
    • components
      • button.tsx
      • card.tsx
      • tree.tsx
    • lib
      • utils.ts
    • globals.css
  • public
    • logo.svg
  • package.json
  • README.md

Installation#

# One-time setup (tokens + lib helpers)npx koalaui-cli@latest init# Add this component (its dependencies come along)npx koalaui-cli@latest add tree

Usage#

usage.tsxTSX
import { Tree, TreeItem } from "@/components/ui/tree"export function Example() {  return (    <Tree defaultExpandedValues={["src"]}>      <TreeItem value="src" label="src">        <TreeItem value="index.ts" label="index.ts" />      </TreeItem>      <TreeItem value="package.json" label="package.json" />    </Tree>  )}

A TreeItem with children is a branch (it renders a caret and a collapsible panel); without children it's a leaf. The value is the node's stable identity for selection and expansion. Pass label and icon so every row stays visually consistent, and nest items as children for depth.

Selection#

Tree holds a single selection. Control it with value / onValueChange, or let it manage its own with defaultValue. Mark any node disabled to take it out of selection, expansion, and the keyboard order.

  • Guides
    • Getting started
    • Installation
  • Components
    • Overview
    • Changelog

Selected: getting-started

Trailing actions & guides#

The tree isn't only for files. Drop a count, a badge, or a menu in the actions slot, and turn off the indent rails with guides={false} when the icons alone carry the hierarchy.

  • Electronics128
    • Phones54
    • Audio31
    • Laptops43

Drag to reorder#

Pass onMove and every row becomes draggable. Drop near the top or bottom of a row to place a node before or after it, or onto the middle of a folder to drop it inside. The tree doesn't own your data, so it reports the move and you apply it; dropping a node into its own subtree is blocked, and Alt + ↑ / ↓ reorders siblings from the keyboard.

  • app
    • layout.tsx
    • page.tsx
  • components
    • button.tsx
    • tree.tsx
  • tailwind.config.ts
  • README.md

Keyboard#

Focus the tree and navigate without the mouse: ↑ / ↓ move between visible rows, → expands a collapsed branch then steps into it, ← collapses an open branch then steps out to its parent, Home / End jump to the first and last rows, and Enter / Space select (and toggle a branch).

API reference#

Tree

The role="tree" root. Owns selection and expansion state and forwards every other ul prop.

  • value / defaultValue / onValueChange: the selected node's value (single selection).
  • expandedValues / defaultExpandedValues / onExpandedChange: the set of expanded branch values.
  • guides: show the nesting guide rails (default true).
  • onMove: enables drag-to-reorder (and Alt+↑/↓); fires { value, target, position } where position is before / after / inside. Apply it to your own data.

TreeItem

A node. A branch when it has children, a leaf when it doesn't. Forwards every other li prop.

  • value: required stable identity for selection and expansion.
  • label: the row label.
  • icon / expandedIcon: leading glyph, with an optional swap while a branch is open.
  • actions: trailing content (a count, a badge, a menu).
  • disabled: removes the node from selection, expansion, and focus.

FAQ#

Children. A `TreeItem` with nested `TreeItem` children renders a caret and a collapsible panel (a branch); one without children is a leaf. There is no separate type prop, just the presence of `children`.