An accessible file tree that drives keyboard navigation and owns selection and folder expansion, controlled or uncontrolled.
- src
- index.ts
- util.ts
- README.md
1
2
3import type { ReactNode } from 'react';
import {Installation#
pnpm dlx shadcn@latest add https://ui.zeroxsolutions.com/r/file-tree.jsonUsage#
import { FileTree, FileTreeGroup, FileTreeItem, FileTreeLabel } from '@/components/data-display/file-tree';The consumer composes FileTreeItem / FileTreeLabel / FileTreeGroup and owns every visible label and icon;
the root ships no copy, so give it an aria-label:
<FileTree aria-label="Files" defaultExpanded={['src']} defaultValue="src/index.ts">
<FileTreeItem value="src">
<FileTreeLabel>src</FileTreeLabel>
<FileTreeGroup>
<FileTreeItem value="src/index.ts">
<FileTreeLabel>index.ts</FileTreeLabel>
</FileTreeItem>
</FileTreeGroup>
</FileTreeItem>
<FileTreeItem value="README.md">
<FileTreeLabel>README.md</FileTreeLabel>
</FileTreeItem>
</FileTree>File Tree and TreeItem (data-display/tree-item) draw a similar row, and stay separate families until a change
shows the two move together.
Composition#
FileTree
|-- FileTreeItem
| |-- FileTreeLabel
| `-- FileTreeGroup
| `-- FileTreeItem
| `-- FileTreeLabel
`-- FileTreeItem
`-- FileTreeLabelAPI reference#
FileTree#
Renders a ul and takes every prop a ul takes except onSelect, plus:
| Prop | Type | Default |
|---|---|---|
value | string | - |
defaultValue | string | - |
onValueChange | (value: string) => void | - |
expanded | string[] | - |
defaultExpanded | string[] | [] |
onExpandedChange | (expanded: string[]) => void | - |
A WAI-ARIA APG Tree View (compound + context): the root owns selection and folder expansion, each controlled or
uncontrolled, and drives keyboard navigation (Up/Down/Home/End move, Left/Right collapse/expand, Enter/Space
select). It sets data-slot="file-tree" and role="tree".
FileTreeItem#
Renders a li and takes every prop a li takes, plus:
| Prop | Type | Default |
|---|---|---|
value | string | required |
A node in a FileTree. It is a folder when it contains a FileTreeGroup (then it carries aria-expanded),
otherwise a leaf. It sets data-slot="file-tree-item" and data-value to its value.
FileTreeLabel#
Renders a div and takes every prop a div takes. The clickable row of a FileTreeItem: a chevron (folders
only, its animated icon playing while the row is hovered or its item focused), then the consumer's icon and file
name as children, indented by depth. Clicking selects the item and toggles a folder. It sets
data-slot="file-tree-label" and data-selected while selected.
FileTreeGroup#
Renders a ul and takes every prop a ul takes. The nested children of a folder FileTreeItem; rendered only
while its parent item is expanded, and deepens aria-level for its descendants. It sets
data-slot="file-tree-group" and role="group".