Collapsible
Show or hide a section of content from a single control.
import { Collapsible, CollapsibleChevron, CollapsibleContent, CollapsibleTrigger } from '@youj/react'
Installation & usage
npm i @youj/reactFor an app already set up with npx @youj/cli init, which installs the peers (@youj/core, @youj/motion, motion and Base UI) and wires the provider. New app? Start at Installation.
Use it to keep secondary content out of the way until someone asks for it: advanced settings, the rest of a long list, details under a summary. For a stack of sections, use an Accordion. For content that should float over the page instead of pushing it down, use a Popover.
import { Button, Collapsible, CollapsibleChevron, CollapsibleContent, CollapsibleTrigger } from '@youj/react'
export function AdvancedSettings() {
return (
<Collapsible>
<CollapsibleTrigger render={<Button variant="ghost" size="sm" />}>
Advanced settings
<CollapsibleChevron />
</CollapsibleTrigger>
<CollapsibleContent>
<div className="pt-3">…</div>
</CollapsibleContent>
</Collapsible>
)
}CollapsibleTrigger renders a plain button by default. Compose it with any button through render, as in the Demo story, and it keeps its look while gaining the disclosure behavior. Pass defaultOpen to start open, or open and onOpenChange to control it.
The chevron
CollapsibleChevron is Youj's chevron icon, turned over while its trigger is expanded. It reads aria-expanded from the nearest trigger around it, so it works in any disclosure without wiring: a collapsible, an accordion, a navigation menu or a sidebar group, including triggers composed through render. It mounts in its real state, so an open section doesn't turn over on first paint. size sets it in pixels.
<CollapsibleTrigger>
Filters
<CollapsibleChevron size={14} className="text-fg-muted" />
</CollapsibleTrigger>Description
A build command field with an Advanced settings section that grows open.
A file list that shows three rows and grows to show the rest, with a trigger label that follows the state.
Controlled, the trigger's label can follow the state. Here the first three files stay visible and the rest of the list grows in below them.
A folder tree where each folder is its own Collapsible.
Each folder in this tree is its own Collapsible, nested in its parent's panel, so opening one never closes another. Its open state also opens the folder icon. It's a list of disclosure buttons, not an ARIA tree: Tab moves between the folders, and Enter or Space toggles one.
Code
collapsible-demo.tsx, the Demo story. The component itself comes from the package.
Reference
Propssize, className (2)
Props
CollapsibleChevron
| Prop | Type | |
|---|---|---|
size | numberRendered size in px. default 16 | 16 |
className | string | – |
Collapsible, CollapsibleTrigger and CollapsibleContent
These pass their props through to Base UI's Collapsible.Root, Collapsible.Trigger and Collapsible.Panel. The ones you'll use most:
| Part | Prop | Type | Default |
|---|---|---|---|
Collapsible | defaultOpen | boolean | false |
Collapsible | open, onOpenChange | boolean, (open, details) => void | – |
Collapsible | disabled | boolean | false |
CollapsibleTrigger | render | ReactElement | (props, state) => ReactElement | – |
CollapsibleContent | keepMounted | boolean | false |
CollapsibleContent | hiddenUntilFound | boolean | false |
MotionPanel, chevron · reduced motion
Motion
| Moment | Tokens | ||
|---|---|---|---|
Panelheight to the measured size, then auto, with a fade | duration.baseease.standard220ms · cubic-bezier(0.2, 0, 0, 1) | 220mscubic-bezier(0.2, 0, 0, 1) | |
| Chevronturns over as the panel opens | spring.snappy0.2s, bounce 0 | 0.2s, bounce 0 |
Reduced motion
The panel opens and closes at once, and the chevron flips without turning.
The panel wears the yj-collapse preset: the height eases between zero and the measured size, then settles on auto so the content can still grow. A toggle mid-way reverses from the current height. The panel clips while it moves, so keep padding and focus rings inside it, as the examples do.
Reduced motion
The section still opens and closes, but at once: no height easing and no fade. The chevron flips without turning.
AccessibilityKeyboard, ARIA, announcements
Accessibility
- The trigger is a
buttonwitharia-expanded, andaria-controlspointing at the panel. - Enter and Space toggle it. Closed content is removed from the tab order, and from the document unless you pass
keepMountedorhiddenUntilFound. - The chevron is decorative. The state is announced through
aria-expanded, so a label that changes ("Show 4 more", "Show less") is optional.