Data display

File tree

A file tree, implementing the WAI-ARIA treeview pattern.

Client componentSource

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
  • index.ts
  • 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
  • index.ts
  • 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.

Props for FileTree
PropTypeDefaultDescription
nodes requiredreadonly TreeNode[]——
label requiredstring—Required. A tree with no accessible name is unnavigable.
selectedIdstring | null——
defaultSelectedIdstring | null——
onSelect(node: TreeNode) => void——
expandedIdsreadonly string[]——
defaultExpandedIdsreadonly string[]——
onExpandedChange(ids: string[]) => void——
guidesboolean—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