File Tree

A hierarchical file explorer with expand/collapse, drag-and-drop, icons, and multi-selection support.

Usage

src
components
button.tsx
card.tsx
modal.tsx
utils
compose.ts
cn.ts
index.ts
package.json
tsconfig.json
README.md
"use client";

import { FileTree, type FileTreeItemRenderProps } from "@thenamespace/uikit";

import { Icon } from "@/demos/icon";

Anatomy

Import the FileTree component and access all parts using dot notation.

import { FileTree } from "@thenamespace/uikit";

<FileTree>
  <FileTree.Section>
    <FileTree.Header />
    <FileTree.Item>
      <FileTree.Indicator />
    </FileTree.Item>
  </FileTree.Section>
</FileTree>;

Reduced Motion

src
components
button.tsx
card.tsx
modal.tsx
utils
compose.ts
cn.ts
index.ts
package.json
tsconfig.json
README.md
"use client";

import { FileTree, type FileTreeItemRenderProps } from "@thenamespace/uikit";

import { Icon } from "@/demos/icon";

Pass reduceMotion to disable expand/collapse animation while keeping the same tree behavior.

With Icons

src
components
button.tsx
card.tsx
modal.tsx
utils
compose.ts
cn.ts
index.ts
package.json
tsconfig.json
README.md
"use client";

import { FileTree, type FileTreeItemRenderProps } from "@thenamespace/uikit";

import { Icon } from "@/demos/icon";

Custom Indicator

src
components
button.tsx
card.tsx
index.ts
package.json
README.md
// @ts-nocheck -- Complex demo data intentionally uses heterogeneous shapes.
"use client";

import { FileTree, type FileTreeItemRenderProps } from "@thenamespace/uikit";

Drag And Drop

src
components
button.tsx
card.tsx
modal.tsx
utils
compose.ts
cn.ts
index.ts
package.json
tsconfig.json
README.md
// @ts-nocheck -- Complex demo data intentionally uses heterogeneous shapes.
"use client";

import { useTreeData } from "@react-stately/data";
import {

Dynamic Collection

src
components
button.tsx
card.tsx
modal.tsx
utils
compose.ts
cn.ts
index.ts
package.json
tsconfig.json
README.md
"use client";

import { FileTree } from "@thenamespace/uikit";
import { Collection } from "react-aria-components";

Sizes

sm
src
components
button.tsx
card.tsx
modal.tsx
utils
compose.ts
cn.ts
index.ts
package.json
tsconfig.json
README.md
md
src
components
button.tsx
card.tsx
modal.tsx
utils
compose.ts
cn.ts
index.ts
package.json
tsconfig.json
README.md
lg
src
components
button.tsx
card.tsx
modal.tsx
utils
compose.ts
cn.ts
index.ts
package.json
tsconfig.json
README.md
"use client";

import { FileTree, type FileTreeItemRenderProps } from "@thenamespace/uikit";

import { Icon } from "@/demos/icon";

Guide Lines

always
src
components
button.tsx
card.tsx
modal.tsx
utils
compose.ts
cn.ts
index.ts
package.json
tsconfig.json
README.md
hover
src
components
button.tsx
card.tsx
modal.tsx
utils
compose.ts
cn.ts
index.ts
package.json
tsconfig.json
README.md
none
src
components
button.tsx
card.tsx
modal.tsx
utils
compose.ts
cn.ts
index.ts
package.json
tsconfig.json
README.md
"use client";

import { FileTree, type FileTreeItemRenderProps } from "@thenamespace/uikit";

import { Icon } from "@/demos/icon";

Multiple Selection

src
components
button.tsx
card.tsx
modal.tsx
README.md

Selected: none

// @ts-nocheck -- Complex demo data intentionally uses heterogeneous shapes.
"use client";

import { useState } from "react";

PR File Review

apps
api
src
routes.ts
auth.ts
openapi.ts
frontend/src
dashboard-sidebar.tsx
team-name-editor.tsx
README.md
"use client";

import { useMemo, useState } from "react";

import {

With Checkboxes

namespace-inc/namespace.pro1664 included
.cursor5 included
.github
.husky
.vscode
apps812 included
api104 included
campaigns23 included
docs248 included
content99 included
public
scripts
skills
src145 included
packages416 included
// @ts-nocheck -- Complex demo data intentionally uses heterogeneous shapes.
"use client";

import { useState } from "react";

CSS Classes

Base & Size Classes

  • .file-tree — Root tree container. Sets flex column layout, padding, and outline.
  • .file-tree--sm — Small size. Tighter indent and smaller item padding/font.
  • .file-tree--md — Medium size (default). Moderate indent and padding.
  • .file-tree--lg — Large size. Wider indent and larger item padding/font.

Element Classes

  • .file-tree__item — Individual tree row (file or folder). Rounded with interactive cursor.
  • .file-tree__item--sm — Small item sizing (text-xs, compact padding).
  • .file-tree__item--md — Medium item sizing (text-sm, default padding).
  • .file-tree__item--lg — Large item sizing (text-base, spacious padding).
  • .file-tree__item-content — Flex layout wrapper inside each item. Handles indent via --tree-item-level.
  • .file-tree__guide-line — Vertical indent guide spanning the full row height, one per parent level.
  • .file-tree__guide-line--hover — Guide lines only visible when the tree is hovered.
  • .file-tree__guide-line--none — Guide lines hidden (display: none).
  • .file-tree__chevron — Expand/collapse toggle button. Hidden when item has no children.
  • .file-tree__indicator — The expand/collapse icon inside the chevron. Rotates 90° when expanded.
  • .file-tree__icon — File/folder icon area next to the label.
  • .file-tree__label — Text label for the tree item. Truncates with ellipsis.
  • .file-tree__section — Optional grouping wrapper for related items.
  • .file-tree__section-header — Section heading label. Muted, uppercase-style text.
  • .file-tree__drag-handle — Grip button rendered when dragging is allowed. Appears on hover.

Interactive States

  • Hover: &:hover / [data-hovered="true"] on .file-tree__item — applies bg-default.
  • Pressed: &:active / [data-pressed="true"] on .file-tree__item — applies bg-default-hover.
  • Focus visible: [data-focus-visible="true"] on .file-tree__item — applies focus ring.
  • Disabled: [aria-disabled="true"] on .file-tree__item — applies disabled opacity.
  • Selected: [data-selected="true"] on .file-tree__item — applies bg-default with merged border-radius for adjacent selected items.
  • Expanded: [data-expanded] on .file-tree__item — rotates .file-tree__indicator to 90°.
  • Dragging: [data-dragging] on .file-tree__item — reduced opacity (0.4).
  • Drop target: [data-drop-target] on .file-tree__item — accent background with outline.
  • Empty tree: [data-empty] on .file-tree — centered italic placeholder text.

CSS Variables

  • --file-tree-indent — Indentation width per nesting level (varies by size).
  • --file-tree-item-px — Horizontal padding for item content.
  • --file-tree-guide-color — Color of the indent guide lines (default: color-mix(in srgb, currentColor 10%, transparent)).

API Reference

FileTree

The root tree container. Renders a <div role="treegrid"> internally.

PropTypeDefaultDescription
reduceMotionbooleanfalseDisables expand/collapse animation. The user's reduced-motion preference is still respected.
showGuideLinesboolean | "hover"trueWhether to show indent guide lines. true = always, false = never, "hover" = on tree hover only.
size"sm" | "md" | "lg""md"Size variant controlling item padding, font size, and indent width.

Also supports all RAC Tree props.

FileTree.Item

An individual tree row representing a file or folder.

PropTypeDefaultDescription
titleReactNodeLabel content rendered as the item text. Required.
iconReactNode | ((props: FileTreeItemRenderProps) => ReactNode)Icon rendered before the label. Can be a render function receiving { isExpanded, hasChildItems, allowsDragging }.
dragIconReactNode | false<GripVertical />Drag handle icon shown when dragging is allowed. Pass false to hide.

Also supports all RAC TreeItem props.

FileTree.Indicator

Custom expand/collapse icon used inside the chevron button. Defaults to a ChevronRight icon that rotates on expand.

PropTypeDefaultDescription
childrenReactNodeCustom icon element. When provided, replaces the default chevron.
classNamestringAdditional CSS classes.

FileTree.Section

Groups related tree items under an optional header.

Also supports all RAC TreeSection props.

FileTree.Header

Section heading label rendered above a group of items.

Also supports all RAC TreeHeader props.

useFileTree

A utility hook for working with tree data structures.

const { expandableKeys, filterTree, leaves } = useFileTree({ items });
OptionTypeDefaultDescription
itemsTreeNode[]The tree data. Each node must have id and optional children.
isLeaf(node: T) => boolean!children || children.length === 0Custom predicate to identify leaf nodes.

Returns:

PropertyTypeDescription
expandableKeysstring[]All branch node keys — useful for defaultExpandedKeys.
filterTree(predicate: (node: T) => boolean) => T[]Filters the tree by a leaf predicate, pruning empty branches.
leavesT[]All leaf nodes flattened from the tree.

useFileTreeDrag

A hook that wires up drag-and-drop for the file tree using RAC's useDragAndDrop.

const { dragAndDropHooks } = useFileTreeDrag({ tree });
OptionTypeDefaultDescription
treeTreeDataManagerThe mutable tree data object returned by useTreeData from RAC.
getItems(keys: Set<Key>) => DragItem[]Serializes each key as text/plainCustom drag data per item.
onMove(keys: Set<Key>, target: { key: Key; dropPosition: string }) => voidCallback after items are successfully moved.

Returns: { dragAndDropHooks } — pass directly to the <FileTree> component.