Noctis

Collapsible

A single in-flow disclosure — a trigger that expands and collapses a panel of content in place, with a height animation that's reduced-motion safe.

Basic

A Collapsible.Trigger toggles a Collapsible.Panel open and closed. The panel animates its height between zero and the measured content height. By default that is all a Collapsible does — show and hide its panel, with a height animation, and nothing else; the heading, group, and twisty affordances below are all opt-in. The trigger is a neutral ghost control (composed from Button), so its hover, focus-visible, and pressed states are the family's — never the accent. A disclosure chevron is rendered after the label and rotates as the panel opens.

FAQ

Wrap each trigger in a Collapsible.Heading (an <h3> by default — set level for another rank) so every entry appears in the document outline and the screen-reader rotor, and stack them in a Collapsible.Group for the bordered, divider-separated card. Because panels keep their content in the DOM and opt into find-in-page by default, Ctrl + F (or + F) finds text inside a collapsed answer and auto-expands it.

Collapsible.Group is presentational only — each disclosure opens and closes independently. Reach for the Accordion when only one section should be open at a time.

File tree

For sidebar and file-tree rows a heading would be wrong, and the down→up accordion chevron reads oddly. The fastest route is the built-in leading "twisty" — indicator="chevron-start" puts the chevron before the label, pointing toward the content's start edge when collapsed (mirrored in RTL) and rotating down on open.

But nothing about the trigger's look is fixed. This tree drops the built-in indicator (indicator={false}) and composes its own: a chevron that rotates and a folder glyph that swaps open/closed, both driven off Base UI's data-panel-open state, with custom monospace styling and an indent guide — all while the trigger still inherits the ghost Button's hover, focus, and press states underneath. Collapsibles nest freely.

button.tsx
collapsible.tsx
index.ts

Custom trigger

The built-in chevron is opt-out: pass indicator={false} to Collapsible.Trigger and compose your own leading or trailing glyph.

Controlled

Drive the open state from outside with open / onOpenChange — an external button, a keyboard shortcut, or a command-menu action can toggle the same disclosure the trigger does.

Keyboard

KeyAction
Enter / SpaceOn the trigger: toggle the panel open or closed.
Ctrl + F / + FThe browser's find-in-page matches text inside a collapsed panel and auto-expands it (hiddenUntilFound).
Tab / Shift + TabMove through the page and into the open panel — focus is not trapped, since the disclosure is non-modal.

Accessibility

  • Heading semantics. Wrap the trigger in Collapsible.Heading for content disclosures (FAQs, "show more" sections) so the section surfaces in the document outline and the screen-reader rotor — the recommended shape. Omit it for sidebar / file-tree rows, where a heading would be wrong.
  • Labelled region. The panel renders as a <section> with role="group" and is named by its trigger via aria-labelledby, so a screen-reader user inside an open panel hears its name and boundary. Set panelRole="region" to promote a significant disclosure to a landmark (use it sparingly so the landmark list stays useful).
  • Find-in-page. hiddenUntilFound defaults to true: closed content stays in the DOM and the browser's find reveals it. Set hiddenUntilFound={false} to opt out, or keepMounted={false} to remove closed content entirely.
  • Indicator. The chevron is decorative (aria-hidden) and directional, so it mirrors under RTL; both the trailing (down→up) and leading twisty (right→down) rotations read correctly in either writing direction.
  • Motion. The height animation and content fade are dropped under prefers-reduced-motion; Base UI still mounts and unmounts correctly.

Anatomy

Compose a collapsible from its parts. Collapsible.Root owns the open state (controlled via open / onOpenChange, or uncontrolled via defaultOpen) on Base UI's Collapsible.

  • Collapsible.Root — owns the open state and groups the parts.
  • Collapsible.Trigger — toggles the panel; composed from the ghost Button. Renders a built-in disclosure chevron after its label by default (indicator: true / "chevron-end" trails it, "chevron-start" leads it as a twisty, false omits it).
  • Collapsible.Panel — the labelled content region that animates open and closed. role="group" by default (panelRole="region" to promote it); kept mounted and findable by default (hiddenUntilFound, keepMounted).
  • Collapsible.Heading (optional) — wraps the trigger in an <h3> (set level) for the document outline.
  • Collapsible.Group (optional) — a presentational container that stacks several collapsibles into one bordered, divider-separated card; it does not coordinate open state.

Every rendered part carries a data-slot (noctis-collapsible, noctis-collapsible-trigger, noctis-collapsible-panel, noctis-collapsible-heading, noctis-collapsible-group) for host-side styling — pair it with the Base UI Collapsible state attributes (data-open / data-closed on the panel, data-panel-open on the trigger, data-starting-style / data-ending-style on the panel during the animation, and data-disabled).

Design tokens

Generated from the component's declaration — the same graph that mints the CSS, so a variable name or its resolution default can't drift. The minted tokens are the public override seam: set one on any ancestor and every collapsible in that region retunes — e.g. .faq { --noctis-collapsible-panel-padding-block: 1rem; } loosens the disclosed content beneath it, and --noctis-collapsible-panel-transition-duration tunes the open/close speed. Knobs that aren't minted are reached through the part's data-slot. See Customization for the full override ladder and Tokens for the whole graph.

Token

API reference

Generated from the component's types — every prop, type, default, and description comes straight from the source. Each part gets its own table; parts that forward to Base UI's Collapsible list just the props they pass through. Expand a row for the full type and description.

Collapsible.Root

Prop

Collapsible.Trigger

Prop

Collapsible.Panel

Prop

Collapsible.Heading

Prop

Collapsible.Group

Prop

AttributeDescription
data-slotThe catalog slot that anchors every `collapsible.css` rule and marks the part for SLOTS.md/testing.
data-openPresent on the panel while the disclosure is open.
data-closedPresent on the panel while the disclosure is closed.
data-panel-openPresent on the trigger while its panel is open — the hook the disclosure chevron rotates off.
data-starting-stylePresent on the panel for the first animation frame as it opens — the from-zero-height keyframe edge.
data-ending-stylePresent on the panel for the final animation frame as it closes — the to-zero-height keyframe edge.
data-disabledPresent on the trigger and panel when the collapsible is disabled.