A vertically stacked set of interactive headings that each reveal an associated section of content.
import React from 'react';import * as Accordion from '@radix-ui/react-accordion';import classNames from 'classnames';import { ChevronDownIcon } from '@radix-ui/react-icons';import './styles.css';const AccordionDemo = () => (<Accordion.Root className="AccordionRoot" type="single" defaultValue="item-1" collapsible><Accordion.Item className="AccordionItem" value="item-1"><AccordionTrigger>Is it accessible?</AccordionTrigger><AccordionContent>Yes. It adheres to the WAI-ARIA design pattern.</AccordionContent></Accordion.Item><Accordion.Item className="AccordionItem" value="item-2"><AccordionTrigger>Is it unstyled?</AccordionTrigger><AccordionContent>Yes. It's unstyled by default, giving you freedom over the look and feel.</AccordionContent></Accordion.Item><Accordion.Item className="AccordionItem" value="item-3"><AccordionTrigger>Can it be animated?</AccordionTrigger><Accordion.Content className="AccordionContent"><div className="AccordionContentText">Yes! You can animate the Accordion with CSS or JavaScript.</div></Accordion.Content></Accordion.Item></Accordion.Root>);const AccordionTrigger = React.forwardRef(({ children, className, ...props }, forwardedRef) => (<Accordion.Header className="AccordionHeader"><Accordion.Trigger className={classNames('AccordionTrigger', className)} {...props} ref={forwardedRef} >{children}<ChevronDownIcon className="AccordionChevron" aria-hidden /></Accordion.Trigger></Accordion.Header>));const AccordionContent = React.forwardRef(({ children, className, ...props }, forwardedRef) => (<Accordion.Content className={classNames('AccordionContent', className)} {...props} ref={forwardedRef} ><div className="AccordionContentText">{children}</div></Accordion.Content>));export default AccordionDemo;
Full keyboard navigation.
Supports horizontal/vertical orientation.
Supports Right to Left direction.
Can expand one or multiple items.
Can be controlled or uncontrolled.
Install the component from your command line.
npm install @radix-ui/react-accordion
Import all parts and piece them together.
import * as Accordion from '@radix-ui/react-accordion';
export default () => (
<Accordion.Root>
<Accordion.Item>
<Accordion.Header>
<Accordion.Trigger />
</Accordion.Header>
<Accordion.Content />
</Accordion.Item>
</Accordion.Root>
);
Contains all the parts of an accordion.
Prop | Type | Default |
---|---|---|
asChild | boolean | false |
type* | enum | |
value | string | |
defaultValue | string | |
onValueChange | function | |
value | string[] | [] |
defaultValue | string[] | [] |
onValueChange | function | |
collapsible | boolean | false |
disabled | boolean | false |
dir | enum | "ltr" |
orientation | enum | "vertical" |
Data attribute | Values |
---|---|
[data-orientation] | "vertical" | "horizontal" |
Contains all the parts of a collapsible section.
Prop | Type | Default |
---|---|---|
asChild | boolean | false |
disabled | boolean | false |
value* | string |
Data attribute | Values |
---|---|
[data-state] | "open" | "closed" |
[data-disabled] | Present when disabled |
[data-orientation] | "vertical" | "horizontal" |
Wraps an Accordion.Trigger
. Use the asChild
prop to update it to the appropriate heading level for your page.
Prop | Type | Default |
---|---|---|
asChild | boolean | false |
Data attribute | Values |
---|---|
[data-state] | "open" | "closed" |
[data-disabled] | Present when disabled |
[data-orientation] | "vertical" | "horizontal" |
Toggles the collapsed state of its associated item. It should be nested inside of an Accordion.Header
.
Prop | Type | Default |
---|---|---|
asChild | boolean | false |
Data attribute | Values |
---|---|
[data-state] | "open" | "closed" |
[data-disabled] | Present when disabled |
[data-orientation] | "vertical" | "horizontal" |
Contains the collapsible content for an item.
Prop | Type | Default |
---|---|---|
asChild | boolean | false |
forceMount | boolean |
Data attribute | Values |
---|---|
[data-state] | "open" | "closed" |
[data-disabled] | Present when disabled |
[data-orientation] | "vertical" | "horizontal" |
CSS Variable | Description |
---|---|
--radix-accordion-content-width | The width of the content when it opens/closes |
--radix-accordion-content-height | The height of the content when it opens/closes |
Use the defaultValue
prop to define the open item by default.
<Accordion.Root type="single" defaultValue="item-2">
<Accordion.Item value="item-1">…</Accordion.Item>
<Accordion.Item value="item-2">…</Accordion.Item>
</Accordion.Root>
Use the collapsible
prop to allow all items to close.
<Accordion.Root type="single" collapsible>
<Accordion.Item value="item-1">…</Accordion.Item>
<Accordion.Item value="item-2">…</Accordion.Item>
</Accordion.Root>
Set the type
prop to multiple
to enable opening multiple items at once.
<Accordion.Root type="multiple">
<Accordion.Item value="item-1">…</Accordion.Item>
<Accordion.Item value="item-2">…</Accordion.Item>
</Accordion.Root>
You can add extra decorative elements, such as chevrons, and rotate it when the item is open.
// index.jsx
import * as Accordion from '@radix-ui/react-accordion';
import { ChevronDownIcon } from '@radix-ui/react-icons';
import './styles.css';
export default () => (
<Accordion.Root type="single">
<Accordion.Item value="item-1">
<Accordion.Header>
<Accordion.Trigger className="AccordionTrigger">
<span>Trigger text</span>
<ChevronDownIcon className="AccordionChevron" aria-hidden />
</Accordion.Trigger>
</Accordion.Header>
<Accordion.Content>…</Accordion.Content>
</Accordion.Item>
</Accordion.Root>
);
/* styles.css */
.AccordionChevron {
transition: transform 300ms;
}
.AccordionTrigger[data-state='open'] > .AccordionChevron {
transform: rotate(180deg);
}
Use the orientation
prop to create a horizontal accordion.
<Accordion.Root orientation="horizontal">
<Accordion.Item value="item-1">…</Accordion.Item>
<Accordion.Item value="item-2">…</Accordion.Item>
</Accordion.Root>
Use the --radix-accordion-content-width
and/or --radix-accordion-content-height
CSS variables to animate the size of the content when it opens/closes:
// index.jsx
import * as Accordion from '@radix-ui/react-accordion';
import './styles.css';
export default () => (
<Accordion.Root type="single">
<Accordion.Item value="item-1">
<Accordion.Header>…</Accordion.Header>
<Accordion.Content className="AccordionContent">…</Accordion.Content>
</Accordion.Item>
</Accordion.Root>
);
/* styles.css */
.AccordionContent {
overflow: hidden;
}
.AccordionContent[data-state='open'] {
animation: slideDown 300ms ease-out;
}
.AccordionContent[data-state='closed'] {
animation: slideUp 300ms ease-out;
}
@keyframes slideDown {
from {
height: 0;
}
to {
height: var(--radix-accordion-content-height);
}
}
@keyframes slideUp {
from {
height: var(--radix-accordion-content-height);
}
to {
height: 0;
}
}
Adheres to the Accordion WAI-ARIA design pattern.
Key | Description |
---|---|
Space | When focus is on an Accordion.Trigger of a collapsed section, expands the section. |
Enter | When focus is on an Accordion.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. |
ArrowDown | Moves focus to the next Accordion.Trigger when orientation is vertical . |
ArrowUp | Moves focus to the previous Accordion.Trigger when orientation is vertical . |
ArrowRight | Moves focus to the next Accordion.Trigger when orientation is horizontal . |
ArrowLeft | Moves focus to the previous Accordion.Trigger when orientation is horizontal . |
Home | When focus is on an Accordion.Trigger , moves focus to the first Accordion.Trigger . |
End | When focus is on an Accordion.Trigger , moves focus to the last Accordion.Trigger . |