Theme studio

Design a theme, preview it live, then export it. Saved in this browser.

Quick picks #10b981
Generated scale
50100200300400500600700800900
Some text is below AA

OrgNode

  • Stable
  • WCAG 2.2 evidence
  • RTL

One person (or open position) of an organisation chart. A card with an avatar, the name, the role, a department badge and a report count; nested OrgNode children are its direct reports. **Inside an OrgChart** the node is a tree item (role="treeitem" with aria-level, aria-setsize, aria-posinset, aria-expanded when it has reports and aria-selected when you pass isSelected), named by the name and role and described by the department and report count. Its reports sit under it, joined by decorative connectors, behind an OrgExpander that is a real button. Pressing a node that has reports and no onPress or href expands or collapses it. **On its own** it draws only the card: plain text when static, a React Aria button when it has onPress, a link when it has href. Hover is data-hovered, keyboard focus a 2 px inside ring plus the halo, and the selected state is isSelected (WCAG 2.1.1, 2.4.7, 4.1.2). Selection and a vacancy are shown by fill, stroke and text ("Open role"), never by colour alone (1.4.1).

import { OrgNode } from "@nexera-ui/react";
Loading example…
10
examples
19
props
4
live controls
1
platform
10
WCAG criteria
1
block uses it

Try every prop. Copy the code.

Change the props and the code updates. Check light and dark, LTR and RTL, and phone width.

Loading…
isSelected
lineStyle
children
variant
Generated code
import { OrgNode } from "@nexera-ui/react";

<OrgNode />

Examples 9

The same examples as Storybook, rendered live. Open Code to copy one.

Compact

The compact card: 200 px wide, a 32 px avatar, name and role only.

Loading example…

Vacant

An open position: "Open role" is text, with a user-x icon and the department in a warning badge.

Loading example…

Selected

Selected: a tinted fill, a 2 px brand stroke and aria-current; the text is not coloured alone.

Loading example…

As button

A button that opens the person's panel: Tab to it, Enter or Space presses. The name and role name it; the rest describes it.

Loading example…

With photo

A photo through the avatar slot (an Avatar of size="lg", decorative because the name is next to it).

Loading example…

Long content

Long content wraps and the card grows.

Loading example…

Right to left

Right-to-left: the avatar moves to the right, the report count to the left, the text aligns to the start.

Loading example…

Narrow width

Narrow container (320 px): the card shrinks to the container (max-w-full) and the text wraps.

Loading example…

Props 19

Press "Try it" on a card to load that prop into the playground.

19 props shown

idNexera
Key

Identifies the node inside an OrgChart: the key used by expandedKeys, defaultExpandedKeys and onExpandedChange. Give every node that has reports a stable one (an employee id); without it the node still works but its expansion cannot be controlled from outside.

Default –
jobTitleNexera
string

The person's role or the open position. Wraps onto more lines instead of being truncated. Named jobTitle because role is the HTML attribute.

Default –
isSelectedNexera
boolean

Whether the node is the selected one: nav/active-bg with a 2 px brand stroke. Inside a chart it becomes aria-selected, so pass a boolean on every node when your chart supports selection (and nothing when it does not); on a standalone card it becomes aria-current. Hover and focus are pointer and keyboard states that React Aria drives.

Default –
lineStyleNexera
"solid" | "dotted"

Line style of the connector that joins this node to its manager: solid, or dotted for a secondary, dotted-line relationship. Only used inside a chart. The line is decorative: also say a dotted relationship in text (for example in jobTitle) (WCAG 1.4.1).

Default solid
directReportsNexera
number

Number of direct reports shown on the expander. Defaults to the number of OrgNode children. Set it when the reports load lazily: a node with a count above zero is expandable even before its children exist; render the children once onExpandedChange reports the node as expanded.

Default –
expandLabelNexera
string

Name of the expander button while the node is collapsed. Translate it.

Default `Expand ${name}'s reports (${count})`
collapseLabelNexera
string

Name of the expander button while the node is expanded. Translate it.

Default `Collapse ${name}'s reports (${count})`
childrenNexera
ReactNode

The node's direct reports, as OrgNode elements (not fragments). They are drawn, with their connectors, under the node while it is expanded, and only inside an OrgChart: a standalone node draws only its card.

Default –
classNameNexera
string

Extra classes for the card, merged last so they win over the defaults.

Default –
styleNexera
CSSProperties

Inline style for the card.

Default –
variantNexera
"default" | "compact" | "vacant"

Presentation: default is the 240 px card, compact a 200 px row without department and reports, vacant an open position. The compact card: 200 px wide, a 32 px avatar, name and role in one row. An open position: a dashed-look card on bg/page with a user-x icon and the department in a warning badge.

Default default
nameNexera
string

The person's name. Names the node. Wraps instead of truncating. The person's name. What the card says in place of a name. Translate it. The text is what tells people the position is vacant, not the colours (WCAG 1.4.1).

Default "Open role"
avatarNexera
ReactNode

The avatar. Pass an Avatar of size="lg" (40 px) with isDecorative to show a photo. By default the initials of name are drawn. The avatar: an Avatar of size="md" with isDecorative. Not used: a vacancy has a user-x icon instead.

Default –
departmentNexera
ReactNode

Department. Shown when provided; the text is the badge's label. Not shown in the compact card. Department of the position.

Default –
reportsNexera
string

Report count: shown with a people icon when provided. Write the whole phrase, translated ("8 direct reports"). Not shown in the compact card. Not shown on a vacancy.

Default –
onPressNexera
((event: PressEvent) => void) | ((event: PressEvent) => void)

Called when the card is pressed (pointer, Enter or Space). The card becomes a button, or a tree item that runs this. Also called when the link is pressed.

Default –
hrefNexera
string

The card becomes a link to this URL (inside a chart, a tree item with a link over it; Enter follows it).

Default –
targetNexera
string

Link target.

Default –
relNexera
string

Link relationship.

Default –

* Required. React Aria props shown are the ones most apps use; the component accepts the rest of its React Aria props too.

Accessible by default.

Built on React Aria, and covered by the WCAG 2.2 evidence generated on every build.

WCAG 2.2 evidence

8 direct · 2 supporting
  • 1.1.1Non-text ContentLevel A · tested directly
  • 1.3.1Info and RelationshipsLevel A · tested directly
  • 1.3.2Meaningful SequenceLevel A · tested directly
  • 1.4.1Use of ColorLevel A · tested directly
  • 1.4.10ReflowLevel AA · supporting test
  • 1.4.12Text SpacingLevel AA · supporting test
  • 2.1.1KeyboardLevel A · tested directly
  • 2.4.7Focus VisibleLevel AA · tested directly
  • 2.5.3Label in NameLevel A · tested directly
  • 4.1.2Name, Role, ValueLevel A · tested directly

Fits any width.

Nexera components respond to the space they are given. Drag the corner of the frame, or pick a width.

0 px · drag the corner

Styling hooks

Pass className to add Tailwind classes (merged last). State is exposed as data attributes, so you can style it with variants like data-pressed:.

  • data-focus-visible
  • data-hovered
  • data-selected
Usage
<OrgNode className="data-focus-visible:opacity-90 shadow-sm" />

Used in blocks

Related components