Accordion
A vertically stacked set of headers that each reveal a section of content. Use it to compress secondary detail into a scannable list — not to hide anything a person needs to complete a task.
Opening an item detaches it from the stack: it becomes its own card with air around it and a lift above the rest, so the section you are reading is visibly separate from the ones you are not. Closed items keep a shared border and collapse back together on close.
Live preview
Installation
pnpm dlx shadcn@latest add @sc1m/accordionThis also merges the token layer and installs
src/lib/cn.ts plus @base-ui/react. For the manual route — prerequisites,
components.json, and app-level setup — see Installation.
Usage
import {
Accordion,
AccordionItem,
AccordionTrigger,
AccordionPanel,
} from "@/components/ui/accordion";<Accordion>
<AccordionItem value="access">
<AccordionTrigger>Is it accessible?</AccordionTrigger>
<AccordionPanel>
Yes. Base UI ships the WAI-ARIA disclosure pattern.
</AccordionPanel>
</AccordionItem>
</Accordion>Composition
Every part is a separate export. Accordion owns state; the rest are
presentational and must appear in this order.
Accordion├── AccordionItem│ ├── AccordionTrigger│ └── AccordionPanel└── AccordionItem ├── AccordionTrigger └── AccordionPanelMultiple
Set multiple to let several items stay open at once. Open state is an array
either way — defaultValue takes one even in single mode.
Note that detached expansion was designed around a single open item: two cards detaching at once loses the sense that they belong to one group. Prefer the default single-open behaviour unless the sections are genuinely independent.
<Accordion multiple defaultValue={["notifications"]}>
<AccordionItem value="notifications">
<AccordionTrigger>Notification settings</AccordionTrigger>
<AccordionPanel>Choose how updates reach you.</AccordionPanel>
</AccordionItem>
<AccordionItem value="privacy">…</AccordionItem>
<AccordionItem value="billing">…</AccordionItem>
</Accordion>Disabled
Put disabled on an AccordionItem to lock a single row. It stays visible and
stops responding; put disabled on the root to lock all of them.
<Accordion>
<AccordionItem value="history">…</AccordionItem>
{/* locked row — visible, not operable */}
<AccordionItem value="premium" disabled>…</AccordionItem>
<AccordionItem value="email">…</AccordionItem>
</Accordion>API reference
Each part forwards every prop of its Base UI counterpart. The table lists the ones you reach for; see Base UI's accordion reference for the rest.
Accordion
onValueChange.keepMounted.AccordionItem
Accessibility
Base UI implements the ARIA disclosure pattern. Each trigger is a real button
inside a heading, labelled by its own text and pointing at its panel with
aria-controls.
Arrow keys do not move between triggers. Base UI dropped roving focus
following the APG guidance
update — every trigger is in
the normal tab order instead, so Tab is the only traversal key.
The focus ring is a 2px outline drawn inside the trigger, and the chevron is
aria-hidden.
Design tokens
The component reads semantic tokens only — no raw colour, radius, or duration appears in its source. Override the token, not the component.
Source
src/components/ui/accordion/accordion.tsx — no next/* imports, so it drops into any
React 19 + Tailwind v4 app.