Accordion
A vertical stack of collapsible sections, for content that would otherwise swamp a page.
Installation
npx shadcn@latest add https://qure-ui.qure.ai/r/accordion.jsonUsage
import {
Accordion, AccordionContent, AccordionItem, AccordionTrigger,
} from '@/components/ui/accordion'<Accordion defaultValue={['nodule']}>
<AccordionItem value="nodule">
<AccordionTrigger>Pulmonary nodule</AccordionTrigger>
<AccordionContent>8mm, right upper lobe.</AccordionContent>
</AccordionItem>
</Accordion>Composition
<Accordion> {/* owns the open state */}
<AccordionItem> {/* one section, keyed by value */}
<AccordionTrigger> {/* the header button, plus the chevron */}
<AccordionContent> {/* the panel, height-animated */}
</AccordionItem>
</Accordion>AccordionTrigger renders its own AccordionPrimitive.Header, so you do not wrap it in a
heading yourself. AccordionContent adds an inner div — the padding lives there rather than on
the panel, because a panel with padding cannot animate to zero height.
Basic
One section at a time — the default, and the right one when the sections are alternatives.
Several at once
Pass multiple when the sections are a list rather than a choice. A findings panel usually
wants this: a radiologist comparing two findings should not have to keep reopening one of them.
Disabled
A disabled item stays in the tab order and is announced as disabled, rather than disappearing — "not yet retrieved" is information.
As a stack of cards
variant="card" gives every item its own border, radius and 8px of air. Figma ships this as a
separate frame — "Accordion list / with padding", next to "full width" — but they are the same
accordion stacked two ways, so it is a variant rather than a second component.
Which one to reach for is a question about the content, not the look. Hairlines say one thing, subdivided: sections of a single report, an FAQ. Cards say several independent things: one per study, one per finding, each of which could stand alone on the page.
A closed card sits on base-secondary and an open one lifts to base-default. That surface
change is doing real work — it marks the open section without relying on anyone noticing which
way a 20px chevron is pointing, and it survives being looked at from across a reading room.
In a card
Different thing: the whole accordion inside one Card. Give the card
gap-0 py-0 and put the padding on each item, so the dividers reach the card's edges instead of
stopping short.
How it animates
Base UI measures the panel and publishes its height as --accordion-panel-height, which is what
lets content animate from nothing to its natural size with no hardcoded height:
.cn-accordion-content {
height: var(--accordion-panel-height);
transition: height 200ms var(--ease-qure);
}
.cn-accordion-content[data-starting-style] { height: 0; }Disabled under prefers-reduced-motion.
Keyboard
Arrow keys move between triggers, Home and End jump to the ends, Enter and Space toggle. None of that is written here — it arrives with the primitive.
The chevron is one icon rotated rather than two swapped. Rotation is the state change, so it animates for free and there is no frame where both or neither are visible.
API Reference
Everything Base UI's Accordion accepts. The ones you will reach for:
Prop
Type