Collapsible
A Collapsible allows users to show and hide one section of content by clicking its trigger.
When to Use
- to keep the rest of a short list out of the way, such as the second and third line items of an invoice
- to cut a long message short, such as a Bubble with a “Show the full message” Button under it
When Not to Use
- for several sections under their own headings (use an Accordion)
- for content that floats over the page (use a Popover)
- for views where one is always shown (use Tabs)
See Accordion for a comparison of the Accordion and the Collapsible.
Anatomy
| Element | Usage |
|---|---|
| Root | Required |
| Trigger | Required |
| Panel | Required |
A Collapsible has no styles of its own. The root is a div, and the trigger is a button with no classes, so pass a Button to the trigger through render. You can place the trigger anywhere inside the root, before the panel or after it.
render so that it looks like a control.States
To disable the trigger, set disabled on Collapsible. A disabled trigger has aria-disabled in place of the disabled attribute, so it stays in the tab order, and it ignores clicks.
Behavior
By default, a Collapsible is closed. While it is closed, the panel isn’t in the page’s markup. When the panel opens, it pushes down the content that follows it.
Hidden Content
To keep the closed panel in the markup with the hidden attribute, set keepMounted on CollapsibleContent. If you set hiddenUntilFound, the panel is hidden with hidden="until-found", so the browser’s find-in-page reaches its text and opens the panel.
Accessibility
Base UI’s Collapsible renders the trigger as a native button and reports the panel’s state on it.
Requirements
A trigger that contains only an icon has no text. It needs an aria-label so that screen readers can announce it,
as WCAG 2.2 SC 4.1.2 Name, Role, Value requires.
The label of the trigger stays the same when the panel opens, and aria-expanded reports the state. If you want to change the words, control open from the parent, as in Change the Label When Open.
Installation
npx shadcn@latest add @summit/collapsibleUsage
import { Button } from '@/components/ui/button';
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from '@/components/ui/collapsible';
<Collapsible>
<CollapsibleContent>The calendar needs a way to pick a time zone.</CollapsibleContent>
<CollapsibleTrigger render={<Button variant="link" size="sm" />}>Show the full message</CollapsibleTrigger>
</Collapsible>;Start Open
To open the panel initially, set defaultOpen on Collapsible.
<Collapsible defaultOpen>
<CollapsibleTrigger render={<Button variant="ghost" size="sm" />}>Line items</CollapsibleTrigger>
<CollapsibleContent>Development, 30 hours</CollapsibleContent>
</Collapsible>Change the Label When Open
To change the label when the panel opens, control the state from the parent with open and onOpenChange on Collapsible, and choose the label there.
import { useState } from 'react';
const [open, setOpen] = useState(false);
<Collapsible open={open} onOpenChange={setOpen}>
<CollapsibleContent>The calendar needs a way to pick a time zone.</CollapsibleContent>
<CollapsibleTrigger render={<Button variant="link" size="sm" />}>
{open ? 'Show less' : 'Show the full message'}
</CollapsibleTrigger>
</Collapsible>;API Reference
Summit adds no props. The parts accept the props of their matching parts in Base UI’s Collapsible, where CollapsibleContent is Collapsible.Panel. See the Base UI Collapsible documentation for open, defaultOpen, onOpenChange, disabled, keepMounted, and hiddenUntilFound.