Skip to content
shadcn.io
shadcn.io is not affiliated with official shadcn/ui

Shadcn Tree View for React and Tailwind

Hierarchical data in a tree structure.

package.json
README.md

Installation

bunx --bun shadcn@latest add https://kit.dev/r/tree-view.json

Anatomy

TreeView
├── TreeViewLabel
└── TreeViewTree
    └── TreeViewNode
        ├── TreeViewBranch
        │   ├── TreeViewBranchItem
        │   │   └── TreeViewBranchIndicator
        │   └── TreeViewBranchContent
        │       └── TreeViewNode …
        └── TreeViewContent
            └── TreeViewItem
                └── TreeViewCheckbox

Usage

import {
  TreeView,
  TreeViewLabel,
  TreeViewTree,
  TreeViewNode,
  TreeViewBranch,
  TreeViewBranchItem,
  TreeViewBranchContent,
  TreeViewContent,
  TreeViewItem,
  createTreeCollection,
} from "@/components/ui/tree-view";
const collection = createTreeCollection({
  rootNode: { id: "ROOT", name: "", children: [...] },
});

const Example = () => (
  <TreeView collection={collection}>
    <TreeViewTree>
      {collection.rootNode.children?.map((node, index) => (
        <TreeNode indexPath={[index]} key={node.id} node={node} />
      ))}
    </TreeViewTree>
  </TreeView>
)

const TreeNode = (props: React.ComponentProps<typeof TreeViewNode>) => {
  const { node, indexPath } = props;

  return (
    <TreeViewNode indexPath={indexPath} key={node.id} node={node}>
      {node.children ? (
        <TreeViewBranch>
          <TreeViewBranchItem>{node.name}</TreeViewBranchItem>
          <TreeViewBranchContent>
            {node.children.map((child, index) => (
              <TreeNode indexPath={[...indexPath, index]} key={child.id} node={child} />
            ))}
          </TreeViewBranchContent>
        </TreeViewBranch>
      ) : (
        <TreeViewContent>
          <TreeViewItem>{node.name}</TreeViewItem>
        </TreeViewContent>
      )}
    </TreeViewNode>
  );
};

Controlled

Use selectedValue and onSelectionChange to control the selected node and react to selection changes.

Examples

Multiple selection

Use selectionMode="multiple" to allow selecting multiple nodes.

Hold Shift and click to select a range, or use Ctrl/Cmd+click to toggle individual nodes.

With Context Menu

Right-click on tree items to show a context menu.

Renaming nodes

Use the canRename prop and onRenameComplete callback to enable inline renaming of nodes. Press F2 to activate rename mode on the focused node.

With checkboxes

Use the checkedValue and onCheckedChange props to control the checked nodes.

Tree items can be rendered as links. Use asChild on TreeViewContent and wrap an <a> element with TreeViewItem inside.

Mini Editor

Use the tree view to create a file editor.

Custom icons

There are three ways to customize icons:

  1. Folder — icon and expandedIcon props on TreeViewBranchItem, or per-node via TreeNodeType
  2. Single item — icon prop on TreeViewItem
  3. By extension — fileIcons prop on TreeView with createFileIcons

Folder icons

Use the icon and expandedIcon props on TreeViewBranchItem to customize folder icons. Pass null to hide the icon.

Single item icon

Pass the icon prop to TreeViewItem to override the icon for a specific leaf node.

With file extensions

Use the fileIcons prop on TreeView with createFileIcons to map file extensions to icon components. Icons are resolved from each node's id; unmatched extensions fall back to FileIcon.

API Reference

TreeView

Root component. Provides tree context and manages expand/selection state.

PropTypeDefault
collectionTreeCollectionrequired
fileIconsRecord<string, React.JSX.ElementType | null>-
selectedValuestring[]-
checkedValuestring[]-
onCheckedChange(details: CheckedChangeDetails) => void-
canRename(details: RenameDetails) => boolean-
onRenameComplete(details: RenameCompleteDetails) => void-
defaultSelectedValuestring[]-
onSelectionChange(details: SelectionChangeDetails) => void-
expandedValuestring[]-
defaultExpandedValuestring[]-
onExpandedChange(details: ExpandedChangeDetails) => void-
selectionMode"single" | "multiple""single"
lazyMountbooleantrue
unmountOnExitbooleantrue
classNamestring-
AttributeDefault
--indentation--spacing(4)
--item-gap--spacing(2)
--padding-block--spacing(1.5)
--padding-inline--spacing(3)
--icon-size--spacing(4)

TreeViewLabel

Accessible label for the tree.

PropTypeDefault
asChildbooleanfalse
classNamestring-

TreeViewTree

Wraps the root-level tree nodes.

PropTypeDefault
asChildbooleanfalse
classNamestring-

TreeViewNode

Provides tree node context. Must wrap each branch or item.

PropTypeDefault
nodeTreeNodeTyperequired
indexPathnumber[]required
classNamestring-

TreeViewBranch

Expandable branch with children. Toggles open/closed.

PropTypeDefault
asChildbooleanfalse
classNamestring-

TreeViewBranchItem

Clickable area to expand or collapse a branch.

PropTypeDefault
asChildbooleanfalse
iconReact.JSX.ElementType | nullFolderIcon
expandedIconReact.JSX.ElementType | nullFolderOpenIcon
classNamestring-

TreeViewBranchContent

Holds the branch children. Shown when expanded.

PropTypeDefault
asChildbooleanfalse
classNamestring-

TreeViewContent

Wrapper for leaf (non-expandable) items.

PropTypeDefault
asChildbooleanfalse
classNamestring-

TreeViewItem

Leaf node (non-expandable). The icon prop is fallback when no fileIcons match.

PropTypeDefault
iconReact.JSX.ElementTypeFileIcon
classNamestring-

TreeViewCheckbox

Checkbox for selecting a node in multi-select mode.

PropTypeDefault
classNamestring-

createTreeCollection

Creates a tree collection from node data. Use with collection prop on TreeView.

Options

PropTypeDefault
rootNodeT extends TreeNodeTyperequired
nodeToValue(node: T) => string(node) => node.id
nodeToString(node: T) => string(node) => node.name

TreeNodeType — Shape of each node (extend with generic T for custom props):

PropertyTypeDefault
idstring-
namestring-
childrenTreeNodeType<T>[]undefined
iconReact.JSX.ElementType | nullundefined
expandedIconReact.JSX.ElementType | nullundefined
const collection = createTreeCollection({
  rootNode: { id: "ROOT", name: "", children: [...] },
});

// With custom node props
type LinkNode = TreeNodeType & { href?: string };
const links = createTreeCollection<LinkNode>({
  rootNode: {
    id: "docs",
    name: "Docs",
    children: [{ id: "intro", name: "Intro", href: "/intro" }],
  },
});

createFileIcons

Creates a type-safe mapping of file extensions to icon components. Use with fileIcons prop on TreeView.

Keys use dotted extensions.

const fileIcons = createFileIcons({
  ".tsx": FileCode,
  ".json": FileJson,
  ".md": FileText,
});

For a complete list of props, see the Ark UI documentation.