Skip to content
EspañolEnglish
All components (204)

Collapsible

Structure · Collapsible · .amset-collapsible

What it is and when to use it

A block that collapses, standalone: "Show more", "Shipping details", an advanced filter that stays out of the way until needed.

When to use it

  • When it is ONE section and it goes inside something that is already drawn. It has no box or lines on purpose.
  • arrowEnd for a row of settings, where the title rules on the left.
  • defaultExpanded to start open; expanded with onExpandedChange to drive the state from outside.

When not to

  • If there are two or more and they go together, it is an Accordion: it brings the box, the lines and the option of having only one open.
  • To hide something that appears on top of the content, Dropdown.

Why it is not a <details>: the native <summary> does not support a title with structure inside without breaking the accessible name, and a click on it changes open by itself, without going through the React state. Here the trigger is a real <button>.

Keyboard: Tab reaches the trigger; Enter and Space open and close it. With disabled it does not take focus.

Accessibility: the trigger carries aria-expanded and aria-controls, and the panel is named after it. When closed, the panel carries hidden="until-found": the browser's search (Ctrl+F) finds its text and opens it. When it closes with focus INSIDE the panel, focus returns to the trigger. Without that the browser would leave it on the body and anyone navigating by keyboard would have to start tabbing from the top of the page. With a finger, the trigger reaches 44 px.

Fine-tuning: --amset-collapsible-font, --amset-collapsible-gap (the gap between the title and the text, which only exists when open: when closed, the collapsible is as tall as its title), --amset-collapsible-color, --amset-collapsible-arrow and --amset-collapsible-inset.

What it looks like

<Collapsible title="Shipment details">
  <Text>Left Madrid on October 1.</Text>
</Collapsible>

Props

Import it with import { Collapsible } from '@amset/ui'. Required props are marked.

PropTypeWhat it does
childrenrequiredReactNode—
titlerequiredReactNodeWhat is read on the trigger. It is the name of the panel.
arrowEndbooleanThe right-hand arrow, for a row of settings.
classNamestringMerged with the library classes; it does not replace them.
defaultExpandedbooleanOpen at the start. For what is used almost always.
disabledboolean—
expandedbooleanControlled from outside. With this, `onExpandedChange` must be passed.
onExpandedChange(expanded: boolean) => void—
size"sm" | "md" | "lg"—

It also accepts the attributes of the element it renders: className, style, data-*, aria-* and its events.

CSS variables

These CSS variables are how you adapt it. Declare them on the component's selector, not on :root: the stylesheet redeclares them in the rule itself, and a declaration on the same element always wins.

VariableDefault
--amset-collapsible-fontvar(--amset-text-base)
--amset-collapsible-gapvar(--amset-space-2)
--amset-collapsible-colorvar(--amset-ink)
--amset-collapsible-arrowvar(--amset-ink-2)
--amset-collapsible-insetvar(--amset-space-5)

How to change it

.amset-collapsible {
  --amset-collapsible-font: ...;
  --amset-collapsible-gap: ...;
}

In the test bench

Every state and variant, to try one at a time, on its page at ui.amset.tech: