Skip to Content

Accordion

A vertically stacked list of headers that reveal or hide associated sections of content.

Usage

OUI exports 4 accordion-related components:

  • Accordion: The main wrapper component (uses React Aria's DisclosureGroup).
  • AccordionItem: The component that wraps each disclosure item.
  • AccordionHeader: The header button that toggles the accordion item.
  • AccordionContent: The collapsible content panel.
import {
  Accordion,
  AccordionContent,
  AccordionHeader,
  AccordionItem,
} from "@opengovsg/oui"
<Accordion>
  <AccordionItem>
    <AccordionHeader>Accordion header</AccordionHeader>
    <AccordionContent>Accordion content</AccordionContent>
  </AccordionItem>
</Accordion>

Features

The Accordion component provides an accessible way to organize and display collapsible content sections.

  • Accessible – Follows the ARIA disclosure pattern with proper keyboard navigation and screen reader support.
  • Flexible – Support for single or multiple expanded items, disabled states, and custom styling.
  • Keyboard Navigation – Full keyboard support with Enter/Space to toggle items and Tab to navigate between them.
  • Animated – Smooth expand/collapse animations with configurable transitions.
  • Customizable – Support for custom icons, start/end content, and size variants.

Examples

Sizes

Use the size prop on Accordion to change the size of the accordion.

Small

Medium (Default)

Multiple Expanded Items

By default, only one accordion item can be expanded at a time. Use the allowsMultipleExpanded prop on the Accordion component to allow multiple items to be expanded simultaneously.

Default Expanded

Use the defaultExpanded prop on AccordionItem to set an item as expanded by default.

You can set an accordion item to be expanded by default using the defaultExpanded prop.

Controlled

Control the expanded state of the accordion using the expandedKeys and onExpandedChange props on the Accordion component.

Start Content

Use the startContent prop on AccordionHeader to add content before the title, such as icons.

Custom Indicator

Use the indicator prop on AccordionHeader to customize the expansion indicator icon.

Hide Indicator

Use the hideIndicator prop on AccordionHeader to hide the indicator icon.

Disabled

Use the isDisabled prop on AccordionItem to disable interaction with specific items.

API Reference

Accordion

The Accordion component wraps React Aria's DisclosureGroup component and provides styling variants. It accepts all props from DisclosureGroup plus the following:

PropTypeDefaultDescription
size"sm" | "md""md"The size of all accordion items.
color"main""main"The color scheme of all accordion items.
allowsMultipleExpandedbooleanfalseWhether multiple items can be expanded at the same time.
expandedKeysSet<string>-The expanded items (controlled).
defaultExpandedKeysSet<string>-The default expanded items (uncontrolled).
onExpandedChange(keys: Set<string>) => void-Handler called when the expanded items change.
childrenReactNode-The accordion items.
classNamesSlotsToClasses<AccordionSlots>-Custom classes for the accordion slots.

AccordionItem

The AccordionItem component wraps React Aria's Disclosure component. It accepts all props from Disclosure including:

PropTypeDefaultDescription
isDisabledbooleanfalseWhether the accordion item is disabled.
defaultExpandedbooleanfalseWhether the accordion item is expanded by default (uncontrolled).
isExpandedboolean-Whether the accordion item is expanded (controlled).
onExpandedChange(isExpanded: boolean) => void-Handler called when the expanded state changes.
childrenReactNode-The accordion header and content.
classNamesSlotsToClasses<AccordionSlots>-Custom classes for the accordion item slots.

AccordionHeader

PropTypeDefaultDescription
childrenReactNode | (props: AccordionHeaderRenderProps) => ReactNode-The header title content. Supports render props.
startContentReactNode | (props: AccordionHeaderRenderProps) => ReactNode-Content displayed before the title. Supports render props.
endContentReactNode | (props: AccordionHeaderRenderProps) => ReactNode-Content displayed after the title. Supports render props.
indicatorReactNode | (props: AccordionHeaderRenderProps) => ReactNode<ChevronDown />The expansion indicator icon. Supports render props.
hideIndicatorbooleanfalseWhether to hide the indicator icon.
classNamesSlotsToClasses<...>-Custom classes for the header slots.

AccordionHeaderRenderProps

When using render props for children, startContent, endContent, or indicator, the following props are available:

PropTypeDescription
isExpandedbooleanWhether the accordion item is currently expanded.
isHoveredbooleanWhether the header button is hovered.
isPressedbooleanWhether the header button is pressed.
isFocusedbooleanWhether the header button is focused.
isFocusVisiblebooleanWhether the header button has keyboard focus visible.
isDisabledbooleanWhether the accordion item is disabled.

AccordionContent

PropTypeDefaultDescription
childrenReactNode-The content to display inside the accordion panel.
classNamesSlotsToClasses<"panel" | "content">-Custom classes for the content slots.

Accessibility

The Accordion component follows the ARIA disclosure pattern:

  • The header button has aria-expanded set to indicate the expanded state.
  • The content panel is properly associated with its header using aria-controls.
  • Keyboard navigation is fully supported:
    • Enter or Space: Toggle the accordion item.
    • Tab: Move focus between accordion items and other focusable elements.
  • Screen readers announce the expanded state and relationship between headers and panels.