# Collapsible

> A single disclosure: a trigger that expands and collapses a region, animated without measuring so an interrupted toggle simply reverses, with the closed content kept in the page.

- Package: `fancy-ui-vue` (Vue 3.5+ + Tailwind CSS v4)
- Category: Navigation
- Tags: collapsible, disclosure, expand, collapse, compound, navigation
- Types: `CollapsibleProps`, `CollapsibleTriggerProps`, `CollapsibleContentProps`, `CollapsibleContext`
- Docs: https://fancy-ui.rama.app/docs/components/collapsible
- Source: https://github.com/RamaHerbin/fancy-ui/tree/main/vue/src/components/collapsible

## Import

```vue
<script setup lang="ts">
import { Collapsible } 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 |
| --- | --- | --- | --- |
| `v-model:open` (Svelte `open`) | `boolean` | `false` | Whether the content is expanded, bindable. |
| `@open-change` (Svelte `onOpenChange`) | `(open: boolean) => void` | — | Called with the new state each time the trigger toggles it. |
| `disabled` | `boolean` | `false` | Makes the trigger inert. A bound open can still be changed from outside. |
| `class` | `string` | — | Additional CSS classes, merged onto the root. |
| `ref` | `HTMLDivElement \| null` | `null` | Bindable reference to the root element. |
| `CollapsibleTrigger.disabled` | `boolean` | `false` | Disables this trigger on top of the root's own disabled. |
| `CollapsibleTrigger.class` | `string` | — | Additional CSS classes, merged onto the trigger button. |
| `CollapsibleTrigger.ref` | `HTMLButtonElement \| null` | `null` | Bindable reference to the trigger's button element. |
| `CollapsibleContent.forceMount` | `boolean` | `true` | Keeps the children mounted while closed (inert and hidden). Pass false to unmount them once the collapse has finished and mount them again on open. |
| `CollapsibleContent.class` | `string` | — | Additional CSS classes, merged onto the inner body so padding collapses with the panel. |
| `CollapsibleContent.ref` | `HTMLDivElement \| null` | `null` | Bindable reference to the region element that animates. |

## Slots

| Slot | Description |
| --- | --- |
| `#default` (Svelte `children`) | A CollapsibleTrigger and a CollapsibleContent. |
| `CollapsibleTrigger.#default` (Svelte `CollapsibleTrigger.children`) | The trigger's content. |
| `CollapsibleContent.#default` (Svelte `CollapsibleContent.children`) | The content. |

## Example

```vue
<script setup lang="ts">
import { ref } from "vue";
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "fancy-ui-vue";

const open = ref(false);
</script>

<template>
	<Collapsible v-model:open="open" class="w-full max-w-sm">
		<div class="flex items-center justify-between gap-4">
			<h4 class="text-sm font-semibold">3 repositories starred</h4>
			<CollapsibleTrigger class="rounded-md border px-3 py-1 text-sm">
				{{ open ? "Show less" : "Show more" }}
			</CollapsibleTrigger>
		</div>
		<div class="mt-2 rounded-md border px-3 py-2 font-mono text-sm">fancy-ui/core</div>
		<CollapsibleContent>
			<div class="mt-2 flex flex-col gap-2">
				<div class="rounded-md border px-3 py-2 font-mono text-sm">fancy-ui/motion</div>
				<div class="rounded-md border px-3 py-2 font-mono text-sm">fancy-ui/registry</div>
			</div>
		</CollapsibleContent>
	</Collapsible>
</template>
```
