Skip to content
Protocore Design Systemv1.6.9

/// Data Display

TreeView

A disclosure tree of expandable nodes with hairline indent rails, single or multiple selection, and the full APG tree keyboard model.

import { TreeView } from "@protocore/pds";
View as Markdown

Basics

Pass a recursive items array of { id, label, children? }. Nodes with children render a chevron toggle; expansion is controllable via expanded / defaultExpanded, selection via value / defaultValue.

  • infra
    • vpc.tf
    • s3.tf
    • iam.tf
  • services
    • worker
  • README.md

Multiple selection

Set selectionMode="multiple" to toggle a set of ids. The tree advertises aria-multiselectable and each node carries its own aria-selected.

  • eu-central-1
    • eu-central-1a
    • eu-central-1b
    • eu-central-1c
  • us-east-1
    • us-east-1a
    • us-east-1b

selected: eu-a, eu-b

Icons & files

Give any node an icon slot (a ReactNode) — a file explorer, a resource hierarchy, an org chart. The label renders in mono; the icon inherits the muted rail color.

  • app
    • layout.tsx
    • page.tsx
  • README.md

When to use it

Reach for TreeView when data is genuinely hierarchical and users need to expand, collapse, and select nodes across depths — a file browser, an infrastructure tree, a nested category picker. For a flat list of collapsible sections, use Accordion. For read-only nested JSON, use JsonViewer. Keep node ids stable and unique — they are the selection and expansion keys.

Usage

Do

  • Give every node a stable, unique `id`.
  • Pass an `aria-label` to the tree so `role="tree"` is named.
  • Provide a `textValue` when a node's `label` isn't plain text, so type-ahead still works.
  • Control `expanded` when the open/closed state must survive navigation.

Don't

  • Don't use a tree for a flat list — a list, RadioGroup, or Accordion reads faster.
  • Don't put interactive controls inside a node label; the row itself is the click target.
  • Don't reuse `id`s across nodes — selection and focus will collide.
  • Don't ship emoji for the expand glyph; the chevron is a monochrome inline SVG for a reason.

Accessibility

KeysAction
Arrow Down / UpMove to the next / previous visible node.
Arrow RightExpand a collapsed branch, or step into its first child if already open.
Arrow LeftCollapse an open branch, or step to the parent node.
Home / EndMove to the first / last visible node.
Enter / SpaceSelect (or toggle, in multiple mode) the focused node.
Type a letterJump to the next node whose label starts with it.
*Expand every sibling branch at the current level.
  • Built to the WAI-ARIA tree pattern: `role="tree"` over `role="treeitem"` with `aria-expanded`, `aria-selected`, `aria-level`, `aria-setsize`, and `aria-posinset`; nested children live in a `role="group"`.
  • Roving tabindex — one node is tabbable at a time, so the tree is a single Tab stop.
  • Each node is named by its own label (not the concatenated subtree), so screen readers announce the node, not its descendants.

TreeView props

PropTypeDefaultDescription
aria-labelstringAccessible name for the tree (required for a labelled `role="tree"`).
classNamestring
defaultExpandedstring[]Initial expanded ids in uncontrolled mode.
defaultValuestring | string[]Initial selection in uncontrolled mode.
expandedstring[]Controlled set of expanded branch ids.
items *TreeNode[]The node forest to render.
onExpandedChange((expanded: string[]) => void)Fires with the next expanded-id array.
onSelect((id: string) => void)Fires with the id each time a node is activated (before selection settles).
onValueChange((value: string | string[]) => void)Fires with the next selection, matching the `selectionMode` shape.
selectionModeenumsingle`single` (default) selects one id; `multiple` toggles a set.
styleCSSProperties
valuestring | string[]Controlled selection — a string in single mode, a string[] in multiple mode.

Related

  • AccordionDisclosure list — hairline-separated rows with a sans title and a mono +/− glyph that swaps as a row opens. Single or multiple.
  • SidebarA left navigation rail of grouped items — mono uppercase group labels over sans links, with an accent rule on the active item.
  • JsonViewerA collapsible JSON tree that auto-masks sensitive keys, with copy and expand/collapse-all.
  • DefinitionListA dt/dd record display — mono uppercase label beside (or above) a typed value atom.