Mischief

19 / Documents

File Tree

An expandable tree of folders and files with full keyboard navigation and correct tree semantics.

Live previewSource
contracts
2026
acme-msa.pdf1.2 MB
northwind-sow.pdf840 KB
readme.md2 KB

Installation

Copy the source into your project, or keep it behind a package.

Copy the component into your project and make it yours.

Usage

const nodes = [
  {
    id: "invoices",
    name: "invoices",
    kind: "folder",
    children: [{ id: "jan", name: "january.pdf" }],
  },
]

export function Files() {
  return <FileTree nodes={nodes} onSelect={openFile} />
}

API

nodesFileTreeNode[]Id, name, kind, optional children, meta, and icon.
expandedIds, defaultExpandedIdsstring[]Which folders are open, controlled or uncontrolled.
selectedId, defaultSelectedIdstring | nullThe selected node, controlled or uncontrolled.
onSelect(node: FileTreeNode) => voidRuns on selection.
onExpandedChange(ids: string[]) => voidRuns when a folder opens or closes.

Accessibility

The tree uses tree and treeitem roles with aria-level and aria-expanded on every row, so depth and state are announced rather than implied by indentation. There is one tab stop into the tree. Up and Down move between visible rows, Right opens a folder or steps into it, Left closes it or moves to its parent, Home and End jump to the ends, and Enter or Space selects.

Dependencies

lucide-react