Tree

A collapsible, hierarchical tree component for organizing nested items like folders and files.

const tree = useTree(folderNodes, {});return (  <Tree tree={tree}>    <TreeList nodeIds={tree.entity.rootIds} />  </Tree>);

Installation

pnpm add @notion-kit/tree

Usage

The new tree package uses a modern, optimized architecture that accepts flat data (arrays with parentId relationships) and handles tree construction internally.

Basic Example

import { Tree, useTree } from "@notion-kit/tree";
import { TreeList } from "@notion-kit/tree/presets";

const data = [
  { id: "1", parentId: null, title: "Folder 1" },
  { id: "1.a", parentId: "1", title: "File A" },
  { id: "2", parentId: null, title: "Folder 2" },
];

export default function MyTree() {
  const tree = useTree(data, {});

  return (
    <Tree tree={tree}>
      <TreeList nodeIds={tree.entity.rootIds} />
    </Tree>
  );
}

Examples


Non-Collapsible Tree

Disable collapsing to show all nodes expanded by default.

F
Folder 1
F
Folder A
File 1 in folder A
File B
F
Folder 2
File C
File D
F
Folder 3
useTree(data, { collapsible: false })

Multi-Select

Enable selection of multiple tree items.

useTree(data, { selectionMode: "multiple" })

Show Empty Children

Display an indicator when a folder has no children.

useTree(data, { showEmptyChild: true })

Command Tree

A searchable tree interface for command palettes.

<CommandTree tree={tree} />

API Reference

useTree

Creates a tree instance from flat data.

const tree = useTree<T>(data, options);

Parameters:

ParameterTypeDescription
dataT[]Flat array of items with id and parentId
optionsTreeOptionsConfiguration options for the tree

TreeOptions:

OptionTypeDefaultDescription
collapsiblebooleantrueWhether nodes can be collapsed
showEmptyChildbooleanfalseShow indicator for empty folders
selectionMode"single" | "multiple""single"Selection behavior
initialExpandedstring[][]IDs of initially expanded nodes
initialSelectedstring[][]IDs of initially selected nodes
onSelectionChange(id: string) => void-Called when selection changes

Returns: TreeInstance<T>

The tree instance exposes:

  • entity: The tree entity with rootIds, nodes, etc.
  • state: Current tree state (expanded, selected nodes)
  • expand(id): Expand/collapse a node
  • select(id): Select a node
  • getVisibleIds(): Get currently visible node IDs

Tree

Root container providing tree context.

PropTypeDescription
tree*TreeInstance<T>Tree instance from useTree
childrenReact.ReactNodeTree content (typically Tree.List)
classNamestringAdditional CSS classes

Tree.Item

A slottable tree item.

Tree.ExpandIndicator

A slottable button to expand/collapse a node.

PropTypeDescription
onToggle() => voidA handler that is called when the node is toggled

Tree.EmptyIndicator

A slottable indicator to show when a node has no children.

Tree.Group

A slottable tree group.

Tree.List

Renders tree nodes recursively.

PropTypeDescription
nodeIds*string[]Array of node IDs to render
renderItem(props) => JSXCustom renderer for tree items (optional)
renderEmpty(props) => JSXCustom renderer for empty children (optional)

TreeList (Preset)

Pre-styled tree list component from @notion-kit/tree/presets.

PropTypeDescription
nodeIds*string[]Array of node IDs to render

CommandTree (Preset)

Searchable tree component for command interfaces.

PropTypeDescription
tree*TreeInstance<T>Tree instance from useTree

type TreeItemData (Preset)

Base interface for tree item data.

interface TreeItemData {
  id: string;
  parentId: string | null;
  title: string;
  icon?: IconData;
  group?: string | null;
}

Architecture

The tree package uses an optimized O(N) architecture:

  1. Flat Data Input: Accepts arrays with parentId relationships (e.g., from database queries)
  2. Automatic Tree Building: Constructs tree structure internally via BFS traversal
  3. ID-Based Rendering: Uses node IDs for efficient recursive rendering
  4. Derived Visibility: Computes visible nodes on-demand via getVisibleIds()
  5. Smart State Management: Handles expand/collapse, selection via tree instance

This design eliminates the need for pre-structured tree data and provides better performance.