Tree view

Navigate nested folders and structured content.

datanavigation
Preview
Tree view preview

When to use

  • 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.

When not to use

  • Use accordion for a few collapsible sections of content.
  • Use breadcrumb to show the path to the current page.

shadcn CLI

Also installs (1)

  • manicat-foundation
Manual install(+)
registry.jsonjson
{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "tree-view",
  "type": "registry:ui",
  "title": "Tree view",
  "description": "Navigate nested folders and structured content.",
  "categories": [
    "data"
  ],
  "dependencies": [
    "lucide-react",
    "motion"
  ],
  "registryDependencies": [
    "https://manicat.viraza.net/r/manicat-foundation.json"
  ],
  "files": [
    {
      "path": "registry/components/tree-view/tree-view.tsx",
      "type": "registry:component",
      "target": "@components/manicat/tree-view/tree-view.tsx"
    },
    {
      "path": "registry/components/tree-view/tree-view.module.css",
      "type": "registry:component",
      "target": "@components/manicat/tree-view/tree-view.module.css"
    }
  ],
  "docs": "Docs and live preview: https://uiarc.dev/components/tree-view",
  "meta": {
    "tier": "free",
    "kind": "component",
    "docs": "https://manicat.viraza.net/components/tree-view",
    "markdown": "https://uiarc.dev/components/tree-view/markdown",
    "tags": [
      "data",
      "navigation"
    ]
  }
}

Usage

Install the component, then copy this into your app. Change the content and the props to fit your screen.

example.tsxtsx
"use client";

import { Folder, FileText } from "lucide-react";
import { TreeView } from "@/components/manicat/tree-view/tree-view";

const treeNodes = [
  {
    id: "src",
    label: "src",
    icon: <Folder className="size-4" />,
    children: [
      { id: "app", label: "app", icon: <Folder className="size-4" /> },
      {
        id: "lib",
        label: "lib",
        icon: <Folder className="size-4" />,
        children: [
          { id: "cn", label: "cn.ts", icon: <FileText className="size-4" /> },
          { id: "registry", label: "registry.ts", icon: <FileText className="size-4" /> },
        ],
      },
      { id: "site", label: "site", icon: <Folder className="size-4" /> },
    ],
  },
  {
    id: "packages",
    label: "packages",
    icon: <Folder className="size-4" />,
    children: [{ id: "manicat", label: "manicat", icon: <Folder className="size-4" /> }],
  },
];

export function TreeViewExample() {
  return <TreeView nodes={treeNodes} defaultExpandedIds={["src", "lib"]} aria-label="Project files" />;
}

Examples

Real screens rather than isolated props. Switch to Code to copy a whole example into your project.

File explorer Nested folders with icons, arrow-key navigation and a few folders open by default.

File explorer Nested folders with icons, arrow-key navigation and a few folders open by default. preview

Keyboard interactions

KeysAction
ArrowDown / ArrowUpMoves to the next or previous visible row.
ArrowRightOpens a folder, or moves to its first child if open.
ArrowLeftCloses an open folder, or moves to the parent.
Home / EndMoves to the first or last visible row.
Enter / SpaceSelects the row and toggles a folder.

Accessibility

  • 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.

Motion

  • 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.

Responsive behavior

  • 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.

Performance

  • 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

  • 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.