Accordion
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.
$ npm add reka-uiAnatomy
Import all parts and piece them together.
<script setup>
import { AccordionContent, AccordionHeader, AccordionItem, AccordionRoot, AccordionTrigger } from 'reka-ui'
</script>
<template>
  <AccordionRoot>
    <AccordionItem>
      <AccordionHeader>
        <AccordionTrigger />
      </AccordionHeader>
      <AccordionContent />
    </AccordionItem>
  </AccordionRoot>
</template>API Reference
Root
Contains all the parts of an Accordion
| Prop | Default | Type | 
|---|---|---|
as | 'div' | AsTag | ComponentThe element or component this component should render as. Can be overwritten by   | 
asChild | booleanChange the default rendered element for the one passed as a child, merging their props and behavior. Read our Composition guide for more details.  | |
collapsible | false | booleanWhen type is "single", allows closing content when clicking trigger for an open item. When type is "multiple", this prop has no effect.  | 
defaultValue | string | string[]The default active value of the item(s). Use when you do not need to control the state of the item(s).  | |
dir | 'ltr' | 'rtl'The reading direction of the accordion when applicable. If omitted, assumes LTR (left-to-right) reading mode.  | |
disabled | false | booleanWhen   | 
modelValue | string | string[]The controlled value of the active item(s). Use this when you need to control the state of the items. Can be binded with   | |
orientation | 'vertical' | 'vertical' | 'horizontal'The orientation of the accordion.  | 
type | 'single' | 'multiple'Determines whether a "single" or "multiple" items can be selected at a time. This prop will overwrite the inferred type from   | |
unmountOnHide | true | booleanWhen   | 
| Emit | Payload | 
|---|---|
update:modelValue | [value: string | string[]]Event handler called when the expanded state of an item changes  | 
| Slots (default) | Payload | 
|---|---|
modelValue | AcceptableValue | AcceptableValue[] | undefinedCurrent active value  | 
| Data Attribute | Value | 
|---|---|
[data-orientation] | "vertical" | "horizontal" | 
Item
Contains all the parts of a collapsible section.
| Prop | Default | Type | 
|---|---|---|
as | 'div' | AsTag | ComponentThe element or component this component should render as. Can be overwritten by   | 
asChild | booleanChange the default rendered element for the one passed as a child, merging their props and behavior. Read our Composition guide for more details.  | |
disabled | booleanWhether or not an accordion item is disabled from user interaction.
When   | |
unmountOnHide | booleanWhen   | |
value* | stringA string value for the accordion item. All items within an accordion should use a unique value.  | 
| Slots (default) | Payload | 
|---|---|
open | booleanCurrent open state  | 
| Data Attribute | Value | 
|---|---|
[data-state] | "open" | "closed" | 
[data-disabled] | Present when disabled | 
[data-orientation] | "vertical" | "horizontal" | 
Header
Wraps an AccordionTrigger. Use the asChild prop to update it to the appropriate heading level for your page.
| Prop | Default | Type | 
|---|---|---|
as | 'h3' | AsTag | ComponentThe element or component this component should render as. Can be overwritten by   | 
asChild | booleanChange the default rendered element for the one passed as a child, merging their props and behavior. Read our Composition guide for more details.  | 
| Data Attribute | Value | 
|---|---|
[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 AccordionHeader.
| Prop | Default | Type | 
|---|---|---|
as | 'div' | AsTag | ComponentThe element or component this component should render as. Can be overwritten by   | 
asChild | booleanChange the default rendered element for the one passed as a child, merging their props and behavior. Read our Composition guide for more details.  | 
| Data Attribute | Value | 
|---|---|
[data-state] | "open" | "closed" | 
[data-disabled] | Present when disabled | 
[data-orientation] | "vertical" | "horizontal" | 
Content
Contains the collapsible content for an item.
| Prop | Default | Type | 
|---|---|---|
as | 'div' | AsTag | ComponentThe element or component this component should render as. Can be overwritten by   | 
asChild | booleanChange the default rendered element for the one passed as a child, merging their props and behavior. Read our Composition guide for more details.  | |
forceMount | booleanUsed to force mounting when more control is needed. Useful when controlling animation with Vue animation libraries.  | 
| Data Attribute | Value | 
|---|---|
[data-state] | "open" | "closed" | 
[data-disabled] | Present when disabled | 
[data-orientation] | "vertical" | "horizontal" | 
| CSS Variable | Description | 
|---|---|
--reka-accordion-content-width | The width of the content when it opens/closes  | 
--reka-accordion-content-height | The height of the content when it opens/closes  | 
Examples
Expanded by default
Use the defaultValue prop to define the open item by default.
<template>
  <AccordionRoot
    type="single"
    default-value="item-2"
  >
    <AccordionItem value="item-1">
      …
    </AccordionItem>
    <AccordionItem value="item-2">
      …
    </AccordionItem>
  </AccordionRoot>
</template>Allow collapsing all items
Use the collapsible prop to allow all items to close.
<template>
  <AccordionRoot
    type="single"
    collapsible
  >
    <AccordionItem value="item-1">
      …
    </AccordionItem>
    <AccordionItem value="item-2">
      …
    </AccordionItem>
  </AccordionRoot>
</template>Multiple items open at the same time
Set the type prop to multiple to enable opening multiple items at once.
<template>
  <AccordionRoot type="multiple">
    <AccordionItem value="item-1">
      …
    </AccordionItem>
    <AccordionItem value="item-2">
      …
    </AccordionItem>
  </AccordionRoot>
</template>Rotated icon when open
You can add extra decorative elements, such as chevrons, and rotate it when the item is open.
// index.vue
<script setup>
import { AccordionContent, AccordionHeader, AccordionItem, AccordionRoot, AccordionTrigger } from 'reka-ui'
import { Icon } from '@iconify/vue'
import './styles.css'
</script>
<template>
  <AccordionRoot type="single">
    <AccordionItem value="item-1">
      <AccordionHeader>
        <AccordionTrigger class="AccordionTrigger">
          <span>Trigger text</span>
          <Icon
            icon="radix-icons:chevron-down"
            class="AccordionChevron"
          />
        </AccordionTrigger>
      </AccordionHeader>
      <AccordionContent>…</AccordionContent>
    </AccordionItem>
  </AccordionRoot>
</template>/* styles.css */
.AccordionChevron {
  transition: transform 300ms;
}
.AccordionTrigger[data-state="open"] > .AccordionChevron {
  transform: rotate(180deg);
}Horizontal orientation
Use the orientation prop to create a horizontal Accordion
<template>
  <AccordionRoot orientation="horizontal">
    <AccordionItem value="item-1">
      …
    </AccordionItem>
    <AccordionItem value="item-2">
      …
    </AccordionItem>
  </AccordionRoot>
</template>Animating content size
Use the --reka-accordion-content-width and/or --reka-accordion-content-height CSS variables to animate the size of the content when it opens/closes:
// index.vue
<script setup>
import { AccordionContent, AccordionHeader, AccordionItem, AccordionRoot, AccordionTrigger } from 'reka-ui'
import './styles.css'
</script>
<template>
  <AccordionRoot type="single">
    <AccordionItem value="item-1">
      <AccordionHeader>…</AccordionHeader>
      <AccordionContent class="AccordionContent">
        …
      </AccordionContent>
    </AccordionItem>
  </AccordionRoot>
</template>/* 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(--reka-accordion-content-height);
  }
}
@keyframes slideUp {
  from {
    height: var(--reka-accordion-content-height);
  }
  to {
    height: 0;
  }
}Render content even when closed
By default hidden content will be removed, use :unmountOnHide="false" to keep the content always available.
This will also allow browser to search the hidden text, and open the accordion.
<template>
  <AccordionRoot :unmount-on-hide="false">
    <AccordionItem value="item-1">
      …
    </AccordionItem>
    <AccordionItem value="item-2">
      …
    </AccordionItem>
  </AccordionRoot>
</template>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 start AccordionTrigger. | 
End  | When focus is on an  AccordionTrigger, moves focus to the last AccordionTrigger. | 
