Components
Collapsible
An interactive panel that expands and collapses a region of content, driven by a single trigger element.
Basic usage
Compose Collapsible, a CollapsibleTrigger, and CollapsibleContent. Pass defaultOpen for an uncontrolled panel. Unlike Accordion, the three parts ship completely unstyled — they only attach data-slot hooks, so every border, spacing and animation below is yours to supply.
Custom trigger
Use asChild to make any element the trigger — here a full-width Button. The content is unmounted while collapsed unless you set forceMount.
Animating the panel
Out of the box the panel snaps open. To slide it, add three classes to CollapsibleContent:
overflow-hidden data-[state=open]:animate-collapsible-down data-[state=closed]:animate-collapsible-up
The keyframes come from tw-animate-css, which @comitor/ui/styles.css already imports — there is nothing to add to your Tailwind config. They read the --radix-collapsible-content-height variable Radix measures, which is why overflow-hidden is not optional: without it the content spills out mid-slide. This is the same recipe SidebarGroup and SidebarMenuItem use in @comitor/ui/shell.
Props
Every part forwards the full Radix prop set and exports its own prop type — CollapsibleProps, CollapsibleTriggerProps and CollapsibleContentProps.
Collapsible — the root that owns the open state.
| Prop | Type | Default | Description |
|---|---|---|---|
defaultOpen | boolean | false | Open state when the component is uncontrolled. Use this for self-managed panels. |
open | boolean | — | Controlled open state. Pair with onOpenChange to drive the panel yourself. |
onOpenChange | (open: boolean) => void | — | Called whenever the open state changes, including via keyboard. |
disabled | boolean | false | Natively disables the trigger button and stamps data-disabled on all three parts for styling. |
className | string | — | Additional Tailwind classes. The root ships with no styling of its own, so this is the only layout you get. |
CollapsibleTrigger — the control that toggles the panel.
| Prop | Type | Default | Description |
|---|---|---|---|
asChild | boolean | false | Merges props onto its single child instead of rendering a bare button — use to wire up a Button. |
className | string | — | Additional Tailwind classes. Nothing is applied by default. |
CollapsibleContent — the region that expands and collapses.
| Prop | Type | Default | Description |
|---|---|---|---|
forceMount | true | — | Keeps the content in the DOM while closed so you can drive the exit with your own animation library. Radix types it as the literal true — omit the prop instead of passing false. |
className | string | — | Additional Tailwind classes. Add overflow-hidden plus the animate-collapsible-* pair here to get the slide. |
Accessibility
- The trigger exposes
aria-expandedandaria-controls, wiring it to the content region automatically. - The trigger is a native button, so Enter and Space toggle the panel out of the box.
- When using
asChild, give icon-only triggers anaria-labelso screen readers announce their purpose. - Setting
disabledpropagatesdata-disabledto every part for consistent styling and behavior. - Because the parts are unstyled, the disabled and focus states are yours too — style them off
data-disabledandfocus-visible, or drive the trigger with aButton, which already carries both.