Accordion

A vertically stacked set of interactive headings that each reveal an associated section of content.

Features

  • Vertical or horizontal
  • Single or multiple
  • Collapsible
  • Controlled or uncontrolled
  • Headless

Installation

npm install @ariaui/accordion

Examples

Two demos—Single (type="single" + collapsible) and Multiple (type="multiple")—each with its own playground and snippet. Style via className on each part.

Single

Only one panel is open at a time. Use collapsible so the active panel can close again.

Preview

No preview output yet.

live.tsxReady

Multiple

Several panels can stay expanded together. Use type="multiple" when users need to compare or reference more than one section at a time.

Preview

No preview output yet.

live.tsxReady

Horizontal

Side-by-side columns with orientation="horizontal"

Preview

No preview output yet.

live.tsxReady

Framer Motion

Use Framer Motion with accordion item state to animate panel height and opacity while preserving the standard trigger semantics.

Preview

No preview output yet.

live.tsxReady

Anatomy

tsx
import * as Accordion from "@ariaui/accordion";

export default function Example() {
  return (
    <Accordion.Root>
      <Accordion.Item>
        <Accordion.Header>
          <Accordion.Trigger />
        </Accordion.Header>
        <Accordion.Content />
      </Accordion.Item>
      <Accordion.Item>
        <Accordion.Header>
          <Accordion.Trigger />
        </Accordion.Header>
        <Accordion.Content />
      </Accordion.Item>
    </Accordion.Root>
  );
}

API Reference

Root

The root container. Manages open state and provides context to all children.

PropTypeDefault
type*
single | multiple
value
string | string[]
defaultValue
string | string[]
onValueChange
(value: string) => void | (value: string[]) => void
collapsible
booleanfalse
disabled
booleanfalse
orientation
vertical | horizontalvertical
AttributeValues
[data-orientation]vertical | horizontal
[data-disabled]Present when disabled

Item

Represents one accordion section. Open state is keyed by value, not render index.

PropTypeDefault
value*
string
disabled
booleanfalse
AttributeValues
[data-state]open | closed
[data-disabled]Present when disabled
[data-orientation]vertical | horizontal

Trigger

The accordion header button. Renders a button, exposes aria-expanded and aria-controls. Must be nested inside Header.

PropTypeDefault
asChild
booleanfalse
AttributeValues
aria-expandedtrue | false
aria-controlsID of the associated Content panel
[data-state]open | closed
[data-disabled]Present when disabled
[data-orientation]vertical | horizontal

Content

The controlled panel region. Unmounted by default when closed. Exposes id and aria-labelledby linking back to the Trigger.

PropTypeDefault
asChild
booleanfalse
AttributeValues
[data-state]open | closed
[data-disabled]Present when disabled
[data-orientation]vertical | horizontal

Keyboard

ShortcutAction
Space/EnterToggle expanded state of the focused trigger.
TabMove focus to the next focusable control.
Shift+TabMove focus to the previous focusable control.
Move focus to the next trigger when orientation is vertical.
Move focus to the previous trigger when orientation is vertical.
Move focus to the next trigger when orientation is horizontal.
Move focus to the previous trigger when orientation is horizontal.
HomeMove focus to the first trigger.
EndMove focus to the last trigger.

Accessibility

The Accordion component implements the WAI-ARIA Accordion pattern. Each trigger renders as a <button> with aria-expanded and aria-controls pointing to its associated content region. Content panels carry role="region" and aria-labelledby linking back to the trigger.

Heading level

Accordion.Header defaults to h3. Use asChild with your own heading element to match the page hierarchy, such as <Accordion.Header asChild><h2>....

Previous
Accessibility
Next
Alert