Skip to content

Checkbox

Select an option with checked, unchecked and mixed states.

import { Checkbox, CheckboxMark } from '@youj/react'

Installation & usage

npm i @youj/react

For an app already set up with npx @youj/cli init, which installs the peers (@youj/core, @youj/motion, motion and Base UI) and wires the provider. New app? Start at Installation.

Use Checkbox for options submitted with a form or for selecting several items. Use a Switch for settings that apply immediately, or a Radio Group for a single choice.

Put the checkbox in a Field with a FieldLabel. The label names the control, and clicking it toggles the box.

import { Checkbox, Field, FieldLabel } from '@youj/react'

export function RememberDevice() {
  return (
    <Field orientation="horizontal">
      <Checkbox defaultChecked />
      <FieldLabel>Remember this device</FieldLabel>
    </Field>
  )
}

It's uncontrolled with defaultChecked. To own the state, pass checked and onCheckedChange. Inside a form, name and value submit it like a native checkbox, and required on the surrounding Field marks the label and makes the box required.

Reference

Propssound (1)

Props

Checkbox props
PropType
soundboolean

With sound on (YoujProvider’s sound), ticking plays toggleOn and unticking toggleOff. false keeps this one silent.

default true

true
Other props pass through: extends CheckboxPrimitive.Root.Props.

The props you'll use most come from Base UI:

PropTypeDescription
checkedbooleanControlled state. Pair it with onCheckedChange.
defaultCheckedbooleanInitial state, uncontrolled. Default false.
onCheckedChange(checked, details) => voidCalled on every tick and untick.
indeterminatebooleanShows the mixed state and reports aria-checked="mixed".
disabledbooleanIgnores presses. Set it on the Field to dim the label too.
readOnlybooleanKeeps the current value.
requiredbooleanMust be checked before the form submits. Defaults to the Field's required.
name, valuestringWhat the hidden input submits. With no value, a checked box submits "on".
MotionCheck, check lands, mixed dash… · reduced motion

Motion

Motion tokens
MomentTokens
Checkthe stroke draws from zero on every tick
duration.slowease.emphasized

340ms · cubic-bezier(0.6, 0, 0.1, 1)

340mscubic-bezier(0.6, 0, 0.1, 1)
Check landsthe mark settles from 88% scale, after a base delay
spring.settle

0.45s, bounce 0.3

0.45s, bounce 0.3
Mixed dashdraws from the start of the line
duration.fastease.enter

140ms · cubic-bezier(0.16, 1, 0.3, 1)

140mscubic-bezier(0.16, 1, 0.3, 1)
Uncheckthe glyph fades
duration.instantease.standard

80ms · cubic-bezier(0.2, 0, 0, 1)

80mscubic-bezier(0.2, 0, 0, 1)
Box fillbackground and border color
duration.fastease.standard

140ms · cubic-bezier(0.2, 0, 0, 1)

140mscubic-bezier(0.2, 0, 0, 1)
Pressthe box squeezes to 90%
duration.instantease.standard

80ms · cubic-bezier(0.2, 0, 0, 1)

80mscubic-bezier(0.2, 0, 0, 1)

Reduced motion

The check and the dash appear whole, and the box doesn't squeeze on press. The fill still changes color.

A tick is a small arrival, so the check earns the settle spring, Youj's one overshoot. The indicator stays mounted while unchecked, so a tick that reverses mid-draw continues from where the stroke is, with no jump.

Reduced motion

The check appears whole instead of drawing, and pressing doesn't squeeze the box. Checked, unchecked and mixed still look different, so the state reads the same without the motion.

AccessibilityKeyboard, ARIA, focus

Accessibility

  • It's a checkbox role with aria-checked of true, false or mixed. Space toggles it and Enter doesn't, as with a native checkbox.
  • A FieldLabel in the same Field names it. Outside a Field, use Label with htmlFor and an id, or an aria-label.
  • The 16px box has a 24px hit area, and 40px on touch screens.
  • The box's border clears 3:1 against the page, and focus shows a 2px accent outline.