How to build an accessible TreeView in React
Implements the WAI-ARIA TreeView pattern: role=tree on the root, role=treeitem with aria-level/posinset/setsize and aria-expanded on each node, a single roving tabindex, and full APG keyboard support (arrows expand/collapse and move, Home/End, Enter/Space select, printable-character typeahead)
When to use a TreeView
- Showing nested, parent/child data the user expands and collapses (file trees, org charts, nav)
- Letting the user pick one or several nodes from a hierarchy
- Navigating deep structures where indentation communicates depth
When not to use it
- A flat, non-nested list of choices — use List or StructuredList
- A small set of mutually exclusive sections of prose — use Accordion
Keyboard interactions
Role tree, verified at WCAG 2.2-AA.
ArrowDownArrowUpArrowRightArrowLeftHomeEndEnterSpaceTypeahead
Common mistakes
Avoid: A single-level TreeView with no children on any node
Prefer: A List or StructuredList
A tree with no hierarchy adds twisties and ARIA tree semantics for content that is flat
Example
<TreeView defaultExpanded={["src"]} items={[{ id: "src", label: "src", children: [{ id: "index", label: "index.ts" }] }]} />