Collapsible

Keeps detail one click away under a heading.

Examples

Raw input

A summary while closed

Questions

Only the model tokens a run used before it failed. Tool calls and retries are free.

Form

  • singledefault

  • Only the model tokens a run used before it failed. Tool calls and retries are free.

    group

Sizes

  • Only the model tokens a run used before it failed. Tool calls and retries are free.

    defaultdefault

  • Only the model tokens a run used before it failed. Tool calls and retries are free.

    lg

Styles

  • Only the model tokens a run used before it failed. Tool calls and retries are free.

    frameddefault

  • Only the model tokens a run used before it failed. Tool calls and retries are free.

    plain

States

  • closed

  • search_tickets

    open

  • hover

  • focus

  • disabled

Usage

When to use it
Use
Detail most people skip: raw input, tool call history, advanced settings.
Use
A list of questions or sections people scan by heading and open one at a time (CollapsibleGroup).
Not for
The sections are views of one object people switch between. Use Tabs.
Not for
The detail is needed to act on the page; show it.
Not for
A card whose body folds. Use Card.

Rules

8 rules
Should
Pass summary with the count and the one fact that matters, such as '1 of 6 failed'. Because a closed section otherwise gives no reason to open it, and a failure inside stays hidden.
Must
Disable the trigger of an empty region and say 0 in the summary. Because a trigger that opens to nothing costs a press and reads as content that failed to load.
Should
Pass hiddenUntilFound to CollapsibleContent when people search the page with the browser's find. Because a standalone panel unmounts when closed, so find-in-page never reaches what is inside.
Must
Name what is inside the trigger, such as 'Raw input', never 'Show more'. Because the label is the button's accessible name, and a list of "Show more" buttons says nothing about any of them.
Should
Keep the summary under 32 characters and add nothing that is missing from the open content. Because the summary truncates on the trigger row and disappears on open, so anything only it says is lost.
Never
Add a plus or second chevron to CollapsibleTrigger. Because the trigger already draws one caret at the start that turns when open, so a second glyph gives two cues that can disagree.
Should
Split a group past 10 sections by topic under headings, or add search.
Must
Let wide content own its scrolling with overflow-x-auto. Because the panel is overflow-hidden, so a long line is clipped with no way to scroll to it.

Accessibility

5 checks
The trigger is a button with aria-expanded and aria-controls, named by label and summary.
Enter or Space toggles; Up, Down, Home and End move between group triggers.
A group trigger sits in an h3; the content is a region named by the trigger.
The caret is aria-hidden.
Group triggers are 40px tall; the standalone trigger is 32px.

Edge cases

12 edge cases
Long trigger label
Wraps; the summary stays one line and truncates.
One-word label
Keeps the 40px row in a group, 32px alone, and the caret.
Wide content
Scrolls in its own box; the panel clips nothing else.
Right to left
The caret points left when closed; content indents from the right.
Zoom 200%
The trigger grows with min-h; the summary truncates.
Text spacing
Trigger and content grow with the text.
Empty region
Opens to nothing; disable the trigger.
Content loading
Show a Skeleton inside; the panel grows when data arrives.
Ten clicks in a second
Each cuts open or shut; it ends in the last state.
Collapsible inside a group item
Renders as an item; wrap nested stacks in their own group.
Forced colors
Field sections get a 1px outline; the caret stays visible.
Reduced motion
Nothing changes: the panel and the caret always cut.

API

9 props
Collapsible open, defaultOpen, onOpenChange, disabled
Base UI Collapsible.Root default closed
CollapsibleGroup value, defaultValue, onValueChange
Base UI Accordion.Root
CollapsibleGroup multiple
boolean default false
CollapsibleGroup variant
'framed' | 'plain' default 'framed'
CollapsibleGroup size
'default' | 'lg' default 'default'
CollapsibleTrigger size
'default' | 'sm' | 'row' default 'default'
CollapsibleTrigger summary
ReactNode
CollapsibleTrigger summaryStatus
'warn' | 'fail'
CollapsibleContent keepMounted, hiddenUntilFound
Base UI default group: hiddenUntilFound on

Tokens

14 tokens
--type-label
400 14px/16px var(--font-sans)
--surface-hover
oklch(var(--ink-c) / 0.05)
--text-disabled
oklch(var(--ink-c) / 0.40)
--row
40px
--control
32px
--radius-soft
6px
--radius-frame
10px
--type-label-sm
400 12px/16px var(--font-sans)
--text-3
oklch(var(--ink-c) / 0.66)
--surface-page
var(--paper)
--line-frame
oklch(var(--ink-c) / var(--line-frame-alpha))
--line-row
oklch(var(--ink-c) / 0.08)
--dur-fast
120ms
--ease-step
cubic-bezier(0.2, 0, 0, 1)

Install

For your coding agent

GitHub

Please star me pookie

141

A new design system every week

Leave your email before you copy the prompt.