Accordion
Vertically stacked disclosure sections built on Base UI. Single or multiple open panels, animated height, and full keyboard support.
Playground
<Accordion className="w-96">
<AccordionItem value="shipping">
<AccordionTrigger>How long does shipping take?</AccordionTrigger>
<AccordionContent>…</AccordionContent>
</AccordionItem>
{/* more items */}
</Accordion>Preview
Each AccordionItem pairs an AccordionTrigger with an AccordionContent panel. The trigger swaps its chevron while expanded, and the panel animates its height open and closed.
<Accordion className="w-96" multiple={false}>
<AccordionItem value="shipping">
<AccordionTrigger>How long does shipping take?</AccordionTrigger>
<AccordionContent>
<p>Orders ship within 24 hours and arrive in 3–5 business days.</p>
</AccordionContent>
</AccordionItem>
<AccordionItem value="returns">
<AccordionTrigger>What is the return policy?</AccordionTrigger>
<AccordionContent>
<p>Every purchase can be returned within 30 days.</p>
</AccordionContent>
</AccordionItem>
</Accordion>Installation
npx shadcn@latest add https://espresso-base-ui.vercel.app/r/accordion.jsonUsage
import {
Accordion,
AccordionContent,
AccordionItem,
AccordionTrigger,
} from "@/components/ui/accordion"<Accordion multiple={false}>
<AccordionItem value="item-1">
<AccordionTrigger>Question</AccordionTrigger>
<AccordionContent>Answer</AccordionContent>
</AccordionItem>
</Accordion>Multiple open
Panels open independently by default (multiple is true). Pass defaultValue an array of item values to pre-expand panels; pass multiple={false} for the classic one-at-a-time accordion.
Orders ship within 24 hours and arrive in 3–5 business days. Express delivery arrives the next business day.
Every purchase can be returned within 30 days in its original condition for a full refund.
<Accordion className="w-96" defaultValue={["shipping", "returns"]}>
{/* items */}
</Accordion>Disabled item
Disable a single item with disabled on AccordionItem – it dims, ignores pointer input and is skipped by keyboard navigation. The same prop on the root disables the whole accordion.
<AccordionItem value="locked" disabled>
<AccordionTrigger>Disabled question</AccordionTrigger>
<AccordionContent>Never visible.</AccordionContent>
</AccordionItem>API reference
Accordion forwards all Base UI accordion root props. Item values default to their index, so value is only required for controlled state or non-positional identity.
Accordion
| Prop | Type | Default | Description |
|---|---|---|---|
| multiple | boolean | true | Whether several panels can be open at once. false gives one-at-a-time behavior. |
| defaultValue | any[] | – | Item values expanded on first render (uncontrolled). |
| value | any[] | – | Controlled list of expanded item values. |
| onValueChange | (value: any[]) => void | – | Fires with the next expanded values. |
| disabled | boolean | false | Disables every item in the accordion. |
AccordionItem
| Prop | Type | Default | Description |
|---|---|---|---|
| value | any | – | Identity of the item within the root value array. Defaults to the item's index. |
| disabled | boolean | false | Disables just this item. |
| Component | Description |
|---|---|
| Accordion | Root flex column (data-slot="accordion"), owns the expanded-value state. |
| AccordionItem | One section (data-slot="accordion-item") with a bottom border between items. |
| AccordionTrigger | Header button (data-slot="accordion-trigger") with automatic up/down chevrons; wrapped in the Base UI heading element. |
| AccordionContent | Collapsible panel (data-slot="accordion-content") animating between 0 and --accordion-panel-height. |
Accessibility & styling hooks
Base UI wires the trigger and panel with aria-expanded and aria-controls, renders the trigger inside a heading, and supports Arrow keys, Home and End between triggers. State is exposed as data-open / data-closed on the panel and aria-expanded on the trigger; every part carries a data-slot attribute for styling.