OrgChart

Top-down organizational chart with collapsible subtrees. Each node renders as a rounded card showing label + subtitle; click any node with children to fold its subtree behind a +N badge.

Installation

pnpm
pnpm dlx @hex-core/cli add org-chart

Usage

tsx
import { OrgChart } from "@/components/ui/org-chart"

Three-level org chart

CEO with two reports, one of whom has further reports.

tsx
<OrgChart root={{
  id: "ceo", label: "Jane Doe", subtitle: "CEO",
  children: [
    { id: "cto", label: "Bob Smith", subtitle: "CTO",
      children: [{ id: "eng", label: "Eng Team", subtitle: "12 people" }] },
    { id: "cfo", label: "Sara Lin", subtitle: "CFO" },
  ],
}} />

Initially collapsed past depth 1

Render only the top two layers expanded; click +N badges to drill down.

tsx
<OrgChart defaultExpandedDepth={1} root={orgTree} />

API Reference

PropTypeDefaultDescription
rootrequired
objectHierarchy root: { id, label, subtitle?, avatarUrl?, children? }.
collapsible
booleantrueWhen true, clicking a node with children toggles its collapsed state.
defaultExpandedDepth
numberNodes deeper than this depth render collapsed initially. Defaults to Infinity (all expanded).
nodeWidth
number180Pixel width of each node card.
nodeHeight
number64Pixel height of each node card.
width
number800SVG pixel width.
height
number480SVG pixel height.
onNodeClick
functionCalled with the clicked OrgNode. Fires before any internal collapse toggle.
className
stringAdditional CSS classes on the SVG element.

AI Guidance

When to use

Visualize people / team / department hierarchies, or any tree where each node is a labeled entity (not a value-sized bucket). Use when relationships are strictly parent-child and the user wants to drill into branches. `onNodeClick` fires for ALL nodes (root, internal, leaves) BEFORE the internal collapse toggle so consumers can observe pre-toggle state.

When not to use

Don't use for value-scaled hierarchies (use TreeMap or Sunburst). Don't use for arbitrary node graphs with cross-edges (use Canvas). Don't use for purely conceptual maps (use MindMap).

Common mistakes

  • Hierarchies thousands of nodes deep — d3.tree's horizontal spread becomes unreadable. Combine with `defaultExpandedDepth` and let users drill
  • Mutating `root` in place when toggling expansion externally — internal collapse state keys off ids, so the controlled escape hatch should provide a stable id and a NEW root object
  • Placing the SVG in a 0×0 container — the layout computes from `width`/`height`, but the rendered SVG inherits its container's dimensions

Accessibility

The SVG carries role="img" with a <title> and <desc> summarizing the visible node count and root label. Collapsed-count badges are visual; for screen readers, also expose a parallel <ul> listing label/subtitle/depth.

Token budget: 360

Verified against @hex-core/components@1.12.0