Collapse Component

A collapse/expand component with a unique animation behavior. When collapsing, the content animates from the top down (rather than the typical bottom-up collapse), keeping the user's viewport position stable.

Animation Behavior

Expand: Standard bottom-down reveal (content pushes down as it appears)

Collapse: Top-down collapse (content disappears from top, viewport stays stable)

Usage

Basic Collapse

<Collapse title="Click to expand">
  <Text.body>
    This is the collapsible content.
  </Text.body>
</Collapse>

Default Open

Use defaultOpen to have the collapse expanded initially.

This content is visible when the component first renders.

<Collapse title="Expanded by default" defaultOpen>
  <Text.body>This content is visible initially.</Text.body>
</Collapse>

Controlled State

Control the open state externally using the open and onOpenChange props.

Current state: closed

const [open, setOpen] = createSignal(false);

<Collapse
  title="Controlled collapse"
  open={open()}
  onOpenChange={setOpen}
>
  <Text.body>Controlled content.</Text.body>
</Collapse>

Disabled State

<Collapse title="Cannot be toggled" disabled>
  <Text.body>This content cannot be revealed.</Text.body>
</Collapse>

CollapseGroup (Accordion)

Basic Accordion

By default, CollapseGroup works as an accordion - only one item can be open at a time.

<CollapseGroup>
  <Collapse title="Section 1">
    <Text.body>Content for section 1.</Text.body>
  </Collapse>
  <Collapse title="Section 2">
    <Text.body>Content for section 2.</Text.body>
  </Collapse>
  <Collapse title="Section 3">
    <Text.body>Content for section 3.</Text.body>
  </Collapse>
</CollapseGroup>

Multiple Open Items

Set multiple={true} to allow multiple items to be open at once.

This can stay open while others open.

<CollapseGroup multiple>
  <Collapse title="First item" defaultOpen>
    <Text.body>This can stay open while others open.</Text.body>
  </Collapse>
  <Collapse title="Second item">
    <Text.body>Try opening this while the first is open.</Text.body>
  </Collapse>
  <Collapse title="Third item">
    <Text.body>All three can be open simultaneously.</Text.body>
  </Collapse>
</CollapseGroup>

Require One Open

Use requireOne to prevent all items from being closed in accordion mode.

Try closing this - another item will need to open first.

<CollapseGroup requireOne>
  <Collapse title="Always one open" defaultOpen>
    <Text.body>You cannot close the last open item.</Text.body>
  </Collapse>
  <Collapse title="Second option">
    <Text.body>At least one must remain open.</Text.body>
  </Collapse>
</CollapseGroup>

With Default Open Items

Individual Collapse items' defaultOpen props are respected for initial state.

This starts open because of defaultOpen.

<CollapseGroup>
  <Collapse title="Closed initially">...</Collapse>
  <Collapse title="Open initially" defaultOpen>...</Collapse>
  <Collapse title="Also closed">...</Collapse>
</CollapseGroup>

Collapse Props

NameTypeDefaultDescription
titlestringrequired

Text displayed in the trigger header

childrenJSX.Elementrequired

Content to be collapsed/expanded

defaultOpenbooleanfalse

Initial open state for uncontrolled mode

openbooleanundefined

Controlled open state

onOpenChange(open: boolean) => voidundefined

Callback when open state changes

disabledbooleanfalse

Prevents toggling and forces closed state

stylesStyleXStylesundefined

Additional StyleX styles to apply

CollapseGroup Props

NameTypeDefaultDescription
childrenJSX.Elementrequired

Collapse components to group together

multiplebooleanfalse

Allow multiple items open at once (false = accordion mode)

requireOnebooleanfalse

When multiple={false}, require at least one item to stay open

stylesStyleXStylesundefined

Additional StyleX styles for the group wrapper

Keyboard Navigation

The Collapse component includes full keyboard support:

Enter / Space - Toggle the focused item

ArrowUp / ArrowDown - Navigate between items in a CollapseGroup (with wrap-around)

Accessibility

The Collapse component follows WAI-ARIA patterns for disclosure widgets:

Trigger button with aria-expanded reflecting current state

Content region with aria-hidden when collapsed

aria-controls linking trigger to content

Focus-visible outline for keyboard navigation

Respects prefers-reduced-motion for animations

Icon Requirements

The Collapse component uses chevron icons from the IconProvider. Make sure your icon index includes:

const icons: IconIndex = {
  "chevron-up": {
    default: `<svg>...</svg>`,
  },
  "chevron-down": {
    default: `<svg>...</svg>`,
  },
  // ... other icons
};