shadcn.io is not affiliated with official shadcn/ui
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, Base UI may unmount a closed panel, so a form field in it might not submit.
Installation
Anatomy

Usage
import {
Accordion, AccordionContent, AccordionItem, AccordionTrigger,
} from "@/components/ui/accordion";<Accordion className="w-full max-w-sm" defaultValue={["shipping"]}>
<AccordionItem value="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 value="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 value="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.
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.
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.
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.
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.
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.
FAQ
How do I let only one Accordion item open at a time in React?
One open item is the default: opening an item closes the one that was open. Add multiple to let several items stay open together.
How do I make an Accordion item open by default?
Pass that item's value in defaultValue, as an array: ["item-1"] opens the item whose value is item-1. The Basic demo starts with its first item open.
How do I control which Accordion items are open?
Pass value and update it in onValueChange. The value is an array of the open items' values, so you can open or close items from anywhere, such as a hash in the URL.
Do form fields inside a closed Accordion item still submit?
Not by default: a closed panel is unmounted. Add keepMounted to Accordion or AccordionContent to keep it in the DOM, hidden, so its fields submit with the form.
Is the Base UI 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.
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.
API Reference
Accordion
<div> data-slot="accordion"
value?AccordionValue<Value>
The controlled value of the item(s) that should be expanded.
To render an uncontrolled accordion, use the defaultValue prop instead.
- Type
AccordionValue<Value>
defaultValue?AccordionValue<Value>
The uncontrolled value of the item(s) that should be initially expanded.
To render a controlled accordion, use the value prop instead.
- Type
AccordionValue<Value>
onValueChange?(value: AccordionValue<Value>, eventDetails: AccordionRootChangeEventDetails) → void
Event handler called when an accordion item is expanded or collapsed. Provides the new value as an argument.
- Type
(value: AccordionValue<Value>, eventDetails: AccordionRootChangeEventDetails) → void- Parameters
value– AccordionValue<Value>eventDetails– AccordionRootChangeEventDetails- Returns
void
disabled?boolean
Whether the component should ignore user interaction.
- Default
false
hiddenUntilFound?boolean
Allows the browser's built-in page search to find and expand the panel contents.
Overrides the keepMounted prop and uses hidden="until-found"
to hide the element without removing it from the DOM.
- Default
false
keepMounted?boolean
Whether to keep the element in the DOM while the panel is closed.
This prop is ignored when hiddenUntilFound is used.
- Default
false
loopFocus?boolean
Deprecated following the [APG guidance update](https://github.com/w3c/aria-practices/pull/3434) to remove roving focus. This prop no longer affects keyboard focus behavior. Deprecated.
multiple?boolean
Whether multiple items can be open at the same time.
- Default
false
orientation?"horizontal" | "vertical"
Deprecated following the [APG guidance update](https://github.com/w3c/aria-practices/pull/3434) to remove roving focus. This prop no longer affects keyboard focus behavior. Deprecated.
- Type
"horizontal" | "vertical"- Default
"vertical"
render?ReactElement | ((props: object, state: object) => ReactElement)
Replace the host element or compose it with another component.
- Type
ReactElement | ((props: object, state: object) => ReactElement)
className?string
Merged with the part's classes.
data-orientationstring
Mirrors the orientation prop.
AccordionItem
<div> data-slot="accordion-item"
disabled?boolean
Whether the component should ignore user interaction.
- Default
false
onOpenChange?(open: boolean, eventDetails: AccordionItem.ChangeEventDetails) → void
Event handler called when the panel is opened or closed.
- Type
(open: boolean, eventDetails: AccordionItem.ChangeEventDetails) → void- Parameters
open– booleaneventDetails– AccordionItem.ChangeEventDetails- Returns
void
value?any
A unique value that identifies this accordion item.
If no value is provided, a unique ID will be generated automatically.
Use when controlling the accordion programmatically, or to set an initial
open state.
``tsx
<Accordion.Root value={[a]}>
<Accordion.Item value="a" /> // initially open
<Accordion.Item value="b" /> // initially closed
</Accordion.Root>
``
render?ReactElement | ((props: object, state: object) => ReactElement)
Replace the host element or compose it with another component.
- Type
ReactElement | ((props: object, state: object) => ReactElement)
className?string
Merged with the part's classes.
data-disabled?string
Present when disabled is true.
data-focus?string
Present when focused is true.
data-orientationstring
Mirrors the orientation prop.
data-state"open" | "closed"
"open" or "closed".
- Type
"open" | "closed"
AccordionTrigger
<button> data-slot="accordion-trigger"
nativeButton?boolean
Whether the component renders a native <button> element when replacing it
via the render prop.
Set to false if the rendered element is not a button (for example, <div>).
- Default
true
render?ReactElement | ((props: object, state: object) => ReactElement)
Replace the host element or compose it with another component.
- Type
ReactElement | ((props: object, state: object) => ReactElement)
className?string
Merged with the part's classes.
AccordionContent
<div> data-slot="accordion-content"
hiddenUntilFound?boolean
Allows the browser's built-in page search to find and expand the panel contents.
Overrides the keepMounted prop and uses hidden="until-found"
to hide the element without removing it from the DOM.
- Default
false
keepMounted?boolean
Whether to keep the element in the DOM while the panel is closed.
This prop is ignored when hiddenUntilFound is used.
- Default
false
render?ReactElement | ((props: object, state: object) => ReactElement)
Replace the host element or compose it with another component.
- Type
ReactElement | ((props: object, state: object) => ReactElement)
className?string
Merged with the part's classes.
--accordion-panel-heightstring