File Tree
betaA file explorer tree whose folders tilt open, whose children unfold in a stagger beside a drawn guide rail, and whose selection glides from row to row.
- Navigation
- 1 file
- 2 npm packages
- Accessibility notes
- Animates with motion
Loading the example…
pnpm dlx @dowel-ui/cli add file-treenpm packages installed: class-variance-authority, motion.
import { FileTree } from "@/components/ui/file-tree";Default
Controlled
Compact
Custom Icons
<FileTree>
| Prop | Type | Default |
|---|---|---|
items (required) | FileTreeNode[] | — |
defaultExpandedIds of folders open at first render (uncontrolled). | string[] | [] |
defaultSelected | string | null | null |
expandedIds of open folders (controlled). | string[] | — |
guidesVertical rails down each open folder's indent. On by default. | boolean | true |
onExpandedChange | (expanded: string[]) => void | — |
onSelectedChange | (id: string, node: FileTreeNode) => void | — |
selectedThe selected node's id, or null (controlled). | string | null | — |
size | "sm" | "md" | "md" |
statusLabelsWords appended to a node's name for its status: "button.tsx, modified". | Partial<Record<FileTreeStatus, string>> | — |
Plus every attribute of <ul> except children, defaultValue.
Implements the WAI-ARIA tree pattern with nested markup: role=tree, treeitems that own a role=group of their children, and aria-level, aria-posinset, aria-setsize, aria-expanded and aria-selected stated on every item. One item is in the tab sequence at a time (roving tabindex). ArrowUp/ArrowDown move between visible items, ArrowRight opens a folder or steps into it, ArrowLeft closes it or steps out to its parent, Home/End jump to the ends, Enter/Space select (and toggle a folder), * opens every sibling folder and a printable character jumps to the next item starting with it. The tree needs a name: pass aria-label or aria-labelledby. Status is a coloured dot and a letter, and is also part of the item's name ("button.tsx, modified"; the words are overridable through statusLabels), so colour is never the only signal. Glyphs, guide rails and the travelling highlight are aria-hidden. Nothing animates on first paint, and under reduced motion every spring, stagger and tilt resolves instantly.
9/9
checks passed
- Tested — passes
- axe assertion — passes
- Keyboard tested — passes
- Storybook examples — passes
- Accessibility documented — passes
- Semantic tokens only — passes
- Motion from tokens — passes
- className merged — passes
- Visible focus — does not apply
- No fixed widths — passes