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

Checkbox

A checkbox allows users to make a binary choice, i.e. a choice between one of two possible mutually exclusive options.

Properties

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:

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

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

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 🔥

import * as checkbox from "@zag-js/checkbox" import { useMachine, normalizeProps } from "@zag-js/react" function Checkbox() { const [state, send] = useMachine(checkbox.machine({ id: "1" })) const api = checkbox.connect(state, send, normalizeProps) return ( <label {...api.getRootProps()}> <span {...api.getLabelProps()}> Input is {api.checked ? "checked" : "unchecked"} </span> <div {...api.getControlProps()} /> <input {...api.getHiddenInputProps()} /> </label> ) }

Indeterminate checkboxes

To make a checkbox indeterminate, set the context's indeterminate property to true

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

Disabling the checkbox

To make a checkbox disabled, set the context's disabled property to true

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

Making it checked by default

To make a checkbox checked by default, set the context's checked property to true

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

Listening for changes

When the checkbox value changes, the onCheckChange callback is invoked.

const [state, send] = useMachine( checkbox.machine({ onCheckChange(details) { // details => { checked: boolean } console.log("checkbox is:", details.checked) }, }), )

Usage within forms

To use checkbox 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.

const [state, send] = useMachine( checkbox.machine({ name: "fruits", }), )

Styling guide

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

Checked state

When the checkbox input is checked, the data-checked attribute is added to the root, control and label parts.

[data-part="root"][data-state="checked|unchecked|indeterminate"] { /* styles for when checkbox is checked */ } [data-part="control"][data-state="checked|unchecked|indeterminate"] { /* styles for when checkbox is checked */ } [data-part="label"][data-state="checked|unchecked|indeterminate"] { /* styles for when checkbox is checked */ }

Focused State

When the checkbox input is focused, the data-focus attribute is added to the root, control and label parts.

[data-part="root"][data-focus] { /* styles for root focus state */ } [data-part="control"][data-focus] { /* styles for control focus state */ } [data-part="label"][data-focus] { /* styles for label focus state */ }

Disabled State

When the checkbox is disabled, the data-disabled attribute is added to the root, control and label parts.

[data-part="root"][data-disabled] { /* styles for root disabled state */ } [data-part="control"][data-disabled] { /* styles for control disabled state */ } [data-part="label"][data-disabled] { /* styles for label disabled state */ }

Invalid State

When the checkbox is invalid, the data-invalid attribute is added to the root, control and label parts.

[data-part="root"][data-invalid] { /* styles for root invalid state */ } [data-part="control"][data-invalid] { /* styles for control invalid state */ } [data-part="label"][data-invalid] { /* styles for label invalid state */ }

Methods and Properties

Machine Context

The checkbox machine exposes the following context properties:

  • idsPartial<{ root: string; hiddenInput: string; control: string; label: string; }>The ids of the elements in the checkbox. Useful for composition.
  • disabledbooleanWhether the checkbox is disabled
  • invalidbooleanWhether the checkbox is invalid
  • requiredbooleanWhether the checkbox is required
  • checkedCheckedStateThe checked state of the checkbox
  • readOnlybooleanWhether the checkbox is read-only
  • onCheckedChange(details: CheckedChangeDetails) => voidThe callback invoked when the checked state changes.
  • namestringThe name of the input field in a checkbox. Useful for form submission.
  • formstringThe id of the form that the checkbox belongs to.
  • valuestringThe value of checkbox input. Useful for form submission.
  • 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 checkbox api exposes the following methods:

  • checkedbooleanWhether the checkbox is checked
  • disabledbooleanWhether the checkbox is disabled
  • indeterminatebooleanWhether the checkbox is indeterminate
  • focusedbooleanWhether the checkbox is focused
  • checkedStateCheckedStateThe checked state of the checkbox
  • setChecked(checked: CheckedState) => voidFunction to set the checked state of the checkbox
  • toggleChecked() => voidFunction to toggle the checked state of the checkbox

Data Attributes

Root
data-active
Present when active or pressed
data-focus
Present when focused
data-focus-visible
Present when focused with keyboard
data-readonly
Present when read-only
data-hover
Present when hovered
data-disabled
Present when disabled
data-state
"indeterminate" | "checked" | "unchecked"
data-invalid
Present when invalid
Label
data-active
Present when active or pressed
data-focus
Present when focused
data-focus-visible
Present when focused with keyboard
data-readonly
Present when read-only
data-hover
Present when hovered
data-disabled
Present when disabled
data-state
"indeterminate" | "checked" | "unchecked"
data-invalid
Present when invalid
Control
data-active
Present when active or pressed
data-focus
Present when focused
data-focus-visible
Present when focused with keyboard
data-readonly
Present when read-only
data-hover
Present when hovered
data-disabled
Present when disabled
data-state
"indeterminate" | "checked" | "unchecked"
data-invalid
Present when invalid
Indicator
data-active
Present when active or pressed
data-focus
Present when focused
data-focus-visible
Present when focused with keyboard
data-readonly
Present when read-only
data-hover
Present when hovered
data-disabled
Present when disabled
data-state
"indeterminate" | "checked" | "unchecked"
data-invalid
Present when invalid

Accessibility

Keyboard Interactions

  • Space
    Toggle the checkbox

Edit this page on GitHub

Proudly made in🇳🇬by Segun Adebayo

Copyright © 2024
On this page