A card that can be expanded and collapsed. When collapsed, only the header is visible.
Import
import { CollapsibleCard } from '@wordpress/ui';
Props
| Name | Type | Default | Required | Description |
|---|---|---|---|---|
className | string | CSS class name to apply to the element. | ||
style | React.CSSProperties | CSS style to apply to the element. | ||
render | | ComponentRenderFn< HTMLAttributesWithRef >
| React.ReactElement< Record< string, unknown > > | Replaces the component’s default HTML element using a given React element, or a function that returns a React element. | ||
children | ReactNode | The content to be rendered inside the collapsible card.
Should include | ||
open | boolean | Whether the collapsible panel is currently open (controlled). To render an uncontrolled collapsible card, use | ||
defaultOpen | boolean | Whether the collapsible panel is initially open (uncontrolled). @default false | ||
onOpenChange | ( open: boolean ) => void | Event handler called when the panel is opened or closed. | ||
disabled | boolean | Whether the component should ignore user interaction. @default false |
Examples
Default
A collapsible card that is open by default.
const Default = () => <CollapsibleCard.Root>(<>
<CollapsibleCard.Header>
<Card.Title>
Collapsible card (closed by default)
</Card.Title>
</CollapsibleCard.Header>
<CollapsibleCard.Content>
<Text>
This is the collapsible content area. It can contain any
elements, just like a regular Card.Content.
</Text>
<Text>
When collapsed, only the header and chevron are visible.
</Text>
</CollapsibleCard.Content>
</>)</CollapsibleCard.Root>;
Initially Opened
A collapsible card that starts collapsed.
const InitiallyOpened = () => <CollapsibleCard.Root defaultOpen>(<>
<CollapsibleCard.Header>
<Card.Title>Collapsed by default</Card.Title>
</CollapsibleCard.Header>
<CollapsibleCard.Content>
<Text>This content was hidden until you expanded it.</Text>
</CollapsibleCard.Content>
</>)</CollapsibleCard.Root>;
Disabled
A disabled collapsible card cannot be toggled by the user.
const Disabled = () => <CollapsibleCard.Root disabled>(<>
<CollapsibleCard.Header>
<Card.Title>Disabled card</Card.Title>
</CollapsibleCard.Header>
<CollapsibleCard.Content>
<Text>The header is not interactive when disabled.</Text>
</CollapsibleCard.Content>
</>)</CollapsibleCard.Root>;
Stacked
Multiple collapsible cards stacked vertically, simulating a typical settings-panel or FAQ-style layout.
const Stacked = () => (
<div
style={ {
display: 'flex',
flexDirection: 'column',
gap: 'var(--wpds-dimension-gap-lg)',
} }
>
{ [
'General',
'Advanced',
'Accessibility',
'Performance',
'Privacy',
'Notifications',
].map( ( title ) => (
<CollapsibleCard.Root key={ title }>
<CollapsibleCard.Header>
<Card.Title>{ title }</Card.Title>
</CollapsibleCard.Header>
<CollapsibleCard.Content>
<Text>
Configure all { title.toLowerCase() } settings for
your site. Changes here affect how your site behaves
across all pages and posts.
</Text>
<Text>
Review each option carefully before saving. Some
changes may require a page reload to take effect.
Hover over individual options for more details about
what they control.
</Text>
<Text>
If you're unsure about a setting, you can
always reset to defaults using the button at the
bottom of this section. Your previous configuration
will be saved as a backup.
</Text>
</CollapsibleCard.Content>
</CollapsibleCard.Root>
) ) }
</div>
);
With Heading Element
CollapsibleCard.Header renders a <div> wrapper by default. Pass an <h1>–<h6> React element to the render prop to wrap the trigger in a heading and contribute to the document outline. The right level depends on the surrounding outline, so the consumer is expected to opt in.
const WithHeadingElement = () => (
<div
style={ {
display: 'flex',
flexDirection: 'column',
gap: 'var(--wpds-dimension-gap-lg)',
} }
>
<CollapsibleCard.Root>
<CollapsibleCard.Header render={ <h2 /> }>
<Card.Title>Heading level 2</Card.Title>
</CollapsibleCard.Header>
<CollapsibleCard.Content>
<Text>
The wrapper renders as an h2 element when the consumer
passes an h2 React element to the render prop.
</Text>
</CollapsibleCard.Content>
</CollapsibleCard.Root>
<CollapsibleCard.Root>
<CollapsibleCard.Header render={ <h3 /> }>
<Card.Title>Heading level 3</Card.Title>
</CollapsibleCard.Header>
<CollapsibleCard.Content>
<Text>
Pass any of h1–h6 to choose the level that fits the
surrounding document outline.
</Text>
</CollapsibleCard.Content>
</CollapsibleCard.Root>
<CollapsibleCard.Root>
<CollapsibleCard.Header>
<Card.Title>No heading (default)</Card.Title>
</CollapsibleCard.Header>
<CollapsibleCard.Content>
<Text>
Without a render prop, the header wraps the trigger in a
plain div and does not contribute to the document
outline.
</Text>
</CollapsibleCard.Content>
</CollapsibleCard.Root>
</div>
);
With Header Description
A collapsible card with a HeaderDescription that provides supplementary information (e.g. status, summary) as an aria-describedby relationship.
const WithHeaderDescription = ( { open, defaultOpen, onOpenChange, disabled, ...restArgs } ) => (
<CollapsibleCard.Root
open={ open }
defaultOpen={ defaultOpen }
onOpenChange={ onOpenChange }
disabled={ disabled }
{ ...restArgs }
>
<CollapsibleCard.Header>
<Stack justify="space-between">
<Card.Title>Settings</Card.Title>
<CollapsibleCard.HeaderDescription>
<span
style={ {
fontSize: 'var(--wpds-typography-font-size-sm)',
color: 'var(--wpds-color-fg-content-neutral-weak)',
} }
>
3 items configured
</span>
</CollapsibleCard.HeaderDescription>
</Stack>
</CollapsibleCard.Header>
<CollapsibleCard.Content>
<Text>
The header description provides supplementary context to the
trigger button. Assistive technologies will announce the
description alongside the button label.
</Text>
</CollapsibleCard.Content>
</CollapsibleCard.Root>
);
Compared To Card
Visual comparison: a CollapsibleCard (open) next to a regular Card to verify identical spacing and layout.
const ComparedToCard = ( { open, defaultOpen, onOpenChange, disabled, ...restArgs } ) => (
<div
style={ {
display: 'flex',
flexDirection: 'column',
gap: 'var( --wpds-dimension-gap-lg )',
} }
>
<CollapsibleCard.Root
open={ open }
defaultOpen={ defaultOpen }
onOpenChange={ onOpenChange }
disabled={ disabled }
{ ...restArgs }
>
<CollapsibleCard.Header>
<Card.Title>CollapsibleCard (open)</Card.Title>
</CollapsibleCard.Header>
<CollapsibleCard.Content>
<Text>
Content should align with the regular card below.
</Text>
</CollapsibleCard.Content>
</CollapsibleCard.Root>
<Card.Root { ...restArgs }>
<Card.Header>
<Card.Title>Regular Card</Card.Title>
</Card.Header>
<Card.Content>
<Text>
Content should align with the collapsible card above.
</Text>
</Card.Content>
</Card.Root>
</div>
);