Accordion

A collapsible component for displaying content in a vertical stack.

Usage

React is a JavaScript library focused on building user interfaces.
import { Accordion } from '@ark-ui/react'
import { ChevronDownIcon } from 'lucide-react'

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>
  )
}

Anatomy

Understanding the Accordion’s anatomy is crucial for proper setup:

Each component part is marked with a data-part attribute for easy DOM identification.

Examples

Collapsible Panels

To create a collapsible Accordion where all panels can be closed simultaneously, utilize the collapsible prop:

React is a JavaScript library for building user interfaces.
import { Accordion } from '@ark-ui/react'
import { ChevronDownIcon } from 'lucide-react'

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>
  )
}

Multiple Panels Open

For an Accordion that allows keeping multiple panels open, apply the multiple prop:

React is a JavaScript library for building user interfaces.
import { Accordion } from '@ark-ui/react'
import { ChevronDownIcon } from 'lucide-react'

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>
  )
}

Accessing the Accordion API

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>
  )
}

Controlled Accordion

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>
  )
}

Changing Orientation

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>
  )
}

Disabling an Accordion Item

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>
  )
}

API Reference

Explore our detailed API Reference for further customization:

Root

PropTypeDefault
asChild
boolean
collapsible
booleanfalse
defaultValue
string[]
dir
'ltr' | 'rtl'"ltr"
disabled
boolean
getRootNode
() => Node | ShadowRoot | Document
id
string
ids
Partial<{ root: string item(value: string): string content(value: string): string trigger(value: string): string }>
lazyMount
booleanfalse
multiple
booleanfalse
onExitComplete
() => void
onFocusChange
(details: FocusChangeDetails) => void
onValueChange
(details: ValueChangeDetails) => void
orientation
'horizontal' | 'vertical'
present
boolean
unmountOnExit
booleanfalse
value
string[]

Item

PropTypeDefault
value
string
asChild
boolean
disabled
boolean

ItemContent

PropTypeDefault
asChild
boolean

ItemTrigger

PropTypeDefault
asChild
boolean

ItemIndicator

PropTypeDefault
asChild
boolean

Previous

Vanilla