Accordion
A collapsible component for displaying content in a vertical stack.
A collapsible component for displaying content in a vertical stack.
import { Accordion } from '@ark-ui/react'
import { ChevronDownIcon } from './icons'
const Basic = () => {
  return (
    <Accordion.Root defaultValue={['React']}>
      {['React', 'Solid', 'Vue'].map((item, id) => (
        <Accordion.Item key={id} value={item}>
          <Accordion.ItemTrigger>
            What is {item}?
            <Accordion.ItemIndicator>
              <ChevronDownIcon />
            </Accordion.ItemIndicator>
          </Accordion.ItemTrigger>
          <Accordion.ItemContent>
            {item} is a JavaScript library for building user interfaces.
          </Accordion.ItemContent>
        </Accordion.Item>
      ))}
    </Accordion.Root>
  )
}
import { Accordion } from '@ark-ui/solid'
import { Index } from 'solid-js'
import { ChevronDownIcon } from './icons'
const Basic = () => {
  return (
    <Accordion.Root value={['React']}>
      <Index each={['React', 'Solid', 'Vue']}>
        {(item) => (
          <Accordion.Item value={item()}>
            <Accordion.ItemTrigger>
              What is {item()}?
              <Accordion.ItemIndicator>
                <ChevronDownIcon />
              </Accordion.ItemIndicator>
            </Accordion.ItemTrigger>
            <Accordion.ItemContent>
              {item()} is a JavaScript library for building user interfaces.
            </Accordion.ItemContent>
          </Accordion.Item>
        )}
      </Index>
    </Accordion.Root>
  )
}
<script setup lang="ts">
import { ref } from 'vue'
import { Accordion } from '@ark-ui/vue'
import { ChevronDownIcon } from './icons'
const items = ref(['React', 'Solid', 'Vue'])
const value = ref(['React'])
</script>
<template>
  <Accordion.Root>
    <Accordion.Item v-for="item in items" :key="item" :value="item">
      <Accordion.ItemTrigger>
        What is {{ item }}?
        <Accordion.ItemIndicator><ChevronDownIcon /></Accordion.ItemIndicator>
      </Accordion.ItemTrigger>
      <Accordion.ItemContent
        >{{ item }} is a JavaScript library for building user interfaces.</Accordion.ItemContent
      >
    </Accordion.Item>
  </Accordion.Root>
</template>
Understanding the Accordion’s anatomy is crucial for proper setup:
Each component part is marked with a
data-partattribute for easy DOM identification.
To create a collapsible Accordion where all panels can be closed simultaneously,
utilize the collapsible prop:
import { Accordion } from '@ark-ui/react'
import { ChevronDownIcon } from './icons'
const Collapsible = () => {
  return (
    <Accordion.Root defaultValue={['React']} collapsible>
      {['React', 'Solid', 'Vue'].map((item, id) => (
        <Accordion.Item key={id} value={item}>
          <Accordion.ItemTrigger>
            {item}
            <Accordion.ItemIndicator>
              <ChevronDownIcon />
            </Accordion.ItemIndicator>
          </Accordion.ItemTrigger>
          <Accordion.ItemContent>
            {item} is a JavaScript library for building user interfaces.
          </Accordion.ItemContent>
        </Accordion.Item>
      ))}
    </Accordion.Root>
  )
}
import { Accordion } from '@ark-ui/solid'
import { Index } from 'solid-js'
import { ChevronDownIcon } from './icons'
const Collapsible = () => {
  return (
    <Accordion.Root value={['React']} collapsible>
      <Index each={['React', 'Solid', 'Vue']}>
        {(item) => (
          <Accordion.Item value={item()}>
            <Accordion.ItemTrigger>
              What is {item()}?
              <Accordion.ItemIndicator>
                <ChevronDownIcon />
              </Accordion.ItemIndicator>
            </Accordion.ItemTrigger>
            <Accordion.ItemContent>
              {item()} is a JavaScript library for building user interfaces.
            </Accordion.ItemContent>
          </Accordion.Item>
        )}
      </Index>
    </Accordion.Root>
  )
}
<script setup lang="ts">
import { ref } from 'vue'
import { Accordion } from '@ark-ui/vue'
import { ChevronDownIcon } from './icons'
const items = ref(['React', 'Solid', 'Vue'])
const value = ref(['React'])
</script>
<template>
  <Accordion.Root collapsible>
    <Accordion.Item v-for="item in items" :key="item" :value="item">
      <Accordion.ItemTrigger>
        What is {{ item }}?
        <Accordion.ItemIndicator><ChevronDownIcon /></Accordion.ItemIndicator>
      </Accordion.ItemTrigger>
      <Accordion.ItemContent
        >{{ item }} is a JavaScript library for building user interfaces.</Accordion.ItemContent
      >
    </Accordion.Item>
  </Accordion.Root>
</template>
For an Accordion that allows keeping multiple panels open, apply the multiple
prop:
import { Accordion } from '@ark-ui/react'
import { ChevronDownIcon } from './icons'
const Multiple = () => {
  return (
    <Accordion.Root defaultValue={['React']} multiple>
      {['React', 'Solid', 'Vue'].map((item, id) => (
        <Accordion.Item key={id} value={item}>
          <Accordion.ItemTrigger>
            {item}
            <Accordion.ItemIndicator>
              <ChevronDownIcon />
            </Accordion.ItemIndicator>
          </Accordion.ItemTrigger>
          <Accordion.ItemContent>
            {item} is a JavaScript library for building user interfaces.
          </Accordion.ItemContent>
        </Accordion.Item>
      ))}
    </Accordion.Root>
  )
}
import { Accordion } from '@ark-ui/solid'
import { Index } from 'solid-js'
import { ChevronDownIcon } from './icons'
const Multiple = () => {
  return (
    <Accordion.Root value={['React']} multiple>
      <Index each={['React', 'Solid', 'Vue']}>
        {(item) => (
          <Accordion.Item value={item()}>
            <Accordion.ItemTrigger>
              What is {item()}?
              <Accordion.ItemIndicator>
                <ChevronDownIcon />
              </Accordion.ItemIndicator>
            </Accordion.ItemTrigger>
            <Accordion.ItemContent>
              {item()} is a JavaScript library for building user interfaces.
            </Accordion.ItemContent>
          </Accordion.Item>
        )}
      </Index>
    </Accordion.Root>
  )
}
<script setup lang="ts">
import { ref } from 'vue'
import { Accordion } from '@ark-ui/vue'
import { ChevronDownIcon } from './icons'
const items = ref(['React', 'Solid', 'Vue'])
const value = ref(['React'])
</script>
<template>
  <Accordion.Root multiple>
    <Accordion.Item v-for="item in items" :key="item" :value="item">
      <Accordion.ItemTrigger>
        What is {{ item }}?
        <Accordion.ItemIndicator><ChevronDownIcon /></Accordion.ItemIndicator>
      </Accordion.ItemTrigger>
      <Accordion.ItemContent
        >{{ item }} is a JavaScript library for building user interfaces.</Accordion.ItemContent
      >
    </Accordion.Item>
  </Accordion.Root>
</template>
For advanced control, access the Accordion API using a function as a child component:
import { Accordion } from '@ark-ui/react'
const RenderProp = () => {
  const items = ['panel-1', 'panel-2', 'panel-3']
  return (
    <Accordion.Root>
      {items.map((item, id) => (
        <Accordion.Item key={id} value={item}>
          {(api) => (
            <>
              <Accordion.ItemTrigger>{api.isOpen ? 'Close' : 'Open'}</Accordion.ItemTrigger>
              <Accordion.ItemContent>{item} content</Accordion.ItemContent>
            </>
          )}
        </Accordion.Item>
      ))}
    </Accordion.Root>
  )
}
import { Accordion } from '@ark-ui/solid'
import { Index } from 'solid-js'
const RenderProp = () => {
  const items = ['panel-1', 'panel-2', 'panel-3']
  return (
    <Accordion.Root>
      <Index each={items}>
        {(item) => (
          <Accordion.Item value={item()}>
            {(api) => (
              <>
                <Accordion.ItemTrigger>{api().isOpen ? 'Close' : 'Open'}</Accordion.ItemTrigger>
                <Accordion.ItemContent>{item()} content</Accordion.ItemContent>
              </>
            )}
          </Accordion.Item>
        )}
      </Index>
    </Accordion.Root>
  )
}
<script setup lang="ts">
import { ref } from 'vue'
import { Accordion } from '@ark-ui/vue'
import { ChevronDownIcon } from './icons'
const items = ref(['React', 'Solid', 'Vue'])
const value = ref(['React'])
</script>
<template>
  <Accordion.Root>
    <Accordion.Item v-for="item in items" :key="item" :value="item" v-slot="{ isOpen }">
      <Accordion.ItemTrigger>{{ isOpen ? 'Close' : 'Open' }}</Accordion.ItemTrigger>
      <Accordion.ItemContent>{{ item }} content</Accordion.ItemContent>
    </Accordion.Item>
  </Accordion.Root>
</template>
To manage the Accordion’s state, use the value prop and update it with the
onValueChange event:
import { Accordion } from '@ark-ui/react'
import { useState } from 'react'
const Controlled = () => {
  const items = ['panel-1', 'panel-2', 'panel-3']
  const [value, setValue] = useState<string[]>([])
  return (
    <Accordion.Root value={value} onValueChange={(details) => setValue(details.value)}>
      {items.map((item, id) => (
        <Accordion.Item key={id} value={item}>
          <Accordion.ItemTrigger>{item} trigger</Accordion.ItemTrigger>
          <Accordion.ItemContent>{item} content</Accordion.ItemContent>
        </Accordion.Item>
      ))}
    </Accordion.Root>
  )
}
import { Accordion } from '@ark-ui/solid'
import { Index, createSignal } from 'solid-js'
const Controlled = () => {
  const [value, setValue] = createSignal<string[]>([])
  const items = ['panel-1', 'panel-2', 'panel-3']
  return (
    <Accordion.Root value={value()} onValueChange={(details) => setValue(details.value)}>
      <Index each={items}>
        {(item) => (
          <Accordion.Item value={item()}>
            <Accordion.ItemTrigger>{item()} trigger</Accordion.ItemTrigger>
            <Accordion.ItemContent>{item()} content</Accordion.ItemContent>
          </Accordion.Item>
        )}
      </Index>
    </Accordion.Root>
  )
}
<script setup lang="ts">
import { ref } from 'vue'
import { Accordion } from '@ark-ui/vue'
import { ChevronDownIcon } from './icons'
const items = ref(['React', 'Solid', 'Vue'])
const value = ref(['React'])
</script>
<template>
  <Accordion.Root v-model="value">
    <Accordion.Item v-for="item in items" :key="item" :value="item">
      <Accordion.ItemTrigger>{{ item }} trigger</Accordion.ItemTrigger>
      <Accordion.ItemContent>{{ item }} content</Accordion.ItemContent>
    </Accordion.Item>
  </Accordion.Root>
</template>
Set the Accordion’s orientation to vertical with the orientation prop:
import { Accordion } from '@ark-ui/react'
const Vertical = () => {
  const items = ['panel-1', 'panel-2', 'panel-3']
  return (
    <Accordion.Root orientation="vertical">
      {items.map((item, id) => (
        <Accordion.Item key={id} value={item} disabled={item === 'panel-2'}>
          <Accordion.ItemTrigger>{item} trigger</Accordion.ItemTrigger>
          <Accordion.ItemContent>{item} content</Accordion.ItemContent>
        </Accordion.Item>
      ))}
    </Accordion.Root>
  )
}
import { Accordion } from '@ark-ui/solid'
import { Index } from 'solid-js'
const Vertical = () => {
  const items = ['panel-1', 'panel-2', 'panel-3']
  return (
    <Accordion.Root orientation="vertical">
      <Index each={items}>
        {(item) => (
          <Accordion.Item value={item()}>
            <Accordion.ItemTrigger>{item()} trigger</Accordion.ItemTrigger>
            <Accordion.ItemContent>{item()} content</Accordion.ItemContent>
          </Accordion.Item>
        )}
      </Index>
    </Accordion.Root>
  )
}
<script setup lang="ts">
import { ref } from 'vue'
import { Accordion } from '@ark-ui/vue'
import { ChevronDownIcon } from './icons'
const items = ref(['React', 'Solid', 'Vue'])
const value = ref(['React'])
</script>
<template>
  <Accordion.Root orientation="vertical">
    <Accordion.Item v-for="item in items" :key="item" :value="item">
      <Accordion.ItemTrigger>{{ item }} trigger</Accordion.ItemTrigger>
      <Accordion.ItemContent>{{ item }} content</Accordion.ItemContent>
    </Accordion.Item>
  </Accordion.Root>
</template>
Disable any Accordion Item using the disabled prop:
import { Accordion } from '@ark-ui/react'
const Disabled = () => {
  const items = ['panel-1', 'panel-2', 'panel-3']
  return (
    <Accordion.Root>
      {items.map((item, id) => (
        <Accordion.Item key={id} value={item} disabled={item === 'panel-2'}>
          <Accordion.ItemTrigger>{item} trigger</Accordion.ItemTrigger>
          <Accordion.ItemContent>{item} content</Accordion.ItemContent>
        </Accordion.Item>
      ))}
    </Accordion.Root>
  )
}
import { Accordion } from '@ark-ui/solid'
import { Index } from 'solid-js'
const Disabled = () => {
  const items = ['panel-1', 'panel-2', 'panel-3']
  return (
    <Accordion.Root>
      <Index each={items}>
        {(item) => (
          <Accordion.Item value={item()} disabled={item() === 'panel-2'}>
            <Accordion.ItemTrigger>{item()} trigger</Accordion.ItemTrigger>
            <Accordion.ItemContent>{item()} content</Accordion.ItemContent>
          </Accordion.Item>
        )}
      </Index>
    </Accordion.Root>
  )
}
<script setup lang="ts">
import { ref } from 'vue'
import { Accordion } from '@ark-ui/vue'
import { ChevronDownIcon } from './icons'
const items = ref(['React', 'Solid', 'Vue'])
const value = ref(['React'])
</script>
<template>
  <Accordion.Root>
    <Accordion.Item v-for="item in items" :key="item" :value="item" :disabled="item === 'Solid'">
      <Accordion.ItemTrigger>{{ item }} trigger</Accordion.ItemTrigger>
      <Accordion.ItemContent>{{ item }} content</Accordion.ItemContent>
    </Accordion.Item>
  </Accordion.Root>
</template>
Explore our detailed API Reference for further customization:
| Prop | Type | Default | 
|---|---|---|
| value | string | |
| asChildRender as a different element type. | boolean | |
| disabled | boolean | 
| Prop | Type | Default | 
|---|---|---|
| asChildRender as a different element type. | boolean | |
| collapsibleWhether an accordion item can be collapsed after it has been opened. | boolean | false | 
| defaultValueThe initial value of the accordion. | string[] | |
| dirThe document's text/writing direction. | 'ltr' | 'rtl' | "ltr" | 
| disabledWhether the accordion items are disabled | boolean | |
| getRootNodeA root node to correctly resolve document in custom environments. E.x.: Iframes, Electron. | () => Node | ShadowRoot | Document | |
| idThe unique identifier of the machine. | string | |
| idsThe ids of the elements in the accordion. Useful for composition. | Partial<{
  root: string
  item(value: string): string
  content(value: string): string
  trigger(value: string): string
}> | |
| lazyMountWhether to enable lazy mounting | boolean | false | 
| multipleWhether multple accordion items can be open at the same time. | boolean | false | 
| onExitCompleteFunction called when the animation ends in the closed state. | () => void | |
| onFocusChangeThe callback fired when the focused accordion item changes. | (details: FocusChangeDetails) => void | |
| onValueChangeThe callback fired when the state of opened/closed accordion items changes. | (details: ValueChangeDetails) => void | |
| orientationThe orientation of the accordion items. | 'horizontal' | 'vertical' | |
| presentWhether the node is present (controlled by the user) | boolean | |
| unmountOnExitWhether to unmount on exit. | boolean | false | 
| valueThe `id` of the accordion item that is currently being opened. | string[] | 
| Prop | Type | Default | 
|---|---|---|
| asChildRender as a different element type. | boolean | 
| Prop | Type | Default | 
|---|---|---|
| asChildRender as a different element type. | boolean | 
| Prop | Type | Default | 
|---|---|---|
| asChildRender as a different element type. | boolean |