Gesso
Layout

Accordion

Stacked disclosure rows. One section open at a time, or many.

Accordion is a stack of rows that each show a heading and hide a block of content until the row is opened. It is the group version of Collapsible, so it manages which rows are open for you, and it can keep one open at a time or let several stay open. A caret trails each label and turns when the row opens, and a rule in border-border separates the rows.

A retune of brand color, type, and radius. Chrome (surfaces, ink, borders) stays in the room unless you pick a paper temperature.

Usage

import {
  Accordion,
  AccordionContent,
  AccordionItem,
  AccordionTrigger,
} from '@/components/ui/accordion';

<Accordion type="single" collapsible defaultValue="one">
  <AccordionItem value="one">
    <AccordionTrigger>What is a look?</AccordionTrigger>
    <AccordionContent>A retune of brand color, type, and radius.</AccordionContent>
  </AccordionItem>
  <AccordionItem value="two">
    <AccordionTrigger>What stays in system?</AccordionTrigger>
    <AccordionContent>Status colors and the chrome ladder.</AccordionContent>
  </AccordionItem>
</Accordion>

Every AccordionItem needs a value, and type is required on the root.

One open or several

type="single" keeps at most one row open, and opening another closes the first. Without collapsible, the open row cannot be closed by pressing it again, so one row stays open once any has been. Add collapsible so the open row can close too. Control it with value as a string and onValueChange, or start it with defaultValue.

type="multiple" lets every row open and close on its own, with value and defaultValue as arrays of item values. It is always collapsible.

Orders leave the warehouse within two business days.

Unworn items can come back within thirty days.

<Accordion type="multiple" defaultValue={['shipping', 'returns']}>
  {/* items */}
</Accordion>

Rows and motion

AccordionTrigger is a full-width button inside an h3, with the label at the start and a 16px CaretDown at the end that turns 180 degrees when the row opens. The label is text-fg in medium weight with py-4, and it underlines on hover. AccordionContent is text-sm text-fg-muted, and its className goes to an inner block that has pb-4, so put spacing there and not on the outer element that animates.

Each item draws a rule on its bottom edge, so the last row has one too. Opening and closing animate the height of the content over --duration-base with --ease-out, and a row that starts open does not animate on mount. A closed row is not rendered at all, so its content is not in the page until it opens. Under reduced motion the caret turns instantly and the content appears without sliding.

Props

Accordion takes every prop of the Radix Accordion, such as type, collapsible, value, defaultValue, onValueChange, disabled, orientation, and dir on the root, and value and disabled on an item. It adds no props of its own.

Accessibility

  • Each trigger is a button with aria-expanded inside a heading, and each panel is a region labelled by its trigger.
  • Every trigger is a tab stop, and Space or Enter toggles the row. Down and Up move focus to the next and previous trigger and wrap at the ends, and Home and End jump to the first and last. With orientation="horizontal" the keys are Right and Left instead. Disabled triggers are skipped.
  • In type="single" without collapsible, the open row's trigger gets aria-disabled while it is open, because pressing it does nothing.
  • Focus shows a 2px ring on :focus-visible, and in forced colors the focus outline still shows. The caret is aria-hidden, since aria-expanded already says whether a row is open. The trigger target is the label row at py-4 and is not enlarged on touch.
  • Under reduced motion the caret does not turn and the panel does not animate.

When to use something else

  • Collapsible for one block that opens on its own, with a trigger you style yourself. Accordion is for a stack of rows that share a look.
  • Tabs when only one panel shows at a time and the reader should see every label at once beside it.
  • Section when the blocks are always visible, with a title and actions on each. Reach for Accordion when the content is long enough that most of it should start closed.

Install

shadcn add @gesso/accordion

On this page