# Accordion URL: https://ark-ui.com/docs/components/accordion Source: https://raw.githubusercontent.com/chakra-ui/ark/refs/heads/main/website/src/content/pages/components/accordion.mdx A collapsible component for displaying content in a vertical stack. --- ## Anatomy ```tsx ``` ## Examples ### Default Value Set the `defaultValue` prop to specify which item should be expanded by default. **Example: basic** ```ripple import { Accordion } from 'ark-ripple/accordion'; import { ChevronDown } from 'lucide-ripple'; import styles from 'styles/accordion.module.css'; export component Basic() { for (const item of items; key item.value) { {item.title}
{item.content}
}
} const items = [ { value: 'ark-ui', title: 'What is Ark UI?', content: 'A headless component library for building accessible web apps.', }, { value: 'getting-started', title: 'How to get started?', content: 'Install the package and import the components you need.', }, { value: 'maintainers', title: 'Who maintains this project?', content: 'Ark UI is maintained by the Chakra UI team.', }, ]; ``` ### Controlled Use the `value` and `onValueChange` props to control the expanded items. **Example: controlled** ```ripple import { Accordion } from 'ark-ripple/accordion'; import { track } from 'ripple'; import { ChevronDown } from 'lucide-ripple'; import styles from 'styles/accordion.module.css'; export component Controlled() { let value = track([]); { @value = details.value; }} > for (const item of items; key item.value) { {item.title}
{item.content}
}
} const items = [ { value: 'ark-ui', title: 'What is Ark UI?', content: 'A headless component library for building accessible web apps.', }, { value: 'getting-started', title: 'How to get started?', content: 'Install the package and import the components you need.', }, { value: 'maintainers', title: 'Who maintains this project?', content: 'Ark UI is maintained by the Chakra UI team.', }, ]; ``` ### Root Provider An alternative way to control the accordion is to use the `RootProvider` component and the `useAccordion` hook. This way you can access the state and methods from outside the component. **Example: root-provider** ```ripple import { Accordion } from 'ark-ripple/accordion'; import { useAccordion } from 'ark-ripple/accordion'; import { ChevronDown } from 'lucide-ripple'; import styles from 'styles/accordion.module.css'; export component RootProvider() { const accordion = useAccordion({ multiple: true, defaultValue: ['ark-ui'] });
{'Value: '} {JSON.stringify(@accordion.value)} for (const item of items; key item.value) { {item.title}
{item.content}
}
} const items = [ { value: 'ark-ui', title: 'What is Ark UI?', content: 'A headless component library for building accessible web apps.', }, { value: 'getting-started', title: 'How to get started?', content: 'Install the package and import the components you need.', }, { value: 'maintainers', title: 'Who maintains this project?', content: 'Ark UI is maintained by the Chakra UI team.', }, ]; ``` ### Collapsible Use the `collapsible` prop to allow the user to collapse all panels. **Example: collapsible** ```ripple import { Accordion } from 'ark-ripple/accordion'; import { ChevronDown } from 'lucide-ripple'; import styles from 'styles/accordion.module.css'; export component Collapsible() { for (const item of items; key item.value) { {item.title}
{item.content}
}
} const items = [ { value: 'ark-ui', title: 'What is Ark UI?', content: 'A headless component library for building accessible web apps.', }, { value: 'getting-started', title: 'How to get started?', content: 'Install the package and import the components you need.', }, { value: 'maintainers', title: 'Who maintains this project?', content: 'Ark UI is maintained by the Chakra UI team.', }, ]; ``` ### Multiple Use the `multiple` prop to allow multiple panels to be expanded simultaneously. **Example: multiple** ```ripple import { Accordion } from 'ark-ripple/accordion'; import { ChevronDown } from 'lucide-ripple'; import styles from 'styles/accordion.module.css'; export component Multiple() { for (const item of items; key item.value) { {item.title}
{item.content}
}
} const items = [ { value: 'ark-ui', title: 'What is Ark UI?', content: 'A headless component library for building accessible web apps.', }, { value: 'getting-started', title: 'How to get started?', content: 'Install the package and import the components you need.', }, { value: 'maintainers', title: 'Who maintains this project?', content: 'Ark UI is maintained by the Chakra UI team.', }, ]; ``` ### Horizontal By default, the Accordion is oriented vertically. Use the `orientation` prop to switch to a horizontal layout. **Example: horizontal** ```ripple import { Accordion } from 'ark-ripple/accordion'; import styles from 'styles/accordion.module.css'; export component Horizontal() { for (const item of items; key item.value) { {item.title}
{item.content}
}
} const items = [ { value: 'ark-ui', title: 'What is Ark UI?', content: 'A headless component library for building accessible web apps.', }, { value: 'getting-started', title: 'How to get started?', content: 'Install the package and import the components you need.', }, { value: 'maintainers', title: 'Who maintains this project?', content: 'Ark UI is maintained by the Chakra UI team.', }, ]; ``` ### Lazy Mount Use the `lazyMount` prop to defer rendering of accordion content until the item is expanded. Combine with `unmountOnExit` to unmount content when collapsed, freeing up resources. **Example: lazy-mount** ```ripple import { Accordion } from 'ark-ripple/accordion'; import { ChevronDown } from 'lucide-ripple'; import styles from 'styles/accordion.module.css'; export component LazyMount() { for (const item of items; key item.value) { {item.title}
{item.content}
}
} const items = [ { value: 'ark-ui', title: 'What is Ark UI?', content: 'A headless component library for building accessible web apps.', }, { value: 'getting-started', title: 'How to get started?', content: 'Install the package and import the components you need.', }, { value: 'maintainers', title: 'Who maintains this project?', content: 'Ark UI is maintained by the Chakra UI team.', }, ]; ``` ### Context Use `Accordion.Context` or `useAccordionContext` to access the accordion state. **Example: context** ```ripple import { Accordion } from 'ark-ripple/accordion'; import { ChevronDown } from 'lucide-ripple'; import styles from 'styles/accordion.module.css'; export component Context() { component children({ context }) {
{'context.value: '} {JSON.stringify(@context.value)}
{'context.focusedValue: '} {@context.focusedValue || 'null'}
}
for (const item of items; key item.value) { {item.title}
{item.content}
}
} const items = [ { value: 'ark-ui', title: 'What is Ark UI?', content: 'A headless component library for building accessible web apps.', }, { value: 'getting-started', title: 'How to get started?', content: 'Install the package and import the components you need.', }, { value: 'maintainers', title: 'Who maintains this project?', content: 'Ark UI is maintained by the Chakra UI team.', }, ]; ``` ### Item State Use `Accordion.ItemContext` or `useAccordionItemContext` to access the state of an accordion item. **Example: item-context** ```ripple import { Accordion } from 'ark-ripple/accordion'; import { ChevronDown } from 'lucide-ripple'; import styles from 'styles/accordion.module.css'; export component ItemContext() { for (const item of items; key item.value) { {item.title} component children({ context }) { if (@context.expanded) { {'Expanded'} } if (@context.focused) { {'Focused'} } }
{item.content}
}
} const items = [ { value: 'ark-ui', title: 'What is Ark UI?', content: 'A headless component library for building accessible web apps.', }, { value: 'getting-started', title: 'How to get started?', content: 'Install the package and import the components you need.', }, { value: 'maintainers', title: 'Who maintains this project?', content: 'Ark UI is maintained by the Chakra UI team.', }, ]; ``` ## Guides ### Content Animation Use the `--height` and/or `--width` CSS variables to animate the size of the content when it expands or closes: ```css @keyframes slideDown { from { opacity: 0.01; height: 0; } to { opacity: 1; height: var(--height); } } @keyframes slideUp { from { opacity: 1; height: var(--height); } to { opacity: 0.01; height: 0; } } [data-scope='accordion'][data-part='item-content'][data-state='open'] { animation: slideDown 250ms ease-in-out; } [data-scope='accordion'][data-part='item-content'][data-state='closed'] { animation: slideUp 200ms ease-in-out; } ``` ## API Reference ### Props **Component API Reference** **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `collapsible` | `boolean` | No | Whether an accordion item can be closed after it has been expanded. | | `defaultValue` | `string[]` | No | The initial value of the expanded accordion items. Use when you don't need to control the value of the accordion. | | `disabled` | `boolean` | No | Whether the accordion items are disabled | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string item: (value: string) => string itemContent: (value: string) => string itemTrigger: (value: string) => string }>` | No | The ids of the elements in the accordion. Useful for composition. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `multiple` | `boolean` | No | Whether multiple accordion items can be expanded at the same time. | | `onFocusChange` | `(details: FocusChangeDetails) => void` | No | The callback fired when the focused accordion item changes. | | `onValueChange` | `(details: ValueChangeDetails) => void` | No | The callback fired when the state of expanded/collapsed accordion items changes. | | `orientation` | `'horizontal' | 'vertical'` | No | The orientation of the accordion items. | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | | `value` | `string[]` | No | The controlled value of the expanded accordion items. | **Root Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | accordion | | `[data-part]` | root | | `[data-orientation]` | The orientation of the accordion | **ItemContent Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemContent Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | accordion | | `[data-part]` | item-content | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-focus]` | Present when focused | | `[data-orientation]` | The orientation of the item | **ItemIndicator Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemIndicator Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | accordion | | `[data-part]` | item-indicator | | `[data-state]` | "open" | "closed" | | `[data-disabled]` | Present when disabled | | `[data-focus]` | Present when focused | | `[data-orientation]` | The orientation of the item | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `string` | Yes | The value of the accordion item. | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `disabled` | `boolean` | No | Whether the accordion item is disabled. | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | accordion | | `[data-part]` | item | | `[data-state]` | "open" | "closed" | | `[data-focus]` | Present when focused | | `[data-disabled]` | Present when disabled | | `[data-orientation]` | The orientation of the item | **ItemTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **ItemTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | accordion | | `[data-part]` | item-trigger | | `[data-controls]` | | | `[data-orientation]` | The orientation of the item | | `[data-state]` | "open" | "closed" | **RootProvider Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `value` | `UseAccordionReturn` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `lazyMount` | `boolean` | No | Whether to enable lazy mounting | | `unmountOnExit` | `boolean` | No | Whether to unmount on exit. | ### Context **API:** | Property | Type | Description | |----------|------|-------------| | `focusedValue` | `string` | The value of the focused accordion item. | | `value` | `string[]` | The value of the accordion | | `setValue` | `(value: string[]) => void` | Sets the value of the accordion | | `getItemState` | `(props: ItemProps) => ItemState` | Returns the state of an accordion item. | ## Accessibility This component complies with the [Accordion WAI-ARIA design pattern](https://www.w3.org/WAI/ARIA/apg/patterns/accordion/). ### Keyboard Support