Skip to content

Accordion

Accordion is a container used for grouping sections of expandable and collapsible content.
Figma logo
Anatomy of an Accordion
Accordion and its sub-components
  • Accordions should always be placed inside an AccordionGroup, even if you only have one
  • Consider the Details component if you only have one Accordion

Multiple Accordions can be open at a time. In this example, the second is open by default.

Only one Accordion can be open at a time

Accordions can live inside of a Card

  • The AccordionSummary will render as an h3 tag
  • Content within a collapsed Accordion will not be discoverable by a find-in-page text search
Navigating an Accordion with a keyboard
KeysAction
return, spaceOpen/close an Accordion
and arrow keysCycle through AccordionSummary elements within an AccordionGroup; screen readers will only read content from AccordionSummary
tabNavigate progressively through the DOM; screen readers will read out content in AccordionSummary and AccordionDescription
home, endNavigate to the first and last Accordion within an AccordionGroup
React props
NameTypeDefaultDescription
children  ReactNodeThe content of the Accordion
open  booleanfalseIf true, the Accordion will be open

Accordions are made up of several sub-components, each with their own special purpose.

Accordion sub-components
SubcomponentPurpose
AccordionGroupContains a collection of Accordions; establishes a grid layout
AccordionSummaryHeading for the Accordion
AccordionDetailsContent of the Accordion

The following testing snippet(s) offer suggestions for testing the component using React Testing Library with occasional help from Jest.

render(
<AccordionGroup>
<Accordion>
<AccordionSummary>Personal information</AccordionSummary>
<AccordionDetails>Personal info content</AccordionDetails>
</Accordion>
<Accordion>
<AccordionSummary>Billing address</AccordionSummary>
<AccordionDetails>Billing address content</AccordionDetails>
</Accordion>
</AccordionGroup>,
);
const personalInfoSummary = screen.getByRole('button', {
name: 'Personal information',
});
const personalInfoDetails = screen.getByLabelText('Personal information');
expect(personalInfoDetails).not.toBeVisible();
userEvent.click(personalInfoSummary);
expect(personalInfoDetails).toBeVisible();