Skip to content

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

Components

Free

Accordion for React Aria

Open one section in a stack and leave the rest closed. For React with React Aria, when an FAQ or a settings block should not show every answer at once.

Headings stacked in one column. Each heading opens its own section.

Use it for an FAQ or a settings list where most sections should stay closed. For one section on its own, use a Collapsible. In React, React Aria may unmount a closed panel, so a form field in it might not submit.

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.

Anatomy

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

Usage

import {
  Accordion, AccordionContent, AccordionItem, AccordionTrigger,
} from "@/components/ui/accordion";
const AccordionDemo = () => (
  <Accordion className="w-full max-w-sm" defaultExpandedKeys={["shipping"]}>
    <AccordionItem id="shipping">
      <AccordionTrigger>What are your shipping options?</AccordionTrigger>
      <AccordionContent>
        We offer standard (5-7 days), express (2-3 days), and overnight
        shipping. Free shipping on international orders.
      </AccordionContent>
    </AccordionItem>
    <AccordionItem id="returns">
      <AccordionTrigger>What is your return policy?</AccordionTrigger>
      <AccordionContent>
        Returns accepted within 30 days. Items must be unused and in original
        packaging. Refunds processed within 5-7 business days.
      </AccordionContent>
    </AccordionItem>
    <AccordionItem id="support">
      <AccordionTrigger>How can I contact customer support?</AccordionTrigger>
      <AccordionContent>
        Reach us via email, live chat, or phone. We respond within 24 hours
        during business days.
      </AccordionContent>
    </AccordionItem>
  </Accordion>
);

Accessibility

Space
When focus is on a trigger of a collapsed item, the item is expanded.
Enter
When focus is on a trigger of a collapsed section, expands the section.
Tab
Moves focus to the next focusable element.
Shift+Tab
Moves focus to the previous focusable element.
Arrow Down
Moves focus to the next trigger.
Arrow Up
Moves focus to the previous trigger.
Home
When focus is on a trigger, moves focus to the first trigger.
End
When focus is on a trigger, moves focus to the last trigger.
Arrow Right
Move to the next item.
Arrow Left
Move to the previous item.

Demos

Basic

Account questions, one open at a time, with the password item starting open. The rows come from a list, so another question is another entry rather than a fresh block of markup. Use this for a short FAQ where two answers on screen at once would be noise. If people compare sections, let more than one stay open.

Preview width

Multiple

Notifications start open, and privacy or billing can open beside them. The copy is settings, not a three-line FAQ. Allow several sections at once when people compare answers or fill related groups without losing the one they just read. A single-open list makes them hunt for the heading they closed by accident.

Preview width

Disabled

History and email still toggle. The middle item, premium feature information, sets disabled on AccordionItem, so its trigger does nothing. Leave a disabled row when the heading should stay visible as a locked feature and the upgrade path lives elsewhere on the page. If the plan will never include it, omit the row.

Preview width

Borders

The root gets a border and a radius. Each item gets a bottom border and horizontal padding, and the last item drops its border so it does not double up with the outline. Use the bordered list when the accordion is the surface, sitting on a plain page. Skip the extra edges when a card already supplies them.

Preview width

Card

The questions sit in CardContent, under a title and a short description about subscription and billing. Plans starts open. Use the card when this FAQ is one block among others, on a pricing or billing screen, and it needs a heading that is not itself a trigger. A bare accordion is enough when the page heading already names the topic.

Preview width

RTL

The same account questions, in Arabic, with dir set to rtl and the first item open. Triggers, text, and the chevron follow the inline direction, so the icon is not stuck on the physical right. Use this when the page language is Arabic or Hebrew. The open behavior does not change, only the direction of the row.

Preview width

FAQ

How do I let only one Accordion item open at a time in React?

One expanded item at a time is the default. Add allowsMultipleExpanded to Accordion to let several stay open.

How do I make an Accordion item open by default?

Give each AccordionItem an id and pass the ones to open in defaultExpandedKeys, such as ["item-1"]. The Basic demo starts with its first item open.

How do I control which Accordion items are open?

Pass expandedKeys and update it in onExpandedChange, which receives the set of expanded item ids.

Do form fields inside a closed Accordion item still submit?

Yes. React Aria keeps a closed panel in the DOM with hidden="until-found", so its fields submit and the browser's find in page can open it.

Is the React Aria Accordion accessible with the keyboard?

Yes. Each trigger is a button with aria-expanded and aria-controls, Enter and Space toggle it, and the Accessibility section lists every key. Keep a real heading level around each trigger in long pages, and don't put interactive controls inside the trigger itself.

How do I change the Accordion chevron or borders?

Edit components/ui/accordion in your project: the icon sits in AccordionTrigger, and the dividers are classes on AccordionItem. The Borders and Card demos show the two common looks. Change the file rather than overriding it from outside, since it's yours.

Can I nest an Accordion inside another Accordion?

You can, but a Collapsible inside the panel is usually better: two nested accordions mean two sets of arrow-key handling in one place. If people jump between every section, Tabs may fit better than an accordion.

How do I install the Accordion in React?

Run the command in the Installation section above: it adds accordion to your components/ui folder with what it needs. React and Solid use the shadcn CLI, Vue uses shadcn-vue and Svelte uses shadcn-svelte, each after its one-time setup.

API Reference

Accordion

data-slot="accordion"

PropType
allowsMultipleExpanded?boolean

Whether multiple items can be expanded at the same time.

defaultExpandedKeys?Iterable<Key>

The initial expanded keys in the group (uncontrolled).

Type
Iterable<Key>
expandedKeys?Iterable<Key>

The currently expanded keys in the group (controlled).

Type
Iterable<Key>
isDisabled?boolean

Whether all items are disabled.

onExpandedChange?(keys: Set<Key>) → any

Handler that is called when items are expanded or collapsed.

Type
(keys: Set<Key>) → any
Parameters

keys – Set<Key>

Returns
any
className?string

Merged with the part's classes.

AttributeType
data-orientationstring

Mirrors the orientation prop.

AccordionItem

data-slot="accordion-item"

PropType
defaultExpanded?boolean

Whether the disclosure is expanded by default (uncontrolled).

onExpandedChange?(isExpanded: boolean) → void

Handler that is called when the disclosure expanded state changes.

Parameters

isExpanded – boolean

Returns
void
isExpanded?boolean

Whether the disclosure is expanded (controlled).

className?string

Merged with the part's classes.

AttributeType
data-orientationstring

Mirrors the orientation prop.

AccordionTrigger

data-slot="accordion-trigger"

PropType
isDisabled?boolean

Whether the button is disabled.

className?string

Merged with the part's classes.

AttributeType
data-orientationstring

Mirrors the orientation prop.

AccordionContent

data-slot="accordion-content"

PropType
childrenReactNode

The children of the component.

labelElementType?ElementType

The HTML element used to render the label, e.g. label, or span.

Default
"label"
role?"group" | "region"

The accessibility role for the disclosure's panel.

Type
"group" | "region"
Default
"group"
style?CSSProperties

The inline [style](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/style) for the element.

render?DOMRenderFunction<E, T>

Overrides the default DOM element with a custom render function. This allows rendering existing components with built-in styles and behaviors such as router links, animation libraries, and pre-styled components. Requirements: - You must render the expected element type (e.g. if <button> is expected, you cannot render an <a>). - Only a single root DOM element can be rendered (no fragments). - You must pass through props and ref to the underlying DOM element, merging with your own prop as appropriate.

Type
DOMRenderFunction<E, T>
className?string

Merged with the part's classes.

AttributeType
data-orientationstring

Mirrors the orientation prop.