# 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. --- ## Anatomy ```tsx ``` ## Examples **Example: basic** #### React ```tsx import { Collapsible } from '@ark-ui/react/collapsible' import { ChevronRightIcon } from 'lucide-react' import styles from 'styles/collapsible.module.css' export const Basic = () => ( What is Ark UI?
Ark UI is a headless component library for building accessible, high-quality UI components for React, Solid, Vue, and Svelte.
) ``` #### Solid ```tsx import { Collapsible } from '@ark-ui/solid/collapsible' import { ChevronRightIcon } from 'lucide-solid' import styles from 'styles/collapsible.module.css' export const Basic = () => ( What is Ark UI?
Ark UI is a headless component library for building accessible, high-quality UI components for React, Solid, Vue, and Svelte.
) ``` #### Vue ```vue ``` #### Svelte ```svelte What is Ark UI?
Ark UI is a headless component library for building accessible, high-quality UI components for React, Solid, Vue, and Svelte.
``` ### 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' import styles from 'styles/collapsible.module.css' export const Disabled = () => ( System Requirements
This section is currently unavailable.
) ``` #### Solid ```tsx import { Collapsible } from '@ark-ui/solid/collapsible' import { ChevronRightIcon } from 'lucide-solid' import styles from 'styles/collapsible.module.css' export const Disabled = () => ( System Requirements
This section is currently unavailable.
) ``` #### Vue ```vue ``` #### Svelte ```svelte System Requirements
This section is currently unavailable.
``` ### 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' import styles from 'styles/collapsible.module.css' export const PartialCollapse = () => ( Read More

Ark UI is a headless component library for building accessible, high-quality UI components for React, Solid, Vue, and Svelte. It provides unstyled, fully accessible components that you can customize to match your design system.

Built on top of Zag.js state machines, Ark UI ensures consistent behavior across all frameworks while giving you complete control over styling. Each component follows WAI-ARIA patterns for accessibility out of the box.

Whether you're building a design system from scratch or need reliable primitives for your next project, Ark UI provides the foundation you need without imposing any visual constraints.

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

Ark UI is a headless component library for building accessible, high-quality UI components for React, Solid, Vue, and Svelte. It provides unstyled, fully accessible components that you can customize to match your design system.

Built on top of Zag.js state machines, Ark UI ensures consistent behavior across all frameworks while giving you complete control over styling. Each component follows WAI-ARIA patterns for accessibility out of the box.

Whether you're building a design system from scratch or need reliable primitives for your next project, Ark UI provides the foundation you need without imposing any visual constraints.

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

Ark UI is a headless component library for building accessible, high-quality UI components for React, Solid, Vue, and Svelte. It provides unstyled, fully accessible components that you can customize to match your design system.

Built on top of Zag.js state machines, Ark UI ensures consistent behavior across all frameworks while giving you complete control over styling. Each component follows WAI-ARIA patterns for accessibility out of the box.

Whether you're building a design system from scratch or need reliable primitives for your next project, Ark UI provides the foundation you need without imposing any visual constraints.

``` > 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** #### React ```tsx import { Collapsible } from '@ark-ui/react/collapsible' import { ChevronRightIcon } from 'lucide-react' import styles from 'styles/collapsible.module.css' export const Nested = () => ( Getting Started

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

Installation

Install Ark UI using your preferred package manager:

npm install @ark-ui/react
Styling

Ark UI components are unstyled by default. Use CSS modules, Tailwind, or any styling solution.

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

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

Installation

Install Ark UI using your preferred package manager:

npm install @ark-ui/solid
Styling

Ark UI components are unstyled by default. Use CSS modules, Tailwind, or any styling solution.

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

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

Installation

Install Ark UI using your preferred package manager:

npm install @ark-ui/svelte
Styling

Ark UI components are unstyled by default. Use CSS modules, Tailwind, or any styling solution.

``` ### Lazy Mount Use `lazyMount` to delay mounting the content until first opened, and `unmountOnExit` to remove it from the DOM when collapsed. Combining both ensures the component is only in the DOM while expanded. **Example: lazy-mount** #### React ```tsx import { Collapsible } from '@ark-ui/react/collapsible' import { ChevronRightIcon } from 'lucide-react' import styles from 'styles/collapsible.module.css' export const LazyMount = () => ( Session Details
This content is lazily mounted when first opened and removed from the DOM when collapsed.
) ``` #### Solid ```tsx import { Collapsible } from '@ark-ui/solid/collapsible' import { ChevronRightIcon } from 'lucide-solid' import styles from 'styles/collapsible.module.css' export const LazyMount = () => ( Session Details
This content is lazily mounted when first opened and removed from the DOM when collapsed.
) ``` #### Vue ```vue ``` #### Svelte ```svelte Session Details
This content is lazily mounted when first opened and removed from the DOM when collapsed.
``` ### Root Provider An alternative way to control the collapsible is to use the `RootProvider` component and the `useCollapsible` hook. This way you can access the state and methods from outside the component. **Example: root-provider** #### React ```tsx import { Collapsible, useCollapsible } from '@ark-ui/react/collapsible' import { ChevronRightIcon } from 'lucide-react' import styles from 'styles/collapsible.module.css' export const RootProvider = () => { const collapsible = useCollapsible() return (
collapsible: {String(collapsible.open)}, visible: {String(collapsible.visible)} Toggle Panel
This panel can be toggled by the button above, which uses the useCollapsible hook for state management.
) } ``` #### Solid ```tsx import { Collapsible, useCollapsible } from '@ark-ui/solid/collapsible' import { ChevronRightIcon } from 'lucide-solid' import styles from 'styles/collapsible.module.css' export const RootProvider = () => { const collapsible = useCollapsible() return (
open: {String(collapsible().open)}, visible: {String(collapsible().visible)} Toggle Panel
This panel can be toggled by the button above, which uses the useCollapsible hook for state management.
) } ``` #### Vue ```vue ``` #### Svelte ```svelte
open: {String(collapsible().open)}, visible: {String(collapsible().visible)} Toggle Panel
This panel can be toggled by the button above, which uses the useCollapsible hook for state management.
``` ## Guides ### Indicator Animation 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`. ### Content Animation 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. | | `collapsedHeight` | `string | number` | No | The height of the content when collapsed. | | `collapsedWidth` | `string | number` | No | The width of the content when collapsed. | | `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 | | `[data-has-collapsed-size]` | Present when the content has collapsed width or height | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--height` | The height of the element | | `--width` | The width of the element | | `--collapsed-height` | The height of the Content | | `--collapsed-width` | The width of the Content | **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. | | `collapsedHeight` | `string | number` | No | The height of the content when collapsed. | | `collapsedWidth` | `string | number` | No | The width of the content when collapsed. | | `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 | | `[data-has-collapsed-size]` | Present when the content has collapsed width or height | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--height` | The height of the element | | `--width` | The width of the element | | `--collapsed-height` | The height of the Content | | `--collapsed-width` | The width of the Content | **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. | | `collapsedHeight` | `string | number` | No | The height of the content when collapsed. | | `collapsedWidth` | `string | number` | No | The width of the content when collapsed. | | `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 | | `[data-has-collapsed-size]` | Present when the content has collapsed width or height | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--height` | The height of the element | | `--width` | The width of the element | | `--collapsed-height` | The height of the Content | | `--collapsed-width` | The width of the Content | **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. | | `collapsedHeight` | `string | number` | No | The height of the content when collapsed. | | `collapsedWidth` | `string | number` | No | The width of the content when collapsed. | | `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 | | `[data-has-collapsed-size]` | Present when the content has collapsed width or height | **Content CSS Variables:** | Variable | Description | |----------|-------------| | `--height` | The height of the element | | `--width` | The width of the element | | `--collapsed-height` | The height of the Content | | `--collapsed-width` | The width of the Content | **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 **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