Accordion
A vertically stacked set of interactive headings that each reveal an associated section of content.
Features
Full keyboard navigation. Supports horizontal/vertical orientation. Supports Right to Left direction. Can expand one or multiple items. Can be controlled or uncontrolled.
Installation
Install the component from your command line.
ng g @ng-cn/core:c accordionAnatomy
Import all parts and piece them together.
import {
Accordion,
AccordionItem,
AccordionTrigger,
AccordionContent
} from '@/ui/accordion';<Accordion>
<AccordionItem>
<AccordionTrigger />
<AccordionContent />
</AccordionItem>
</Accordion>API Reference
Root
Contains all the parts of an accordion.
| Prop | Type | Default |
|---|---|---|
| type | 'single' | 'multiple' | 'single' |
| Determines whether one or multiple items can be opened at the same time. | ||
| value | string | string[] | — |
| The controlled value of the item(s) to expand. Use with (valueChange). | ||
| defaultValue | string | string[] | — |
| The value of the item(s) to expand when initially rendered. Use when you do not need to control the state. | ||
| collapsible | boolean | false |
| When type is "single", allows closing content when clicking on the open trigger. | ||
| disabled | boolean | false |
| When true, prevents the user from interacting with the accordion. | ||
| class | string | — |
| Additional CSS classes to apply to the accordion root. |
Data Attributes
| Attribute | Values |
|---|---|
| [data-orientation] | "vertical" | "horizontal" |
Item
Contains all the parts of a collapsible section.
| Prop | Type | Default |
|---|---|---|
| value * | string | — |
| A unique value for the item. | ||
| disabled | boolean | false |
| When true, prevents the user from interacting with this item. | ||
| class | string | — |
| Additional CSS classes to apply to the item. |
Data Attributes
| Attribute | Values |
|---|---|
| [data-state] | "open" | "closed" |
| [data-disabled] | Present when disabled |
| [data-orientation] | "vertical" | "horizontal" |
Trigger
Toggles the collapsed state of its associated item. It should be nested inside of an AccordionItem.
| Prop | Type | Default |
|---|---|---|
| class | string | — |
| Additional CSS classes to apply to the trigger. |
Data Attributes
| Attribute | Values |
|---|---|
| [data-state] | "open" | "closed" |
| [data-disabled] | Present when disabled |
| [data-orientation] | "vertical" | "horizontal" |
Content
Contains the collapsible content for an item.
| Prop | Type | Default |
|---|---|---|
| forceMount | boolean | — |
| Used to force mounting when more control is needed. Useful for animation libraries. | ||
| class | string | — |
| Additional CSS classes to apply to the content. |
Data Attributes
| Attribute | Values |
|---|---|
| [data-state] | "open" | "closed" |
| [data-disabled] | Present when disabled |
| [data-orientation] | "vertical" | "horizontal" |
CSS Variables
| Variable | Description |
|---|---|
| --accordion-content-width | The width of the content when it opens/closes |
| --accordion-content-height | The height of the content when it opens/closes |
Examples
Basic
A simple accordion with three items.
<Accordion type="single" collapsible class="w-full max-w-md">
<AccordionItem value="item-1">
<AccordionTrigger>Is it accessible?</AccordionTrigger>
<AccordionContent>
Yes. It adheres to the WAI-ARIA design pattern.
</AccordionContent>
</AccordionItem>
<AccordionItem value="item-2">
<AccordionTrigger>Is it styled?</AccordionTrigger>
<AccordionContent>
Yes. It comes with default styles that match the shadcn/ui aesthetic.
</AccordionContent>
</AccordionItem>
<AccordionItem value="item-3">
<AccordionTrigger>Is it animated?</AccordionTrigger>
<AccordionContent>
Yes. It's animated by default with smooth transitions.
</AccordionContent>
</AccordionItem>
</Accordion>Expanded by default
Use the defaultValue prop to define the open item by default.
<Accordion type="single" defaultValue="item-2" collapsible>
<AccordionItem value="item-1">
<AccordionTrigger>First Item</AccordionTrigger>
<AccordionContent>Content for first item.</AccordionContent>
</AccordionItem>
<AccordionItem value="item-2">
<AccordionTrigger>Second Item (Open by default)</AccordionTrigger>
<AccordionContent>This item is open by default.</AccordionContent>
</AccordionItem>
</Accordion>Allow collapsing all items
Use the collapsible prop to allow all items to close.
<Accordion type="single" collapsible>
<AccordionItem value="item-1">
<AccordionTrigger>Collapsible Item</AccordionTrigger>
<AccordionContent>
Click the trigger again to collapse this item.
</AccordionContent>
</AccordionItem>
</Accordion>Multiple items open at the same time
Set the type prop to "multiple" to enable opening multiple items at once.
<Accordion type="multiple" class="w-full max-w-md">
<AccordionItem value="item-1">
<AccordionTrigger>Section One</AccordionTrigger>
<AccordionContent>
Content for section one. This can be open alongside other sections.
</AccordionContent>
</AccordionItem>
<AccordionItem value="item-2">
<AccordionTrigger>Section Two</AccordionTrigger>
<AccordionContent>
Content for section two. Multiple sections can be expanded.
</AccordionContent>
</AccordionItem>
<AccordionItem value="item-3">
<AccordionTrigger>Section Three</AccordionTrigger>
<AccordionContent>
Content for section three.
</AccordionContent>
</AccordionItem>
</Accordion>Controlled
Use the value input and valueChange output to control the accordion state.
// In your component class:
value = signal<string | undefined>('item-1');
// In your template:
<Accordion
type="single"
[value]="value()"
(valueChange)="value.set($event)"
collapsible
>
<AccordionItem value="item-1">
<AccordionTrigger>Controlled Item 1</AccordionTrigger>
<AccordionContent>Content controlled externally.</AccordionContent>
</AccordionItem>
<AccordionItem value="item-2">
<AccordionTrigger>Controlled Item 2</AccordionTrigger>
<AccordionContent>You can open this from outside.</AccordionContent>
</AccordionItem>
</Accordion>
<Button (click)="value.set('item-2')">Open Item 2</Button>Animating content size
Use the --accordion-content-height CSS variable to animate the size of the content when it opens/closes.
<Accordion type="single" collapsible>
<AccordionItem value="item-1">
<AccordionTrigger>Animated Content</AccordionTrigger>
<AccordionContent class="data-[state=open]:animate-accordion-down data-[state=closed]:animate-accordion-up">
This content animates smoothly using CSS animations
and the height CSS variable.
</AccordionContent>
</AccordionItem>
</Accordion>/* In your tailwind.config.js */
animation: {
'accordion-down': 'accordion-down 0.2s ease-out',
'accordion-up': 'accordion-up 0.2s ease-out',
},
keyframes: {
'accordion-down': {
from: { height: '0' },
to: { height: 'var(--accordion-content-height)' },
},
'accordion-up': {
from: { height: 'var(--accordion-content-height)' },
to: { height: '0' },
},
}Accessibility
Adheres to the Accordion WAI-ARIA design pattern .
Keyboard Interactions
| Key | Description |
|---|---|
| Space | When focus is on an AccordionTrigger of a collapsed section, expands the section. |
| Enter | When focus is on an AccordionTrigger 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 AccordionTrigger when orientation is vertical. |
| ArrowUp | Moves focus to the previous AccordionTrigger when orientation is vertical. |
| ArrowRight | Moves focus to the next AccordionTrigger when orientation is horizontal. |
| ArrowLeft | Moves focus to the previous AccordionTrigger when orientation is horizontal. |
| Home | When focus is on an AccordionTrigger, moves focus to the first AccordionTrigger. |
| End | When focus is on an AccordionTrigger, moves focus to the last AccordionTrigger. |