Accordion
When to use it
Section titled “When to use it”From the Lumo.Web.Component.V1.0.Complete library — theUse an accordion to let the user expand one answer at a time without leaving the page — an FAQ list on a marketing page.
accordion description, read 2026-10-19.Where it goes
Section titled “Where it goes”- stacked in a list, as an FAQ
When not to use it
Section titled “When not to use it”- Don’t use it for primary content the user needs to see without an extra click.
- No alternative named. The source states the prohibition without saying what to reach for instead.
What each variant is for
Section titled “What each variant is for”| Property | Value | What it is for |
|---|---|---|
state |
closed |
not stated in the source |
state |
open |
not stated in the source |
Accessibility
Section titled “Accessibility”- the header is a real <button> carrying aria-expanded and aria-controls over a role=“region” panel — the disclosure pattern, so Space and Enter operate it
src/components/accordion/accordion.jsx:150 - the panel is role=“region” labelled by the header button, so its content is reachable and named
src/components/accordion/accordion.jsx:37 - uses aria-disabled rather than the DOM attribute, keeping a disabled header focusable so it can still be read
src/components/accordion/accordion.jsx:152 - the chevron is aria-hidden decoration; aria-expanded already conveys the state, so announcing it twice is worse
src/components/accordion/accordionIcon.jsx:12 - headingLevel wraps the header in a real heading, which is what lets a screen reader jump between questions in an FAQ list
src/components/accordion/accordion.jsx:168
Composition
Section titled “Composition”Nothing in the stories shows this component composed with another.
What this version promises
Section titled “What this version promises”See Versioning. At 0.1.0 the public surface is the named exports of src/index.ts; this component is one of them.
Every story that is not a variant-matrix row, embedded live from the deployed Storybook in both themes. The matrix itself is on the Design tab.
Disabled — not drawn in Figma
Section titled “Disabled — not drawn in Figma”It works — uncontrolled
Section titled “It works — uncontrolled”It works — one open at a time
Section titled “It works — one open at a time”With real content — shows gap 3
Section titled “With real content — shows gap 3”Heading level — an addition
Section titled “Heading level — an addition”Long title — wraps, chevron holds
Section titled “Long title — wraps, chevron holds”Import
Section titled “Import”import { Accordion } from '@ds-house/lumo-design-system';| Prop | Type | Default | Notes |
|---|---|---|---|
state |
`‘closed’ | ‘open’` | — |
defaultState |
`‘closed’ | ‘open’` | 'closed' |
title |
string |
'' |
The header text (208:4899 / 208:4906). title is also a global HTML attribute, so the DOM one is exposed separately as htmlTitle — see docs/naming-conflicts.md for why the Figma name keeps the prop. |
htmlTitle |
string |
— | The DOM title attribute, i.e. the browser’s own hover tooltip. Nothing in the node asks for one; this is the escape hatch that keeps title free for the Figma property. Unset by default. |
disabled |
boolean |
false |
Not a variant in Figma — see docs/accordion.md, gap 1. Blocks the toggle and is announced, while the header stays focusable so it can be read. |
iconName |
string |
'expand_more' |
Material Symbols glyph for the chevron. Defaults to expand_more, which is what node 208:4895 draws. |
headingLevel |
number |
0 |
Not a Figma property and not claimed to be one. The node draws a card, not a document outline, so it has no heading level. Pass 1–6 to wrap the header button in that heading element, which is what lets a screen reader user jump between the questions in an FAQ list. Defaults to 0 — no wrapper — so the default output is exactly what the node draws. |
onToggle |
`(state: ‘closed’ | ‘open’, event: React.MouseEvent) => void` | — |
children |
React.ReactNode |
— | The content region — the _Slot/Content instance (41:21) in the open variant. Named children per the Card precedent in docs/naming-conflicts.md, since the accordion has exactly one slot. |
className |
string |
'' |
|
id |
string |
— | Seeds the ids the button and the panel need to point at each other. Generated when absent. |
Union types
Section titled “Union types”state:'closed'|'open'defaultState:'closed'|'open'onToggle:(state: 'closed'|'open', event: React.MouseEvent) => void
Tokens it needs
Section titled “Tokens it needs”| Token | Light | Dark |
|---|---|---|
--body-body3 |
not in the build | — |
--body-body6-intense |
not in the build | — |
--border-radius-card |
not in the build | — |
--border-width-default |
not in the build | — |
--border-width-focused |
not in the build | — |
--color-bg-base |
not in the build | — |
--color-bg-surfaceprimary |
not in the build | — |
--color-bg-surfacesecondary |
not in the build | — |
--color-border-primary-default |
not in the build | — |
--color-text-placeholder |
not in the build | — |
--color-text-primary |
not in the build | — |
--color-text-secondary |
not in the build | — |
--elevation-focused |
not in the build | — |
--motion-duration-fast |
not in the build | — |
--motion-duration-instant |
not in the build | — |
--opacity-disabled |
not in the build | — |
--size-72 |
not in the build | — |
--size-icon-md |
not in the build | — |
--spacing-padding-lg |
not in the build | — |
--spacing-padding-md |
not in the build | — |
--typography-fontweight-regular |
not in the build | — |
A dash under Dark means the token does not change between themes.
Storybook’s own props table
Section titled “Storybook’s own props table”The Figma node
Section titled “The Figma node”The variant matrix
Section titled “The variant matrix”Each row as the set draws it, in both themes.
Closed
Section titled “Closed”Both variants — as the set is drawn
Section titled “Both variants — as the set is drawn”States — not drawn in Figma
Section titled “States — not drawn in Figma”What Figma never bound, and the gaps recorded against it
Section titled “What Figma never bound, and the gaps recorded against it”The build report docs/accordion.md records no “Design gaps” section.
Where Figma and this repo disagree across the system, see the disagreements record.
Every commit touching this component and its subcomponents — a change to a subcomponent changes the component, and a log that reads only the parent file misses it.
| Commit | Date | Shipped in | Subject |
|---|---|---|---|
2b94809 |
2026-10-19 | unknown | Write the ten component intent files |
c8bc699 |
2026-10-18 | unknown | Add the test suite, and retire the deliberate stop |
9525e0f |
2026-10-17 | unknown | Make the repo a publishable npm package |
445d407 |
2026-10-15 | unknown | Build Accordion from Figma 208:4912 — two states, seven gaps reported |
7ccfbbb53757.