---
id: "packages/active-ui/accordion"
title: "Accordion"
description: "A list of headings whose content opens under them, one at a time or several, such as questions and answers."
url: "/packages/active-ui/accordion"
locale: "en"
revision: "048d4ac00eceac08"
---

# Accordion

An accordion stacks headings whose content opens under them. Use it to shorten a long page of
parallel sections the reader scans by heading, such as frequently asked questions. Content that
most readers need should not hide behind it. For a single section that shows and hides, use a
[collapsible](/packages/active-ui/collapsible).

**Example: One answer at a time, and several**

Client: Runs entirely in your browser. Source: `examples/ui/accordion.tsx`.

```tsx
// apps/docs/examples/ui/accordion.tsx
'use client';

import {
  Accordion,
  AccordionContent,
  AccordionItem,
  AccordionTrigger,
} from '@workspace/active-ui/components/primitives/accordion';

const QUESTIONS = [
  {
    value: 'when',
    question: 'When are contributions collected?',
    answer: 'On the first working day of each month, for that month.',
  },
  {
    value: 'change',
    question: 'Can a participant change the investment profile?',
    answer: 'Yes, once a quarter, in the participant portal.',
  },
  {
    value: 'leave',
    question: 'What happens when a participant leaves?',
    answer:
      'The accrued capital stays in the scheme until retirement, unless it is transferred to a new employer.',
  },
];

/**
 * Questions whose answers open under them: one at a time by default, or
 * several with `multiple`. The second list opens on the first answer.
 */
export default function AccordionExample() {
  return (
    <div className="grid w-full max-w-lg gap-10">
      <Accordion>
        {QUESTIONS.map((item) => (
          <AccordionItem key={item.value} value={item.value}>
            <AccordionTrigger>{item.question}</AccordionTrigger>
            <AccordionContent>{item.answer}</AccordionContent>
          </AccordionItem>
        ))}
      </Accordion>
      <Accordion multiple defaultValue={['when']}>
        {QUESTIONS.map((item) => (
          <AccordionItem key={item.value} value={item.value}>
            <AccordionTrigger>{item.question}</AccordionTrigger>
            <AccordionContent>{item.answer}</AccordionContent>
          </AccordionItem>
        ))}
      </Accordion>
    </div>
  );
}
```

## Usage

```tsx
import {
  Accordion,
  AccordionContent,
  AccordionItem,
  AccordionTrigger,
} from '@workspace/active-ui/components/primitives/accordion';

<Accordion>
  <AccordionItem value="when">
    <AccordionTrigger>When are contributions collected?</AccordionTrigger>
    <AccordionContent>On the first working day of each month.</AccordionContent>
  </AccordionItem>
</Accordion>;
```

## Anatomy

- `Accordion`: the open items. `value` and `onValueChange` (controlled) or `defaultValue`, an
  array of item values. `multiple` (default `false`) lets several items be open at once.
  `hiddenUntilFound` keeps closed content searchable with the browser's find, which opens the item
  that holds the match.
- `AccordionItem`: one section, by its `value`; `disabled` keeps it closed.
- `AccordionTrigger`: the heading button, inside a heading element, with a chevron that turns.
- `AccordionContent`: the panel, animated open and closed.

## What your application provides

- The headings and the content.
- The heading level: the trigger sits in an `<h3>` (Base UI's header part). For another level,
  compose a trigger of your own from Base UI's `Accordion.Header` and `Accordion.Trigger`.

## Accessibility and keyboard

- Each trigger is a button with `aria-expanded`, controlling its panel.
- `Tab` moves between the triggers, and `Enter` or `Space` opens and closes one. The arrow keys do
  not move between triggers: Base UI dropped that navigation.

## API

| Prop | Type | Required | Description |
| --- | --- | --- | --- |
| `defaultValue` | `AccordionValue<any>` | no | The uncontrolled value of the item(s) that should be initially expanded.  To render a controlled accordion, use the `value` prop instead. |
| `disabled` | `boolean` | no | Whether the component should ignore user interaction. |
| `hiddenUntilFound` | `boolean` | no | Allows the browser's built-in page search to find and expand the panel contents.  Overrides the `keepMounted` prop and uses `hidden="until-found"` to hide the element without removing it from the DOM. |
| `keepMounted` | `boolean` | no | Whether to keep the element in the DOM while the panel is closed. This prop is ignored when `hiddenUntilFound` is used. |
| `loopFocus` | `boolean` | no | Deprecated following the [APG guidance update](https://github.com/w3c/aria-practices/pull/3434) to remove roving focus.  This prop no longer affects keyboard focus behavior. |
| `multiple` | `boolean` | no | Whether multiple items can be open at the same time. |
| `onValueChange` | `((value: AccordionValue<any>, eventDetails: AccordionRootChangeEventDetails) => void)` | no | Event handler called when an accordion item is expanded or collapsed. Provides the new value as an argument. |
| `orientation` | `Orientation` | no | Deprecated following the [APG guidance update](https://github.com/w3c/aria-practices/pull/3434) to remove roving focus.  This prop no longer affects keyboard focus behavior. |
| `render` | `ComponentRenderFn<HTMLProps, AccordionRoot.State<any>> \| ReactElement<unknown, string \| JSXElementConstructor<any>>` | no | Allows you to replace the component's HTML element with a different tag, or compose it with another component.  Accepts a `ReactElement` or a function that returns the element to render. |
| `value` | `AccordionValue<any>` | no | The controlled value of the item(s) that should be expanded.  To render an uncontrolled accordion, use the `defaultValue` prop instead. |

### Other parts

**AccordionItem**

| Prop | Type | Required | Description |
| --- | --- | --- | --- |
| `disabled` | `boolean` | no | Whether the component should ignore user interaction. |
| `onOpenChange` | `((open: boolean, eventDetails: AccordionItem.ChangeEventDetails) => void)` | no | Event handler called when the panel is opened or closed. |
| `render` | `ComponentRenderFn<HTMLProps, AccordionItemState> \| ReactElement<unknown, string \| JSXElementConstructor<any>>` | no | Allows you to replace the component's HTML element with a different tag, or compose it with another component.  Accepts a `ReactElement` or a function that returns the element to render. |
| `value` | `any` | no | A unique value that identifies this accordion item. If no value is provided, a unique ID will be generated automatically. Use when controlling the accordion programmatically, or to set an initial open state. |

**AccordionTrigger**

| Prop | Type | Required | Description |
| --- | --- | --- | --- |
| `nativeButton` | `boolean` | no | Whether the component renders a native `<button>` element when replacing it via the `render` prop. Set to `false` if the rendered element is not a button (for example, `<div>`). |
| `render` | `ComponentRenderFn<HTMLProps, AccordionTriggerState> \| ReactElement<unknown, string \| JSXElementConstructor<any>>` | no | Allows you to replace the component's HTML element with a different tag, or compose it with another component.  Accepts a `ReactElement` or a function that returns the element to render. |

**AccordionContent**

| Prop | Type | Required | Description |
| --- | --- | --- | --- |
| `hiddenUntilFound` | `boolean` | no | Allows the browser's built-in page search to find and expand the panel contents.  Overrides the `keepMounted` prop and uses `hidden="until-found"` to hide the element without removing it from the DOM. |
| `keepMounted` | `boolean` | no | Whether to keep the element in the DOM while the panel is closed. This prop is ignored when `hiddenUntilFound` is used. |
| `render` | `ComponentRenderFn<HTMLProps, AccordionPanelState> \| ReactElement<unknown, string \| JSXElementConstructor<any>>` | no | Allows you to replace the component's HTML element with a different tag, or compose it with another component.  Accepts a `ReactElement` or a function that returns the element to render. |

> [!NOTE]
> **Based on shadcn/ui**
>
> This page adapts the Accordion documentation of shadcn/ui (MIT licence) to
> this package; see [Third-party notices](/third-party-notices).
