Skip to content

shadcn.io is an independent project built on shadcn/ui

Free

Accordion with Subtitle Text for React

Help topics whose triggers show a title over a muted subtitle, with the chevron on the right.

Getting started, Billing, Integrations, and Security. Each trigger stacks a title over a muted subtitle, and the chevron stays on the right. Getting started starts open.

Use it for help topics that need a one-line summary. A single topic can be a Collapsible. In React, Base UI does not write that summary.

Preview

Preview width

Installation

Sign in to get your install command
Free with an account. It carries your token, so the CLI installs everything in one go.
Use email insteadNo credit card

Anatomy

Accordion anatomy: root, item, item trigger, item content, item indicator

Usage

<Accordion
  className="w-full max-w-md -space-y-px"
  defaultValue={["getting-started"]}
>
  {items.map((item) => (
    <AccordionItem
      className="overflow-hidden border bg-background px-4 first:rounded-t-lg last:rounded-b-lg"
      key={item.value}
      value={item.value}
    >
      <AccordionTrigger className="hover:no-underline">
        <span className="flex flex-col items-start text-start">
          <span>{item.title}</span>
          <span className="text-muted-foreground text-sm">
            {item.subtitle}
          </span>
        </span>
      </AccordionTrigger>
      <AccordionContent>
        <p className="text-muted-foreground">{item.content}</p>
      </AccordionContent>
    </AccordionItem>
  ))}
</Accordion>

FAQ

How is the subtitle marked up?

Each item stores a subtitle string under its title. The trigger puts them in a flex flex-col items-start text-start stack, and the subtitle is text-sm text-muted-foreground.

Why does the trigger set hover:no-underline?

hover:no-underline is on AccordionTrigger, so hovering the two-line heading does not underline it. The built-in chevron stays, because this trigger leaves accordion-trigger-icon visible.

Why does Getting started start open?

defaultValue={["getting-started"]} opens Getting started on first render. The string matches that item's value.

How do I let several items stay open at once?

One open item is the default. Add multiple to Accordion to let several stay open, and list every item that should start open in the defaultValue array.

How do the row borders meet?

-space-y-px on Accordion pulls the rows together so neighboring borders share one line. Each AccordionItem has border, px-4, first:rounded-t-lg and last:rounded-b-lg.

Where does the answer sit relative to the subtitle?

AccordionItem has px-4, and AccordionContent adds no padding class of its own, so the paragraph lines up with the title and the subtitle. The paragraph is text-muted-foreground.

API Reference

Accordion

Sets defaultValue={["getting-started"]} and value={item.value}. The rest is on the Accordion page.