Data display
File tree
A file tree, implementing the WAI-ARIA treeview pattern.
Import
import { FileTree } from '@the_viveksingh/vivek-ui'A project tree
The full WAI-ARIA treeview keyboard model: arrows navigate across folder boundaries, Right opens and steps in, Left collapses or moves to the parent, * expands the level, and typing jumps to a match.
Click into the tree, then use the arrow keys. Right opens a folder and steps in, Left collapses or moves out to the parent, and typing a letter jumps to a match.
- src
- components
- hooks
- index.ts
- docs
- package.json
- pnpm-lock.yaml
Selected: nothing yet
const tree = [
{
id: 'src',
label: 'src',
// The presence of a children array is what makes a node a folder.
children: [
{ id: 'index', label: 'index.ts' },
{ id: 'components', label: 'components', children: [...] },
],
},
{ id: 'pkg', label: 'package.json' },
{ id: 'lock', label: 'pnpm-lock.yaml', disabled: true },
]
<FileTree
nodes={tree}
label="Project files"
defaultExpandedIds={['src']}
onSelect={(node) => open(node.id)}
/>Controlled expansion
Drive the open folders yourself to persist them, or to open to a path.
- src
- components
- button.tsx
- button.css
- card.tsx
- hooks
- index.ts
- docs
- package.json
- pnpm-lock.yaml
<FileTree
nodes={tree}
label="Project files"
expandedIds={open}
onExpandedChange={setOpen}
/>Props
Generated from the package's own type declarations, so this table cannot drift from the code.
| Prop | Type | Default | Description |
|---|---|---|---|
nodes required | readonly TreeNode[] | — | — |
label required | string | — | Required. A tree with no accessible name is unnavigable. |
selectedId | string | null | — | — |
defaultSelectedId | string | null | — | — |
onSelect | (node: TreeNode) => void | — | — |
expandedIds | readonly string[] | — | — |
defaultExpandedIds | readonly string[] | — | — |
onExpandedChange | (ids: string[]) => void | — | — |
guides | boolean | — | Show the connecting guide lines. Default `true`. |
onSelectedIdChange | (id: string) => void | — | Reports selection changes for a controlled tree — the id twin of `onSelect`, which hands you the whole node. Fires alongside it. |
Every remaining prop is spread onto the root element, so all standard HTML and ARIA attributes work. className and style are merged with the library's own, never replaced, and the ref forwards to the root DOM node.
Rendering
FileTree declares 'use client' because it needs state, effects or event handlers. Importing it into a Server Component creates a client boundary at this component — everything above it stays on the server.