Collapse
Collapse stacks CollapseItems: each is a header that shows or hides the content below it. The content’s height animates in CSS.
Demos
Basic
Items open and close independently. defaultExpandedNames opens some at first.
Accordion
accordion keeps at most one item open: opening one closes the others.
Arrow placement
arrowPlacement="right" puts the arrow after the title.
Controlled
expandedNames with onUpdateExpandedNames holds the open items in your state.
Header extra
headerExtra puts content at the end of the header, such as a count or a timestamp.
Custom arrow
arrow replaces the chevron. Like title and headerExtra it takes a node or a function of { collapsed }; set on the Collapse it applies to every item. A custom arrow is not rotated.
Disabled
A disabled item can’t be toggled.
Trigger areas
triggerAreas picks which parts of the header toggle on click: main (the title), arrow and extra. The header stays a button, so Enter and Space always toggle it.
Display directive
With displayDirective="if" (the default) collapsed content is unmounted once it has closed; with show it stays mounted and is only hidden, so it keeps its state.
Nested
Accessibility
Each header follows the WAI-ARIA accordion pattern: a heading (role="heading", aria-level="3") holding a native button with aria-expanded and aria-controls, and the content is a role="region" labelled by that button. Tab moves between headers and Enter or Space toggles. Collapsed content is visibility: hidden, so it is out of the tab order and the accessibility tree. With prefers-reduced-motion the content opens and closes without animating.
Collapse Props
| Name | Type | Default | Description | Version |
|---|---|---|---|---|
accordion | boolean | false | Keeps at most one item open. | Unreleased |
arrow | ReactNode | (state: { collapsed: boolean }) => ReactNode | undefined | A custom arrow for every item. | Unreleased |
arrowPlacement | left | right | left | Which side of the title the arrow sits on. | Unreleased |
defaultExpandedNames | string | number | Array<string | number> | null | null | The items open at first when uncontrolled. | Unreleased |
displayDirective | if | show | if | if unmounts collapsed content; show keeps it mounted and hidden. | Unreleased |
expandedNames | string | number | Array<string | number> | null | undefined | The open items when controlled. | Unreleased |
headerExtra | ReactNode | (state: { collapsed: boolean }) => ReactNode | undefined | Extra content at the end of every header. | Unreleased |
triggerAreas | Array<main | arrow | extra> | ['main', 'extra', 'arrow'] | Which parts of a header toggle on click. | Unreleased |
onItemHeaderClick | (info: { name: string | number, expanded: boolean, event: MouseEvent }) => void | undefined | Called when a header click toggles an item. | Unreleased |
onUpdateExpandedNames | (names: Array<string | number>) => void | undefined | Called with the open items when one is toggled. | Unreleased |
CollapseItem Props
| Name | Type | Default | Description | Version |
|---|---|---|---|---|
name | string | number | a generated id | Identifies the item in expandedNames. | Unreleased |
title | ReactNode | (state: { collapsed: boolean }) => ReactNode | undefined | The header’s title. | Unreleased |
headerExtra | ReactNode | (state: { collapsed: boolean }) => ReactNode | undefined | Extra content at the end of the header; overrides the Collapse’s. | Unreleased |
arrow | ReactNode | (state: { collapsed: boolean }) => ReactNode | undefined | Replaces the chevron; overrides the Collapse’s. | Unreleased |
disabled | boolean | false | Keeps the item from toggling. | Unreleased |
displayDirective | if | show | undefined | Overrides the Collapse’s displayDirective. | Unreleased |
Both components also accept native div attributes and a ref. The header parts are the title, headerExtra and arrow props, and the content is children. onUpdateExpandedNames always receives an array.