Skip to main content
View Zag.js on Github
Join the Discord server


A collapsible is a component which expands and collapses a panel.



  • Can be controlled or uncontrolled.
  • Works for width and height collapsibles.


To use the collapsible machine in your project, run the following command in your command line:

npm install @zag-js/collapsible @zag-js/react # or yarn add @zag-js/collapsible @zag-js/react

This command will install the framework agnostic collapsible logic and the reactive utilities for your framework of choice.


First, import the collapsible package into your project

import * as collapsible from "@zag-js/collapsible"

The collapsible package exports two key functions:

  • machine — The state machine logic for the collapsible widget.
  • connect — The function that translates the machine's state to JSX attributes and event handlers.

You'll also need to provide a unique id to the useMachine hook. This is used to ensure that every part has a unique identifier.

Next, import the required hooks and functions for your framework and use the collapsible machine in your project 🔥

import * as collapsible from "@zag-js/collapsible" import { normalizeProps, useMachine } from "@zag-js/react" import { useId } from "react" function Collapsible() { const [state, send] = useMachine(collapsible.machine({ id: useId() })) const api = collapsible.connect(state, send, normalizeProps) return ( <div {...api.rootProps}> <button {...api.triggerProps}>Collapse Trigger</button> <div {...api.contentProps}>Collape Content</div> </div> ) }

Listening for changes

When the collapsible state changes, the onOpenChange callback is invoked.

const [state, send] = useMachine( collapsible.machine({ onOpenChange(details) { // details => { open: boolean } console.log("collapsible open:", }, }), )

Disabling the collapsible

Set the disabled machine context property to true to disable the collapsible.

const [state, send] = useMachine( collapsible.machine({ disabled: true, }), )

Animating the collapsible

Use CSS animations to animate the collapsible when it expands and collapses. The --height and --width custom properties are attached to the content part.

@keyframes expand { from { height: 0; } to { height: var(--height); } } @keyframes collapse { from { height: var(--height); } to { height: 0; } } [data-scope="collapsible"][data-part="content"] { overflow: hidden; max-width: 400px; } [data-scope="collapsible"][data-part="content"][data-state="open"] { animation: expand 110ms cubic-bezier(0, 0, 0.38, 0.9); } [data-scope="collapsible"][data-part="content"][data-state="closed"] { animation: collapse 110ms cubic-bezier(0, 0, 0.38, 0.9); }

Styling guide

Earlier, we mentioned that each collapsible part has a data-part attribute added to them to select and style them in the DOM.

Open and closed state

When a collapsible is expanded or collapsed, a data-state attribute is set on the root, trigger and content elements. This attribute is removed when it is closed.

[data-part="root"][data-state="open|closed"] { /* styles for the collapsible is open or closed state */ } [data-part="trigger"][data-state="open|closed"] { /* styles for the collapsible is open or closed state */ } [data-part="content"][data-state="open|closed"] { /* styles for the collapsible is open or closed state */ }

Focused state

When a collapsible's trigger is focused, a data-focused attribute is set on the root, trigger and content.

[data-part="root"][data-focus] { /* styles for the item's focus state */ } [data-part="trigger"][data-focus] { /* styles for the content's focus state */ } [data-part="content"][data-focus] { /* styles for the content's focus state */ }

Methods and Properties

The collapsible's api exposes the following methods and properties:

Machine Context

The collapsible machine exposes the following context properties:

  • idsPartial<{ root: string; content: string; trigger: string; }>The ids of the elements in the collapsible. Useful for composition.
  • onOpenChange(details: OpenChangeDetails) => voidFunction called when the popup is opened
  • openbooleanWhether the collapsible is open
  • disabledbooleanWhether the collapsible is disabled
  • open.controlledbooleanWhether the collapsible open state is controlled by the user
  • dir"ltr" | "rtl"The document's text/writing direction.
  • idstringThe unique identifier of the machine.
  • getRootNode() => ShadowRoot | Node | DocumentA root node to correctly resolve document in custom environments. E.x.: Iframes, Electron.

Machine API

The collapsible api exposes the following methods:

  • isOpenbooleanWhether the collapsible is open.
  • isDisabledbooleanWhether the collapsible is disabled
  • open() => voidFunction to open the collapsible.
  • close() => voidFunction to close the collapsible.


Adheres to the Disclosure WAI-ARIA design pattern.

Keyboard Interactions

  • Space
    Opens/closes the collapsible.
  • Enter
    Opens/closes the collapsible.

Edit this page on GitHub

On this page