# Collapsible

A region that a trigger button shows and hides, with a height animation.

Docs: https://corsairui.vercel.app/docs/collapsible

## Install

```bash
pnpm dlx shadcn@latest add @corsair-ui/collapsible
```

Also adds: `utils`.
npm: `@radix-ui/react-collapsible`, `clsx`, `tailwind-merge`.

## API

Built on Radix Collapsible (https://www.radix-ui.com/primitives/docs/components/collapsible); its props pass through.

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `open / defaultOpen / onOpenChange` | `boolean / boolean / (open) => void` |  | Collapsible: controlled or uncontrolled. |
| `CollapsibleTrigger asChild` | `boolean` | `false` | Turn your own button into the trigger. |

## Styling

Restyle it in the project that installs it: `className` on each part, the theme variables, and these attributes with arbitrary variants (`[&_[data-slot=…]]:…`, `data-[state=…]:…`).

data-slot: `collapsible`, `collapsible-content`, `collapsible-trigger`

## Accessibility

- The trigger is a button announced as expanded or collapsed, pointing at the region.
- Give an icon-only trigger an aria-label.
- The region opens without sliding with prefers-reduced-motion.

## Examples

On the docs page: Show more. The usage examples in the source comments below are the reference.

## Source

What `shadcn add` writes into the project:

### collapsible.tsx

```tsx
"use client";
import * as CollapsiblePrimitive from "@radix-ui/react-collapsible";
import type { ComponentProps } from "react";
import { cn } from "@/registry/default/lib/utils";
/**
 * One region that a button shows and hides: "show more" lists, advanced
 * options, a sidebar group. The trigger is a button, so Tab reaches it and
 * Enter or Space toggles it; screen readers hear "expanded" or "collapsed"
 * and the button points at the region it controls. Controlled with `open` /
 * `onOpenChange` or uncontrolled with `defaultOpen`. With reduced motion the
 * region opens without sliding. For several sections under headings, use
 * Accordion.
 *
 * @example
 * <Collapsible>
 *   <CollapsibleTrigger asChild>
 *     <Button variant="ghost" size="sm">Advanced options</Button>
 *   </CollapsibleTrigger>
 *   <CollapsibleContent>…</CollapsibleContent>
 * </Collapsible>
 */
function Collapsible(props: ComponentProps<typeof CollapsiblePrimitive.Root>) {
  return <CollapsiblePrimitive.Root data-slot="collapsible" {...props} />;
}
/** Toggles the region. Use `asChild` to turn your own button into the trigger. */
function CollapsibleTrigger(props: ComponentProps<typeof CollapsiblePrimitive.Trigger>) {
  return <CollapsiblePrimitive.Trigger data-slot="collapsible-trigger" {...props} />;
}
/** The region that opens and closes. Its height animates, unless motion is reduced. */
function CollapsibleContent({
  className,
  ...props
}: ComponentProps<typeof CollapsiblePrimitive.Content>) {
  return (
    <CollapsiblePrimitive.Content
      data-slot="collapsible-content"
      className={cn(
        "overflow-hidden",
        // Behind motion-safe: so reduced motion really turns the height animation off.
        "motion-safe:data-[state=open]:animate-collapsible-open motion-safe:data-[state=closed]:animate-collapsible-close",
        className
      )}
      {...props}
    />
  );
}
export { Collapsible, CollapsibleContent, CollapsibleTrigger };
```
