# Accordion An accordion is a vertically stacked set of interactive headings containing a title, content snippet, or thumbnail representing a section of content. ## Resources [Latest version: v1.7.0](https://www.npmjs.com/package/@zag-js/accordion) [Logic Visualizer](https://zag-visualizer.vercel.app/accordion) [Source Code](https://github.com/chakra-ui/zag/tree/main/packages/machines/accordion) **Features** - Full keyboard navigation. - Can expand one or multiple items. - Collapse each accordion item. ## Installation To use the accordion machine in your project, run the following command in your command line: ```bash npm install @zag-js/accordion @zag-js/solid # or yarn add @zag-js/accordion @zag-js/solid ``` This command will install the framework agnostic accordion logic and the reactive utilities for your framework of choice. ## Anatomy To set up the accordion correctly, you'll need to understand its anatomy and how we name its parts. > Each part includes a `data-part` attribute to help identify them in the DOM. ## Usage First, import the accordion package into your project ```jsx import * as accordion from "@zag-js/accordion" ``` The accordion package exports two key functions: - `machine` — The state machine logic for the accordion 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 accordion machine in your project 🔥 ```jsx import * as accordion from "@zag-js/accordion" import { normalizeProps, useMachine } from "@zag-js/solid" import { createMemo, createUniqueId, For } from "solid-js" const data = [ { title: "Watercraft", content: "Sample accordion content" }, { title: "Automobiles", content: "Sample accordion content" }, { title: "Aircraft", content: "Sample accordion content" }, ] function Accordion() { const service = useMachine(accordion.machine, { id: createUniqueId() }) const api = createMemo(() => accordion.connect(service, normalizeProps)) return (
{(item) => (

{item.content}
)}
) } ``` You may have noticed we wrapped each accordion trigger within an `h3`. This is recommended by the [WAI-ARIA](https://www.w3.org/TR/wai-aria-practices-1.1/#wai-aria-roles-states-and-properties) design pattern to ensure the accordion has the appropriate hierarchy on the page. ## Opening multiple accordions at once To allow multiple items to be expanded at once, set `multiple` to `true`. This mode implicitly sets `collapsible` to `true` and ensures that each accordion can be expanded. ```jsx {2} const service = useMachine(accordion.machine, { multiple: true, }) ``` ## Opening specific accordions To set the value of the accordion(s) that should be opened initially, pass the `value` property to the machine function. ```jsx {3,4,9} // for multiple accordions const service = useMachine(accordion.machine, { multiple: true, defaultValue: ["home"], }) // for single accordions const service = useMachine(accordion.machine, { defaultValue: ["home"], }) ``` ## Toggle each accordion item To collapse an already expanded accordion item by clicking on it, set the context's `collapsible` property to `true`. > Note: If `multiple` is `true`, we internally set `collapsible` to be `true`. ```jsx {2} const service = useMachine(accordion.machine, { collapsible: true, }) ``` ## Listening for changes When the accordion value changes, the `onValueChange` callback is invoked. ```jsx {2-5} const service = useMachine(accordion.machine, { onValueChange(details) { // details => { value: string[] } console.log("selected accordion:", details.value) }, }) ``` ## Disabling an accordion item To disable a specific accordion item, pass the `disabled: true` property to the `getItemProps`, `getItemTriggerProps` and `getItemContentProps`. When an accordion item is disabled, it is skipped from keyboard navigation and can't be interacted with. ```jsx //...

Content
//... ``` You can also disable the entire accordion items by passing `disabled` to the machine's context. ```jsx {2} const service = useMachine(accordion.machine, { disabled: true, }) ``` ## Styling guide Earlier, we mentioned that each accordion part has a `data-part` attribute added to them to select and style them in the DOM. ### Open and closed state When an accordion item is expanded or collapsed, a `data-state` attribute is set on the item, trigger and content elements. This attribute is removed when it is closed. ```css [data-part="item"][data-state="open|closed"] { /* styles for the item is open or closed state */ } [data-part="item-trigger"][data-state="open|closed"] { /* styles for the item is open or closed state */ } [data-part="item-content"][data-state="open|closed"] { /* styles for the item is open or closed state */ } ``` ### Focused state When an accordion item's trigger is focused, a `data-focus` attribute is set on the item and content. ```css [data-part="item"][data-focus] { /* styles for the item's focus state */ } [data-part="item-trigger"]:focus { /* styles for the trigger's focus state */ } [data-part="item-content"][data-focus] { /* styles for the content's focus state */ } ``` ## Creating Component Create your accordion component by abstracting the machine into your own component. ### Usage ```tsx import { Accordion } from "./your-accordion" function Demo() { return ( ) } ``` ### Implementation Use the the `splitProps` utility to separate the machine's props from the component's props. ```tsx import * as accordion from "@zag-js/accordion" import { normalizeProps, useMachine } from "@zag-js/solid" import { mergeProps, splitProps, createMemo, createUniqueId, For, JSX, } from "solid-js" interface Item { value: string title: JSX.Element content: JSX.Element } export interface AccordionProps extends Omit { items: Item[] } export function Accordion(props: AccordionProps) { const [machineProps, localProps] = splitProps(props, accordion.props) const context = mergeProps(machineProps, { id: createUniqueId() }) const service = useMachine(accordion.machine, context) const api = createMemo(() => accordion.connect(service, normalizeProps)) return (
{(item) => (

{item.content}
)}
) } ``` ## Methods and Properties The accordion's `api` exposes the following methods and properties: ### Machine Context The accordion machine exposes the following context properties: **`ids`** Type: `Partial<{ root: string; item(value: string): string; itemContent(value: string): string; itemTrigger(value: string): string; }>` Description: The ids of the elements in the accordion. Useful for composition. **`multiple`** Type: `boolean` Description: Whether multiple accordion items can be expanded at the same time. **`collapsible`** Type: `boolean` Description: Whether an accordion item can be closed after it has been expanded. **`value`** Type: `string[]` Description: The controlled value of the expanded accordion items. **`defaultValue`** Type: `string[]` Description: The initial value of the expanded accordion items. Use when you don't need to control the value of the accordion. **`disabled`** Type: `boolean` Description: Whether the accordion items are disabled **`onValueChange`** Type: `(details: ValueChangeDetails) => void` Description: The callback fired when the state of expanded/collapsed accordion items changes. **`onFocusChange`** Type: `(details: FocusChangeDetails) => void` Description: The callback fired when the focused accordion item changes. **`orientation`** Type: `"horizontal" | "vertical"` Description: The orientation of the accordion items. **`dir`** Type: `"ltr" | "rtl"` Description: The document's text/writing direction. **`id`** Type: `string` Description: The unique identifier of the machine. **`getRootNode`** Type: `() => ShadowRoot | Node | Document` Description: A root node to correctly resolve document in custom environments. E.x.: Iframes, Electron. ### Machine API The accordion `api` exposes the following methods: **`focusedValue`** Type: `string` Description: The value of the focused accordion item. **`value`** Type: `string[]` Description: The value of the accordion **`setValue`** Type: `(value: string[]) => void` Description: Sets the value of the accordion. **`getItemState`** Type: `(props: ItemProps) => ItemState` Description: Gets the state of an accordion item. ### Data Attributes **`Root`** **`data-scope`**: accordion **`data-part`**: root **`data-orientation`**: The orientation of the accordion **`Item`** **`data-scope`**: accordion **`data-part`**: item **`data-state`**: "open" | "closed" **`data-focus`**: Present when focused **`data-disabled`**: Present when disabled **`data-orientation`**: The orientation of the item **`ItemContent`** **`data-scope`**: accordion **`data-part`**: item-content **`data-state`**: "open" | "closed" **`data-disabled`**: Present when disabled **`data-focus`**: Present when focused **`data-orientation`**: The orientation of the item **`ItemIndicator`** **`data-scope`**: accordion **`data-part`**: item-indicator **`data-state`**: "open" | "closed" **`data-disabled`**: Present when disabled **`data-focus`**: Present when focused **`data-orientation`**: The orientation of the item **`ItemTrigger`** **`data-scope`**: accordion **`data-part`**: item-trigger **`data-orientation`**: The orientation of the item **`data-state`**: "open" | "closed" ## Accessibility ### Keyboard Interactions **`Space`** Description: When focus is on an trigger of a collapsed item, the item is expanded **`Enter`** Description: When focus is on an trigger of a collapsed section, expands the section. **`Tab`** Description: Moves focus to the next focusable element **`Shift + Tab`** Description: Moves focus to the previous focusable element **`ArrowDown`** Description: Moves focus to the next trigger **`ArrowUp`** Description: Moves focus to the previous trigger. **`Home`** Description: When focus is on an trigger, moves focus to the first trigger. **`End`** Description: When focus is on an trigger, moves focus to the last trigger. # Angle Slider An angle slider is a circular dial that allows users to select an angle, typically in degrees, within a 360° range. It provides an intuitive way to control rotations or orientations, offering accessibility features. ## Resources [Latest version: v1.7.0](https://www.npmjs.com/package/@zag-js/angle-slider) [Logic Visualizer](https://zag-visualizer.vercel.app/angle-slider) [Source Code](https://github.com/chakra-ui/zag/tree/main/packages/machines/angle-slider) **Features** - Fully managed keyboard navigation. - Supports touch or click on track to update value. - Supports Right-to-Left directionality. ## Installation To use the angle slider machine in your project, run the following command in your command line: ```bash npm install @zag-js/angle-slider @zag-js/solid # or yarn add @zag-js/angle-slider @zag-js/solid ``` This command will install the framework agnostic angle slider logic and the reactive utilities for your framework of choice. ## Anatomy To set up the angle slider correctly, you'll need to understand its anatomy and how we name its parts. > Each part includes a `data-part` attribute to help identify them in the DOM. ## Usage First, import the angle-slider package into your project ```jsx import * as angleSlider from "@zag-js/angle-slider" ``` The angle slider package exports two key functions: - `machine` — The state machine logic for the angle slider widget as described in the WAI-ARIA spec. - `connect` — The function that translates the machine's state to JSX attributes and event handlers. > You'll 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 angle slider machine in your project 🔥 ```jsx import * as angleSlider from "@zag-js/angle-slider" import { normalizeProps, useMachine } from "@zag-js/solid" import { createMemo, createUniqueId, Index } from "solid-js" export function AngleSlider() { const service = useMachine(angleSlider.machine, { id: createUniqueId() }) const api = createMemo(() => angleSlider.connect(service, normalizeProps)) return (
{(value) => (
)}
) } ``` ## Setting the initial value ```jsx {2} const service = useMachine(angleSlider.machine, { defaultValue: 45, }) ``` ## Setting the value's granularity By default, the granularity, is `1`, meaning that the value is always an integer. You can change the step attribute to control the granularity. For example, If you need a value between `5` and `10`, accurate to two decimal places, you should set the value of step to `0.01`: ```jsx {2} const service = useMachine(angleSlider.machine, { step: 0.01, }) ``` ## Listening for changes When the angle slider value changes, the `onValueChange` and `onValueChangeEnd` callbacks are invoked. You can use this to setup custom behaviors in your app. ```jsx {2-7} const service = useMachine(angleSlider.machine, { onValueChange(details) { console.log("value is changing to:", details) }, onValueChangeEnd(details) { console.log("value has changed to:", details) }, }) ``` ## Usage within forms To use angle slider within forms, use the exposed `hiddenInputProps` from the `connect` function and ensure you pass `name` value to the machine's context. It will render a hidden input and ensure the value changes get propagated to the form correctly. ```jsx {2} const service = useMachine(angleSlider.machine, { name: "wind-direction", }) ``` ## Using angle slider marks To show marks or ticks along the angle slider track, use the exposed `api.getMarkerProps()` method to position the angle slider marks at desired angles. ```jsx {7-11} //...
{[0, 45, 90, 135, 180, 225, 270, 315].map((value) => (
))}
{api().value} degrees
//... ``` ## Styling guide Earlier, we mentioned that each angle slider part has a `data-part` attribute added to them to select and style them in the DOM. ### Disabled State When the angle slider is disabled, the `data-disabled` attribute is added to the root, label, control, thumb and marker. ```css [data-part="root"][data-disabled] { /* styles for root disabled state */ } [data-part="label"][data-disabled] { /* styles for label disabled state */ } [data-part="control"][data-disabled] { /* styles for control disabled state */ } [data-part="thumb"][data-disabled] { /* styles for thumb disabled state */ } [data-part="range"][data-disabled] { /* styles for thumb disabled state */ } ``` ### Invalid State When the slider is invalid, the `data-invalid` attribute is added to the root, track, range, label, and thumb parts. ```css [data-part="root"][data-invalid] { /* styles for root invalid state */ } [data-part="label"][data-invalid] { /* styles for label invalid state */ } [data-part="control"][data-invalid] { /* styles for control invalid state */ } [data-part="valueText"][data-invalid] { /* styles for output invalid state */ } [data-part="thumb"][data-invalid] { /* styles for thumb invalid state */ } [data-part="marker"][data-invalid] { /* styles for marker invalid state */ } ``` ### Styling the markers ```css [data-part="marker"][data-state="(at|under|over)-value"] { /* styles for when the value exceeds the marker's value */ } ``` ## Methods and Properties ### Machine Context The slider machine exposes the following context properties: **`ids`** Type: `Partial<{ root: string; thumb: string; hiddenInput: string; control: string; valueText: string; }>` Description: The ids of the elements in the machine. Useful for composition. **`step`** Type: `number` Description: The step value for the slider. **`value`** Type: `number` Description: The value of the slider. **`defaultValue`** Type: `number` Description: The initial value of the slider. Use when you don't need to control the value of the slider. **`onValueChange`** Type: `(details: ValueChangeDetails) => void` Description: The callback function for when the value changes. **`onValueChangeEnd`** Type: `(details: ValueChangeDetails) => void` Description: The callback function for when the value changes ends. **`disabled`** Type: `boolean` Description: Whether the slider is disabled. **`readOnly`** Type: `boolean` Description: Whether the slider is read-only. **`invalid`** Type: `boolean` Description: Whether the slider is invalid. **`name`** Type: `string` Description: The name of the slider. Useful for form submission. **`dir`** Type: `"ltr" | "rtl"` Description: The document's text/writing direction. **`id`** Type: `string` Description: The unique identifier of the machine. **`getRootNode`** Type: `() => ShadowRoot | Node | Document` Description: A root node to correctly resolve document in custom environments. E.x.: Iframes, Electron. ### Machine API The slider `api` exposes the following methods: **`value`** Type: `number` Description: The current value of the angle slider **`valueAsDegree`** Type: `string` Description: The current value as a degree string **`setValue`** Type: `(value: number) => void` Description: Sets the value of the angle slider **`dragging`** Type: `boolean` Description: Whether the slider is being dragged. ### Data Attributes **`Root`** **`data-scope`**: angle-slider **`data-part`**: root **`data-disabled`**: Present when disabled **`data-invalid`**: Present when invalid **`data-readonly`**: Present when read-only **`Label`** **`data-scope`**: angle-slider **`data-part`**: label **`data-disabled`**: Present when disabled **`data-invalid`**: Present when invalid **`data-readonly`**: Present when read-only **`Control`** **`data-scope`**: angle-slider **`data-part`**: control **`data-disabled`**: Present when disabled **`data-invalid`**: Present when invalid **`data-readonly`**: Present when read-only **`Thumb`** **`data-scope`**: angle-slider **`data-part`**: thumb **`data-disabled`**: Present when disabled **`data-invalid`**: Present when invalid **`data-readonly`**: Present when read-only **`Marker`** **`data-scope`**: angle-slider **`data-part`**: marker **`data-value`**: The value of the item **`data-state`**: **`data-disabled`**: Present when disabled ### Keyboard Interactions **`ArrowRight`** Description: Increments the angle slider based on defined step **`ArrowLeft`** Description: Decrements the angle slider based on defined step **`ArrowUp`** Description: Decreases the value by the step amount. **`ArrowDown`** Description: Increases the value by the step amount. **`Shift + ArrowUp`** Description: Decreases the value by a larger step **`Shift + ArrowDown`** Description: Increases the value by a larger step **`Home`** Description: Sets the value to 0 degrees. **`End`** Description: Sets the value to 360 degrees. # Avatar The Avatar component is a React component that represents a user avatar or profile picture. It displays an image or initials within container. Avatar provides support for fallback text or elements when the image fails to load, or when the image is not provided. ## Resources [Latest version: v1.7.0](https://www.npmjs.com/package/@zag-js/avatar) [Logic Visualizer](https://zag-visualizer.vercel.app/avatar) [Source Code](https://github.com/chakra-ui/zag/tree/main/packages/machines/avatar) ## Installation To use the avatar machine in your project, run the following command in your command line: ```bash npm install @zag-js/avatar @zag-js/solid # or yarn add @zag-js/avatar @zag-js/solid ``` This command will install the framework agnostic avatar logic and the reactive utilities for your framework of choice. ## Anatomy To set up the avatar correctly, you'll need to understand its anatomy and how we name its parts. > Each part includes a `data-part` attribute to help identify them in the DOM. ## Usage First, import the avatar package into your project ```jsx import * as avatar from "@zag-js/avatar" ``` The avatar package exports two key functions: - `machine` — The state machine logic for the avatar 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 avatar machine in your project 🔥 ```jsx import * as avatar from "@zag-js/avatar" import { useMachine, normalizeProps } from "@zag-js/solid" function Avatar() { const service = useMachine(avatar.machine, { id: "1" }) const api = createMemo(() => avatar.connect(service, normalizeProps)) return (
PA PA
) } ``` ## Listening for loading status changes When the image has loaded or failed to load, the `onStatusChange` callback is invoked. ```jsx {2} const service = useMachine(avatar.machine, { onStatusChange(details) { // details => { status: "error" | "loaded" } }, }) ``` ## Styling guide Earlier, we mentioned that each avatar part has a `data-part` attribute added to them to select and style them in the DOM. ```css [data-scope="avatar"][data-part="root"] { /* Styles for the root part */ } [data-scope="avatar"][data-part="image"] { /* Styles for the image part */ } [data-scope="avatar"][data-part="fallback"] { /* Styles for the fallback part */ } ``` ## Creating Component Create your avatar component by abstracting the machine into your own component. ### Usage ### Implementation Use the the `splitProps` utility to separate the machine's props from the component's props. ## Methods and Properties ### Machine Context The avatar machine exposes the following context properties: **`onStatusChange`** Type: `(details: StatusChangeDetails) => void` Description: Functional called when the image loading status changes. **`ids`** Type: `Partial<{ root: string; image: string; fallback: string; }>` Description: The ids of the elements in the avatar. Useful for composition. **`id`** Type: `string` Description: The unique identifier of the machine. **`getRootNode`** Type: `() => ShadowRoot | Node | Document` Description: A root node to correctly resolve document in custom environments. E.x.: Iframes, Electron. **`dir`** Type: `"ltr" | "rtl"` Description: The document's text/writing direction. ### Machine API The avatar `api` exposes the following methods: **`loaded`** Type: `boolean` Description: Whether the image is loaded. **`setSrc`** Type: `(src: string) => void` Description: Function to set new src. **`setLoaded`** Type: `() => void` Description: Function to set loaded state. **`setError`** Type: `() => void` Description: Function to set error state. ### Data Attributes **`Image`** **`data-scope`**: avatar **`data-part`**: image **`data-state`**: "visible" | "hidden" **`Fallback`** **`data-scope`**: avatar **`data-part`**: fallback **`data-state`**: "hidden" | "visible" # Carousel an accessible carousel component that leverages native CSS Scroll Snap for smooth, performant scrolling between slides. ## Resources [Latest version: v1.7.0](https://www.npmjs.com/package/@zag-js/carousel) [Logic Visualizer](https://zag-visualizer.vercel.app/carousel) [Source Code](https://github.com/chakra-ui/zag/tree/main/packages/machines/carousel) **Features** - Uses native CSS Scroll Snap. - Supports horizontal and vertical orientations. - Supports alignment of slides (start, center or end alignment). - Show multiple slides at a time. - Supports looping and auto-playing. - Supports custom spacing between slides. ## Installation To use the carousel machine in your project, run the following command in your command line: ```bash npm install @zag-js/carousel @zag-js/solid # or yarn add @zag-js/carousel @zag-js/solid ``` This command will install the framework agnostic carousel logic and the reactive utilities for your framework of choice. ## Anatomy To set up the carousel correctly, you'll need to understand its anatomy and how we name its parts. > Each part includes a `data-part` attribute to help identify them in the DOM. ## Usage First, import the carousel package into your project ```jsx import * as carousel from "@zag-js/carousel" ``` The carousel package exports two key functions: - `machine` — The state machine logic for the carousel 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 carousel machine in your project 🔥 > **Note:** The carousel requires that you provide a `slideCount` property in > the machine's context. This is the number of slides in the carousel. ```jsx import * as carousel from "@zag-js/carousel" import { normalizeProps, useMachine } from "@zag-js/solid" import { createMemo, createUniqueId, For } from "solid-js" const items = [ "https://tinyurl.com/5b6ka8jd", "https://tinyurl.com/7rmccdn5", "https://tinyurl.com/59jxz9uu", ] export function Carousel() { const service = useMachine(carousel.machine, { id: createUniqueId(), slideCount: items.length, }) const api = createMemo(() => carousel.connect(service, normalizeProps)) return (
{(image, index) => (
)}
{(_, index) =>
) } ``` ## Vertical carousel To create a vertical carousel, set the `orientation` property in the machine's context to `vertical`. ```jsx {2} const service = useMachine(carousel.machine, { orientation: "vertical", }) ``` ## Setting the initial slide To set the initial slide of the carousel, pass the `page` property to the machine's context. The `page` corresponds to the scroll snap position index based on the layout. It does not necessarily correspond to the index of the slide in the carousel. ```jsx {2} const service = useMachine(carousel.machine, { defaultPage: 2, }) ``` ## Setting the number of slides to show at a time To customize number of slides to show at a time, set the `slidesPerPage` property in the machine's context. The value must be an integer. ```jsx {2} const service = useMachine(carousel.machine, { slidesPerPage: 2, }) ``` ## Setting the number of slides to move at a time To customize number of slides to move at a time, set the `slidesPerMove` property in the machine's context. The value must be an integer or `auto`. > If the value is `auto`, the carousel will move the number of slides equal to > the number of slides per page. ```jsx {2} const service = useMachine(carousel.machine, { slidesPerMove: 2, }) ``` > Ensure the `slidesPerMove` is less than or equal to the `slidesPerPage` to > avoid skipping slides. ## Setting the carousel should loop around To allow looping of slides, set the `loop` property in the machine's context to `true`. ```jsx {2} const service = useMachine(carousel.machine, { loop: true, }) ``` ## Setting the gap between slides To customize spacing between slides, set the `spacing` property in the machine's context to a valid CSS unit. ```jsx {2} const service = useMachine(carousel.machine, { spacing: "16px", }) ``` ## Listening for page changes When the carousel page changes, the `onPageChange` callback is invoked. ```jsx {2-5} const service = useMachine(carousel.machine, { onPageChange(details) { // details => { page: number } console.log("selected page:", details.page) }, }) ``` ## Dragging the carousel To allow dragging the carousel with the mouse, set the `allowMouseDrag` property in the machine's context to `true`. ```jsx {2} const service = useMachine(carousel.machine, { allowMouseDrag: true, }) ``` ## Autoplaying the carousel To allow the carousel to autoplay, set the `autoplay` property in the machine's context to `true`. ```jsx {2} const service = useMachine(carousel.machine, { autoplay: true, }) ``` Alternatively, you can configure the autoplay interval by setting the `delay` property in the machine's context. ```jsx {2} const service = useMachine(carousel.machine, { autoplay: { delay: 2000 }, }) ``` ## Styling guide Earlier, we mentioned that each carousel part has a `data-part` attribute added to them to select and style them in the DOM. ```css [data-part="root"] { /* styles for the root part */ } [data-part="item-group"] { /* styles for the item-group part */ } [data-part="item"] { /* styles for the root part */ } [data-part="control"] { /* styles for the control part */ } [data-part="next-trigger"] { /* styles for the next-trigger part */ } [data-part="prev-trigger"] { /* styles for the prev-trigger part */ } [data-part="indicator-group"] { /* styles for the indicator-group part */ } [data-part="indicator"] { /* styles for the indicator part */ } [data-part="autoplay-trigger"] { /* styles for the autoplay-trigger part */ } ``` ### Active state When a carousel's indicator is active, a `data-current` attribute is set on the indicator. ```css [data-part="indicator"][data-current] { /* styles for the indicator's active state */ } ``` ## Methods and Properties The carousel's `api` exposes the following methods and properties: ### Machine Context The carousel machine exposes the following context properties: **`ids`** Type: `Partial<{ root: string; item(index: number): string; itemGroup: string; nextTrigger: string; prevTrigger: string; indicatorGroup: string; indicator(index: number): string; }>` Description: The ids of the elements in the carousel. Useful for composition. **`translations`** Type: `IntlTranslations` Description: The localized messages to use. **`slidesPerPage`** Type: `number` Description: The number of slides to show at a time. **`slidesPerMove`** Type: `number | "auto"` Description: The number of slides to scroll at a time. When set to `auto`, the number of slides to scroll is determined by the `slidesPerPage` property. **`autoplay`** Type: `boolean | { delay: number; }` Description: Whether to scroll automatically. The default delay is 4000ms. **`allowMouseDrag`** Type: `boolean` Description: Whether to allow scrolling via dragging with mouse **`loop`** Type: `boolean` Description: Whether the carousel should loop around. **`page`** Type: `number` Description: The controlled page of the carousel. **`defaultPage`** Type: `number` Description: The initial page to scroll to when rendered. Use when you don't need to control the page of the carousel. **`spacing`** Type: `string` Description: The amount of space between items. **`padding`** Type: `string` Description: Defines the extra space added around the scrollable area, enabling nearby items to remain partially in view. **`onPageChange`** Type: `(details: PageChangeDetails) => void` Description: Function called when the page changes. **`inViewThreshold`** Type: `number | number[]` Description: The threshold for determining if an item is in view. **`snapType`** Type: `"proximity" | "mandatory"` Description: The snap type of the item. **`slideCount`** Type: `number` Description: The total number of slides. Useful for SSR to render the initial ating the snap points. **`onDragStatusChange`** Type: `(details: DragStatusDetails) => void` Description: Function called when the drag status changes. **`onAutoplayStatusChange`** Type: `(details: AutoplayStatusDetails) => void` Description: Function called when the autoplay status changes. **`dir`** Type: `"ltr" | "rtl"` Description: The document's text/writing direction. **`id`** Type: `string` Description: The unique identifier of the machine. **`getRootNode`** Type: `() => ShadowRoot | Node | Document` Description: A root node to correctly resolve document in custom environments. E.x.: Iframes, Electron. **`orientation`** Type: `"horizontal" | "vertical"` Description: The orientation of the element. ### Machine API The carousel `api` exposes the following methods: **`page`** Type: `number` Description: The current index of the carousel **`pageSnapPoints`** Type: `number[]` Description: The current snap points of the carousel **`isPlaying`** Type: `boolean` Description: Whether the carousel is auto playing **`isDragging`** Type: `boolean` Description: Whether the carousel is being dragged. This only works when `draggable` is true. **`canScrollNext`** Type: `boolean` Description: Whether the carousel is can scroll to the next view **`canScrollPrev`** Type: `boolean` Description: Whether the carousel is can scroll to the previous view **`scrollToIndex`** Type: `(index: number, instant?: boolean) => void` Description: Function to scroll to a specific item index **`scrollTo`** Type: `(page: number, instant?: boolean) => void` Description: Function to scroll to a specific page **`scrollNext`** Type: `(instant?: boolean) => void` Description: Function to scroll to the next page **`scrollPrev`** Type: `(instant?: boolean) => void` Description: Function to scroll to the previous page **`getProgress`** Type: `() => number` Description: Returns the current scroll progress as a percentage **`play`** Type: `() => void` Description: Function to start/resume autoplay **`pause`** Type: `() => void` Description: Function to pause autoplay **`isInView`** Type: `(index: number) => boolean` Description: Whether the item is in view **`refresh`** Type: `() => void` Description: Function to re-compute the snap points and clamp the page ### Data Attributes **`Root`** **`data-scope`**: carousel **`data-part`**: root **`data-orientation`**: The orientation of the carousel **`ItemGroup`** **`data-scope`**: carousel **`data-part`**: item-group **`data-orientation`**: The orientation of the item **`data-dragging`**: Present when in the dragging state **`Item`** **`data-scope`**: carousel **`data-part`**: item **`data-index`**: The index of the item **`data-inview`**: Present when in viewport **`data-orientation`**: The orientation of the item **`Control`** **`data-scope`**: carousel **`data-part`**: control **`data-orientation`**: The orientation of the control **`PrevTrigger`** **`data-scope`**: carousel **`data-part`**: prev-trigger **`data-orientation`**: The orientation of the prevtrigger **`NextTrigger`** **`data-scope`**: carousel **`data-part`**: next-trigger **`data-orientation`**: The orientation of the nexttrigger **`IndicatorGroup`** **`data-scope`**: carousel **`data-part`**: indicator-group **`data-orientation`**: The orientation of the indicatorgroup **`Indicator`** **`data-scope`**: carousel **`data-part`**: indicator **`data-orientation`**: The orientation of the indicator **`data-index`**: The index of the item **`data-readonly`**: Present when read-only **`data-current`**: Present when current **`AutoplayTrigger`** **`data-scope`**: carousel **`data-part`**: autoplay-trigger **`data-orientation`**: The orientation of the autoplaytrigger **`data-pressed`**: Present when pressed # Checkbox A checkbox allows users to make a binary choice, i.e. a choice between one of two possible mutually exclusive options. ## Resources [Latest version: v1.7.0](https://www.npmjs.com/package/@zag-js/checkbox) [Logic Visualizer](https://zag-visualizer.vercel.app/checkbox) [Source Code](https://github.com/chakra-ui/zag/tree/main/packages/machines/checkbox) **Features** - Tri-state checkbox. i.e. `indeterminate` state - Syncs with `disabled` state of fieldset - Syncs with form `reset` events - Can be toggled programmatically ## Installation To use the checkbox machine in your project, run the following command in your command line: ```bash npm install @zag-js/checkbox @zag-js/solid # or yarn add @zag-js/checkbox @zag-js/solid ``` This command will install the framework agnostic checkbox logic and the reactive utilities for your framework of choice. ## Anatomy To set up the checkbox correctly, you'll need to understand its anatomy and how we name its parts. > Each part includes a `data-part` attribute to help identify them in the DOM. ## Usage First, import the checkbox package into your project ```jsx import * as checkbox from "@zag-js/checkbox" ``` The checkbox package exports two key functions: - `machine` — The state machine logic for the checkbox widget. - `connect` — The function that translates the machine's state to JSX attributes and event handlers. Next, import the required hooks and functions for your framework and use the checkbox machine in your project 🔥 ```jsx import * as checkbox from "@zag-js/checkbox" import { normalizeProps, useMachine } from "@zag-js/solid" import { createMemo, createUniqueId } from "solid-js" function Checkbox() { const service = useMachine(checkbox.machine, { id: createUniqueId() }) const api = createMemo(() => checkbox.connect(service, normalizeProps)) return (