Skip to content

Hierarchy Chart

Draw an org chart, a team of teams or any parent-and-children structure as a tidy tree that folds, pans and zooms.

import { HierarchyChart, HierarchyChartHandle } from '@youj/react'

Installation & usage

npm i @youj/react

For an app already set up with npx @youj/cli init, which installs the peers (@youj/core, @youj/motion, motion and Base UI) and wires the provider. New app? Start at Installation.

Use a hierarchy chart when the shape of a tree is the point: who reports to whom, which teams sit under which group, how a product breaks down. For a tree people browse and pick from (files, settings, categories), use a Tree View; for steps that depend on each other, a Flow Graph.

import { HierarchyChart } from '@youj/react'

<HierarchyChart
  nodes={{
    id: 'maya',
    name: 'Maya Lindqvist',
    role: 'CEO',
    children: [
      { id: 'jonas', name: 'Jonas Okafor', role: 'VP Engineering', badge: 'Hiring', children: [/* … */] },
      { id: 'elena', name: 'Elena Petrova', role: 'VP Product' },
    ],
  }}
  selected={selected}
  onSelectedChange={setSelected}
/>

nodes is one root or an array of them, each { id, name, role?, avatar?, badge?, children? }; the default card shows the avatar (or the name's initials), the name, the role and the badge. Pass your own type that extends HierarchyNode and a renderNode(node, state) to draw the card yourself; state says its depth, whether it's selected, on the selected path, a branch and open, and how many nodes sit below it. Every card has one size, nodeSize (224 × 64 by default).

The layout is a tidy tree (Reingold–Tilford, in Walker's linear form): every parent is centered over its children, subtrees pack as close as the gaps allow without overlapping, and identical subtrees are drawn identically. It handles a few hundred nodes at once; layoutHierarchy(nodes, options) returns the same layout for drawing your own.

Branches are all open by default; defaultExpanded or expanded with onExpandedChange take the open ids. To find someone, hold a ref: ref.current.focusNode(id) opens the branches above them, focuses their card and centers it, and ref.current.fit() fits the chart.

Reference

Propsnodes, renderNode, orientation… (14)

Props

HierarchyChart props
PropType
nodesRequiredT | readonly T[]

The tree: one root, or several side by side. Ids must be unique.

–
renderNode(node: T, state: HierarchyNodeState) => ReactNode

A node's card contents, inside the chart's card frame (which draws focus, selection and the path). Default: avatar, name, role and badge.

–
orientationHierarchyOrientation
'vertical''horizontal'

vertical (default) grows down from the root; horizontal grows along the reading direction.

default 'vertical'

'vertical'
expandedstring[]

Open branches (controlled).

–
defaultExpandedstring[]

Default: every branch open.

–
onExpandedChange(ids: string[]) => void–
selectedstring | null

The selected node (controlled); null for none.

–
defaultSelectedstring | null

default null

null
onSelectedChange(id: string | null) => void–
nodeSize{ width: number; height: number }

Every card's size in pixels.

default NODE

NODE
heightnumber

The canvas height in pixels.

default 480

480
labelstring

The tree's accessible name. Default: the labels' "Hierarchy chart".

–
localestring

Default: the YoujProvider locale.

–
soundboolean

With sound on, selecting plays select, opening a branch open and closing it close.

default true

true
refRef<HierarchyChartHandle>–
Other props pass through: extends ComponentProps<'div'>.
StylingParts and data attributes

Styling

Parts: hierarchy-chart (with data-orientation), hierarchy-chart-viewport (with data-dragging), hierarchy-chart-world, hierarchy-chart-edges, hierarchy-chart-edge (with data-active on the selected path), hierarchy-chart-nodes, hierarchy-chart-node (with data-yj-node holding its id, data-selected, data-yj-path on the selection's ancestors, and data-state open or closed on a branch), hierarchy-chart-name, hierarchy-chart-role, hierarchy-chart-toggle (with data-state), hierarchy-chart-controls and hierarchy-chart-zoom. Connectors use the theme's strong line, and the accent on the selected path.

MotionOpen and close, zoom and fit, pan · reduced motion

Motion

Motion tokens
MomentTokens
Open and closethe toggled node stays put while the others glide to their new places; children grow out of their parent and shrink back into it, and the connectors redraw as they move
spring.smooth

0.36s, bounce 0

0.36s, bounce 0
Zoom, fit and focusthe view glides to its new place and scale
duration.slowease.standard

340ms · cubic-bezier(0.2, 0, 0, 1)

340mscubic-bezier(0.2, 0, 0, 1)
Panthe view follows the pointer, the wheel and the pinch, never eased
no token

Reduced motion

Nothing glides: branches open and close in place, and zoom, fit and focus land at once.

Reduced motion

Branches open and close in place, connectors are redrawn at once, and zoom, fit and focus jump to their view. Panning is unchanged, since it never animates.

AccessibilityKeyboard, ARIA

Accessibility

  • The chart is a WAI-ARIA tree named by label (default "Hierarchy chart") and described by a hint that explains the keys. Each card is a treeitem with aria-level, aria-setsize, aria-posinset, aria-selected and, on a branch, aria-expanded. It's named by the node's name and described by its role, its badge and, when closed, how many it hides ("3 hidden below").
  • One Tab stop. ↑ and ↓ move through the nodes in reading order, → opens a branch or steps into it, ← closes it or steps out to its parent (mirrored under RTL), Home and End go to the first and last node, and * opens every sibling branch. Enter opens or closes a branch, Space selects. +, − and 0 zoom and fit.
  • Focus from the keyboard brings its node into view, and closing a branch that holds the focus hands it to the branch.
  • The open/close chip is a pointer shortcut for Enter, hidden from assistive technology; selection is shown by a border and a ring as well as the path's color.
  • With sound on, selecting plays select, opening a branch open and closing it close.
  • Its words come from the labels (hierarchyChart, hierarchyChartHint, hierarchyChartHidden, hierarchyChartExpand, hierarchyChartCollapse, zoomIn, zoomOut, zoomToFit), translated by the language packs.