Skip to content

Accordion

Expand and collapse sections to show the content you need.

import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from '@youj/react'

Installation & usage

npm i @youj/react

For 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>

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:

PartPropTypeDefault
AccordiondefaultValueany[]–
Accordionvalue, onValueChangeany[], (value, details) => void–
Accordionmultiplebooleanfalse
AccordionhiddenUntilFoundbooleanfalse
AccordionkeepMountedbooleanfalse
Accordiondisabledbooleanfalse
AccordionItemvalueany–
AccordionItemdisabledbooleanfalse
AccordionItemonOpenChange(open, details) => void–
AccordionTriggerheadingLevel2 | 3 | 4 | 5 | 63

Accordion adds no props of its own. They pass through to AccordionPrimitive.Root.Props.

MotionPanel, chevron, chevron color · reduced motion

Motion

Motion tokens
MomentTokens
Panelheight to the measured size, then auto, with a fade
duration.baseease.standard

220ms · cubic-bezier(0.2, 0, 0, 1)

220mscubic-bezier(0.2, 0, 0, 1)
Chevronturns over as the item opens
spring.snappy

0.2s, bounce 0

0.2s, bounce 0
Chevron coloron trigger hover
duration.fastease.standard

140ms · 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 button inside a heading (h3 by default; set headingLevel on AccordionTrigger to match your outline, such as 2 straight under a page's h1), with aria-expanded and aria-controls. Each panel is a region labeled 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.