Skip to content

Accordion

Edit on GitHub

Toggle the visibility of content sections using native details/summary elements.

@volvo-cars/css v2.5.1@volvo-cars/react-accordion v2.3.22

Compose AccordionDetails and AccordionSummary on the native <details> and <summary> elements.

Exterior

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse malesuada lacus ex, sit amet blandit leo lobortis eget.

Charging

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse malesuada lacus ex, sit amet blandit leo lobortis eget.

Climate

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse malesuada lacus ex, sit amet blandit leo lobortis eget.

Show codeHide code
import {
AccordionDetails,
AccordionSummary,
} from '@volvo-cars/react-accordion';
export function BasicAccordion() {
return (
<>
{['Exterior', 'Charging', 'Climate'].map((item) => (
<AccordionDetails key={item}>
<AccordionSummary>{item}</AccordionSummary>
<p className="pb-24 text-secondary">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse
malesuada lacus ex, sit amet blandit leo lobortis eget.
</p>
</AccordionDetails>
))}
</>
);
}

AccordionDetails wraps each section. Its first child should be an AccordionSummary: this becomes the toggle. Everything else is the collapsible content.

AccordionSummary renders a <summary> element with an implicit button role. It must not contain interactive children (links, buttons, checkboxes).

Control where the chevron icon appears with iconPlacement. Use iconAlignment to adjust vertical alignment when labels wrap.

Icon at end (default)

The chevron appears after the label.

Icon at start

The chevron appears before the label.

Show codeHide code
import {
AccordionDetails,
AccordionSummary,
} from '@volvo-cars/react-accordion';
export function IconPlacement() {
return (
<>
<AccordionDetails>
<AccordionSummary iconPlacement="end">
Icon at end (default)
</AccordionSummary>
<p className="pb-24 text-secondary">
The chevron appears after the label.
</p>
</AccordionDetails>
<AccordionDetails>
<AccordionSummary iconPlacement="start">Icon at start</AccordionSummary>
<p className="pb-24 text-secondary">
The chevron appears before the label.
</p>
</AccordionDetails>
</>
);
}
PropValuesDefault
iconPlacement'start', 'end''end'
iconAlignment'top', 'center''top'

By default, the browser manages toggle state via native <details>. Use defaultOpen to start a section expanded:

<AccordionDetails defaultOpen>
<AccordionSummary>Open by default</AccordionSummary>
<p>Content</p>
</AccordionDetails>

Use open and onToggle for full control. Useful for wizard-style flows or syncing with external state. See the controlled scenario in Examples.

Wrap items in AccordionController to allow only one open at a time. Set exclusive="until-lg" to make it exclusive on mobile/tablet but allow multiple on desktop.

The Stepped Accordion organizes content into collapsible sections displayed vertically with a connecting left border. Only one step can be open at a time, guiding users through sequential information.

The component uses three parts:

  • SteppedAccordion – Container that provides the vertical layout and left border
  • SteppedAccordionDetails – Wraps each step, controls open state via the open prop
  • SteppedAccordionSummary – The clickable header for each step

The stepped accordion is always controlled. Track the current step with state and update it via the onToggle callback. An open step cannot be closed directly. Opening another step closes the current one.

const [currentStep, setCurrentStep] = useState(0);
<SteppedAccordionDetails
open={currentStep === 0}
onToggle={() => setCurrentStep(0)}
>

Add content inside each step after the summary. Use the standard padding classes for consistent spacing.

Key consumer responsibilities from the WCAG audit:

  • Accessible name: provide clear accordion header text. If using icons or non-text indicators, add aria-label or aria-labelledby.
  • No interactive children in summary: <summary> has an implicit button role. Nesting links, buttons, or other interactive elements inside AccordionSummary is invalid.
  • Expand/collapse via keyboard: handled natively (Space / Enter on <summary>). Ensure users can tab in and out without getting trapped.
  • Consistent labeling: use the same naming pattern for accordion headers across your interface.
PropTypeRequiredDefault
hiddenboolean--
idstring--
titlestring--
dirstring--
langstring--
slotstring--
translate"yes" | "no"--
styleCSSProperties--
onClickMouseEventHandler<HTMLDetailsElement>--
onPointerEnterPointerEventHandler<HTMLDetailsElement>--
onPointerMovePointerEventHandler<HTMLDetailsElement>--
onPointerDownPointerEventHandler<HTMLDetailsElement>--
onPointerUpPointerEventHandler<HTMLDetailsElement>--
onPointerLeavePointerEventHandler<HTMLDetailsElement>--
childrenReactNode-
The content of the accordion. The first child should be the `AccordionSummary` component.
classNamestring--
Custom class name, merged with existing classes.
onToggle((open: boolean) => void)--
Called when the accordion is toggled.
onAnimationFinish((open: boolean) => void)--
Called when the toggle animation is finished.
openboolean--
If set, the accordion will be controlled by the value of this prop. Must be used together with the `onToggle` prop.
defaultOpenboolean--
If true, the accordion will be open by default but can then be toggled freely by the user.
PropTypeRequiredDefault
hiddenboolean--
idstring--
titlestring--
dirstring--
langstring--
slotstring--
translate"yes" | "no"--
styleCSSProperties--
onFocusFocusEventHandler<HTMLElement>--
onBlurFocusEventHandler<HTMLElement>--
onClickMouseEventHandler<HTMLElement>--
onKeyDownKeyboardEventHandler<HTMLElement>--
onKeyUpKeyboardEventHandler<HTMLElement>--
onPointerEnterPointerEventHandler<HTMLElement>--
onPointerMovePointerEventHandler<HTMLElement>--
onPointerDownPointerEventHandler<HTMLElement>--
onPointerUpPointerEventHandler<HTMLElement>--
onPointerLeavePointerEventHandler<HTMLElement>--
childrenReactNode-
The label of the summary. Should not contain interactive elements.
iconReactNode--
The icon to display.
iconPlacement"start" | "end"-end
The placement of the icon - before or after the label.
iconAlignment"top" | "center"-top
The vertical alignment of the icon.
classNamestring--
Custom class name, merged with existing classes.
PropTypeRequiredDefault
exclusiveboolean | "until-lg"-true
PropTypeRequiredDefault
classNamestring--
onClickMouseEventHandler<HTMLDivElement>--
onMouseOverMouseEventHandler<HTMLDivElement>--
onMouseOutMouseEventHandler<HTMLDivElement>--
styleCSSProperties--
PropTypeRequiredDefault
openboolean-
Whether the details are open.
hiddenboolean--
idstring--
titlestring--
dirstring--
langstring--
slotstring--
translate"yes" | "no"--
styleCSSProperties--
onClickMouseEventHandler<HTMLDetailsElement>--
onPointerEnterPointerEventHandler<HTMLDetailsElement>--
onPointerMovePointerEventHandler<HTMLDetailsElement>--
onPointerDownPointerEventHandler<HTMLDetailsElement>--
onPointerUpPointerEventHandler<HTMLDetailsElement>--
onPointerLeavePointerEventHandler<HTMLDetailsElement>--
childrenReactNode-
The content of the accordion. The first child should be the `AccordionSummary` component.
classNamestring--
Custom class name, merged with existing classes.
onToggle((open: boolean) => void)--
Called when the accordion is toggled.
onAnimationFinish((open: boolean) => void)--
Called when the toggle animation is finished.
PropTypeRequiredDefault
hiddenboolean--
idstring--
titlestring--
dirstring--
langstring--
slotstring--
translate"yes" | "no"--
styleCSSProperties--
onFocusFocusEventHandler<HTMLElement>--
onBlurFocusEventHandler<HTMLElement>--
onClickMouseEventHandler<HTMLElement>--
onKeyDownKeyboardEventHandler<HTMLElement>--
onKeyUpKeyboardEventHandler<HTMLElement>--
onPointerEnterPointerEventHandler<HTMLElement>--
onPointerMovePointerEventHandler<HTMLElement>--
onPointerDownPointerEventHandler<HTMLElement>--
onPointerUpPointerEventHandler<HTMLElement>--
onPointerLeavePointerEventHandler<HTMLElement>--
childrenReactNode-
The label of the summary. Should not contain interactive elements.
iconReactNode--
The icon to display.
iconPlacement"start" | "end"--
The placement of the icon - before or after the label.
iconAlignment"top" | "center"--
The vertical alignment of the icon.
classNamestring--
Custom class name, merged with existing classes.