# Collapsible

<div class="not-content sl-bejamas-component-preview flex justify-center px-4 md:px-10 py-12 border border-border rounded-t-lg min-h-72 items-center">
<Collapsible class="w-[350px] flex flex-col gap-2"> <div class="flex items-center justify-between gap-4 px-4"> <span class="text-sm font-semibold">{"@thomkrupa starred 3 repositories"}</span> <CollapsibleTrigger asChild> <Button variant="ghost" size="icon" class="size-8"> <ChevronsUpDownIcon class="size-4" /> <span class="sr-only">{"Toggle"}</span> </Button> </CollapsibleTrigger> </div> <div class="rounded-md border px-4 py-2 font-mono text-sm">{"@data-slot/collapsible"}</div> <CollapsibleContent animation="slide" class="flex flex-col gap-2"> <div class="rounded-md border px-4 py-2 font-mono text-sm">{"@bejamas/ui"}</div> <div class="rounded-md border px-4 py-2 font-mono text-sm">{"@astrojs/astro"}</div> </CollapsibleContent> </Collapsible>
</div>

```astro
---
---

<Collapsible class="w-[350px] flex flex-col gap-2">
  <div class="flex items-center justify-between gap-4 px-4">
    <span class="text-sm font-semibold">@thomkrupa starred 3 repositories</span>
    <CollapsibleTrigger asChild>
      <Button variant="ghost" size="icon" class="size-8">
        <ChevronsUpDownIcon class="size-4" />
        <span class="sr-only">Toggle</span>
      </Button>
    </CollapsibleTrigger>
  </div>
  <div class="rounded-md border px-4 py-2 font-mono text-sm">@data-slot/collapsible</div>
  <CollapsibleContent animation="slide" class="flex flex-col gap-2">
    <div class="rounded-md border px-4 py-2 font-mono text-sm">@bejamas/ui</div>
    <div class="rounded-md border px-4 py-2 font-mono text-sm">@astrojs/astro</div>
  </CollapsibleContent>
</Collapsible>
```

## Installation

<DocsTabs syncKey="pkg">
  <DocsTabItem label="bun">
  ```bash
  bunx bejamas add collapsible
  ```
  </DocsTabItem>
  <DocsTabItem label="npm">
  ```bash
  npx bejamas add collapsible
  ```
  </DocsTabItem>
  <DocsTabItem label="pnpm">
  ```bash
  pnpm dlx bejamas add collapsible
  ```
  </DocsTabItem>
  <DocsTabItem label="yarn">
  ```bash
  yarn dlx bejamas add collapsible
  ```
  </DocsTabItem>
</DocsTabs>

## Usage

```astro nocollapse
---
---

<Collapsible>
  <CollapsibleTrigger>
    <Button variant="ghost">Toggle</Button>
  </CollapsibleTrigger>
  <CollapsibleContent animation="slide">
    Hidden content here
  </CollapsibleContent>
</Collapsible>
```

## Props

| Prop | Type | Default |
|---|---|---|
| <code>class</code> | `string` | `""` |
| <code>open</code> | `boolean` | `false` |
| <code>hiddenUntilFound</code> | `boolean` | `false` |

## Examples

### Default open

<div class="not-content sl-bejamas-component-preview flex justify-center px-4 md:px-10 py-12 border border-border rounded-t-lg min-h-72 items-center">
<Collapsible open class="w-[350px] flex flex-col gap-2"> <div class="flex items-center justify-between gap-4 px-4"> <span class="text-sm font-semibold">{"Expanded by default"}</span> <CollapsibleTrigger asChild> <Button variant="ghost" size="icon" class="size-8"> <ChevronsUpDownIcon class="size-4" /> <span class="sr-only">{"Toggle"}</span> </Button> </CollapsibleTrigger> </div> <CollapsibleContent class="flex flex-col gap-2"> <div class="rounded-md border px-4 py-2 font-mono text-sm">{"This content is visible by default"}</div> </CollapsibleContent> </Collapsible>
</div>

```astro
---
---

<Collapsible open class="w-[350px] flex flex-col gap-2">
  <div class="flex items-center justify-between gap-4 px-4">
    <span class="text-sm font-semibold">Expanded by default</span>
    <CollapsibleTrigger asChild>
      <Button variant="ghost" size="icon" class="size-8">
        <ChevronsUpDownIcon class="size-4" />
        <span class="sr-only">Toggle</span>
      </Button>
    </CollapsibleTrigger>
  </div>
  <CollapsibleContent class="flex flex-col gap-2">
    <div class="rounded-md border px-4 py-2 font-mono text-sm">This content is visible by default</div>
  </CollapsibleContent>
</Collapsible>
```

### Animated content

<div class="not-content sl-bejamas-component-preview flex justify-center px-4 md:px-10 py-12 border border-border rounded-t-lg min-h-72 items-center">
<Collapsible class="w-[350px] flex flex-col gap-2"> <CollapsibleTrigger asChild> <Button variant="outline">{"Toggle with slide"}</Button> </CollapsibleTrigger> <CollapsibleContent animation="slide" class="pt-2"> <div class="rounded-md border px-4 py-2 text-sm">{" This content animates panel height using CSS variables. "}</div> </CollapsibleContent> </Collapsible>
</div>

```astro
---
---

<Collapsible class="w-[350px] flex flex-col gap-2">
  <CollapsibleTrigger asChild>
    <Button variant="outline">Toggle with slide</Button>
  </CollapsibleTrigger>
  <CollapsibleContent animation="slide" class="pt-2">
    <div class="rounded-md border px-4 py-2 text-sm">
      This content animates panel height using CSS variables.
    </div>
  </CollapsibleContent>
</Collapsible>
```

### Find-in-page support

<div class="not-content sl-bejamas-component-preview flex justify-center px-4 md:px-10 py-12 border border-border rounded-t-lg min-h-72 items-center">
<Collapsible hiddenUntilFound class="w-[350px] flex flex-col gap-2"> <CollapsibleTrigger asChild> <Button variant="outline">{"Toggle hidden-until-found content"}</Button> </CollapsibleTrigger> <CollapsibleContent class="pt-2"> <div class="rounded-md border px-4 py-2 text-sm">{" Search this sentence with browser find to auto-expand. "}</div> </CollapsibleContent> </Collapsible>
</div>

```astro
---
---

<Collapsible hiddenUntilFound class="w-[350px] flex flex-col gap-2">
  <CollapsibleTrigger asChild>
    <Button variant="outline">Toggle hidden-until-found content</Button>
  </CollapsibleTrigger>
  <CollapsibleContent class="pt-2">
    <div class="rounded-md border px-4 py-2 text-sm">
      Search this sentence with browser find to auto-expand.
    </div>
  </CollapsibleContent>
</Collapsible>
```

## API Reference

### Props

| Prop | Element | Values | Default |
|------|---------|--------|---------|
| `open` | collapsible | `boolean` | `false` |
| `hiddenUntilFound` | collapsible | `boolean` | `false` |
| `animation` | collapsible-content | `none`, `slide` | `none` |

`slide` uses `--collapsible-panel-height` for smooth height transitions.

### Events

The collapsible emits custom events that you can listen to:

| Event | Detail | Description |
|-------|--------|-------------|
| `collapsible:change` | `{ open: boolean }` | Fired when the open state changes |

<div class="not-content sl-bejamas-component-preview flex justify-center px-4 md:px-10 py-12 border border-border rounded-t-lg min-h-72 items-center">
<Collapsible id="my-collapsible"> <CollapsibleTrigger>{"Toggle"}</CollapsibleTrigger> <CollapsibleContent>{"Hidden content"}</CollapsibleContent> </Collapsible>
</div>

```astro nocollapse
<Collapsible id="my-collapsible">
  <CollapsibleTrigger>Toggle</CollapsibleTrigger>
  <CollapsibleContent>Hidden content</CollapsibleContent>
</Collapsible>
```

```js nocollapse
  const collapsible = document.getElementById('my-collapsible');

  collapsible.addEventListener('collapsible:change', (e) => {
    console.log('Is open:', e.detail.open);
  });
```

### Programmatic Control

You can control the collapsible programmatically by dispatching a `collapsible:set` event:

```js nocollapse
const collapsible = document.getElementById('my-collapsible');

// Open the collapsible
collapsible.dispatchEvent(new CustomEvent('collapsible:set', {
  detail: { open: true }
}));

// Close the collapsible
collapsible.dispatchEvent(new CustomEvent('collapsible:set', {
  detail: { open: false }
}));
```

### Data Attributes

The collapsible sets these data attributes that you can use for styling or querying state:

| Attribute | Element | Description |
|-----------|---------|-------------|
| `data-state` | collapsible, collapsible-content | Current state (`open` or `closed`) |
| `data-hidden-until-found` | collapsible | Enables `hidden="until-found"` when closed |
| `data-starting-style` | collapsible-content | Added while enter transition styles are applied |
| `data-ending-style` | collapsible-content | Added while exit transition styles are applied |

### CSS Variables

The collapsible content exposes size variables for dimension animations:

| Variable | Element | Description |
|----------|---------|-------------|
| `--collapsible-panel-height` | collapsible-content | Measured panel height |
| `--collapsible-panel-width` | collapsible-content | Measured panel width |