UnflowUI
Components

Checkbox

A styled native checkbox input with size variants and a customizable check mark.

Overview

Checkbox wraps a native <input type="checkbox"> in a small square container that draws the checked/unchecked/disabled visuals via CSS, and shows a check-mark icon on top of the input when checked. Because it's a real checkbox, it participates in forms and works with standard React controlled-state patterns.

Two implementation notes worth knowing:

  • Checkbox is always rendered as a controlled input — pass checked and onChange yourself; there's no uncontrolled/defaultChecked mode.
  • If you don't pass aria-label, Checkbox falls back to a translated default label so it's never unlabeled for assistive tech — but a descriptive aria-label (or an associated <label>) is strongly recommended.

Import

import { Checkbox } from '@unflow.io/ui/components/Checkbox';

Props

PropTypeDefaultDescription
checkedbooleanfalseControlled checked state
onChangeChangeEventHandler<HTMLInputElement>Change handler
disabledbooleanfalseDisables interaction and applies the disabled visual style
requiredbooleanMarks the underlying input as required
size'xs' | 'sm' | 'md' | 'lg''sm'Size of the checkbox box and its check mark
slots.checkMarkReactNodeOverrides the default check-mark icon
slotProps.inputRootBaseHTMLProps<HTMLDivElement>Props for the outer container div
slotProps.checkMarkBaseHTMLProps<HTMLDivElement>Props for the check-mark wrapper div

className is applied directly to the <input> element (not the container) — use slotProps.inputRoot/slotProps.checkMark to style the wrapper or the check mark. All standard HTMLInputElement props (id, name, value, onBlur, aria-label, etc.) are forwarded to the input.

Sizes

<Checkbox checked onChange={() => {}} size="xs" aria-label="Extra small" />
<Checkbox checked onChange={() => {}} size="sm" aria-label="Small" />
<Checkbox checked onChange={() => {}} size="md" aria-label="Medium" />
<Checkbox checked onChange={() => {}} size="lg" aria-label="Large" />

States

unchecked
checked
disabled unchecked
disabled checked
const [checked, setChecked] = useState(false);

<Checkbox checked={checked} onChange={(e) => setChecked(e.target.checked)} aria-label="Toggle" />
<Checkbox checked={false} disabled aria-label="Disabled unchecked" />
<Checkbox checked={true} disabled aria-label="Disabled checked" />

Custom check mark

Swap the default check icon via slots.checkMark.

import { useState } from 'react';
import { Heart } from '@unflow-ui/icons/games/heart';

const [favorite, setFavorite] = useState(true);

<Checkbox
  checked={favorite}
  onChange={(e) => setFavorite(e.target.checked)}
  slots={{ checkMark: <Heart variant="Fill" /> }}
  aria-label="Favorite"
/>

Customization (slots & slotProps)

SlotTypeDescription
checkMarkReactNodeIcon override rendered inside the check-mark wrapper when checked
Slot PropPropsDescription
inputRootBaseHTMLProps<HTMLDivElement>The outer container div that holds the input and check mark
checkMarkBaseHTMLProps<HTMLDivElement>The check-mark wrapper div shown when checked is true

Accessibility

  • Renders a real <input type="checkbox">, so it's natively keyboard-operable (Space to toggle) and participates in form submission.
  • Falls back to a translated default aria-label when none is provided, so the control is never unlabeled — but prefer passing a descriptive aria-label, or associate a visible <label>.
  • The check-mark icon is aria-hidden, since the checked state is already conveyed by the native input's checked property.
  • disabled uses the container's inert attribute alongside the native disabled attribute, removing the control from the accessibility tree and tab order.