Capítulo 13 de 43

Chapter 13: Checkbox

Core Idea

A tri-state (checked/unchecked/indeterminate) toggle control with full keyboard support and automatic form-compatible hidden input rendering.

Key Concepts

  • Anatomy: RootIndicator (renders only when checked/indeterminate; wrap an icon or style directly).
  • Tri-state: checked/defaultChecked accept boolean | "indeterminate" — indeterminate must be driven by controlled state (there's no defaultChecked="indeterminate" auto-toggle).
  • Form compatibility: Root renders a visually-hidden native input automatically so the checkbox participates in form submission/events like a real checkbox.
  • unstable_Provider/unstable_Trigger/unstable_BubbleInput: lower-level parts (API may still change) for recomposing or excluding the hidden input.

Code Examples

const [checked, setChecked] = React.useState("indeterminate");

<Checkbox.Root checked={checked} onCheckedChange={setChecked}>
  <Checkbox.Indicator>
    {checked === "indeterminate" && <DividerHorizontalIcon />}
    {checked === true && <CheckIcon />}
  </Checkbox.Indicator>
</Checkbox.Root>
  • What it demonstrates: driving the indeterminate state explicitly via controlled checked, since it can't be reached through user interaction alone.

Reference Tables

PartKey propsKey data attributes
Rootchecked/defaultChecked (boolean | "indeterminate"), onCheckedChange, disabled, required, name, value[data-state] (checked|unchecked|indeterminate), [data-disabled]
IndicatorforceMountsame as Root

Anti-patterns

  • Relying on defaultChecked="indeterminate" to let users toggle into indeterminate: indeterminate is a programmatic-only state — you must set it via controlled checked + onCheckedChange, users can't reach it by clicking.

Key Takeaways

  1. Indeterminate is presentation-only and must be managed by your own state — it's never a user-reachable click target.
  2. The hidden native input means Checkbox works inside plain <form> submission without extra glue code.
  3. Only use the unstable_* parts if you specifically need to move/exclude the hidden input — expect their API to change in future releases.

Connects To

  • Radio Group: the mutually-exclusive-selection counterpart to Checkbox's independent toggle.
  • Form: for validation-aware usage in complex forms.