Collapsible
One section that opens and closes.
Installation
npx shadcn@latest add https://qure-ui.qure.ai/r/collapsible.jsonUsage
import {
Collapsible, CollapsibleContent, CollapsibleTrigger,
} from '@/components/ui/collapsible'<Collapsible>
<CollapsibleTrigger>Prior studies (3)</CollapsibleTrigger>
<CollapsibleContent>CT Thorax — 14 March 2025</CollapsibleContent>
</Collapsible>Reach for Accordion when there are several sections and their open states are related — one
at a time, or a set that shares a keyboard ring. Reach for Collapsible when there is one
section, or several that happen to sit near each other and know nothing about one another. It
has no value, no roving focus and no header element to argue with.
Basic
Closed by default. Pass defaultOpen for the other way round.
Controlled
open with onOpenChange when something outside the disclosure has to open it — a "show all"
control, a deep link into a finding, a keyboard shortcut.
Report sections
Three independent disclosures rather than an accordion: a radiologist reading Technique does not
want Impression to shut. The middle one uses hiddenUntilFound, so the browser's own find can
reach text inside a closed section and open it — worth having wherever the hidden content is
prose someone might Ctrl+F for.
In a sidebar
showChevron={false} drops the trailing chevron so a leading one can take its place. Give your
own icon the cn-collapsible-icon class and it turns with the panel — the rotation lives in the
stylesheet, keyed off data-panel-open:
<CollapsibleTrigger showChevron={false}>
<ChevronDownIcon className="cn-collapsible-icon size-4" />
Worklist
</CollapsibleTrigger>data-panel-open lives on the trigger. The panel's own data-open is on a different
element, and styling against it from the trigger fails silently — the section opens and the
chevron does not move. It cost an hour here.
How it animates
Base UI measures the panel and publishes its height as --collapsible-panel-height, so content
animates from nothing to its natural size with no hardcoded number:
.cn-collapsible-content {
height: var(--collapsible-panel-height);
transition: height 200ms var(--ease-qure);
}
.cn-collapsible-content[data-starting-style] { height: 0; }The padding lives on an inner div rather than on the panel, because a panel with padding cannot
animate to zero height. Disabled under prefers-reduced-motion.
API Reference
Everything Base UI's Collapsible accepts, plus one prop of ours on the trigger.
Prop
Type