Source: https://monarchui.dev/components/accordion/

Components · Data display

# Accordion

Stacked sections whose bodies expand and collapse under heading triggers.

@rookcom/monarch-react

Component

## Single, collapsible

## Usage examples

The example at the top of the page is the only one for this component.

## Purpose

Shows a list of headings and reveals the body of one (or several) on demand, so long reference content stays scannable. FAQ in the marketing entry is built on it.

### Use when

- Reference content where people look for one item: FAQs, policy sections, help topics.
- Optional detail under a summary, such as advanced settings explained in prose.

### Avoid when

- Switching between views of the same object: use Tabs.
- Content everyone must read: show it; hiding it costs a click.
- Form steps: use a stepper or separate pages.

## Design principles

- Each trigger is a real heading (h3 by default, `headingAs` to change), so items appear in the page outline.
- Quiet chrome: hairline dividers, medium-weight labels, one chevron that rotates; no boxes or fills.
- Built on Radix Accordion for the keyboard model and ARIA wiring.

## API reference

```tsx
import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from '@rookcom/monarch-react';
```

| Export | Kind | Rendering | Root class |
| --- | --- | --- | --- |
| `Accordion` | component | client | `.mn-accordion` |
| `AccordionContent` | component | client | `.mn-accordion` |
| `AccordionItem` | component | client | `.mn-accordion` |
| `AccordionTrigger` | component | client | `.mn-accordion` |

Accordion is Radix `Accordion.Root`: `type="single"` (with `collapsible`) or `type="multiple"`, controlled via `value`/`onValueChange` or uncontrolled via `defaultValue`.

AccordionTrigger renders `Header` (as the chosen heading element) and `Trigger` together.

AccordionContent wraps children in `.mn-accordion__body`, which caps line length at `--mn-width-narrow`.

Generated from the TypeScript declarations of `packages/react/src/components/data-display/accordion`.

## Properties

### `Accordion`

Stacked disclosure sections. Enter/Space toggle, arrow keys move between headers, Home/End jump to the first and last. Built on Radix Accordion.

| Prop | Type | Description |
| --- | --- | --- |
| `asChild` | `boolean` |  |
| `children` | `ReactNode` |  |
| `className` | `string` |  |
| `disabled` | `boolean` | Whether or not an accordion is disabled from user interaction. |
| `id` | `string` |  |

### `AccordionContent`

| Prop | Type | Description |
| --- | --- | --- |
| `asChild` | `boolean` |  |
| `children` | `ReactNode` |  |
| `className` | `string` |  |
| `id` | `string` |  |

### `AccordionItem`

| Prop | Type | Description |
| --- | --- | --- |
| `asChild` | `boolean` |  |
| `children` | `ReactNode` |  |
| `className` | `string` |  |
| `disabled` | `boolean` | Whether or not an accordion item is disabled from user interaction. |
| `id` | `string` |  |

### `AccordionTrigger`

| Prop | Type | Description |
| --- | --- | --- |
| `asChild` | `boolean` |  |
| `children` | `ReactNode` |  |
| `className` | `string` |  |
| `disabled` | `boolean` |  |
| `headingAs` | `HeadingLevel` | Heading element wrapping the trigger, so the item appears in the page outline. |
| `id` | `string` |  |

## Variants

| Prop | Values | Description |
| --- | --- | --- |
| `type` | `'single'``'multiple'` | One open item at a time, or any number. |
| `headingAs (AccordionTrigger)` | `'h2'``'h3'``'h4'` | Heading level of each trigger. Pick the level below the surrounding heading. |

## States

| State | Exposed as | Behaviour |
| --- | --- | --- |
| Open | `data-state="open"` | Body shown; chevron rotated 180°. |
| Closed | `data-state="closed"` | Body removed. |
| Disabled | `data-disabled` | Set `disabled` on an item or the root; the trigger cannot toggle. |

## Interaction behaviour

- Click, Enter or Space on a trigger toggles its item.
- With `type="single"`, opening one item closes the other; `collapsible` lets the open item close.
- The body animates its height over `--mn-duration-base`; reduced motion removes the animation.

## Keyboard support

| Keys | Action |
| --- | --- |
| Tab | Moves to the next trigger or into an open body. |
| Enter / Space | Toggles the focused item. |
| Arrow Down / Arrow Up | Moves focus to the next / previous trigger. |
| Home / End | Moves focus to the first / last trigger. |

## Accessibility

Role

button (inside a heading)

Accessible name

The trigger text.

- Triggers expose `aria-expanded` and `aria-controls`; bodies are `role="region"` labelled by their trigger.
- The chevron is decorative (`aria-hidden`).
- The focus ring uses `--mn-color-focus-ring`, which inverse marketing sections remap.
- Trigger rows are at least 56px tall, beyond the 24px target size (WCAG 2.5.8).

## Responsive behaviour

- Full width of its container at every size; labels wrap, and the chevron stays top-aligned to the first line.

## Theme support

- Borders use `--mn-color-border-default`, text `--mn-color-text-default` and `-muted`; light, dark and more-contrast apply automatically.
- Open/close animation is disabled under `prefers-reduced-motion: reduce` by the foundation stylesheet.

## Do and don't

### Do

- Write triggers as the question or topic people scan for.
- Set `headingAs` so the outline has no skipped levels.

### Don't

- Do not nest accordions.
- Do not hide the only copy of critical information (prices, legal terms) in a closed item.

## Related components

- [Tabs](https://monarchui.dev/components/tabs/): Switch between peer views instead of expanding in place.
- [Marketing sections](https://monarchui.dev/components/marketing-section-blocks/): FAQ is Accordion with marketing defaults (one open, heading per question).

## Dependencies

| Kind | Depends on |
| --- | --- |
| npm packages | `@radix-ui/react-accordion``react` |
| Monarch components | None |

## Testing coverage

- Triggers sit inside a heading of the requested level.
- Enter toggles; Arrow keys, Home and End move between triggers; single mode closes the other item.
- No axe violations; renders on the server.

| Check | Covered |
| --- | --- |
| Axe in jsdom | Yes |
| Server rendering | Yes |
| Browser suites | Visual and three-browser axe: /__marketing (FAQ) |

Tests: `packages/react/src/components/data-display/accordion`

## All example code

### Single, collapsible

```tsx
import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from '@rookcom/monarch-react';

<Accordion type="single" collapsible defaultValue="billing">
  <AccordionItem value="billing">
    <AccordionTrigger>When am I billed?</AccordionTrigger>
    <AccordionContent>
      On the first of each month, for the seats in use.
    </AccordionContent>
  </AccordionItem>
  <AccordionItem value="cancel">
    <AccordionTrigger>Can I cancel at any time?</AccordionTrigger>
    <AccordionContent>
      Yes. Access continues to the end of the paid period.
    </AccordionContent>
  </AccordionItem>
</Accordion>
```
