# 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-vue` (Vue 3.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/vue/src/components/accordion

## Import

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

Setup (once per project): `npm install fancy-ui-vue`, then put these lines in your main CSS file (the stylesheet imports go right after `@import "tailwindcss";`):

```css
@import "tailwindcss";
@import "fancy-ui-vue/tailwind.css";
@import "fancy-ui-vue/styles.css";
```

Full guide: https://fancy-ui.rama.app/llms.txt

The names below are the ones to write in a Vue template; when one differs from the Svelte name, the Svelte name follows in parentheses. Snippets become named slots (`#default` is the default snippet), a prop the Vue port declares as a model is a `v-model:<name>` (except `ref`, exposed via `defineExpose({ ref })`: put a template ref on the component and read `.ref`) and callbacks are listeners (`onclick` is `@click`). Every component sets `inheritAttrs: false`: `class` is a declared prop, merged where the Svelte component applies it (not always the root element), and only when the props table below lists it; other attributes do not fall through unless the package README lists the component as forwarding native attributes. Divergences: https://github.com/RamaHerbin/fancy-ui/tree/main/vue#divergences-from-the-svelte-api

## Props

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `type` | `"single" \| "multiple"` | `"single"` | "single" keeps one item open at a time, "multiple" lets any number be open. |
| `v-model:value` (Svelte `value`) | `string \| string[]` | — | The open item, bindable. A string for type="single" ("" when none is open), a string array for type="multiple". |
| `@value-change` (Svelte `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. |

## Slots

| Slot | Description |
| --- | --- |
| `#default` (Svelte `children`) | The AccordionItems. |
| `AccordionItem.#default` (Svelte `AccordionItem.children`) | An AccordionTrigger and an AccordionContent. |
| `AccordionTrigger.#default` (Svelte `AccordionTrigger.children`) | The trigger's label. |
| `AccordionContent.#default` (Svelte `AccordionContent.children`) | The item's content. |

## Example

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

const value = ref<string | string[]>("shipping");
</script>

<template>
	<Accordion v-model:value="value" type="single" collapsible 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>
</template>
```
