Collapsible
Shows and hides a block of content from a trigger, like a record's details.
Acme Corporation
Installation
The CLI installs the Radix or Base UI file to match your project.
If your project doesn't have Wisty UI's theme yet, add it once with npx shadcn@latest add @wisty/cosmos. Until then, components keep shadcn's default look. Installation has the details.
When to use
Use it
- A block of content is useful but not always needed, like an account's address and owner under its summary, as the Account details example shows.
- People show and hide each section on its own, and opening one leaves the others as they are.
- A section of a form people fold away, like advanced options.
- You want an expandable section: a gray title bar with a chevron above content that folds away.
Usage
Collapsible
├── CollapsibleTrigger
└── CollapsibleContentCollapsible has no styles of its own. Style the trigger as a button with buttonVariants(), as the Account details example does, or build an expandable section: the trigger goes in a heading, and the chevron turns on the trigger's aria-[expanded=false].
import { ChevronDownIcon } from "lucide-react"
import {
Collapsible,
CollapsibleContent,
CollapsibleTrigger,
} from "@/components/ui/collapsible"<Collapsible defaultOpen>
<h2 className="my-2 text-(length:--section-title-size) leading-[1.875rem]">
<CollapsibleTrigger className="flex w-full items-center gap-2 rounded-(--radius-2) border border-transparent bg-muted px-2 text-start font-(--section-title-weight) text-foreground outline-none focus-visible:shadow-(--shadow-focus) aria-[expanded=false]:[&>svg]:-rotate-90 [&>svg]:size-3.5 [&>svg]:shrink-0">
<ChevronDownIcon />
System information
</CollapsibleTrigger>
</h2>
<CollapsibleContent className="pt-2 text-muted-foreground">
{/* section body */}
</CollapsibleContent>
</Collapsible>Closed content leaves the page, and with it any form state inside. In Base UI projects, pass keepMounted to CollapsibleContent to keep it there hidden, or hiddenUntilFound so find-in-page can find and open it. In Radix projects, forceMount keeps it there but also keeps it showing, so hide it yourself with data-[state=closed]:hidden.
API reference
| Part | Built on |
|---|---|
Collapsible | Radix Collapsible.Root (opens in a new tab) |
CollapsibleTrigger | Radix Collapsible.Trigger (opens in a new tab) |
CollapsibleContent | Radix Collapsible.Content (opens in a new tab) |
SLDS mapping
Collapsible has no SLDS classes. The section in Usage builds SLDS's expandable section (slds-section): the heading is slds-section__title, the trigger slds-section__title-action, the chevron slds-section__title-action-icon, and the content slds-section__content. The Account details example uses a bare icon button (slds-button_icon-container) and bordered rows (slds-box).
Known gaps:
- The section's chevron is lucide's
ChevronDownIcon. SLDS uses itsutility:switchcaret.
Accessibility
- Put a section's trigger inside a heading, at the level that follows the page's headings, so the section shows up in the outline.
- An icon-only trigger needs an
aria-labelthat says what it shows. Keep the chevron decorative.
Rules
- Keep the chevron inside the trigger, so it turns with the trigger's
aria-expanded.