Collapsible
One region that shows and hides — and nothing else. Collapsible is "headless", which is a short way of saying it handles the behaviour and leaves the looks to you: it tracks whether the region is open, wires up the ARIA attributes and keyboard handling so screen readers and keyboard users get a real disclosure, and stops there. No chevron, no border, no padding, no focus ring. Every pixel of the trigger and the content is yours to write, which is exactly what you want when the toggle has to disappear into the surrounding UI. Aurora re-exports reka-ui's Collapsible unchanged.
ts
import { CollapsibleRoot, CollapsibleTrigger, CollapsibleContent } from '@scaler-tech/aurora/collapsible'Import from Aurora rather than from reka-ui directly — the family re-exports these three as-is.
Nordhavn Office
112 kWh/m² · reporting year 2025
Everything visible above — the chevron, its rotation, the type, the spacing, the divider — is hand-written. Collapsible only decided what was showing.
Use when
| Situation | Use | Why |
|---|---|---|
| One region, trigger must look like the surrounding UI (a quiet "More details" line in a form) | Collapsible | no styling to override — you own the chevron, spacing, and type |
| Several stacked sections, or one section that should look like the rest of the app | Accordion | styled headers, dividers, hint labels, single/multiple modes — a one-item Accordion is fine |
API
All props are reka's; Aurora adds none.
| Component | Prop | Type | Default | Description |
|---|---|---|---|---|
CollapsibleRoot | open | boolean | — | Controlled open state; use v-model:open |
CollapsibleRoot | defaultOpen | boolean | false | Initial state when uncontrolled |
CollapsibleRoot | disabled | boolean | false | Blocks toggling and disables the trigger button |
CollapsibleRoot | unmountOnHide | boolean | true | Destroys the content subtree while closed |
CollapsibleContent | forceMount | boolean | false | Keeps content in the DOM regardless of state |
CollapsibleTrigger | asChild | boolean | false | Renders your child element instead of a <button> |
Examples
The disclosure from the demo, in full:
vue
<CollapsibleRoot v-model:open="isOpen" class="border-secondary mt-4 border-t pt-4">
<CollapsibleTrigger as-child>
<button type="button" class="flex w-full items-center gap-2 text-left">
<Icon
name="chevron-down"
:size="16"
class="text-secondary transition-transform duration-200"
:class="isOpen && 'rotate-180'"
/>
<span class="paragraph-sm-medium text-primary">
{{ isOpen ? 'Show less' : 'More details' }}
</span>
</button>
</CollapsibleTrigger>
<CollapsibleContent class="overflow-hidden">
<dl class="mt-3 flex flex-col gap-2">…</dl>
</CollapsibleContent>
</CollapsibleRoot>Gotchas
- Anything the region holds resets when it closes —
unmountOnHidedefaults totrue, so the subtree is destroyed. Keep state in the parent, or passforce-mount.[external] - Your own
<button>insideCollapsibleTriggerneedsas-child, otherwise you nest a button in a button: invalid HTML with unreliable clicks.[external] - Height animations need
--reka-collapsible-content-height(set byCollapsibleContenton itself) plusoverflow-hidden, or the content spills mid-transition.[external] - Nothing here reads as Aurora until you style it. If you're rebuilding an accordion header, stop and use
Accordion.