XDSCollapsible@xds/core · Collapsible

Usage

Collapsible hides and reveals content behind a trigger button. Use it in settings panels, FAQ pages, or detail views to keep the page scannable while letting users drill into sections they care about. Wrap multiple collapsibles in XDSCollapsibleGroup for accordion behavior. For custom collapsible components, use the `useXDSCollapsible` hook directly (`xds hook useXDSCollapsible`).

Best practices

GuidancePractices
DoWrap each XDSCollapsible in an XDSCard for visual separation in accordion layouts.
DoUse XDSCollapsibleGroup with type="single" for settings or FAQ pages where only one section should be open at a time.
DoUse type="multiple" when users need to compare content across sections, like feature lists or pricing tiers.
DoStart sections open (defaultIsOpen) when the content is likely needed on first view — don't make users click to see essential info.
Don'tHide critical or required content behind a collapsible — users may not discover it.
Don'tNest collapsibles more than two levels deep — it makes content hard to find and navigate.
Don'tUse a collapsible for a single short paragraph — just show the text directly instead.

Anatomy

ElementDescription
TriggerrequiredThe always-visible button that toggles the content. Shows a label and a chevron indicator.
ChevronAnimated arrow that rotates to show open or closed state.
ContentThe area that hides or reveals when the trigger is clicked.

Import

ts
import {XDSCollapsible} from '@xds/core/Collapsible'

Props

PropTypeDescription
triggerrequired
ReactNodeContent shown in the trigger area (always visible).
children
ReactNodeContent that collapses and expands.
defaultIsOpen
boolean (default: true)Default open state (uncontrolled).
isOpen
booleanControlled open state.
onOpenChange
(isOpen: boolean) => voidCallback invoked when the open state changes.
value
stringIdentifier used for group coordination. Required when placed inside an XDSCollapsibleGroup.

Sub-components

Collapsible is a compound component with 2 sub-components.

XDSCollapsible

A primitive that makes any content collapsible — a trigger button toggles visibility of the content area, managing its own state or deferring to a parent XDSCollapsibleGroup.
PropTypeDescription
triggerrequired
ReactNodeContent shown in the trigger area (always visible).
children
ReactNodeContent that collapses and expands.
defaultIsOpen
boolean (default: true)Default open state (uncontrolled).
isOpen
booleanControlled open state.
onOpenChange
(isOpen: boolean) => voidCallback invoked when the open state changes.
value
stringIdentifier used for group coordination. Required when placed inside an XDSCollapsibleGroup.

XDSCollapsibleGroup

Coordinates multiple XDSCollapsible instances so only one (single mode) or any number (multiple mode) can be open at a time. Renders no wrapper DOM element.
PropTypeDescription
childrenrequired
ReactNodeXDSCollapsible instances to coordinate.
type
'single' | 'multiple' (default: 'single')Whether one or many items can be open simultaneously.
defaultValue
string | string[]Default open item(s) for uncontrolled usage. Use a string for single mode and an array for multiple mode.
value
string | string[]Controlled open item(s).
onChange
(value: string | string[]) => voidCallback invoked when the set of open items changes.

Examples

Common configurations, variations, and states.
Collapsible — ControlledManage the open section from parent state. Use when the open state needs to sync with a URL param, form, or external control.
tsx
'use client';
import {useState} from 'react';
import {XDSCollapsible, XDSCollapsibleGroup} from '@xds/core/Collapsible';
import {XDSCard} from '@xds/core/Card';
import {XDSText} from '@xds/core/Text';
import {XDSVStack} from '@xds/core/Layout';
export default function CollapsibleControlledAccordion() {
const [open, setOpen] = useState<string | string[]>('profile');
return (
<XDSCollapsibleGroup type="single" value={open} onChange={setOpen}>
<XDSVStack gap={2}>
<XDSCard>
<XDSCollapsible trigger="Profile Information" value="profile">
<XDSText type="body">
Update your name, email, and profile photo. Changes are saved
automatically.
</XDSText>
</XDSCollapsible>
</XDSCard>
<XDSCard>
<XDSCollapsible trigger="Security" value="security">
<XDSText type="body">
Manage two-factor authentication, active sessions, and login
history.
</XDSText>
</XDSCollapsible>
</XDSCard>
<XDSCard>
<XDSCollapsible trigger="Billing" value="billing">
<XDSText type="body">
View invoices, update payment method, and manage your subscription
plan.
</XDSText>
</XDSCollapsible>
</XDSCard>
</XDSVStack>
</XDSCollapsibleGroup>
);
}
Collapsible — Multiple ModeSeveral sections open at once. Use when users need to compare content across sections, like feature lists or pricing tiers.
tsx
'use client';
import {XDSCollapsible, XDSCollapsibleGroup} from '@xds/core/Collapsible';
import {XDSCard} from '@xds/core/Card';
import {XDSText} from '@xds/core/Text';
import {XDSVStack} from '@xds/core/Layout';
export default function CollapsibleMultipleAccordion() {
return (
<XDSCollapsibleGroup type="multiple" defaultValue={['features', 'pricing']}>
<XDSVStack gap={2}>
<XDSCard>
<XDSCollapsible trigger="Features" value="features">
<XDSText type="body">
Includes real-time collaboration, version history, and granular
permissions for teams of any size.
</XDSText>
</XDSCollapsible>
</XDSCard>
<XDSCard>
<XDSCollapsible trigger="Pricing" value="pricing">
<XDSText type="body">
Free for up to 5 users. Pro plans start at $12/user/month with
annual billing.
</XDSText>
</XDSCollapsible>
</XDSCard>
<XDSCard>
<XDSCollapsible trigger="Integrations" value="integrations">
<XDSText type="body">
Connect with Slack, GitHub, Jira, and 40+ other tools through our
REST API and pre-built connectors.
</XDSText>
</XDSCollapsible>
</XDSCard>
</XDSVStack>
</XDSCollapsibleGroup>
);
}
Collapsible — Single ModeOnly one section open at a time. Use for settings pages or any list where expanding one item should close the others.
tsx
'use client';
import {XDSCollapsible, XDSCollapsibleGroup} from '@xds/core/Collapsible';
import {XDSSection} from '@xds/core/Section';
import {XDSText} from '@xds/core/Text';
import {XDSVStack} from '@xds/core/Layout';
export default function CollapsibleSingleAccordion() {
return (
<XDSCollapsibleGroup type="single" defaultValue="general">
<XDSVStack gap={2}>
<XDSSection>
<XDSCollapsible trigger="General Settings" value="general">
<XDSText type="body">
Configure your general preferences including language, timezone,
and display options.
</XDSText>
</XDSCollapsible>
</XDSSection>
<XDSSection>
<XDSCollapsible trigger="Privacy Settings" value="privacy">
<XDSText type="body">
Manage who can see your profile, activity, and personal
information.
</XDSText>
</XDSCollapsible>
</XDSSection>
<XDSSection>
<XDSCollapsible trigger="Notification Settings" value="notifications">
<XDSText type="body">
Choose which notifications you receive and how they are delivered.
</XDSText>
</XDSCollapsible>
</XDSSection>
</XDSVStack>
</XDSCollapsibleGroup>
);
}
Collapsible — With DividersCollapsible sections separated by dividers instead of cards. Use for inline disclosure in detail panels or sidebar content where cards would add too much weight.
tsx
'use client';
import {XDSCollapsible} from '@xds/core/Collapsible';
import {XDSDivider} from '@xds/core/Divider';
import {XDSText} from '@xds/core/Text';
import {XDSVStack} from '@xds/core/Layout';
export default function CollapsibleWithoutCard() {
return (
<XDSVStack gap={3}>
<XDSCollapsible trigger="Deployment Details">
<XDSText type="body">
Last deployed on April 18, 2026 at 3:42 PM by Sarah Chen. Build
duration was 2m 14s with zero warnings.
</XDSText>
</XDSCollapsible>
<XDSDivider />
<XDSCollapsible trigger="Environment Variables" defaultIsOpen={false}>
<XDSText type="body">
12 variables configured. Last updated March 30, 2026. All secrets are
encrypted at rest with AES-256.
</XDSText>
</XDSCollapsible>
<XDSDivider />
<XDSCollapsible trigger="Build Logs" defaultIsOpen={false}>
<XDSText type="body">
Build completed successfully. 847 modules compiled, 0 errors, 0
warnings. Bundle size: 142 KB gzipped.
</XDSText>
</XDSCollapsible>
</XDSVStack>
);
}

Showcase source

tsx
'use client';
import {XDSCollapsible, XDSCollapsibleGroup} from '@xds/core/Collapsible';
import {XDSText} from '@xds/core/Text';
import {XDSCard} from '@xds/core/Card';
import {XDSVStack} from '@xds/core/Layout';
export default function CollapsibleShowcase() {
return (
<XDSCard width={400}>
<XDSCollapsibleGroup type="single" defaultValue="notifications">
<XDSVStack gap={2}>
<XDSCollapsible trigger="General settings" value="general">
<XDSText type="body" color="secondary">
Configure your display name, language, and time zone preferences.
</XDSText>
</XDSCollapsible>
<XDSCollapsible trigger="Notifications" value="notifications">
<XDSText type="body" color="secondary">
Choose which email and push notifications you want to receive.
</XDSText>
</XDSCollapsible>
<XDSCollapsible trigger="Privacy" value="privacy">
<XDSText type="body" color="secondary">
Manage your data sharing preferences and account visibility.
</XDSText>
</XDSCollapsible>
</XDSVStack>
</XDSCollapsibleGroup>
</XDSCard>
);
}