<!-- Generated by scripts/gen-docs.mts from the JSDoc in registry/. Do not edit; run `pnpm run docs`. -->

# Collapsible

One section that opens and closes under its title, such as nutrition facts under a recipe. The content grows to its measured height with CSS, the closed content is in the server HTML and found by the page search of browsers that support `hidden="until-found"`, and the title is a 44px row on touch screens.

```tsx
import { Collapsible } from "@/components/ouro/collapsible/collapsible";
```

## Example

```tsx
<Collapsible title="Nutrition facts">
  <NutritionTable />
</Collapsible>
```

## Use instead when

- Use `Accordion` instead for a stack of such sections.
- Use `ShowMore` instead to cut a long list or text short behind a "Show more" button.
- Use `Dialog` or `Sheet` instead when the content is a task of its own.

## Props

Type: `CollapsibleProps`.

| Prop | Type | Description |
| --- | --- | --- |
| `children` (required) | `ReactNode` | What shows while it is open. |
| `className` | `string` | Layout only: margins, width, grid placement (`mt-4`). Appearance classes warn in development. |
| `defaultOpen` | `boolean` | Opens it first, when the component keeps its own state. |
| `disabled` | `boolean` | Keeps it from opening or closing. |
| `onOpenChange` | `((open: boolean) => void)` | Called with the new state when the person opens or closes it. |
| `open` | `boolean` | Whether it is open, when you control it. Pair it with `onOpenChange`. |
| `ref` | `Ref<HTMLDivElement>` | Reaches the rendered element. |
| `title` (required) | `ReactNode` | The title, in view whether open or closed. It is the button that opens and closes the content. |

## Don't use

These are not props. Passing one fails the type check with the fix in the error, and in development a console message names the fix.

- `isOpen`: Not a prop. Ouro UI uses `open`: `<Collapsible open>`.
- `label`: Not a prop. Ouro UI uses `title`: `<Collapsible title="Nutrition facts">`.
- `onChange`: Not a prop. Ouro UI uses `onOpenChange`: `<Collapsible onOpenChange={(open) => …}>`.
- `trigger`: Not a prop. The button is drawn for you from `title`: `<Collapsible title="Nutrition facts">`.

## `className` is for layout only

Pass margins, width and grid placement (`mt-4`, `w-full`, `col-span-2`). Your classes always win over Ouro UI's: Collapsible merges `className` last with `cn` (tailwind-merge), so a class that conflicts with its own replaces it.[^layout-classes]

Appearance comes from props, not classes. In development, a class that sets appearance logs one warning per component instance, naming the prop to use instead. A class sets appearance when, after its variants (`hover:`, `sm:`) and any `!` are removed, it starts with `bg-`, `text-`, `border-`, `rounded-`, `shadow-`, `font-`, `ring-`, `from-`, `via-`, `to-`, `fill-` or `stroke-`, or is `border`, `rounded`, `shadow` or `ring`, or has a `dark:` variant. Text wrapping, overflow and table layout classes (`text-wrap`, `text-ellipsis`, `border-collapse`) are layout and do not warn.

Alignment classes (`text-center`) warn too: set alignment on a parent element.

[^layout-classes]: test:registry/ouro/components/ouro/collapsible/collapsible.test.tsx::Collapsible > lets app layout classes win and forwards a ref to the root verify:testExists(registry/ouro/components/ouro/collapsible/collapsible.test.tsx::Collapsible > lets app layout classes win and forwards a ref to the root)
