Accordion
A coordinated set of collapsible sections for progressively revealing content.
Use Accordion for related disclosures such as product details or frequently asked questions. A single item also supports a compact show-more pattern.
Installation
The copied source is available in the registry JSON. The canonical implementation lives in packages/react/src/components/accordion.tsx.
Usage
<Accordion defaultValue={["item-1"]}>
<AccordionItem value="item-1">
<AccordionTrigger>Can multiple sections be open?</AccordionTrigger>
<AccordionPanel>
<p className="pb-3 text-small text-ink-muted">
Yes. Accordion allows multiple open items by default.
</p>
</AccordionPanel>
</AccordionItem>
</Accordion>Each item needs a unique value. Panel content stays mounted while collapsed, which preserves find-in-page behavior.
Composition
Accordion
└── AccordionItem
├── AccordionTrigger
└── AccordionPanelExamples
Visual treatments
Use flush for content integrated into a page, bordered for a divided list, and card when each disclosure is a distinct content object.
Custom indicator
Replace the default caret with any node, or pass null when another visual treatment communicates disclosure state.
API reference
| Prop | Type | Default | Description |
|---|---|---|---|
| variant | "flush" | "bordered" | "card" | "flush" | Selects integrated, divided, or discrete-card presentation. |
| defaultValue | string[] | [] | Sets initially expanded items for uncontrolled state. |
| value / onValueChange | string[] / (value: string[]) => void | - | Controls the expanded item values. |
| openMultiple | boolean | true | Allows multiple panels to remain open. Set false for exclusive expansion. |
Every AccordionItem needs a unique value. AccordionTrigger renders a CaretDown by default; pass another node to caret, or null to hide it.
Accessibility
- Triggers use buttons and expose expanded state through the underlying Base UI primitive.
- Enter or Space toggles the focused item. Arrow keys move between triggers, while Home and End move to the first or last trigger.
- Keep trigger labels concise and make panel content understandable when reached directly through find-in-page.
- Use
openMultiple={false}only when simultaneous comparison is unnecessary.