Headless / Disclosure

Collapsible

Collapsible is the disclosure atom — one trigger, one region of content, open or closed. Accordion is several of these linked together.

Loading playground…
Updated 3 days agoEdit on GitHubWeb & native

What it is

A compound component with three parts. Collapsible.Root holds the open state — controlled or uncontrolled. Collapsible.Trigger clones its child to toggle it, with aria-expanded and aria-controls. Collapsible.Content is a role="region" that mounts only when open, unless forceMount keeps it mounted for animation.

Install

example.tsx
yarn add @usemotif/headless
example.tsx
import { Collapsible } from '@usemotif/headless';

Anatomy

example.tsx
<Collapsible.Root>
<Collapsible.Trigger>
  <button>Show details</button>
</Collapsible.Trigger>
<Collapsible.Content>
  <DetailPanel />
</Collapsible.Content>
</Collapsible.Root>

API

Collapsible.Root

Collapsible.Root

stable
function Collapsible.Root(props: CollapsibleRootProps): JSX.Element
openboolean

Controlled open state. Pass alongside `onOpenChange`.

defaultOpenboolean= false

Initial open state for the uncontrolled mode.

onOpenChange(open: boolean) => void

Called whenever the open state changes.

childrenReactNode

The Trigger and Content parts.

Collapsible.Trigger

Clones its single element child to add the toggle handler, aria-expanded, aria-controls, and a generated id.

Collapsible.Content

Collapsible.Content

stable
function Collapsible.Content(props: { children?: ReactNode; forceMount?: boolean; style?: CSSProperties }): JSX.Element | null
forceMountboolean= false

Keep the content mounted when closed — hidden via the `hidden` attribute. Use it when an exit animation needs the node to stay in the tree.

childrenReactNode

The collapsible content.

styleCSSProperties

Inline style for the content region.

Accessibility

The trigger carries aria-expanded so a screen reader announces whether the region is open, and aria-controls pointing at the content. The content is a role="region" labelled by the trigger. By default the region is unmounted when closed; with forceMount it stays mounted but takes the hidden attribute, which keeps it out of the accessibility tree and the Tab order while closed.

Examples

A "show more" toggle:

example.tsx
<Collapsible.Root>
<Collapsible.Trigger>
  <Button variant="ghost">Show more</Button>
</Collapsible.Trigger>
<Collapsible.Content>
  <Text>The extra detail, revealed on demand.</Text>
</Collapsible.Content>
</Collapsible.Root>