---
title: Accordion
description: "A collapsible content panel that organizes information into expandable sections."
type: component
section: Components
order: 1
---

A collapsible content panel that organizes information into expandable sections.

---

## Import

```jsx
import { Accordion } from "asheeui";
```

---

## Usage

```tsx
import { Accordion } from "asheeui";

export default function Basic() {
	const items = [
		{ id: "1", title: "Section 1", content: "Content for section 1" },
		{ id: "2", title: "Section 2", content: "Content for section 2" },
	];

	return <Accordion items={items} />;
}
```

---

## Examples

### Variant

<ComponentPreview path="accordion/variant" />


### Size

<ComponentPreview path="accordion/size" />


### Radius

<ComponentPreview path="accordion/radius" />


### Allow multiple open

<ComponentPreview path="accordion/multiple" />


### Controlled

<ComponentPreview path="accordion/controlled" />


### With icons

<ComponentPreview path="accordion/icons" />


### Custom expand icon

<ComponentPreview path="accordion/expand-icon" />


### Disabled item

<ComponentPreview path="accordion/disabled" />


### Without animation

<ComponentPreview path="accordion/no-animation" />


## Props

| Prop | Type | Default | Description |
|---|---|---|---|
| `items` | `AccordionItem[]` | `[]` | Array of accordion sections to render |
| `variant` | `"bordered" \| "separated" \| "ghost" \| "flush"` | `"separated"`* | Visual style of accordion container |
| `size` | `"sm" \| "md" \| "lg"` | `"md"` | Size scale for header and content |
| `radius` | `"none" \| "xs" \| "sm" \| "md" \| "lg" \| "xl" \| "full"` | `"md"`* | Corner rounding for container |
| `allowMultiple` | `boolean` | `false` | Allows multiple sections to be open simultaneously |
| `defaultValue` | `string \| string[]` | None | Initial open item(s) for uncontrolled usage |
| `value` | `string \| string[]` | None | Controlled open item(s) |
| `onValueChange` | `(value: string[]) => void` | None | Callback when open item(s) change |
| `expandIcon` | `ReactNode` | `ChevronDownIcon` | Custom expand/collapse indicator |
| `disableAnimation` | `boolean` | `false` | Disables expand/collapse animations |
| `itemClassName` | `string` | None | Extra classes applied to each item container |
| `headerClassName` | `string` | None | Extra classes applied to each header button |
| `contentClassName` | `string` | None | Extra classes applied to each content panel |
| `className` | `string` | None | Extra classes, merged with internal styles |

\* *Falls back through Global Configuration if not set. See below.*

### AccordionItem

| Prop | Type | Description |
|---|---|---|
| `id` | `string` | Unique identifier for the item |
| `title` | `ReactNode` | Header content |
| `content` | `ReactNode` | Expandable content |
| `subtitle` | `ReactNode` | Optional subtext shown below title |
| `icon` | `ReactNode` | Optional icon shown before title |
| `disabled` | `boolean` | Prevents item from being toggled |

---

## Global Configuration

Accordion reads defaults from four places, in this order of precedence:

1. **Instance prop**: set directly on `<Accordion />`
2. **Component config**: `components.accordion` in your `ashee.config`
3. **Theme default**: `defaultVariant` / `defaultRadius` in your `ashee.config`
4. **Built-in fallback**: component's internal default values

### Component config

```ts
// ashee.config.ts
import type { ExternalConfig } from "asheeui";

export const config: ExternalConfig = {
  components: {
    accordion: {
      variant: "bordered",
      size: "md",
      radius: "md",
      allowMultiple: false,
    },
  },
};
```

### Built-in fallbacks

```ts
{
  size: "md",
  variant: "separated",
  radius: "md",
  allowMultiple: false,
}
```

---

## Accessibility

- Renders a native `<button>` element for each header with proper `type="button"`
- Uses `aria-expanded` and `aria-controls` to indicate state and associate headers with content panels
- `disabled` items set `disabled` attribute on the trigger button
- Implements `focus-visible` ring for keyboard navigation
- Uses `pointer-events-none` on closed content panels to prevent focus trapping
- Active item state exposed via `data-state="open"`/`"closed"` on content panels

---

## Notes

- **Item IDs**: Each item should have a unique `id`. If not provided, it will use the array index, which may cause issues with reordering.
- **Controlled vs Uncontrolled**: Use `value`/`onValueChange` for controlled usage, or `defaultValue` for uncontrolled.
- **Animation**: Uses CSS Grid for smooth height transitions. Can be disabled with `disableAnimation`.
- **Radius Application**: `ghost` and `flush` variants don't apply radius to the container, while `separated` and `ghost` apply radius to individual items. This is by design for visual consistency.
