# Collapsible

URL: https://ark-ui.com/docs/components/collapsible
Source: https://raw.githubusercontent.com/chakra-ui/ark/refs/heads/main/website/src/content/pages/components/collapsible.mdx

An interactive component that can be expanded or collapsed.

---

<ComponentPreview id="Collapsible" />

## Animation

You can use CSS animations to create smooth transitions for opening and closing the Collapsible content. Utilize the
`data-state` attribute in combination with the `--height` CSS variable to animate the open and closed states.

```css
@keyframes slideDown {
  from {
    height: 0;
  }
  to {
    height: var(--height);
  }
}

@keyframes slideUp {
  from {
    height: var(--height);
  }
  to {
    height: 0;
  }
}

[data-scope='collapsible'][data-part='content'][data-state='open'] {
  animation: slideDown 250ms;
}

[data-scope='collapsible'][data-part='content'][data-state='closed'] {
  animation: slideUp 200ms;
}
```

## Examples

Learn how to use the `Collapsible` component in your project. Let's examine the most basic example

**Example: basic**

#### React

```tsx
import { Collapsible } from '@ark-ui/react/collapsible'
import { ChevronRightIcon } from 'lucide-react'

export const Basic = () => (
  <Collapsible.Root>
    <Collapsible.Trigger>
      Toggle
      <Collapsible.Indicator>
        <ChevronRightIcon />
      </Collapsible.Indicator>
    </Collapsible.Trigger>
    <Collapsible.Content>Content</Collapsible.Content>
  </Collapsible.Root>
)

```

#### Solid

```tsx
import { Collapsible } from '@ark-ui/solid/collapsible'
import { ChevronRightIcon } from 'lucide-solid'

export const Basic = () => (
  <Collapsible.Root>
    <Collapsible.Trigger>
      Toggle
      <Collapsible.Indicator>
        <ChevronRightIcon />
      </Collapsible.Indicator>
    </Collapsible.Trigger>
    <Collapsible.Content>Content</Collapsible.Content>
  </Collapsible.Root>
)

```

#### Vue

```vue
<script setup lang="ts">
import { useForwardPropsEmits } from '@ark-ui/vue'
import { Collapsible, type CollapsibleRootEmits, type CollapsibleRootProps } from '@ark-ui/vue/collapsible'
import { ChevronRightIcon } from 'lucide-vue-next'

const props = defineProps<CollapsibleRootProps>()
const emits = defineEmits<CollapsibleRootEmits>()
const localProps = useForwardPropsEmits(props, emits)
</script>

<template>
  <Collapsible.Root v-bind="localProps">
    <Collapsible.Trigger>
      Toggle
      <Collapsible.Indicator>
        <ChevronRightIcon />
      </Collapsible.Indicator>
    </Collapsible.Trigger>
    <Collapsible.Content>Content</Collapsible.Content>
  </Collapsible.Root>
</template>

```

#### Svelte

```svelte
<script lang="ts">
  import { Collapsible } from '@ark-ui/svelte/collapsible'
  import { ChevronRightIcon } from 'lucide-svelte'
</script>

<Collapsible.Root>
  <Collapsible.Trigger>
    Toggle
    <Collapsible.Indicator>
      <ChevronRightIcon />
    </Collapsible.Indicator>
  </Collapsible.Trigger>
  <Collapsible.Content>Content</Collapsible.Content>
</Collapsible.Root>

```

### Disabled

Use the `disabled` prop to disable the collapsible and prevent it from being toggled.

**Example: disabled**

#### React

```tsx
import { Collapsible } from '@ark-ui/react/collapsible'
import { ChevronRightIcon } from 'lucide-react'

export const Disabled = () => (
  <Collapsible.Root disabled>
    <Collapsible.Trigger>
      Toggle
      <Collapsible.Indicator>
        <ChevronRightIcon />
      </Collapsible.Indicator>
    </Collapsible.Trigger>
    <Collapsible.Content>Content</Collapsible.Content>
  </Collapsible.Root>
)

```

#### Solid

```tsx
import { Collapsible } from '@ark-ui/solid/collapsible'
import { ChevronRightIcon } from 'lucide-solid'

export const Disabled = () => (
  <Collapsible.Root disabled>
    <Collapsible.Trigger>
      Toggle
      <Collapsible.Indicator>
        <ChevronRightIcon />
      </Collapsible.Indicator>
    </Collapsible.Trigger>
    <Collapsible.Content>Content</Collapsible.Content>
  </Collapsible.Root>
)

```

#### Vue

```vue
<script setup lang="ts">
import { Collapsible } from '@ark-ui/vue/collapsible'
import { ChevronRightIcon } from 'lucide-vue-next'
</script>

<template>
  <Collapsible.Root disabled>
    <Collapsible.Trigger>
      Toggle
      <Collapsible.Indicator>
        <ChevronRightIcon />
      </Collapsible.Indicator>
    </Collapsible.Trigger>
    <Collapsible.Content>Content</Collapsible.Content>
  </Collapsible.Root>
</template>

```

#### Svelte

```svelte
<script lang="ts">
  import { Collapsible } from '@ark-ui/svelte/collapsible'
  import { ChevronRight } from 'lucide-svelte'
</script>

<Collapsible.Root disabled>
  <Collapsible.Trigger>
    Toggle
    <Collapsible.Indicator>
      <ChevronRight />
    </Collapsible.Indicator>
  </Collapsible.Trigger>
  <Collapsible.Content>Content</Collapsible.Content>
</Collapsible.Root>

```

### Partial Collapse

Use the `collapsedHeight` or `collapsedWidth` props to create a "show more/less" pattern. When set, the content
maintains the specified dimensions when collapsed instead of collapsing to 0px.

We expose the `--collapsed-height` or `--collapsed-width` variables to use in your CSS animations.

**Example: partial-collapse**

#### React

```tsx
import { Collapsible } from '@ark-ui/react/collapsible'
import { ChevronRightIcon } from 'lucide-react'

export const PartialCollapse = () => (
  <Collapsible.Root collapsedHeight="100px">
    <Collapsible.Trigger>
      Show More
      <Collapsible.Indicator>
        <ChevronRightIcon />
      </Collapsible.Indicator>
    </Collapsible.Trigger>
    <Collapsible.Content>
      <p>
        Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore
        magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
        consequat.
      </p>
      <p>
        Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur
        sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
      </p>
      <p>
        Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem
        aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo.
      </p>
    </Collapsible.Content>
  </Collapsible.Root>
)

```

#### Solid

```tsx
import { Collapsible } from '@ark-ui/solid/collapsible'
import { ChevronRightIcon } from 'lucide-solid'

export const PartialCollapse = () => (
  <Collapsible.Root collapsedHeight="100px">
    <Collapsible.Trigger>
      Show More
      <Collapsible.Indicator>
        <ChevronRightIcon />
      </Collapsible.Indicator>
    </Collapsible.Trigger>
    <Collapsible.Content>
      <p>
        Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore
        magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
        consequat.
      </p>
      <p>
        Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur
        sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
      </p>
      <p>
        Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem
        aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo.
      </p>
    </Collapsible.Content>
  </Collapsible.Root>
)

```

#### Vue

```vue
<script setup lang="ts">
import { Collapsible } from '@ark-ui/vue/collapsible'
import { ChevronRightIcon } from 'lucide-vue-next'
</script>

<template>
  <Collapsible.Root collapsed-height="100px">
    <Collapsible.Trigger>
      Show More
      <Collapsible.Indicator>
        <ChevronRightIcon />
      </Collapsible.Indicator>
    </Collapsible.Trigger>
    <Collapsible.Content>
      <p>
        Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore
        magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
        consequat.
      </p>
      <p>
        Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur
        sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
      </p>
      <p>
        Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem
        aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo.
      </p>
    </Collapsible.Content>
  </Collapsible.Root>
</template>

```

#### Svelte

```svelte
<script lang="ts">
  import { Collapsible } from '@ark-ui/svelte/collapsible'
  import { ChevronRight } from 'lucide-svelte'
</script>

<Collapsible.Root collapsedHeight="100px">
  <Collapsible.Trigger>
    Show More
    <Collapsible.Indicator>
      <ChevronRight />
    </Collapsible.Indicator>
  </Collapsible.Trigger>
  <Collapsible.Content>
    <p>
      Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut
      labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco
      laboris nisi ut aliquip ex ea commodo consequat.
    </p>
    <p>
      Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla
      pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt
      mollit anim id est laborum.
    </p>
    <p>
      Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque
      laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi
      architecto beatae vitae dicta sunt explicabo.
    </p>
  </Collapsible.Content>
</Collapsible.Root>

```

> Interactive elements (links, buttons, inputs) within the collapsed area automatically become `inert` to prevent
> keyboard navigation to hidden content.

### Nested Collapsibles

You can nest collapsibles within collapsibles to create hierarchical content structures.

**Example: nested-collapsible**

#### React

```tsx
import { Collapsible } from '@ark-ui/react/collapsible'
import { ChevronRightIcon } from 'lucide-react'

export const NestedCollapsible = () => (
  <Collapsible.Root>
    <Collapsible.Trigger>
      Getting Started
      <Collapsible.Indicator>
        <ChevronRightIcon />
      </Collapsible.Indicator>
    </Collapsible.Trigger>
    <Collapsible.Content>
      <p>Welcome to the documentation. Here are some topics to explore:</p>

      <Collapsible.Root>
        <Collapsible.Trigger>
          Installation
          <Collapsible.Indicator>
            <ChevronRightIcon />
          </Collapsible.Indicator>
        </Collapsible.Trigger>
        <Collapsible.Content>
          <p>To install the package, run one of the following commands:</p>
          <p>npm install @ark-ui/react</p>
        </Collapsible.Content>
      </Collapsible.Root>

      <Collapsible.Root>
        <Collapsible.Trigger>
          Configuration
          <Collapsible.Indicator>
            <ChevronRightIcon />
          </Collapsible.Indicator>
        </Collapsible.Trigger>
        <Collapsible.Content>
          <p>Configure your project settings to use Ark UI components.</p>
        </Collapsible.Content>
      </Collapsible.Root>
    </Collapsible.Content>
  </Collapsible.Root>
)

```

#### Solid

```tsx
import { Collapsible } from '@ark-ui/solid/collapsible'
import { ChevronRightIcon } from 'lucide-solid'

export const NestedCollapsible = () => (
  <Collapsible.Root>
    <Collapsible.Trigger>
      Getting Started
      <Collapsible.Indicator>
        <ChevronRightIcon />
      </Collapsible.Indicator>
    </Collapsible.Trigger>
    <Collapsible.Content>
      <p>Welcome to the documentation. Here are some topics to explore:</p>

      <Collapsible.Root>
        <Collapsible.Trigger>
          Installation
          <Collapsible.Indicator>
            <ChevronRightIcon />
          </Collapsible.Indicator>
        </Collapsible.Trigger>
        <Collapsible.Content>
          <p>To install the package, run one of the following commands:</p>
          <p>npm install @ark-ui/solid</p>
        </Collapsible.Content>
      </Collapsible.Root>

      <Collapsible.Root>
        <Collapsible.Trigger>
          Configuration
          <Collapsible.Indicator>
            <ChevronRightIcon />
          </Collapsible.Indicator>
        </Collapsible.Trigger>
        <Collapsible.Content>
          <p>Configure your project settings to use Ark UI components.</p>
        </Collapsible.Content>
      </Collapsible.Root>
    </Collapsible.Content>
  </Collapsible.Root>
)

```

#### Vue

```vue
<script setup lang="ts">
import { Collapsible } from '@ark-ui/vue/collapsible'
import { ChevronRightIcon } from 'lucide-vue-next'
</script>

<template>
  <Collapsible.Root>
    <Collapsible.Trigger>
      Getting Started
      <Collapsible.Indicator>
        <ChevronRightIcon />
      </Collapsible.Indicator>
    </Collapsible.Trigger>
    <Collapsible.Content>
      <p>Welcome to the documentation. Here are some topics to explore:</p>

      <Collapsible.Root>
        <Collapsible.Trigger>
          Installation
          <Collapsible.Indicator>
            <ChevronRightIcon />
          </Collapsible.Indicator>
        </Collapsible.Trigger>
        <Collapsible.Content>
          <p>To install the package, run one of the following commands:</p>
          <p>npm install @ark-ui/vue</p>
        </Collapsible.Content>
      </Collapsible.Root>

      <Collapsible.Root>
        <Collapsible.Trigger>
          Configuration
          <Collapsible.Indicator>
            <ChevronRightIcon />
          </Collapsible.Indicator>
        </Collapsible.Trigger>
        <Collapsible.Content>
          <p>Configure your project settings to use Ark UI components.</p>
        </Collapsible.Content>
      </Collapsible.Root>
    </Collapsible.Content>
  </Collapsible.Root>
</template>

```

#### Svelte

```svelte
<script lang="ts">
  import { Collapsible } from '@ark-ui/svelte/collapsible'
  import { ChevronRightIcon } from 'lucide-svelte'
</script>

<Collapsible.Root>
  <Collapsible.Trigger>
    Getting Started
    <Collapsible.Indicator>
      <ChevronRightIcon />
    </Collapsible.Indicator>
  </Collapsible.Trigger>
  <Collapsible.Content>
    <p>Welcome to the documentation. Here are some topics to explore:</p>

    <Collapsible.Root>
      <Collapsible.Trigger>
        Installation
        <Collapsible.Indicator>
          <ChevronRightIcon />
        </Collapsible.Indicator>
      </Collapsible.Trigger>
      <Collapsible.Content>
        <p>To install the package, run one of the following commands:</p>
        <p>npm install @ark-ui/svelte</p>
      </Collapsible.Content>
    </Collapsible.Root>

    <Collapsible.Root>
      <Collapsible.Trigger>
        Configuration
        <Collapsible.Indicator>
          <ChevronRightIcon />
        </Collapsible.Indicator>
      </Collapsible.Trigger>
      <Collapsible.Content>
        <p>Configure your project settings to use Ark UI components.</p>
      </Collapsible.Content>
    </Collapsible.Root>
  </Collapsible.Content>
</Collapsible.Root>

```

### Events

Use `onExitComplete` callback to listen for when the `Collapsible.Content` is no longer visible

**Example: on-exit-complete**

#### React

```tsx
import { Collapsible } from '@ark-ui/react/collapsible'
import { ChevronRightIcon } from 'lucide-react'

export const OnExitComplete = () => (
  <Collapsible.Root onExitComplete={() => alert('on exit')}>
    <Collapsible.Trigger>
      Toggle
      <Collapsible.Indicator>
        <ChevronRightIcon />
      </Collapsible.Indicator>
    </Collapsible.Trigger>
    <Collapsible.Content>Content</Collapsible.Content>
  </Collapsible.Root>
)

```

#### Solid

```tsx
import { Collapsible } from '@ark-ui/solid/collapsible'
import { ChevronRightIcon } from 'lucide-solid'

export const OnExitComplete = () => (
  <Collapsible.Root onExitComplete={() => alert('on exit')}>
    <Collapsible.Trigger>
      Toggle
      <Collapsible.Indicator>
        <ChevronRightIcon />
      </Collapsible.Indicator>
    </Collapsible.Trigger>
    <Collapsible.Content>Content</Collapsible.Content>
  </Collapsible.Root>
)

```

#### Vue

```vue
<script setup lang="ts">
import { Collapsible } from '@ark-ui/vue/collapsible'
import { ChevronRightIcon } from 'lucide-vue-next'
</script>

<template>
  <Collapsible.Root @exit-complete="() => console.log('on exit')">
    <Collapsible.Trigger>
      Toggle
      <Collapsible.Indicator>
        <ChevronRightIcon />
      </Collapsible.Indicator>
    </Collapsible.Trigger>
    <Collapsible.Content>Content</Collapsible.Content>
  </Collapsible.Root>
</template>

```

#### Svelte

```svelte
<script lang="ts">
  import { Collapsible } from '@ark-ui/svelte/collapsible'
  import { ChevronRightIcon } from 'lucide-svelte'

  let logs = $state<string[]>([])
</script>

<div>
  <Collapsible.Root onExitComplete={() => (logs = [...logs, `Exit complete at ${new Date().toLocaleTimeString()}`])}>
    <Collapsible.Trigger>
      Toggle (with exit callback)
      <Collapsible.Indicator>
        <ChevronRightIcon />
      </Collapsible.Indicator>
    </Collapsible.Trigger>
    <Collapsible.Content>This content has an exit callback</Collapsible.Content>
  </Collapsible.Root>

  {#if logs.length > 0}
    <div style="margin-top: 1rem;">
      <h4>Exit logs:</h4>
      <ul>
        {#each logs as log}
          <li>{log}</li>
        {/each}
      </ul>
    </div>
  {/if}
</div>

```

### Lazy Mount

To delay the mounting of the `Collapsible.Content`, use the `lazyMount` prop

**Example: lazy-mount**

#### React

```tsx
import { Collapsible } from '@ark-ui/react/collapsible'
import { ChevronRightIcon } from 'lucide-react'

export const LazyMount = () => (
  <Collapsible.Root lazyMount>
    <Collapsible.Trigger>
      Toggle
      <Collapsible.Indicator>
        <ChevronRightIcon />
      </Collapsible.Indicator>
    </Collapsible.Trigger>
    <Collapsible.Content>Content</Collapsible.Content>
  </Collapsible.Root>
)

```

#### Solid

```tsx
import { Collapsible } from '@ark-ui/solid/collapsible'
import { ChevronRightIcon } from 'lucide-solid'

export const LazyMount = () => (
  <Collapsible.Root lazyMount>
    <Collapsible.Trigger>
      Toggle
      <Collapsible.Indicator>
        <ChevronRightIcon />
      </Collapsible.Indicator>
    </Collapsible.Trigger>
    <Collapsible.Content>Content</Collapsible.Content>
  </Collapsible.Root>
)

```

#### Vue

```vue
<script setup lang="ts">
import { Collapsible } from '@ark-ui/vue/collapsible'
import { ChevronRightIcon } from 'lucide-vue-next'
</script>

<template>
  <Collapsible.Root lazyMount>
    <Collapsible.Trigger>
      Toggle
      <Collapsible.Indicator>
        <ChevronRightIcon />
      </Collapsible.Indicator>
    </Collapsible.Trigger>
    <Collapsible.Content>Content</Collapsible.Content>
  </Collapsible.Root>
</template>

```

#### Svelte

```svelte
<script lang="ts">
  import { Collapsible } from '@ark-ui/svelte/collapsible'
  import { ChevronRightIcon } from 'lucide-svelte'
</script>

<Collapsible.Root lazyMount>
  <Collapsible.Trigger>
    Toggle (lazy mount)
    <Collapsible.Indicator>
      <ChevronRightIcon />
    </Collapsible.Indicator>
  </Collapsible.Trigger>
  <Collapsible.Content>This content is only mounted when opened</Collapsible.Content>
</Collapsible.Root>

```

### Unmount on Exit

To remove the `Collapsible.Content` from the DOM when it is not visible, use the `unmountOnExit` prop

**Example: unmount-on-exit**

#### React

```tsx
import { Collapsible } from '@ark-ui/react/collapsible'
import { ChevronRightIcon } from 'lucide-react'

export const UnmountOnExit = () => (
  <Collapsible.Root unmountOnExit>
    <Collapsible.Trigger>
      Toggle
      <Collapsible.Indicator>
        <ChevronRightIcon />
      </Collapsible.Indicator>
    </Collapsible.Trigger>
    <Collapsible.Content>Content</Collapsible.Content>
  </Collapsible.Root>
)

```

#### Solid

```tsx
import { Collapsible } from '@ark-ui/solid/collapsible'
import { ChevronRightIcon } from 'lucide-solid'

export const UnmountOnExit = () => (
  <Collapsible.Root unmountOnExit>
    <Collapsible.Trigger>
      Toggle
      <Collapsible.Indicator>
        <ChevronRightIcon />
      </Collapsible.Indicator>
    </Collapsible.Trigger>
    <Collapsible.Content>Content</Collapsible.Content>
  </Collapsible.Root>
)

```

#### Vue

```vue
<script setup lang="ts">
import { Collapsible } from '@ark-ui/vue/collapsible'
import { ChevronRightIcon } from 'lucide-vue-next'
</script>

<template>
  <Collapsible.Root unmountOnExit>
    <Collapsible.Trigger>
      Toggle
      <Collapsible.Indicator>
        <ChevronRightIcon />
      </Collapsible.Indicator>
    </Collapsible.Trigger>
    <Collapsible.Content>Content</Collapsible.Content>
  </Collapsible.Root>
</template>

```

#### Svelte

```svelte
<script lang="ts">
  import { Collapsible } from '@ark-ui/svelte/collapsible'
  import { ChevronRightIcon } from 'lucide-svelte'
</script>

<Collapsible.Root unmountOnExit>
  <Collapsible.Trigger>
    Toggle (unmount on exit)
    <Collapsible.Indicator>
      <ChevronRightIcon />
    </Collapsible.Indicator>
  </Collapsible.Trigger>
  <Collapsible.Content>This content is unmounted when closed</Collapsible.Content>
</Collapsible.Root>

```

### Lazy Mount + Unmount on Exit

Both `lazyMount` and `unmountOnExit` can be combined to ensure that the component is mounted only when the `Collapsible`
is expanded and unmounted when it is collapsed:

**Example: lazy-mount-and-unmount-on-exit**

#### React

```tsx
import { Collapsible } from '@ark-ui/react/collapsible'
import { ChevronRightIcon } from 'lucide-react'

export const LazyMountAndUnmountOnExit = () => (
  <Collapsible.Root lazyMount unmountOnExit>
    <Collapsible.Trigger>
      Toggle
      <Collapsible.Indicator>
        <ChevronRightIcon />
      </Collapsible.Indicator>
    </Collapsible.Trigger>
    <Collapsible.Content>Content</Collapsible.Content>
  </Collapsible.Root>
)

```

#### Solid

```tsx
import { Collapsible } from '@ark-ui/solid/collapsible'
import { ChevronRightIcon } from 'lucide-solid'

export const LazyMountAndUnmountOnExit = () => (
  <Collapsible.Root lazyMount unmountOnExit>
    <Collapsible.Trigger>
      Toggle
      <Collapsible.Indicator>
        <ChevronRightIcon />
      </Collapsible.Indicator>
    </Collapsible.Trigger>
    <Collapsible.Content>Content</Collapsible.Content>
  </Collapsible.Root>
)

```

#### Vue

```vue
<script setup lang="ts">
import { Collapsible } from '@ark-ui/vue/collapsible'
import { ChevronRightIcon } from 'lucide-vue-next'
</script>

<template>
  <Collapsible.Root lazyMount unmountOnExit>
    <Collapsible.Trigger>
      Toggle
      <Collapsible.Indicator>
        <ChevronRightIcon />
      </Collapsible.Indicator>
    </Collapsible.Trigger>
    <Collapsible.Content>Content</Collapsible.Content>
  </Collapsible.Root>
</template>

```

#### Svelte

```svelte
<script lang="ts">
  import { Collapsible } from '@ark-ui/svelte/collapsible'
  import { ChevronRightIcon } from 'lucide-svelte'
</script>

<Collapsible.Root lazyMount unmountOnExit>
  <Collapsible.Trigger>
    Toggle (lazy + unmount)
    <Collapsible.Indicator>
      <ChevronRightIcon />
    </Collapsible.Indicator>
  </Collapsible.Trigger>
  <Collapsible.Content>This content is lazy mounted and unmounted on exit</Collapsible.Content>
</Collapsible.Root>

```

### Root Provider

Use the `useCollapsible` hook to create the collapsible store and pass it to the `Collapsible.RootProvider` component.
This allows you to have maximum control over the collapsible programmatically.

**Example: root-provider**

#### React

```tsx
import { Collapsible, useCollapsible } from '@ark-ui/react/collapsible'
import { ChevronRightIcon } from 'lucide-react'

export const RootProvider = () => {
  const collapsible = useCollapsible()

  return (
    <>
      <span>{collapsible.visible ? 'Visible' : 'Hidden'}</span>

      <Collapsible.RootProvider value={collapsible}>
        <Collapsible.Trigger>
          Toggle
          <Collapsible.Indicator>
            <ChevronRightIcon />
          </Collapsible.Indicator>
        </Collapsible.Trigger>
        <Collapsible.Content>Content</Collapsible.Content>
      </Collapsible.RootProvider>
    </>
  )
}

```

#### Solid

```tsx
import { Collapsible, useCollapsible } from '@ark-ui/solid/collapsible'
import { ChevronRightIcon } from 'lucide-solid'

export const RootProvider = () => {
  const collapsible = useCollapsible()

  return (
    <>
      <span>{collapsible().visible ? 'Visible' : 'Hidden'}</span>

      <Collapsible.RootProvider value={collapsible}>
        <Collapsible.Trigger>
          Toggle
          <Collapsible.Indicator>
            <ChevronRightIcon />
          </Collapsible.Indicator>
        </Collapsible.Trigger>
        <Collapsible.Content>Content</Collapsible.Content>
      </Collapsible.RootProvider>
    </>
  )
}

```

#### Vue

```vue
<script setup lang="ts">
import { Collapsible, useCollapsible } from '@ark-ui/vue/collapsible'
import { ChevronRightIcon } from 'lucide-vue-next'

const collapsible = useCollapsible()
</script>

<template>
  <span>{{ collapsible.visible ? 'Visible' : 'Hidden' }}</span>

  <Collapsible.RootProvider :value="collapsible">
    <Collapsible.Trigger>
      Toggle
      <Collapsible.Indicator>
        <ChevronRightIcon />
      </Collapsible.Indicator>
    </Collapsible.Trigger>
    <Collapsible.Content>Content</Collapsible.Content>
  </Collapsible.RootProvider>
</template>

```

#### Svelte

```svelte
<script lang="ts">
  import { Collapsible, useCollapsible } from '@ark-ui/svelte/collapsible'
  import { ChevronRightIcon } from 'lucide-svelte'

  const id = $props.id()
  const collapsible = useCollapsible({ id })
</script>

<div>
  <button onclick={() => collapsible().setOpen(true)}>Open</button>
  <button onclick={() => collapsible().setOpen(false)}>Close</button>
  
  <Collapsible.RootProvider value={collapsible}>
    <Collapsible.Trigger>
      Toggle (with external control)
      <Collapsible.Indicator>
        <ChevronRightIcon />
      </Collapsible.Indicator>
    </Collapsible.Trigger>
    <Collapsible.Content>This collapsible is controlled externally</Collapsible.Content>
  </Collapsible.RootProvider>
</div> 

```

> If you're using the `Collapsible.RootProvider` component, you don't need to use the `Collapsible.Root` component.

### Programmatic Control

Use the `useCollapsible` hook with `Collapsible.RootProvider` to programmatically control the collapsible using the
`setOpen()` method and read state properties like `open` and `visible`.

**Example: programmatic-open**

#### React

```tsx
import { Collapsible, useCollapsible } from '@ark-ui/react/collapsible'
import { ChevronRightIcon } from 'lucide-react'

export const ProgrammaticOpen = () => {
  const collapsible = useCollapsible()

  return (
    <>
      <div>
        <p>
          Open: <strong>{String(collapsible.open)}</strong>
        </p>
        <p>
          Visible: <strong>{String(collapsible.visible)}</strong>
        </p>
      </div>

      <div style={{ display: 'flex', gap: '8px', marginTop: '8px' }}>
        <button type="button" onClick={() => collapsible.setOpen(true)}>
          Open
        </button>
        <button type="button" onClick={() => collapsible.setOpen(false)}>
          Close
        </button>
      </div>

      <Collapsible.RootProvider value={collapsible}>
        <Collapsible.Trigger>
          Toggle
          <Collapsible.Indicator>
            <ChevronRightIcon />
          </Collapsible.Indicator>
        </Collapsible.Trigger>
        <Collapsible.Content>Content</Collapsible.Content>
      </Collapsible.RootProvider>
    </>
  )
}

```

#### Solid

```tsx
import { Collapsible, useCollapsible } from '@ark-ui/solid/collapsible'
import { ChevronRightIcon } from 'lucide-solid'

export const ProgrammaticOpen = () => {
  const collapsible = useCollapsible()

  return (
    <>
      <div>
        <p>
          Open: <strong>{String(collapsible().open)}</strong>
        </p>
        <p>
          Visible: <strong>{String(collapsible().visible)}</strong>
        </p>
      </div>

      <div style={{ display: 'flex', gap: '8px', 'margin-top': '8px' }}>
        <button type="button" onClick={() => collapsible().setOpen(true)}>
          Open
        </button>
        <button type="button" onClick={() => collapsible().setOpen(false)}>
          Close
        </button>
      </div>

      <Collapsible.RootProvider value={collapsible}>
        <Collapsible.Trigger>
          Toggle
          <Collapsible.Indicator>
            <ChevronRightIcon />
          </Collapsible.Indicator>
        </Collapsible.Trigger>
        <Collapsible.Content>Content</Collapsible.Content>
      </Collapsible.RootProvider>
    </>
  )
}

```

#### Vue

```vue
<script setup lang="ts">
import { Collapsible, useCollapsible } from '@ark-ui/vue/collapsible'
import { ChevronRightIcon } from 'lucide-vue-next'

const collapsible = useCollapsible()
</script>

<template>
  <div>
    <p>
      Open:
      <strong>{{ String(collapsible.open) }}</strong>
    </p>
    <p>
      Visible:
      <strong>{{ String(collapsible.visible) }}</strong>
    </p>
  </div>

  <div style="display: flex; gap: 8px; margin-top: 8px">
    <button type="button" @click="collapsible.setOpen(true)">Open</button>
    <button type="button" @click="collapsible.setOpen(false)">Close</button>
  </div>

  <Collapsible.RootProvider :value="collapsible">
    <Collapsible.Trigger>
      Toggle
      <Collapsible.Indicator>
        <ChevronRightIcon />
      </Collapsible.Indicator>
    </Collapsible.Trigger>
    <Collapsible.Content>Content</Collapsible.Content>
  </Collapsible.RootProvider>
</template>

```

#### Svelte

```svelte
<script lang="ts">
  import { Collapsible, useCollapsible } from '@ark-ui/svelte/collapsible'
  import { ChevronRight } from 'lucide-svelte'

  const collapsible = useCollapsible()
</script>

<div>
  <p>
    Open: <strong>{String(collapsible().open)}</strong>
  </p>
  <p>
    Visible: <strong>{String(collapsible().visible)}</strong>
  </p>
</div>

<div style="display: flex; gap: 8px; margin-top: 8px">
  <button type="button" onclick={() => collapsible().setOpen(true)}>Open</button>
  <button type="button" onclick={() => collapsible().setOpen(false)}>Close</button>
</div>

<Collapsible.RootProvider value={collapsible}>
  <Collapsible.Trigger>
    Toggle
    <Collapsible.Indicator>
      <ChevronRight />
    </Collapsible.Indicator>
  </Collapsible.Trigger>
  <Collapsible.Content>Content</Collapsible.Content>
</Collapsible.RootProvider>

```

## Guides

### Animating the Indicator

To rotate the indicator icon (such as a chevron) when the collapsible opens and closes, use CSS transforms with the
`data-state` attribute:

```css
[data-scope='collapsible'][data-part='indicator'] {
  transition: transform 200ms;

  &[data-state='open'] {
    transform: rotate(180deg);
  }
}
```

### `open` vs `visible`

When using `useCollapsible` or `useCollapsibleContext`, you can access the `open` and `visible` state properties. They
seem similar but serve different purposes:

- **`open`**: Indicates the intended state of the collapsible. This is `true` when the collapsible should be expanded
  and `false` when it should be collapsed. This changes immediately when triggered.

- **`visible`**: Indicates whether the content is currently visible in the DOM. This accounts for exit animations - the
  content remains `visible` while the closing animation plays, even though `open` is already `false`. Once the animation
  completes, `visible` becomes `false`.

### Animating the Content

Use the `--height` and/or `--width` CSS variables to animate the size of the content when it expands or closes.

If you use `collapsedHeight` or `collapsedWidth`, update your CSS animations to use the `--collapsed-height` or
`--collapsed-width` variables as the starting/ending point:

```css
@keyframes expand {
  from {
    height: var(--collapsed-height, 0);
  }
  to {
    height: var(--height);
  }
}

@keyframes collapse {
  from {
    height: var(--height);
  }
  to {
    height: var(--collapsed-height, 0);
  }
}

[data-scope='collapsible'][data-part='content'] {
  &[data-state='open'] {
    animation: expand 250ms;
  }
  &[data-state='closed'] {
    animation: collapse 250ms;
  }
}
```

## API Reference

### Props

**Component API Reference**

#### React

**Root Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `defaultOpen` | `boolean` | No | The initial open state of the collapsible when rendered.
Use when you don't need to control the open state of the collapsible. |
| `disabled` | `boolean` | No | Whether the collapsible is disabled. |
| `ids` | `Partial<{ root: string; content: string; trigger: string }>` | No | The ids of the elements in the collapsible. Useful for composition. |
| `lazyMount` | `boolean` | No | Whether to enable lazy mounting |
| `onExitComplete` | `VoidFunction` | No | The callback invoked when the exit animation completes. |
| `onOpenChange` | `(details: OpenChangeDetails) => void` | No | The callback invoked when the open state changes. |
| `open` | `boolean` | No | The controlled open state of the collapsible. |
| `unmountOnExit` | `boolean` | No | Whether to unmount on exit. |


**Root Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | collapsible |
| `[data-part]` | root |
| `[data-state]` | "open" | "closed" |


**Content Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**Content Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | collapsible |
| `[data-part]` | content |
| `[data-collapsible]` |  |
| `[data-state]` | "open" | "closed" |
| `[data-disabled]` | Present when disabled |


**Indicator Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**Indicator Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | collapsible |
| `[data-part]` | indicator |
| `[data-state]` | "open" | "closed" |
| `[data-disabled]` | Present when disabled |


**RootProvider Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `value` | `UseCollapsibleReturn` | Yes |  |
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**Trigger Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**Trigger Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | collapsible |
| `[data-part]` | trigger |
| `[data-state]` | "open" | "closed" |
| `[data-disabled]` | Present when disabled |


#### Solid

**Root Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `defaultOpen` | `boolean` | No | The initial open state of the collapsible when rendered.
Use when you don't need to control the open state of the collapsible. |
| `disabled` | `boolean` | No | Whether the collapsible is disabled. |
| `ids` | `Partial<{ root: string; content: string; trigger: string }>` | No | The ids of the elements in the collapsible. Useful for composition. |
| `lazyMount` | `boolean` | No | Whether to enable lazy mounting |
| `onExitComplete` | `VoidFunction` | No | The callback invoked when the exit animation completes. |
| `onOpenChange` | `(details: OpenChangeDetails) => void` | No | The callback invoked when the open state changes. |
| `open` | `boolean` | No | The controlled open state of the collapsible. |
| `unmountOnExit` | `boolean` | No | Whether to unmount on exit. |


**Root Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | collapsible |
| `[data-part]` | root |
| `[data-state]` | "open" | "closed" |


**Content Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**Content Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | collapsible |
| `[data-part]` | content |
| `[data-collapsible]` |  |
| `[data-state]` | "open" | "closed" |
| `[data-disabled]` | Present when disabled |


**Indicator Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**Indicator Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | collapsible |
| `[data-part]` | indicator |
| `[data-state]` | "open" | "closed" |
| `[data-disabled]` | Present when disabled |


**RootProvider Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `value` | `UseCollapsibleReturn` | Yes |  |
| `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**Trigger Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**Trigger Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | collapsible |
| `[data-part]` | trigger |
| `[data-state]` | "open" | "closed" |
| `[data-disabled]` | Present when disabled |


#### Vue

**Root Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `defaultOpen` | `boolean` | No | The initial open state of the collapsible when rendered.
Use when you don't need to control the open state of the collapsible. |
| `disabled` | `boolean` | No | Whether the collapsible is disabled. |
| `id` | `string` | No | The unique identifier of the machine. |
| `ids` | `Partial<{ root: string; content: string; trigger: string }>` | No | The ids of the elements in the collapsible. Useful for composition. |
| `lazyMount` | `boolean` | No | Whether to enable lazy mounting |
| `open` | `boolean` | No | The controlled open state of the collapsible. |
| `unmountOnExit` | `boolean` | No | Whether to unmount on exit. |


**Root Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | collapsible |
| `[data-part]` | root |
| `[data-state]` | "open" | "closed" |


**Content Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**Content Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | collapsible |
| `[data-part]` | content |
| `[data-collapsible]` |  |
| `[data-state]` | "open" | "closed" |
| `[data-disabled]` | Present when disabled |


**Indicator Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**Indicator Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | collapsible |
| `[data-part]` | indicator |
| `[data-state]` | "open" | "closed" |
| `[data-disabled]` | Present when disabled |


**RootProvider Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `value` | `Collapsible` | Yes |  |
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**Trigger Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |


**Trigger Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | collapsible |
| `[data-part]` | trigger |
| `[data-state]` | "open" | "closed" |
| `[data-disabled]` | Present when disabled |


#### Svelte

**Root Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `defaultOpen` | `boolean` | No | The initial open state of the collapsible when rendered.
Use when you don't need to control the open state of the collapsible. |
| `disabled` | `boolean` | No | Whether the collapsible is disabled. |
| `id` | `string` | No | The unique identifier of the machine. |
| `ids` | `Partial<{ root: string; content: string; trigger: string }>` | No | The ids of the elements in the collapsible. Useful for composition. |
| `lazyMount` | `boolean` | No | Whether the content should be lazy mounted |
| `onExitComplete` | `() => void` | No | Callback fired when the animation ends |
| `onOpenChange` | `(details: OpenChangeDetails) => void` | No | The callback invoked when the open state changes. |
| `open` | `boolean` | No | The controlled open state of the collapsible. |
| `ref` | `Element` | No |  |
| `unmountOnExit` | `boolean` | No | Whether the content should be unmounted when collapsed |


**Root Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | collapsible |
| `[data-part]` | root |
| `[data-state]` | "open" | "closed" |


**Content Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `ref` | `Element` | No |  |


**Content Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | collapsible |
| `[data-part]` | content |
| `[data-collapsible]` |  |
| `[data-state]` | "open" | "closed" |
| `[data-disabled]` | Present when disabled |


**Context Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `render` | `Snippet<[UseCollapsibleContext]>` | No |  |


**Indicator Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `ref` | `Element` | No |  |


**Indicator Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | collapsible |
| `[data-part]` | indicator |
| `[data-state]` | "open" | "closed" |
| `[data-disabled]` | Present when disabled |


**RootProvider Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `value` | `UseCollapsibleReturn` | Yes |  |
| `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `ref` | `Element` | No |  |


**Trigger Props:**

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `ref` | `Element` | No |  |


**Trigger Data Attributes:**

| Attribute | Value |
|-----------|-------|
| `[data-scope]` | collapsible |
| `[data-part]` | trigger |
| `[data-state]` | "open" | "closed" |
| `[data-disabled]` | Present when disabled |


### Context

These are the properties available when using `Collapsible.Context`, `useCollapsibleContext` hook or `useCollapsible` hook.

**API:**

| Property | Type | Description |
|----------|------|-------------|
| `open` | `boolean` | Whether the collapsible is open. |
| `visible` | `boolean` | Whether the collapsible is visible (open or closing) |
| `disabled` | `boolean` | Whether the collapsible is disabled |
| `setOpen` | `(open: boolean) => void` | Function to open or close the collapsible. |
| `measureSize` | `VoidFunction` | Function to measure the size of the content. |


## Accessibility

### Keyboard Support

<KeyBindingsTable id="collapsible" />