# 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. --- ## 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 = () => ( Toggle Content ) ``` #### Solid ```tsx import { Collapsible } from '@ark-ui/solid/collapsible' import { ChevronRightIcon } from 'lucide-solid' export const Basic = () => ( Toggle Content ) ``` #### Vue ```vue ``` #### Svelte ```svelte Toggle Content ``` ### 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 = () => ( Toggle Content ) ``` #### Solid ```tsx import { Collapsible } from '@ark-ui/solid/collapsible' import { ChevronRightIcon } from 'lucide-solid' export const Disabled = () => ( Toggle Content ) ``` #### Vue ```vue ``` #### Svelte ```svelte Toggle Content ``` ### 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 = () => ( Show More

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.

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.

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.

) ``` #### Solid ```tsx import { Collapsible } from '@ark-ui/solid/collapsible' import { ChevronRightIcon } from 'lucide-solid' export const PartialCollapse = () => ( Show More

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.

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.

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.

) ``` #### Vue ```vue ``` #### Svelte ```svelte Show More

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.

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.

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.

``` > 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 = () => ( Getting Started

Welcome to the documentation. Here are some topics to explore:

Installation

To install the package, run one of the following commands:

npm install @ark-ui/react

Configuration

Configure your project settings to use Ark UI components.

) ``` #### Solid ```tsx import { Collapsible } from '@ark-ui/solid/collapsible' import { ChevronRightIcon } from 'lucide-solid' export const NestedCollapsible = () => ( Getting Started

Welcome to the documentation. Here are some topics to explore:

Installation

To install the package, run one of the following commands:

npm install @ark-ui/solid

Configuration

Configure your project settings to use Ark UI components.

) ``` #### Vue ```vue ``` #### Svelte ```svelte Getting Started

Welcome to the documentation. Here are some topics to explore:

Installation

To install the package, run one of the following commands:

npm install @ark-ui/svelte

Configuration

Configure your project settings to use Ark UI components.

``` ### 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 = () => ( alert('on exit')}> Toggle Content ) ``` #### Solid ```tsx import { Collapsible } from '@ark-ui/solid/collapsible' import { ChevronRightIcon } from 'lucide-solid' export const OnExitComplete = () => ( alert('on exit')}> Toggle Content ) ``` #### Vue ```vue ``` #### Svelte ```svelte
(logs = [...logs, `Exit complete at ${new Date().toLocaleTimeString()}`])}> Toggle (with exit callback) This content has an exit callback {#if logs.length > 0}

Exit logs:

    {#each logs as log}
  • {log}
  • {/each}
{/if}
``` ### 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 = () => ( Toggle Content ) ``` #### Solid ```tsx import { Collapsible } from '@ark-ui/solid/collapsible' import { ChevronRightIcon } from 'lucide-solid' export const LazyMount = () => ( Toggle Content ) ``` #### Vue ```vue ``` #### Svelte ```svelte Toggle (lazy mount) This content is only mounted when opened ``` ### 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 = () => ( Toggle Content ) ``` #### Solid ```tsx import { Collapsible } from '@ark-ui/solid/collapsible' import { ChevronRightIcon } from 'lucide-solid' export const UnmountOnExit = () => ( Toggle Content ) ``` #### Vue ```vue ``` #### Svelte ```svelte Toggle (unmount on exit) This content is unmounted when closed ``` ### 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 = () => ( Toggle Content ) ``` #### Solid ```tsx import { Collapsible } from '@ark-ui/solid/collapsible' import { ChevronRightIcon } from 'lucide-solid' export const LazyMountAndUnmountOnExit = () => ( Toggle Content ) ``` #### Vue ```vue ``` #### Svelte ```svelte Toggle (lazy + unmount) This content is lazy mounted and unmounted on exit ``` ### 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 ( <> {collapsible.visible ? 'Visible' : 'Hidden'} Toggle Content ) } ``` #### Solid ```tsx import { Collapsible, useCollapsible } from '@ark-ui/solid/collapsible' import { ChevronRightIcon } from 'lucide-solid' export const RootProvider = () => { const collapsible = useCollapsible() return ( <> {collapsible().visible ? 'Visible' : 'Hidden'} Toggle Content ) } ``` #### Vue ```vue ``` #### Svelte ```svelte
Toggle (with external control) This collapsible is controlled externally
``` > 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 ( <>

Open: {String(collapsible.open)}

Visible: {String(collapsible.visible)}

Toggle Content ) } ``` #### Solid ```tsx import { Collapsible, useCollapsible } from '@ark-ui/solid/collapsible' import { ChevronRightIcon } from 'lucide-solid' export const ProgrammaticOpen = () => { const collapsible = useCollapsible() return ( <>

Open: {String(collapsible().open)}

Visible: {String(collapsible().visible)}

Toggle Content ) } ``` #### Vue ```vue ``` #### Svelte ```svelte

Open: {String(collapsible().open)}

Visible: {String(collapsible().visible)}

Toggle Content ``` ## 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