Collapsible
A collapsible is a component which expands and collapses a panel.
Lorem dfd dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna sfsd. Ut enim ad minimdfd v eniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Some Link
Features
- Can be controlled or uncontrolled.
- Works for width and height collapsibles.
Installation
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
npm install @zag-js/collapsible @zag-js/solid # or yarn add @zag-js/collapsible @zag-js/solid
npm install @zag-js/collapsible @zag-js/vue # or yarn add @zag-js/collapsible @zag-js/vue
npm install @zag-js/collapsible @zag-js/svelte # or yarn add @zag-js/collapsible @zag-js/svelte
This command will install the framework agnostic collapsible logic and the reactive utilities for your framework of choice.
Usage
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 theuseMachine
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.getRootProps()}> <button {...api.getTriggerProps()}>Collapse Trigger</button> <div {...api.getContentProps()}>Collape Content</div> </div> ) }
import * as collapsible from "@zag-js/collapsible" import { normalizeProps, useMachine } from "@zag-js/solid" import { createMemo, createUniqueId } from "solid-js" function Collapsible() { const [state, send] = useMachine( collapsible.machine({ id: createUniqueId() }), ) const api = createMemo(() => collapsible.connect(state, send, normalizeProps)) return ( <div {...api().getRootProps()}> <button {...api().getTriggerProps()}>Collapse Trigger</button> <div {...api().getContentProps()}>Collape Content</div> </div> ) }
<script setup> import * as collapsible from "@zag-js/collapsible" import { normalizeProps, useMachine } from "@zag-js/vue" import { computed } from "vue" const [state, send] = useMachine(collapsible.machine({ id: "1" })) const api = computed(() => collapsible.connect(state.value, send, normalizeProps), ) </script> <template> <div v-bind="api.getRootProps()"> <button v-bind="api.getTriggerProps()">Collapse Trigger</button> <div v-bind="api.getContentProps()">Collape Content</div> </div> </template>
<script lang="ts"> import * as collapsible from "@zag-js/collapsible" import { normalizeProps, useMachine } from "@zag-js/svelte" const [snapshot, send] = useMachine(collapsible.machine({ id: "1" })) const api = $derived(collapsible.connect(snapshot, send, normalizeProps)) </script> <div {...api.getRootProps()}> <button {...api.getTriggerProps()}>Collapse Trigger</button> <div {...api.getContentProps()}>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:", details.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-focus
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:
ids
Partial<{ root: string; content: string; trigger: string; }>
The ids of the elements in the collapsible. Useful for composition.onExitComplete
() => void
Function called when the animation ends in the closed state.onOpenChange
(details: OpenChangeDetails) => void
Function called when the popup is openedopen
boolean
Whether the collapsible is opendisabled
boolean
Whether the collapsible is disabledopen.controlled
boolean
Whether the collapsible open state is controlled by the userdir
"ltr" | "rtl"
The document's text/writing direction.id
string
The unique identifier of the machine.getRootNode
() => ShadowRoot | Node | Document
A root node to correctly resolve document in custom environments. E.x.: Iframes, Electron.
Machine API
The collapsible api
exposes the following methods:
open
boolean
Whether the collapsible is open.visible
boolean
Whether the collapsible is visible (open or closing)disabled
boolean
Whether the collapsible is disabledsetOpen
(open: boolean) => void
Function to open or close the collapsible.measureSize
() => void
Function to measure the size of the content.
Data Attributes
Accessibility
Adheres to the Disclosure WAI-ARIA design pattern.
Keyboard Interactions
- SpaceOpens/closes the collapsible.
- EnterOpens/closes the collapsible.
Edit this page on GitHub