One section that expands and collapses, wrapping the Base UI Collapsible. The height animates from a measured CSS variable, so the motion works without JavaScript. A stack of these with one value is an Accordion.

Playground

Click the trigger to watch the panel's height animate open and closed; Disabled greys the trigger and blocks toggling. The Code tab shows the markup for exactly what you've configured.

States

Closed, open, and disabled. Hover changes nothing on purpose and keyboard focus adds a ring around the trigger; Space and Enter toggle it.

Two endpoints listening; last delivery 4 minutes ago.

Styling states

The trigger carries data-panel-open while expanded (the built-in chevron rotates on it), and the panel exposes its measured height as --collapsible-panel-height during the transition:

.ub-collapsible-trigger[data-panel-open] {
  color: var(--ub-accent);
}

Props

Open state lives on the root; the panel decides how closed content behaves. The essentials:

PropTypeDefaultDescription
defaultOpenbooleanfalseStarts expanded when uncontrolled.
openbooleanControlled state. Pair with onOpenChange.
disabledbooleanfalseBlocks toggling and dims the trigger.
CollapsiblePanel.hiddenUntilFoundbooleanfalseKeeps closed content findable with the browser's in-page search.
CollapsiblePanel.keepMountedbooleanfalseKeeps the panel in the DOM while closed.

Agent instructions

Working with a coding agent? Paste this into its context, or point it at llms.txt for the whole library.

CollapsibleRoot, CollapsibleTrigger, CollapsiblePanel, from @usebones/react.
- Structure: CollapsibleRoot wraps CollapsibleTrigger (children become the label; chevron renders automatically) + CollapsiblePanel (the content).
- defaultOpen or open + onOpenChange on the root; disabled blocks toggling.
- hiddenUntilFound on the panel keeps closed content findable via in-page search; keepMounted keeps it in the DOM.
- Put padding on a wrapper inside CollapsiblePanel, never on the panel itself: its height is measured, and padding on the animated element makes the measurement jump.
- Restyle in CSS via .ub-collapsible-trigger, .ub-collapsible-panel, [data-panel-open] on the trigger, [data-starting-style]/[data-ending-style] on the panel. Height animates via --collapsible-panel-height; keep the transition on height. Tokens only.