When to Use
Use Accordion when a page has several related sections and readers should open
only the sections they need. It works well for settings, product details, and
frequently asked questions. Use Collapsible instead when there is only one
independent section to show or hide.
Features
The behavior Atom owns before your product adds appearance.
- Supports single and multiple expanded items.
- Supports controlled and uncontrolled state.
- Supports horizontal and vertical arrow-key navigation.
- Exposes orientation consistently on every behavioral part.
- Links each trigger to its content with stable ARIA IDs.
- Supports mounted and unmounted closed content.
- Supports RTL-aware horizontal navigation through
dir and
Direction.Provider.
- Supports
asChild and render on every part.
Import
Anatomy
API Reference
Root
Owns the expanded-item state and keyboard-navigation settings for every item.
It renders a div by default and accepts native div props.
asChild | boolean | false |
render | RenderProp | - |
type | "single" | "multiple" | "single" |
value | string | string[] | - |
defaultValue | string | string[] | "" or [], based on type |
onValueChange | (value: string | string[]) => void | - |
collapsible | boolean | true |
disabled | boolean | false |
orientation | "vertical" | "horizontal" | "vertical" |
dir | "ltr" | "rtl" | Direction.Provider |
[data-slot] | "accordion-root" |
[data-orientation] | "vertical" | "horizontal" |
[data-disabled] | Present when the whole accordion is disabled |
Item
Provides one item value and its open, closed, and disabled state to the nested
Header, Trigger, and Content. It renders a div by default.
asChild | boolean | false |
render | RenderProp | - |
value | string | Required |
disabled | boolean | false |
[data-slot] | "accordion-item" |
[data-state] | "open" | "closed" |
[data-disabled] | Present when the item or Root is disabled |
[data-orientation] | "vertical" | "horizontal" |
Renders the semantic heading that contains a Trigger. Choose an as level that
fits the surrounding page heading structure.
asChild | boolean | false |
render | RenderProp | - |
as | "h1" | "h2" | "h3" | "h4" | "h5" | "h6" | "h3" |
[data-slot] | "accordion-header" |
[data-orientation] | "vertical" | "horizontal" |
Trigger
Renders the control that toggles its Item and moves focus between sibling
triggers. It renders a native button by default and supplies button semantics
to custom renders.
asChild | boolean | false |
render | RenderProp | - |
role | "button" for non-native renders |
aria-expanded | "true" when open, otherwise "false" |
aria-controls | ID of the associated Content |
aria-disabled | "true" when disabled or open and not collapsible |
[data-slot] | "accordion-trigger" |
[data-state] | "open" | "closed" |
[data-disabled] | Present when the Item or Root is disabled |
[data-locked-open] | Present when an open single Item cannot collapse |
[data-orientation] | "vertical" | "horizontal" |
Content
Renders the region controlled and labelled by its Trigger. Closed content
unmounts by default; keepMounted keeps it available in the DOM and hides it
after any closing animation finishes.
asChild | boolean | false |
render | RenderProp | - |
keepMounted | boolean | false |
landmark | boolean | true |
role | "region" |
aria-labelledby | ID of the associated Trigger |
[data-slot] | "accordion-content" |
[data-state] | "open" | "closed" |
[data-initial-open] | Present while initially open Content has not transitioned |
[data-orientation] | "vertical" | "horizontal" |
--content-height | Measured content height for consumer-owned animation |
--content-width | Measured content width for consumer-owned animation |
The measured height and width stay synchronized while Content is mounted when
responsive reflow, fonts, images, or other intrinsic content changes alter the
panel size. Set landmark={false} when a large or multiple-open Accordion
would otherwise create excessive region landmarks.
Examples
Single Accordion
Multiple Expanded Sections
Accessibility
Accordion follows the
WAI-ARIA Accordion pattern.
Triggers are buttons with aria-expanded and aria-controls. Each Content is
a labelled region, and each Header should use a heading level that fits the
page. Keep the Trigger as the only interactive control inside its Header.
When a single non-collapsible Item is open, its Trigger remains focusable and
uses aria-disabled="true" to announce that it cannot close. Horizontal
orientation is an Atom extension over the same heading/button/panel semantics;
the current APG documents the vertically stacked presentation.
Space / Enter | Toggles the focused Trigger. |
ArrowDown | Moves to the next Trigger when orientation is vertical. |
ArrowUp | Moves to the previous Trigger when orientation is vertical. |
ArrowRight | Moves next in horizontal LTR, or previous in horizontal RTL. |
ArrowLeft | Moves previous in horizontal LTR, or next in horizontal RTL. |
Home | Moves to the first enabled Trigger. |
End | Moves to the last enabled Trigger. |
Changelog
0.22.6 - 2026-08-10
- Added public Agent Knowledge for grouped disclosure selection, complete
anatomy, heading and landmark policy, state ownership, and validation.
0.20.9
- Expose initially open Content with
data-initial-open until its first state
transition so styled layers can suppress page-load entrance motion.
0.20.8
- Measure newly opened Content before its first painted animation frame so
height and width transitions begin with stable intrinsic dimensions.
0.14.0
- Propagate
orientation to Item, Header, Trigger, and Content and publish
live --content-width alongside --content-height.
- Mark the open Trigger in non-collapsible single mode with
aria-disabled="true" and data-locked-open while keeping it focusable.
- Add
Accordion.Content landmark={false} to omit optional region landmarks.
0.13.1
- Keep each Content
--content-height synchronized while mounted when
responsive reflow, fonts, images, or other intrinsic resizing changes the
panel height.
0.2.0
- Fixed horizontal arrow-key navigation so Accordion mirrors ArrowLeft and
ArrowRight under
Direction.Provider dir="rtl" or Accordion.Root dir="rtl".
0.1.0