Skip to Content
Puzzle
UI ComponentsNavigation

Accordion

Show and hide related sections of content.

Accordion groups related sections behind expandable headings. Prefer stable item IDs when sections may be reordered.

Import

import { Accordion, type AccordionValue } from "@puzzle-ui/ui";

Basic usage

Each item has a title and content. When using defaultValue or value, every item must also have a unique id.

390 × 360

The Support item demonstrates disabled: its trigger cannot be activated.

Multiple sections

type="multiple" is the default. Pass an array of IDs to open more than one section. In multiple mode, onValueChange returns an array; in single mode it returns an ID or null when the last section closes.

390 × 380

Keep one section open

In single mode, collapsible={false} prevents the currently open section from being closed by its trigger. Set an initial value if a section should be open from the start.

390 × 360

Controlled selection

Pair value with onValueChange. Stable IDs keep open sections associated with the same items after reordering. Do not mix the ID-based and index-based selection APIs.

390 × 420

Panel lifecycle and semantics

headingLevel matches the surrounding document hierarchy. region explicitly enables or disables panel landmarks. With unMountOnClose, content unmounts after the closing animation; reopening resets local state. Enter a note and close/reopen the section to try it.

390 × 320

API

Accordion

AccordionItemId is string | number. AccordionValue is an ID, a readonly array of IDs, or null.

PropTypeDefaultDescription
itemsAccordionItemData[]RequiredSections to render.
type"single" | "multiple""multiple"Whether more than one section can open.
valueAccordionValue-Controlled open IDs; requires unique IDs on every item.
defaultValueAccordionValue-Initial uncontrolled open IDs.
onValueChange(value: AccordionItemId | AccordionItemId[] | null) => void-Next open ID(s).
collapsiblebooleantrueAllows the open item to collapse in single mode.
initialOpenItemIndexesnumber[][]Initial uncontrolled open indexes (compatibility API).
openItemIndexesnumber[]-Controlled open indexes (compatibility API).
onChange(indexes: number[]) => void-Next open indexes, also called in ID mode.
headingLevel1 | 2 | 3 | 4 | 5 | 63Semantic heading level for triggers.
regionbooleanitems.length <= 6Adds region landmarks to panels.
unMountOnClosebooleanfalseUnmounts content after its closing animation.
classNamestring-Additional class on the root div.
triggerClassNamestring-Additional class on each trigger.
panelClassNamestring-Additional class on each animated panel.
contentClassNamestring-Additional class on each content wrapper.

Other native div attributes are forwarded to the root, except children and onChange.

AccordionItemData

PropTypeDefaultDescription
idstring | number-Stable identifier; required for ID-based selection.
titleReactNodeRequiredTrigger content.
contentReactNodeRequiredExpandable panel content.
disabledbooleanfalsePrevents user toggling.

Accessibility

Triggers are native buttons inside headings, with aria-expanded and aria-controls. Use Tab to move between enabled triggers and Enter or Space to toggle them. Keep headings concise and use the panel for longer content.

;