Collapsible
An interactive component which expands/collapses a panel.
Installation
npx shadcn@latest add @redpanda/collapsiblepnpm dlx shadcn@latest add @redpanda/collapsibleyarn dlx shadcn@latest add @redpanda/collapsiblebunx shadcn@latest add @redpanda/collapsiblenubx shadcn@latest add @redpanda/collapsibleaube dlx shadcn@latest add @redpanda/collapsibleControlled
Multiple independent collapsibles
Disabled
Default open
Chevron on leading edge
Reveal sensitive content
Usage
<Collapsible> <CollapsibleTrigger>Collapsible Trigger</CollapsibleTrigger> <CollapsibleContent>Collapsible Content</CollapsibleContent></Collapsible>When to use
Use this decision tree to determine when to use the Collapsible component:
Props
Keyboard interactions
| Key | Action |
|---|---|
Enter / Space on CollapsibleTrigger |
Toggles the panel open / closed. |
Tab |
Moves focus to the next focusable element (including into the panel when open). |
Accessibility
- The trigger exposes
aria-expanded+aria-controlspointing at the panel; Base UI sets the nativedata-open(root/trigger) /data-panel-open(panel) attributes you can target with CSS selectors. - The trigger must be a real button (or another focusable element via the
renderprop); static<div>triggers lose keyboard activation. - Use
keepMountedonCollapsibleContentwhen the hidden content must remain in the DOM for SEO, intersection observers, or mid-animation measurements.
Controlled vs uncontrolled
Uncontrolled — trigger toggles the panel locally:
<Collapsible> <CollapsibleTrigger>Toggle</CollapsibleTrigger> <CollapsibleContent>{/* ... */}</CollapsibleContent></Collapsible>Controlled — drive open from parent state (e.g. expand all / collapse all from a toolbar):
const [open, setOpen] = useState(false);
<Collapsible open={open} onOpenChange={setOpen}> <CollapsibleTrigger>Toggle</CollapsibleTrigger> <CollapsibleContent>{/* ... */}</CollapsibleContent></Collapsible>;Don’t delete from the DOM
The choice made (also Base UI’s default) is to remove the element from the DOM for accessibility and performance reasons. However, this may pose a problem for SEO. If you want your Collapsible content to be taken into account by Google, pass keepMounted to CollapsibleContent — the closed panel stays in the DOM (hidden via the hidden attribute):
<Collapsible> <CollapsibleTrigger>Toggle</CollapsibleTrigger> <CollapsibleContent keepMounted>{/* stays in the DOM while closed */}</CollapsibleContent></Collapsible>To additionally let the browser’s find-in-page (Ctrl/Cmd + F) reveal the closed content, use hiddenUntilFound instead (implies keepMounted and hides the panel with hidden="until-found"):
<CollapsibleContent hiddenUntilFound>{/* discoverable by find-in-page */}</CollapsibleContent>