apx-dsv0.1Local renderer · live
K
Foundations4
  • Getting started
  • Theming
  • Templates
  • Icons
  • Avatar
  • Badge
  • DataGrid
  • Scheduler
  • Stat
  • Table
  • Timeline
  • TreeView
  • Accordion
  • Alert
  • EmptyState
  • Progress
  • Skeleton
  • Spinner
  • SplashScreen
  • Toast
  • ColorPicker
  • FileUpload
  • Form
  • Rating
  • TagsInput
  • Combobox
  • Field
  • Select
  • Toggle
  • Button
  • Calendar
  • Checkbox
  • DatePicker
  • Input
  • NumberInput
  • Radio
  • Slider
  • Switch
  • Textarea
  • AppShell
  • Div
  • Divider
  • Sidebar
  • Stack
  • Typography
  • Image
  • Breadcrumbs
  • Carousel
  • NavigationMenu
  • Pagination
  • Stepper
  • Tabs
  • Toolbar
  • CommandPalette
  • Confirm
  • Drawer
  • HoverCard
  • Menu
  • Modal
  • Popover
  • Tooltip
  • Icon
  • Card
  • PricingCard
60 componentsapx-ds/renderer
Divider
Variant↳ other

Layout

Divider

Token-mapped separator primitive. Horizontal or vertical rule, optional inline label (start/center/end), three thickness values and three border-color tokens. Renders

Divider

The canonical separator primitive. Renders an <hr> by default, switches to a <div role="separator"> when given a label.

Overview — horizontal, vertical, and labeled dividers

Loading preview…
Overview.tsx
tsx
import { Divider } from 'apx-ds';

<Divider />
<Divider orientation="vertical" />
<Divider>OR</Divider>
<Divider color="strong" thickness={2} variant="dashed" />
import { Divider } from 'apx-ds';

<Divider />
<Divider orientation="vertical" />
<Divider>OR</Divider>
<Divider color="strong" thickness={2} variant="dashed" />

Why a Divider primitive

Card / Modal / Menu had been reaching for <hr className="border-t border-…"> in markup. That pattern works but:

  • It silently leaks theme colors when a consumer's <hr> reset wipes them.
  • It cannot express the labeled-divider pattern (<Divider>OR</Divider>) without a 3-element ad-hoc wrapper.
  • It doesn't share the token surface (border-border-subtle / border-border-default / border-border-strong), so theme swaps don't retint every divider at once.

<Divider /> packages all three concerns into one tiny component.

API

PropTypeDefaultDescription
orientation'horizontal' | 'vertical''horizontal'Axis along which the rule runs.
variant'solid' | 'dashed' | 'dotted''solid'Border-style.
thickness1 | 2 | 41Pixel width.
color'subtle' | 'default' | 'strong''subtle'Token-mapped border color.
labelPosition'start' | 'center' | 'end''center'Where the label sits when children is present.
decorativebooleanfalseWhen true, sets role="presentation" + aria-hidden="true".
asElementType'hr' / 'div'Override the rendered element. Defaults to <hr> (no children) or <div role="separator"> (labeled).
childrenReactNode—Optional inline label. When present, the rendered element switches to a wrapping div.
className / style / sx——Standard escape hatches.

Patterns

Vertical divider in a toolbar

tsx
<HStack gap={2} align="center">
  <Button variant="ghost">Cut</Button>
  <Button variant="ghost">Copy</Button>
  <Divider orientation="vertical" />
  <Button variant="ghost">Paste</Button>
</HStack>
<HStack gap={2} align="center">
  <Button variant="ghost">Cut</Button>
  <Button variant="ghost">Copy</Button>
  <Divider orientation="vertical" />
  <Button variant="ghost">Paste</Button>
</HStack>

The vertical divider uses border-inline-start, so RTL flips it to the correct visual edge automatically.

Labeled divider — "OR" separator

tsx
<Divider>OR</Divider>
<Divider>OR</Divider>

Renders a flex row with the label between two flex-grow rule spans. The spans inherit the same color / variant / thickness you pass.

As section heading

tsx
<Divider labelPosition="start">Account settings</Divider>
<Divider labelPosition="start">Account settings</Divider>

Drops the leading rule; the label sits at the start with a single trailing rule.

Inside a Card body

tsx
<Card>
  <div className="p-4">Account</div>
  <Divider />
  <div className="p-4">Security</div>
</Card>
<Card>
  <div className="p-4">Account</div>
  <Divider />
  <div className="p-4">Security</div>
</Card>

The default color="subtle" reads as a quiet section break — exactly what Card asks for.

Decorative usage

tsx
<section aria-labelledby="account-heading">
  <h2 id="account-heading">Account</h2>
  …
  <Divider decorative />
  …
</section>
<section aria-labelledby="account-heading">
  <h2 id="account-heading">Account</h2>
  …
  <Divider decorative />
  …
</section>

When the surrounding region is already announced as a landmark, the divider's screen-reader role becomes noise. decorative={true} makes axe + the AT happy.

Accessibility

  • Unlabeled <hr> carries native role="separator". We emit aria-orientation="vertical" only when needed (horizontal is the spec default).
  • Labeled dividers render <div role="separator"> with the label as its accessible name.
  • decorative={true} switches the role to presentation and applies aria-hidden="true".
  • Both flank-rules in the labeled form are aria-hidden="true" — only the label is announced.
  • axe-core: zero violations across every prop combination.

Theming

tsx
defineTheme({
  components: {
    Divider: {
      styleOverrides: {
        rule: 'opacity-50',
        labeled: 'uppercase tracking-wider',
      },
    },
  },
});
defineTheme({
  components: {
    Divider: {
      styleOverrides: {
        rule: 'opacity-50',
        labeled: 'uppercase tracking-wider',
      },
    },
  },
});

Two slots: rule (every <hr>-form divider + the flank spans of the labeled form) and labeled (the wrapper of the labeled form).

More examples

Basic

Loading preview…
Basic.tsx

Colors

Loading preview…
Colors.tsx

Decorative

Loading preview…
Decorative.tsx

InCard

Loading preview…
InCard.tsx

LabelPositions

Loading preview…
LabelPositions.tsx

Thickness

Loading preview…
Thickness.tsx

Variant

Loading preview…
Variant.tsx

Vertical

Loading preview…
Vertical.tsx

WithLabel

Loading preview…
WithLabel.tsx

Props

PropTypeDefaultDescription
aria-hiddenboolean | "true" | "false"—Pass through `aria-hidden` (e.g. when `decorative` semantics need explicit hiding).
aria-orientationenum—ARIA orientation override. Set automatically when `orientation="vertical"`.
asElementType—Override the rendered element. Defaults to `<hr>` when no children, `<div role="separator">` when children are present (because `<hr>` cannot contain content).
childrenReactNode—Optional inline label. When present, the rendered element switches to a wrapping `<div>`.
classNamestring——
colorenum'subtle'—
decorativebooleanfalseWhen `true`, the divider is announced as `role="presentation"` (or `aria-hidden`) — use it when a surrounding region already conveys the section boundary semantically.
labelPositionenum'center'Where the label sits when `children` is non-empty.
orientationenum'horizontal'Axis.
refRef<HTMLElement>—Forwarded ref. Type is `unknown` because `as` makes the element variable. Allows getting a ref to the component instance. Once the component unmounts, React will set `ref.current` to `null` (or call the ref with `null` if you passed a callback ref). @see {@link https://react.dev/learn/referencing-values-with-refs#refs-and-the-dom React Docs}
rolestring—Escape hatch for ARIA when consumers need a different `role` (e.g. `role="menuitem"`-adjacent usage). Defaults to native `<hr>` semantics or `role="separator"` for labeled dividers.
styleCSSProperties——
sxSx—Theme-aware inline style.
thicknessenum1—
variantenum'solid'—