Collapsible
One region that opens under its trigger: show more, advanced settings, the log behind an error. No chrome of its own, a height tween on the system's motion tokens, and a mark that turns rather than swaps.
Installation#
Usage#
import {
Collapsible,
CollapsibleTrigger,
CollapsibleIcon,
CollapsibleContent,
} from "@/components/ui/collapsible"
export function Example() {
return (
<Collapsible>
<CollapsibleTrigger>
Advanced settings
<CollapsibleIcon />
</CollapsibleTrigger>
<CollapsibleContent>…</CollapsibleContent>
</Collapsible>
)
}The trigger#
On its own, CollapsibleTrigger is a quiet text control with the mark beside it, and its target grows to 40px without growing the text. With asChild it hands its behavior to your own control and keeps none of its look, which is how the Button above works: the Button stays a Button, and its label rolls while the caret turns.
Markers#
CollapsibleIcon turns with the trigger it sits in, on the same caret-turn beat as the height, so the mark and the region move as one gesture. marker picks the glyph and its turn: caret (the default) flips 180° for a panel below, branch turns 90° into a nested list, and plus turns 45° into a cross, the same mark Accordion and FAQ rows use.
Advanced settings#
The fields most people never touch, folded under the ones everyone fills in. Layout goes on CollapsibleContent's className: it styles the body, never the wrapper whose height is tweening, so the motion stays smooth.
Detail on demand#
Collapsible paints nothing, so it drops inside other components without a second frame. Here an Alert says what happened, and the log that says why stays folded until someone asks for it.
Motion#
The region's height tweens on the collapsible keyframes, retimed to duration-base and ease-out, and its body fades in with a 4px drop on the same clock, then out with a plain fade, softer than the way in. Content that renders open is never animated on page load: Radix skips the height, and the root holds the fade back until the state has changed once.
API reference#
Collapsible
A plain <div> with no chrome. Props: open, defaultOpen, onOpenChange, disabled, asChild, className.
CollapsibleTrigger
A <button> carrying aria-expanded, aria-controls and data-state. Styled as a text control unless asChild is set, in which case your element keeps its own look.
CollapsibleIcon
The disclosure mark, decorative. Props: marker (caret · branch · plus), className, and any SVG attribute. It turns on the state of the trigger it sits in.
CollapsibleContent
The region, unmounted while closed. Takes every <div> prop; className styles the body inside the animated wrapper.