Accordion
Expand and collapse sections to show the content you need.
import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } 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 Accordion for sections people open as needed, such as FAQs or groups of settings. Keep essential content and side-by-side comparisons visible. Use Collapsible for a single section, or Tabs for related views.
import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from '@youj/react'
export function Faq() {
return (
<Accordion defaultValue={['seats']}>
<AccordionItem value="seats">
<AccordionTrigger>What counts as a seat?</AccordionTrigger>
<AccordionContent>Anyone who can sign in to the workspace.</AccordionContent>
</AccordionItem>
<AccordionItem value="plans">
<AccordionTrigger>Can I change plans mid-cycle?</AccordionTrigger>
<AccordionContent>Yes. Upgrades apply at once and are prorated.</AccordionContent>
</AccordionItem>
</Accordion>
)
}Give each item a value. The accordion's value is always an array of the open items' values, so defaultValue={['seats']} opens one item and defaultValue={[]} opens none. Pass value and onValueChange to control it. Opening an item closes the others unless you set multiple.
Find in page
hiddenUntilFound keeps closed panels in the document with hidden="until-found", so the browser's find-in-page can search their text and open the panel that matches. Try ⌘F or Ctrl+F for "prorated" in the Demo story. Without it, closed panels are unmounted, unless you set keepMounted to keep them in the DOM, hidden.
<Accordion hiddenUntilFound>…</Accordion>Description
A set of frequently asked questions where opening one item closes the others.
Build checks that can stay open together, with one disabled while it runs.
With multiple, items open and close independently. Here the build checks can all stay open for comparison, and the running check is disabled until it finishes.
A trigger can hold more than its label. Put icons, badges or counts inside it and they become part of the trigger's accessible name, so keep them short.
One button that expands or collapses every environment, driven by the accordion's value.
Pass value and onValueChange to keep the open items in your own state, so anything on the page can open or close them. Here one button expands or collapses every environment, and its label and icon follow along. Keep multiple on, or opening one item by hand closes the rest.
Code
accordion-demo.tsx, the Demo story. The component itself comes from the package.
Reference
PropsEvery part passes its props through to the Base UI part of the same…
Props
Every part passes its props through to the Base UI part of the same name: Accordion.Root, Accordion.Item, Accordion.Trigger and Accordion.Panel. The ones you'll use most:
| Part | Prop | Type | Default |
|---|---|---|---|
Accordion | defaultValue | any[] | – |
Accordion | value, onValueChange | any[], (value, details) => void | – |
Accordion | multiple | boolean | false |
Accordion | hiddenUntilFound | boolean | false |
Accordion | keepMounted | boolean | false |
Accordion | disabled | boolean | false |
AccordionItem | value | any | – |
AccordionItem | disabled | boolean | false |
AccordionItem | onOpenChange | (open, details) => void | – |
AccordionTrigger | headingLevel | 2 | 3 | 4 | 5 | 6 | 3 |
Accordion adds no props of its own. They pass through to AccordionPrimitive.Root.Props.
MotionPanel, chevron, chevron color · 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 item opens | spring.snappy0.2s, bounce 0 | 0.2s, bounce 0 | |
| Chevron coloron trigger hover | duration.fastease.standard140ms · cubic-bezier(0.2, 0, 0, 1) | 140mscubic-bezier(0.2, 0, 0, 1) |
Reduced motion
Panels open and close at once, and the chevron flips without turning.
The panel wears the yj-collapse preset. A toggle mid-way reverses from the current height, so fast clicking never jumps. The panel clips while it moves, which is why the content's padding and focus rings sit inside it.
Reduced motion
Panels still open and close, the same way, but at once: the height doesn't ease and the content doesn't fade. The chevron flips to its new direction without turning.
AccessibilityKeyboard, ARIA, announcements
Accessibility
- Each trigger is a
buttoninside a heading (h3by default; setheadingLevelonAccordionTriggerto match your outline, such as2straight under a page'sh1), witharia-expandedandaria-controls. Each panel is aregionlabeled by its trigger. - Tab moves between triggers, and Enter or Space toggles one. Base UI follows the updated ARIA Authoring Practices here, which dropped arrow-key navigation for accordions.
- A disabled item's trigger doesn't toggle.
- The chevron is decorative. The open state is announced through
aria-expanded.