File Tree

Accessible project tree with keyboard navigation, selection, search filtering, animated folders, and hover highlights.

Installation

npx shadcn@latest add @iconiq/file-tree

File Structure

Usage

"use client";

import { File, FileText, Image } from "lucide-react";

import { FileTree, FileTreeItem, FileTreeList } from "@/components/ui/file-tree";

export function FileTreePreview() {
  return (
    <FileTree
      className="w-full max-w-sm"
      defaultExpandedIds={["documents","projects","project1"]}
      defaultSelectedId="index"
    >
      <FileTreeList>
        <FileTreeItem nodeId="documents" label="Documents" hasChildren>
          <FileTreeItem nodeId="projects" label="Projects" hasChildren>
            <FileTreeItem nodeId="project1" label="Project 1" hasChildren>
              <FileTreeItem nodeId="readme" label="README.md" icon={<FileText className="size-4.5" />} />
              <FileTreeItem nodeId="index" label="index.tsx" icon={<FileText className="size-4.5" />} highlight />
            </FileTreeItem>
          </FileTreeItem>
          <FileTreeItem nodeId="images" label="Images" hasChildren>
            <FileTreeItem nodeId="logo" label="logo.png" icon={<Image className="size-4.5" />} />
            <FileTreeItem nodeId="banner" label="banner.jpg" icon={<Image className="size-4.5" />} />
          </FileTreeItem>
        </FileTreeItem>
        <FileTreeItem nodeId="notes" label="notes.md" icon={<File className="size-4.5" />} />
      </FileTreeList>
    </FileTree>
  );
}

Props

Props
Description

FileTree

defaultExpandedIds

Folder node ids that should start expanded on first render.

Type string[]·Default []

expandedIds

Controlled expanded folder ids. Pair with `onExpandedIdsChange`.

Type string[] | Set<string>

onExpandedIdsChange

Called when expanded folder ids change.

Type (expandedIds: string[]) => void

defaultSelectedId

Node id selected on first render in single-select mode.

Type string

defaultSelectedIds

Node ids selected on first render in multiple-select mode.

Type string[]

selectedIds

Controlled selected node ids. Pair with `onSelectedIdsChange`.

Type string[] | Set<string>

onSelectedIdsChange

Called when selected node ids change.

Type (selectedIds: string[]) => void

selectionMode

Selection behavior. Multiple mode supports Cmd/Ctrl additive and Shift range selection.

Type "single" | "multiple"·Default "single"

searchQuery

Case-insensitive label filter. Matching branches auto-expand.

Type string·Default ""

highlightColor

Text color applied to items with `highlight` on `FileTreeItem`.

Type string·Default var(--color-brand, #3b82f6)

iconMap

Custom extension or filename to icon map merged over built-in defaults.

Type Record<string, LucideIcon>

indentSize

Horizontal indent in pixels for each nested folder level.

Type number·Default 24

maxHeight

Enables a scrollable viewport for large trees via overflow-y auto.

Type number | string

showIcons

Whether to render icons. File icons are inferred from the label extension when no custom icon is provided.

Type boolean·Default true

truncate

Truncate long labels with a native title tooltip on each row.

Type boolean·Default false

onLoadChildren

Called when a lazy branch with `hasChildren` opens before children are mounted.

Type (nodeId: string) => void

onNodeClick

Called when a file or folder row is activated.

Type (nodeId: string, event?: React.MouseEvent) => void

onNodeExpand

Called when a folder branch opens or closes.

Type (nodeId: string, expanded: boolean) => void

onNodeContextMenu

Called when a row receives a context menu event.

Type (nodeId: string, event: React.MouseEvent) => void

onNodeDragStart

Called when a draggable row starts dragging.

Type (nodeId: string, event: React.DragEvent) => void

onNodeDragOver

Called when a drag moves over a row.

Type (nodeId: string, event: React.DragEvent) => void

onNodeDrop

Called when a drag is dropped on a row.

Type (nodeId: string, event: React.DragEvent) => void

onNodeDragEnd

Called when a row drag ends.

Type (nodeId: string, event: React.DragEvent) => void

ref

Imperative handle with `expandAll`, `collapseAll`, and `focusNode`.

Type FileTreeHandle

className

Optional class names applied to the bordered root container.

Type string

children

Usually a single `FileTreeList` with nested `FileTreeItem` rows, or use `FileTreeFromItems`.

Type React.ReactNode

FileTreeFromItems

items

Nested node definitions with `id`, `label`, optional `children`, `icon`, `highlight`, `disabled`, and `loading`.

Type FileTreeNodeData[]

...FileTreeProps

All `FileTree` root props are supported.

Type FileTreeProps

FileTreeList

className

Merged with the default vertical stack layout.

Type string

render

Optional Base UI render override for the list container element.

Type ReactElement | ((props) => ReactElement)

FileTreeItem

nodeId

Stable unique id used for expand state, selection, callbacks, and tree semantics.

Type string

label

Display label for the row. File extension or filename is used to pick a default icon.

Type string

icon

Optional custom icon node rendered before the label.

Type React.ReactNode

openIcon

Optional open-state icon for folder rows. Defaults to FolderOpen.

Type React.ReactNode

hasChildren

Marks the row as a branch even when it has no nested children yet. Otherwise inferred from child items.

Type boolean

loading

Shows a spinner icon while lazy children are loading.

Type boolean

disabled

Disables row activation and removes it from keyboard focus order.

Type boolean·Default false

draggable

Enables native drag interactions on the row button.

Type boolean·Default false

highlight

When true, tints the row with `highlightColor` to mark it as new or relevant.

Type boolean

render

Optional Base UI render override for the row button element.

Type ReactElement | ((props) => ReactElement)

children

Nested `FileTreeItem` rows rendered when the branch is expanded.

Type React.ReactNode

Registry bundle

Install the exact registry entry shown on the right when you want the component file and its declared runtime dependencies together.

Dependencies: @base-ui/react, motion, lucide-react.

This page documents the Base UI install only. File and folder rows use Base UI Button with full tree keyboard navigation.

The generated registry file is /r/file-tree.json.

Contact

Additionally, if you find any bug or issue, feel free to raise an issue.