# Accordion

> A stack of headed sections where one or several open at a time, with a collapse that animates without measuring, arrow-key navigation between headers and labelled regions for assistive tech.

- Package: `fancy-ui-svelte` (Svelte 5 + Tailwind CSS v4)
- Category: Navigation
- Tags: accordion, disclosure, faq, collapse, compound, navigation
- Dependencies: collapsible
- Types: `AccordionProps`, `AccordionItemProps`, `AccordionTriggerProps`, `AccordionContentProps`, `AccordionOrientation`, `AccordionType`, `AccordionValue`, `AccordionContext`, `AccordionItemContext`
- Docs: https://fancy-ui.rama.app/docs/components/accordion
- Source: https://github.com/RamaHerbin/fancy-ui/tree/main/src/lib/fancy-ui/accordion

## Import

```svelte
<script lang="ts">
  import { Accordion } from 'fancy-ui-svelte';
</script>
```

Setup (once per project): `npm install fancy-ui-svelte`, then add `@import "fancy-ui-svelte/tailwind.css";` after `@import "tailwindcss";` in your main CSS file. Full guide: https://fancy-ui.rama.app/llms.txt

React: `import { Accordion } from 'fancy-ui-react';` (`class` becomes `className`, snippets become `ReactNode`, DOM callbacks are camel-cased; exact names on https://fancy-ui.rama.app/docs/components/react/accordion.md).

## Props

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `type` | `"single" \| "multiple"` | `"single"` | "single" keeps one item open at a time, "multiple" lets any number be open. |
| `value` | `string \| string[]` | — | The open item, bindable. A string for type="single" ("" when none is open), a string array for type="multiple". |
| `onValueChange` | `(value: string \| string[]) => void` | — | Called with the new value each time an item toggles. |
| `collapsible` | `boolean` | `false` | With type="single", lets the open item be closed again. Without it one item stays open once opened. |
| `disabled` | `boolean` | `false` | Disables every item. |
| `orientation` | `"horizontal" \| "vertical"` | `"vertical"` | The axis the items stack on, and which arrow-key pair moves focus. |
| `class` | `string` | — | Additional CSS classes, merged onto the root. |
| `ref` | `HTMLDivElement \| null` | `null` | Bindable reference to the root element. |
| `AccordionItem.value` (required) | `string` | — | This item's value: what the accordion's value holds while it is open. |
| `AccordionItem.disabled` | `boolean` | `false` | Disables just this item; its trigger is skipped by the arrow keys. |
| `AccordionItem.class` | `string` | — | Additional CSS classes, merged onto the item. |
| `AccordionItem.ref` | `HTMLDivElement \| null` | `null` | Bindable reference to the item element. |
| `AccordionTrigger.headingLevel` | `1 \| 2 \| 3 \| 4 \| 5 \| 6` | `3` | The level of the heading that wraps the trigger button. |
| `AccordionTrigger.disabled` | `boolean` | `false` | Disables just this trigger, on top of its item and the accordion. |
| `AccordionTrigger.class` | `string` | — | Additional CSS classes, merged onto the trigger button. |
| `AccordionTrigger.ref` | `HTMLButtonElement \| null` | `null` | Bindable reference to the trigger's button element. |
| `AccordionContent.forceMount` | `boolean` | `true` | Keeps the children mounted while the item is closed. Pass false to unmount them once the collapse has finished. |
| `AccordionContent.class` | `string` | — | Additional CSS classes, merged onto the inner body so padding collapses with the panel. |
| `AccordionContent.ref` | `HTMLDivElement \| null` | `null` | Bindable reference to the region element that animates. |

## Snippets

| Snippet | Description |
| --- | --- |
| `children` | The AccordionItems. |
| `AccordionItem.children` | An AccordionTrigger and an AccordionContent. |
| `AccordionTrigger.children` | The trigger's label. |
| `AccordionContent.children` | The item's content. |

## Examples

### Basic Usage

One item open at a time, and the open item can be closed again.

```svelte
<script lang="ts">
	import {
		Accordion,
		AccordionItem,
		AccordionTrigger,
		AccordionContent,
	} from "fancy-ui-svelte";

	let value = $state("shipping");
</script>

<Accordion type="single" collapsible bind:value class="w-full max-w-md">
	<AccordionItem value="shipping">
		<AccordionTrigger>How long does shipping take?</AccordionTrigger>
		<AccordionContent>Orders leave the warehouse within two working days.</AccordionContent>
	</AccordionItem>
	<AccordionItem value="returns">
		<AccordionTrigger>Can I return an item?</AccordionTrigger>
		<AccordionContent>
			Yes, within 30 days, as long as it is unused and in its original packaging.
		</AccordionContent>
	</AccordionItem>
	<AccordionItem value="support">
		<AccordionTrigger>How do I reach support?</AccordionTrigger>
		<AccordionContent>Write to us any time and we reply within one working day.</AccordionContent>
	</AccordionItem>
</Accordion>
```

### Multiple

Any number of items open at once, with one item disabled.

```svelte
<script lang="ts">
	import {
		Accordion,
		AccordionItem,
		AccordionTrigger,
		AccordionContent,
	} from "fancy-ui-svelte";

	let value = $state<string[]>(["profile", "security"]);
</script>

<Accordion type="multiple" bind:value class="w-full max-w-md">
	<AccordionItem value="profile">
		<AccordionTrigger>Profile</AccordionTrigger>
		<AccordionContent>Your name, avatar and the address people can find you at.</AccordionContent>
	</AccordionItem>
	<AccordionItem value="notifications">
		<AccordionTrigger>Notifications</AccordionTrigger>
		<AccordionContent>Choose which events send an email and which stay in the app.</AccordionContent
		>
	</AccordionItem>
	<AccordionItem value="security">
		<AccordionTrigger>Security</AccordionTrigger>
		<AccordionContent>Password, two-factor authentication and signed-in devices.</AccordionContent>
	</AccordionItem>
	<AccordionItem value="billing" disabled>
		<AccordionTrigger>Billing</AccordionTrigger>
		<AccordionContent>Only workspace owners can see this section.</AccordionContent>
	</AccordionItem>
</Accordion>
```

### Controlled

The open item driven from outside through a bound value.

```svelte
<script lang="ts">
	import {
		Accordion,
		AccordionItem,
		AccordionTrigger,
		AccordionContent,
	} from "fancy-ui-svelte";
	import { Button } from "fancy-ui-svelte";

	let value = $state("");
</script>

<div class="flex w-full max-w-md flex-col gap-4">
	<div class="flex flex-wrap items-center gap-2">
		<Button size="sm" variant="outline" onclick={() => (value = "one")}>Open step one</Button>
		<Button size="sm" variant="outline" onclick={() => (value = "two")}>Open step two</Button>
		<Button size="sm" variant="ghost" onclick={() => (value = "")}>Close all</Button>
		<span class="text-muted-foreground text-sm">Open: {value || "none"}</span>
	</div>

	<Accordion type="single" collapsible bind:value>
		<AccordionItem value="one">
			<AccordionTrigger>Step one: install</AccordionTrigger>
			<AccordionContent>Add the package to your project with your package manager.</AccordionContent
			>
		</AccordionItem>
		<AccordionItem value="two">
			<AccordionTrigger>Step two: import</AccordionTrigger>
			<AccordionContent>Import the components you need and render them.</AccordionContent>
		</AccordionItem>
	</Accordion>
</div>
```
