Checkbox

import {Checkbox} from "@qualcomm-ui/react/checkbox"

Examples

Simple

The simple API provides a standalone component with built-in layout.

<Checkbox label="Checkbox" />

Composite

Build with the composite API for granular control. This API requires you to provide each subcomponent, but gives you full control over the structure and layout.

<Checkbox.Root>
  <Checkbox.HiddenInput />
  <Checkbox.Label>Label</Checkbox.Label>
  <Checkbox.Control />
</Checkbox.Root>

States

Based on the inputs, the checkbox will render as checked, indeterminate, or unchecked (default). The checked state takes precedence over indeterminate.

Checked
Unchecked
Indeterminate
<Checkbox defaultChecked label="Label" />
<Checkbox label="Label" />
<Checkbox indeterminate label="Label" />

Disabled State

When disabled is true, the checkbox becomes non-interactive and is typically rendered with reduced opacity to indicate its unavailable state.

Checked
Unchecked
Indeterminate
<Checkbox defaultChecked disabled label="Label" />
<Checkbox disabled label="Label" />
<Checkbox disabled indeterminate label="Label" />

Controlled State

Set the initial value using the defaultChecked prop, or use checked and onCheckedChange to control the value manually. These props follow our controlled state pattern.

import {type ReactElement, useState} from "react"

import {Checkbox} from "@qualcomm-ui/react/checkbox"

export default function CheckboxControlledDemo(): ReactElement {
  const [checked, setChecked] = useState<boolean>(false)

  return (
    <Checkbox.Root
      checked={checked}
      onCheckedChange={(nextState) => {
        console.log("checkbox state change:", nextState)
        setChecked(nextState)
      }}
    >
      <Checkbox.HiddenInput />
      <Checkbox.Control />
      <Checkbox.Label>Label</Checkbox.Label>
    </Checkbox.Root>
  )
}

Sizes

import type {ReactElement} from "react"

import {Checkbox} from "@qualcomm-ui/react/checkbox"

export default function CheckboxSizesDemo(): ReactElement {
  return (
    <div className="flex flex-col items-start gap-4">
      <Checkbox label="Small (sm)" size="sm" />
      <Checkbox label="Medium (md)" size="md" />
      <Checkbox label="Large (lg)" size="lg" />
    </div>
  )
}

Forms

Choose the form library that fits your needs—we've built examples with React Hook Form and Tanstack Form to get you started.

React Hook Form

Use React Hook Form to handle the checkbox state and validation. ArkType works great for schema validation if you need it.

import type {ReactElement} from "react"

import {arktypeResolver} from "@hookform/resolvers/arktype"
import {type} from "arktype"
import {Controller, useForm} from "react-hook-form"

import {Button} from "@qualcomm-ui/react/button"
import {Checkbox} from "@qualcomm-ui/react/checkbox"

interface FormData {
  acceptTerms: boolean
  newsletter: boolean
}

const acceptTermsSchema = type("boolean")
  .narrow((value: boolean) => value === true)
  .configure({
    message: "Please accept the Terms of Service to continue",
  })
const FormSchema = type({
  // must be true
  acceptTerms: acceptTermsSchema,
  // can be true or false
  newsletter: "boolean",
})

export default function CheckboxReactHookFormDemo(): ReactElement {
  const {control, handleSubmit} = useForm<FormData>({
    defaultValues: {
      acceptTerms: false,
      newsletter: true,
    },
    resolver: arktypeResolver(FormSchema),
  })

  return (
    <form
      className="flex w-56 flex-col gap-2"
      onSubmit={(e) => {
        void handleSubmit((data) => console.log(data))(e)
      }}
    >
      <Controller
        control={control}
        name="newsletter"
        render={({field: {name, onChange, value, ...fieldProps}}) => {
          return (
            <Checkbox.Root
              checked={value}
              name={name}
              onCheckedChange={onChange}
              {...fieldProps}
            >
              <Checkbox.HiddenInput />
              <Checkbox.Control />
              <Checkbox.Label>Subscribe to our Newsletter</Checkbox.Label>
            </Checkbox.Root>
          )
        }}
      />

      <Controller
        control={control}
        name="acceptTerms"
        render={({
          field: {onChange, value, ...fieldProps},
          fieldState: {error},
        }) => {
          return (
            <Checkbox.Root
              checked={value}
              invalid={!!error?.message}
              onCheckedChange={onChange}
              {...fieldProps}
            >
              <Checkbox.HiddenInput />
              <Checkbox.Control />
              <Checkbox.Label>Accept Terms of Service</Checkbox.Label>
              <Checkbox.ErrorText>{error?.message}</Checkbox.ErrorText>
            </Checkbox.Root>
          )
        }}
      />

      <Button
        className="mt-1"
        emphasis="primary"
        size="sm"
        type="submit"
        variant="fill"
      >
        Submit
      </Button>
    </form>
  )
}

Tanstack Form

Tanstack Form handles checkbox validation with its built-in validators.

import type {ReactElement} from "react"

import {useForm} from "@tanstack/react-form"

import {Button} from "@qualcomm-ui/react/button"
import {Checkbox} from "@qualcomm-ui/react/checkbox"

interface FormData {
  acceptTerms: boolean
  newsletter: boolean
}

const defaultFormData: FormData = {
  acceptTerms: false,
  newsletter: true,
}

const errorMessage = "Please accept the Terms of Service to continue"

export default function CheckboxTanstackFormDemo(): ReactElement {
  const form = useForm({
    defaultValues: defaultFormData,
    onSubmit: async ({value}) => {
      // Do something with form data
      console.log(value)
    },
  })

  return (
    <form
      className="flex w-56 flex-col gap-2"
      onSubmit={(event) => {
        event.preventDefault()
        event.stopPropagation()
        void form.handleSubmit()
      }}
    >
      <form.Field name="newsletter">
        {({handleChange, name, state}) => {
          return (
            <Checkbox
              checked={state.value}
              label="Subscribe to our Newsletter"
              name={name}
              onCheckedChange={handleChange}
            />
          )
        }}
      </form.Field>

      <form.Field
        name="acceptTerms"
        validators={{
          onChange: (field) => (field.value ? undefined : errorMessage),
          onSubmit: (field) => (field.value ? undefined : errorMessage),
        }}
      >
        {({handleChange, name, state}) => {
          const fieldError =
            state.meta.errorMap["onChange"] || state.meta.errorMap["onSubmit"]
          return (
            <Checkbox
              checked={state.value}
              errorText={fieldError}
              invalid={!!fieldError}
              label="Accept Terms"
              name={name}
              onCheckedChange={handleChange}
            />
          )
        }}
      </form.Field>

      <Button
        className="mt-1"
        emphasis="primary"
        size="sm"
        type="submit"
        variant="fill"
      >
        Submit
      </Button>
    </form>
  )
}

Tanstack form also supports ArkType.

Composite Guidelines

The composite elements are only intended to be used as direct descendants of the <Checkbox.Root> component.

/* Won't work alone ❌ */
<Checkbox.HiddenInput />
<Checkbox.Control />

/* Works as expected ✅ */
<Checkbox.Root>
  <Checkbox.HiddenInput />
  <Checkbox.Control />
</Checkbox.Root>

API

<Checkbox>

The Checkbox extends the Checkbox.Root with the following props:

PropType
Props applied to the control element.
Optional error that describes the element when invalid is true.
string
Props applied to the error text element.
Props applied to the hidden input element.
Props applied to the indicator element.
Optional label describing the element. Recommended. This element is automatically associated with the component's input element for accessibility.
Props applied to the label element.
Description
Props applied to the control element.
Type
string
Description
Optional error that describes the element when invalid is true.
Description
Props applied to the error text element.
Description
Props applied to the hidden input element.
Description
Props applied to the indicator element.
Description
Optional label describing the element. Recommended. This element is automatically associated with the component's input element for accessibility.
Description
Props applied to the label element.

Composite API

<Checkbox.Root>

Groups all parts of the checkbox. Renders a <label> element by default.
PropTypeDefault
The controlled checked state of the checkbox
boolean
React children prop.
The initial checked state of the checkbox when rendered. Use when you don't need to control the checked state of the checkbox.
boolean
The document's text/writing direction.
'ltr' | 'rtl'
'ltr'
Whether the input is disabled. When true, prevents user interaction and applies visual styling to indicate the disabled state.
boolean
The id of the form that the checkbox belongs to.
string
A root node to correctly resolve document in custom environments. i.e., Iframes, Electron.
    () =>
    | Node
    | ShadowRoot
    | Document
    id attribute. If omitted, a unique identifier will be automatically generated for accessibility.
    string
    The ids of the elements that are associated with the checkbox. These will be automatically generated if omitted.
    Partial<{
    control: string
    errorText: string
    hiddenInput: string
    label: string
    root: string
    }>
    If true and the checkbox is not checked, the checkbox will be in the indeterminate state.
    boolean
    Controls the visual error state of the input. When true, applies semantic error styling to indicate validation failure.
    boolean
    The name of the input field in a checkbox. Useful for form submission.
    string
    The callback invoked when the checked state changes.
      (
      checked: boolean,
      ) => void
      The callback invoked when the field is focused.
        (
        focused: boolean,
        ) => void
        Whether the input is read-only. When true, prevents user interaction while keeping the input focusable and visible.
        boolean
        Allows you to replace the component's HTML element with a different tag or component. Learn more
        | ReactElement
        | ((
        props: object,
        ) => ReactElement)
        Whether the input is required. When true, the input must have a value for form validation to pass.
        boolean
        The size of the checkbox and its elements. Governs properties like label font size, control size, and indicator size.
        | 'sm'
        | 'md'
        | 'lg'
        'md'
        
        The value of checkbox input. Useful for form submission.
        string
        "on"
        
        Type
        boolean
        Description
        The controlled checked state of the checkbox
        Description
        React children prop.
        Type
        boolean
        Description
        The initial checked state of the checkbox when rendered. Use when you don't need to control the checked state of the checkbox.
        Type
        'ltr' | 'rtl'
        Description
        The document's text/writing direction.
        Type
        boolean
        Description
        Whether the input is disabled. When true, prevents user interaction and applies visual styling to indicate the disabled state.
        Type
        string
        Description
        The id of the form that the checkbox belongs to.
        Type
        () =>
        | Node
        | ShadowRoot
        | Document
        Description
        A root node to correctly resolve document in custom environments. i.e., Iframes, Electron.
          Type
          string
          Description
          id attribute. If omitted, a unique identifier will be automatically generated for accessibility.
          Type
          Partial<{
          control: string
          errorText: string
          hiddenInput: string
          label: string
          root: string
          }>
          Description
          The ids of the elements that are associated with the checkbox. These will be automatically generated if omitted.
          Type
          boolean
          Description
          If true and the checkbox is not checked, the checkbox will be in the indeterminate state.
          Type
          boolean
          Description
          Controls the visual error state of the input. When true, applies semantic error styling to indicate validation failure.
          Type
          string
          Description
          The name of the input field in a checkbox. Useful for form submission.
          Type
          (
          checked: boolean,
          ) => void
          Description
          The callback invoked when the checked state changes.
            Type
            (
            focused: boolean,
            ) => void
            Description
            The callback invoked when the field is focused.
              Type
              boolean
              Description
              Whether the input is read-only. When true, prevents user interaction while keeping the input focusable and visible.
              Type
              | ReactElement
              | ((
              props: object,
              ) => ReactElement)
              Description
              Allows you to replace the component's HTML element with a different tag or component. Learn more
              Type
              boolean
              Description
              Whether the input is required. When true, the input must have a value for form validation to pass.
              Type
              | 'sm'
              | 'md'
              | 'lg'
              Description
              The size of the checkbox and its elements. Governs properties like label font size, control size, and indicator size.
              Type
              string
              Description
              The value of checkbox input. Useful for form submission.

              <Checkbox.Label>

              An accessible label that is automatically associated with the checkbox. Renders a <span> element by default.
              PropType
              React children prop.
              id attribute. If omitted, a unique identifier will be automatically generated for accessibility.
              string
              Allows you to replace the component's HTML element with a different tag or component. Learn more
              | ReactElement
              | ((
              props: object,
              ) => ReactElement)
              Description
              React children prop.
              Type
              string
              Description
              id attribute. If omitted, a unique identifier will be automatically generated for accessibility.
              Type
              | ReactElement
              | ((
              props: object,
              ) => ReactElement)
              Description
              Allows you to replace the component's HTML element with a different tag or component. Learn more

              <Checkbox.Control>

              Visual control that wraps the checkbox indicator. Renders a <div> element by default.
              PropTypeDefault
              React children prop.
              <CheckboxIndicator />
              id attribute. If omitted, a unique identifier will be automatically generated for accessibility.
              string
              Allows you to replace the component's HTML element with a different tag or component. Learn more
              | ReactElement
              | ((
              props: object,
              ) => ReactElement)
              Description
              React children prop.
              Type
              string
              Description
              id attribute. If omitted, a unique identifier will be automatically generated for accessibility.
              Type
              | ReactElement
              | ((
              props: object,
              ) => ReactElement)
              Description
              Allows you to replace the component's HTML element with a different tag or component. Learn more

              <Checkbox.ErrorText>

              Error message displayed when the checkbox is invalid. Renders a <div> element by default.
              PropTypeDefault
              React children prop.
              An icon to display next to the error text.
              | LucideIcon
              | ReactNode
              <AlertCircle />
              id attribute. If omitted, a unique identifier will be automatically generated for accessibility.
              string
              Allows you to replace the component's HTML element with a different tag or component. Learn more
              | ReactElement
              | ((
              props: object,
              ) => ReactElement)
              Description
              React children prop.
              Type
              | LucideIcon
              | ReactNode
              Description
              An icon to display next to the error text.
              Type
              string
              Description
              id attribute. If omitted, a unique identifier will be automatically generated for accessibility.
              Type
              | ReactElement
              | ((
              props: object,
              ) => ReactElement)
              Description
              Allows you to replace the component's HTML element with a different tag or component. Learn more

              <Checkbox.HiddenInput>

              Hidden input element used for accessibility and form submissions. Renders an <input> element. Note: do not apply typical input props like disabled to this element. Those are applied to the root element and propagated via internal context.
              PropType
              id attribute. If omitted, a unique identifier will be automatically generated for accessibility.
              string
              Type
              string
              Description
              id attribute. If omitted, a unique identifier will be automatically generated for accessibility.

              <Checkbox.Indicator>

              Visual indicator that displays the checkbox state. Renders a <div> element by default.
              PropTypeDefault
              React children prop. Defaults to the check icon when the checkbox is checked.
              <CheckboxIndicatorIcon />
              Allows you to replace the component's HTML element with a different tag or component. Learn more
              | ReactElement
              | ((
              props: object,
              ) => ReactElement)
              Description
              React children prop. Defaults to the check icon when the checkbox is checked.
              Type
              | ReactElement
              | ((
              props: object,
              ) => ReactElement)
              Description
              Allows you to replace the component's HTML element with a different tag or component. Learn more