Nested structure, one tab stop

TreeView renders files, folders, and other nested structures as an accessible tree. Branches expand and collapse, one row can be selected, and the whole tree is a single tab stop: arrow keys walk the visible rows. Expansion and selection each work controlled or uncontrolled.

File tree

Branches default to the folder icon and leaves to draft. Clicking a branch row toggles it; clicking any row selects it. Seed the open branches with defaultExpandedIds.

  • src
    • index.ts
  • package.json
  • README.md

Selection

Pass selectedId with onSelect for controlled selection, or defaultSelectedId to leave the component in charge. This demo is controlled and echoes the selected id below the tree.

  • src
    • components
      • Button.tsx
      • Button.css
      • Badge.tsx
    • index.ts
  • package.json
  • README.md

Selected: button-tsx

Custom icons

Any node can name its own Material Symbol via icon, so a tree can hold media, tables, or settings rather than files.

  • Assets
    • hero.png
    • intro.mp4
    • theme.json
  • Database
    • users
    • orders
  • Settings

Deep nesting

Each level indents by one step of the spacing scale. Depth is a CSS custom property, so the indent stays on tokens however deep the data goes.

  • Level 1
    • Level 2
      • Level 3
        • Level 4
          • Deepest leaf
    • Level 2 sibling

Keyboard

The tree follows the WAI-ARIA tree pattern with a roving tabindex: Tab enters and leaves the tree once, and everything else happens on the arrows.

DownUpMove through the visible rows
RightExpand a branch, then step into its first child
LeftCollapse a branch, or move to the parent
EnterSpaceSelect the focused row
HomeEndJump to the first or last visible row