File Tree

Browses files and folders in a keyboard-navigable tree.

app
layout.tsx
page.tsx
globals.css
components
ui
button.tsx
tabs.tsx
tooltip.tsx
icons.tsx
package.json
.env

Selected: components/ui/button.tsx

Installation

pnpm dlx shadcn@latest add @paneui/file-tree

Usage

Composition

Examples

Explicit Values

From Data

Controlled Expanded

Open File and Icons

Keyboard

Follows the WAI-ARIA tree pattern. ↑ / ↓ move, → opens a folder or enters it, ← closes it or goes to the parent, Home / End jump, Enter or Space activates, * expands every sibling folder, and typing jumps to the next matching name.

Values

A node without value uses its path from the root: app for a top-level folder, app/page.tsx for a file in it. defaultExpanded, value and onValueChange all use these paths. Two nodes with the same value log a warning in development.

Icons

A file gets its icon and tint from its extension, and an unknown extension gets a plain file. getFileKind(name) returns the same icon and tint for use elsewhere.

Motion

Under reduced motion, rows only fade in and the selection fill jumps instead of gliding.

API Reference

FileTree

The tree. Reads its FileTreeFolder / FileTreeFile children (or items) into one keyboard-navigable list. Also accepts every prop of div.

items
FileTreeItem[]
Data alternative to declarative children; value is optional as on the parts.
value
string | null
Controlled selected node.
defaultValue= null
string | null
Initial selection when uncontrolled.
onValueChange
(value: string, node: FileTreeNode) => void
Called when a node is selected.
expanded
string[]
Controlled open folder values.
defaultExpanded= []
string[]
Folders open on first render.
onExpandedChange
(expanded: string[]) => void
Called when folders open or close.
onOpenFile
(node: FileTreeNode) => void
Called when a file (not a folder) is activated with Enter or a click.
indent= 12
number
Indent per level, px.
label= "Files"
string
Accessible name of the tree.
PropTypeDefaultDescription
itemsFileTreeItem[]—Data alternative to declarative children; value is optional as on the parts.
valuestring | null—Controlled selected node.
defaultValuestring | nullnullInitial selection when uncontrolled.
onValueChange(value: string, node: FileTreeNode) => void—Called when a node is selected.
expandedstring[]—Controlled open folder values.
defaultExpandedstring[][]Folders open on first render.
onExpandedChange(expanded: string[]) => void—Called when folders open or close.
onOpenFile(node: FileTreeNode) => void—Called when a file (not a folder) is activated with Enter or a click.
indentnumber12Indent per level, px.
labelstring"Files"Accessible name of the tree.
data-type
file or folder, on each row.
data-selected
On the selected row.
Data attributeDescription
data-typefile or folder, on each row.
data-selectedOn the selected row.

FileTreeFolder

Declarative folder; renders nothing on its own. Nest folders and files inside it.

value= path (`parent/name`)
string
Unique id. Defaults to the path from the root.
name*
string
Label; also used for typeahead.
icon
ReactNode
Replaces the chevron. Folders have no folder icon; the chevron is their only leading mark.
meta
ReactNode
Trailing content (status dot, size, badge).
disabled
boolean
Dim it and ignore activation.
className
string
Class for the row.
PropTypeDefaultDescription
valuestringpath (`parent/name`)Unique id. Defaults to the path from the root.
name*string—Label; also used for typeahead.
iconReactNode—Replaces the chevron. Folders have no folder icon; the chevron is their only leading mark.
metaReactNode—Trailing content (status dot, size, badge).
disabledboolean—Dim it and ignore activation.
classNamestring—Class for the row.

FileTreeFile

Declarative file; renders nothing on its own. Same props as FileTreeFolder, without children.

FileTreeNode

A resolved entry, as passed to onValueChange and onOpenFile: the folder props with a required value, plus type: "file" | "folder" and children?: FileTreeNode[]. FileTreeItem is the input form for items, with value optional.