Skip to main content

Accordion

Implemented

Vertical stack of expandable sections. Single or multi-expand modes. Each header is a button with aria-expanded.

Categorymolecules
Sourcepatterns/molecules/accordion.html
AI HintUse for stacked expandable sections (FAQ-style lists, settings groups) with roving keyboard focus. For a question/answer section with heading + card chrome, the FAQ organism composes this molecule (multiple always on, locale-aware heading); for menus and command palettes use Menu or CommandMenu instead.

Vertical, keyboard-friendly disclosure list. Each item has a single-button header and an animated panel; arrows, Home, and End keys navigate the headers; Space/Enter toggles the panel. NASA Rule 2 governs: between 2 and 10 items, duplicate ids warn in dev.

Accordion

Content & Layout — Family 6

Uncontrolled disclosure list. Pass defaultOpenId to open a single item on first mount, or set defaultOpen on individual items — the component manages open state internally (there is no controlled API). Multiple open panels are supported via the multiple flag.

Usage

Accordion is the canonical disclosure list for FAQ-style content. Provide an accessible name via ariaLabel so screen-reader users get the context.

import { Accordion } from '@epasslive/design-system'

<Accordion
  items={[
    { id: 'one', title: 'Question 1', content: <p>Answer 1</p> },
    { id: 'two', title: 'Question 2', content: <p>Answer 2</p> },
  ]}
  ariaLabel="FAQ"
  multiple={false}
/>

Keyboard shortcuts

  • ArrowDown / ArrowUp — move focus to the next / previous header.
  • Home / End — focus the first / last header.
  • Space / Enter — toggle the focused panel.

Props

Prop
Type
Default
Description
items*
AccordionItem[]
—

Items to render. Each has id, title, content, plus optional defaultOpen and disabled flags.

multiple
boolean
—

When true, multiple panels can be open at once. When false, opening one panel closes the others. Defaults to false.

ariaLabel*
string
—

Accessible label for the accordion. Surfaced to assistive tech.

className
string
—

Additional classes appended to the root container.

id
string
—

Optional id for the root container. Defaults to a useId-derived value.

defaultOpenId
string
—

When provided, that item is open on first mount (single-open mode).

Props

Preview

Accordion

Prop
Type
Required
Default
Description
items
AccordionItem[]
Required
—

2-10 items

multiple
boolean
Optional
false

Allow several panels open at once. When false, opening a panel closes the others; on mount the first open candidate wins.

ariaLabel
string
Required
—

Accessible name for the group root (role='group'). No default — every consumer must pass one.

className
string
Optional
—

Class appended to the root group container.

id
string
Optional
useId()

Stable id base for the root; item button/panel ids are derived from it.

defaultOpenId
string
Optional
—

Id of the panel open on mount. Takes precedence over per-item defaultOpen flags; ignored when the target item is disabled.

Quick use:<Accordion />

Accessibility

ARIA rolegroup

Type

1 rule

NASA Rule 2

items bounded 2-10 (NASA Rule 2)

ARIA

1 rule

WAI-ARIA Accordion Pattern

Each header is <button aria-expanded aria-controls=panelId>; panel has role='region'

Usage

Import

tsxSnippet
import { Accordion } from "@epasslive/design-system"

Example 1

tsxSnippet
<Accordion items={faqItems} ariaLabel="Frequently asked questions" />

Example 2

tsxSnippet
<Accordion items={settingsSections} multiple ariaLabel="Settings sections" />

Anti-patterns

— Do not ship collapsed panels containing focusable children (panels stay in the DOM with aria-hidden)

— Keep items within 2-10 — the component warns outside that range (NASA Rule 2)

— Do not omit ariaLabel — the group root has no default accessible name

Design System v4.1.0 | ePassLive