Tree view

Navigate nested folders and structured content.

pnpm dlx shadcn@latest add @uiarc/tree-view
Live · keyboard ready
  • Files, folders, and nested categories people expand and select.
  • Side panels next to code-block or a detail view where selection drives content.
  • Hierarchies that need full keyboard navigation with arrow keys.
  • Use accordion for a few collapsible sections of content.
  • Use breadcrumb to show the path to the current page.

Installation

Add Tree view with the shadcn CLI, or copy the source by hand.

pnpm dlx shadcn@latest add @uiarc/tree-view

Adds the component and its local dependencies, and installs motion, lucide-react. First time? Add the @uiarc registry to components.json, or use the full URL:

example.tsx
import { TreeView, type TreeNode } from "@/registry/components/tree-view/tree-view"; const files: TreeNode[] = [  { id: "app", label: "app", children: [    { id: "page", label: "page.tsx" },    { id: "layout", label: "layout.tsx" },  ] },  { id: "readme", label: "README.md" },]; export function Files() {  return <TreeView nodes={files} defaultExpandedIds={["app"]} onSelect={node => open(node.id)} />;}

TreeView

A keyboard navigable file tree with animated expand and a gliding selection.

PropTypeDefaultDescription
nodesRequired{ id: string; label: string; children?: TreeNode[]; icon?: ReactNode }[]–Root nodes. Nodes with children are folders.
defaultExpandedIdsstring[][]Folders open on first render when uncontrolled.
expandedIdsstring[]–Controlled open folders.
onExpandedChange(expandedIds: string[]) => void–Called with the new open set.
onSelect(node: TreeNode) => void–Called when a row is clicked or activated.
aria-labelstring"File tree"Accessible name for the tree.
ArrowDownorArrowUp
Moves to the next or previous visible row.
ArrowRight
Opens a folder, or moves to its first child if open.
ArrowLeft
Closes an open folder, or moves to the parent.
HomeorEnd
Moves to the first or last visible row.
EnterorSpace
Selects the row and toggles a folder.
  • Uses role="tree" and role="treeitem" with aria-level, aria-posinset, aria-setsize, aria-expanded, and aria-selected.
  • Roving tabindex keeps one row in the tab order.
  • Icons, chevrons, and branch lines are aria-hidden.
  • Opening a folder grows the space and staggers its children in; closing collapses rows smoothly.
  • The selection highlight glides between rows and the chevron rotates on a snappy spring.
  • Reduced motion shows and hides rows instantly.
  • Rows are a fixed 36px and labels ellipsize, so deep paths clip rather than overflow on narrow panels.
  • Each level indents 18px, so very deep trees lose label space on mobile.
  • Hover highlights apply only on hover-capable fine pointers.
  • Every visible row renders with position layout animation; nodes are not virtualized, so keep open folders reasonable.
  • Closed folders do not render their children.

Notes for AI

Give your coding assistant the Markdown reference instead of screenshots.

  • Use for hierarchical data such as files or nested categories. Use accordion for a few collapsible sections of content.
  • IDs must be unique across the whole tree. Control expandedIds when the open set must persist or sync with routing.
/components/tree-view/markdown

The full library index for assistants is at /llms.txt.