components / checkbox

Checkbox

Binary or indeterminate choice control with native-input semantics and proof-backed sizing.

Overview

What it is

This section explains the intent of the component before the implementation details.

  • Checkbox is the DK contract for binary or tri-state selection when independent choices can be combined.
  • It keeps the semantics native while the styling stays aligned with the rest of the choice family.

Aliases

check box

Decision guide

How to choose it

Use these notes to decide quickly whether this is the right DK component for the job.

Decision guide

  • Choose Checkbox when the interaction should feel deliberate, documented, and reusable across product surfaces.
  • If the scenario is more specialized than the current Checkbox contract, prefer a simpler component or build a dedicated workflow on top of the lower-level DK primitives.

Do

  • Keep the Checkbox label, value, or status language direct enough to scan quickly.
  • Use the documented size and state recipes instead of inventing one-off variants in product code.

Do not

  • Do not hide the main purpose of Checkbox behind decorative copy or overloaded surface treatments.
  • Do not stretch Checkbox into a workflow it was not designed to handle just because the visuals are close.

Usage

When to use

Prefer these situations when choosing this component.

  • Use Checkbox for independent choices that can be combined.
  • Use the indeterminate state for parent or aggregate selections when some children are selected.

Usage

When not to use

These patterns are better served by a different component or a simpler surface.

  • Do not use Checkbox when only one option can be selected; use RadioGroup or SegmentedControl.
  • Do not use Checkbox as a binary system toggle; use Switch when the state reads as on or off.

Anti-patterns

  • Using Checkbox as a generic layout container instead of a purpose-built interaction or content surface.
  • Forking the documented recipe in product code instead of extending the shared DK contract.

Migration notes

  • Migrate legacy checkbox usage by mapping existing variants and states onto the documented DK props before porting any custom styling.
  • Treat the docs examples as the reference contract for accessibility and event behavior during adoption.

Anatomy

Structural parts

The anatomy explains which pieces matter to the recipe and accessibility model.

native checkbox

control

The interactive binary or indeterminate control.

state mark

mark

Shows checked or indeterminate state.

visible label

label

Explains the choice.

supporting copy

description

Optional clarifying helper copy.

API

Public interface

The docs contract distinguishes props, DOM events, and slots so integration behavior is explicit.

Props

NameTypeDefaultDescription
checkedbooleanfalseControlled checked state.
indeterminatebooleanfalseControlled mixed state.
labelstringVisible checkbox label.
descriptionstringSupporting helper copy.
errorstringOptional problem text for grouped or validated use.
requiredbooleanfalseMarks the checkbox as required.
disabledbooleanfalseDisables interaction.
namestringNative form field name.
idstringOptional explicit id for label binding.
size'sm' | 'md''md'Chooses the checkbox size recipe.
onChange(detail: { value: string | undefined }) => voidCallback fired when the checked state changes.
themeThemeContractOverrides the compiled DK theme used to resolve tokens and recipes for this component.

Events

NamePayloadDescription
change{ value: string | undefined }Fires when the component commits a new value.

Slots

NameDescription
defaultCheckbox is prop-driven in v1 and does not expose custom slots.

Recipes

Variants, sizes, and states

These notes summarize the intended recipe surface rather than exposing raw implementation detail first.

Variants

  • default: Checkbox uses one structural recipe and varies by size and state.

Sizes

  • sm: Compact checkbox for dense UI.
  • md: Default checkbox size.

States

  • unchecked: No selection.
  • checked: The choice is selected.
  • indeterminate: A mixed or partial aggregate state.
  • disabled: Semantically disabled and visibly muted.

Accessibility

Accessibility contract

This is the behavior the component promises to assistive tech and keyboard users today.

Semantics

  • Uses a native checkbox input and exposes correct checked or mixed semantics.

Keyboard

  • Supports native focus and Space activation behavior.

Screen readers

  • Label and description remain attached to the checkbox input, including the mixed state.

Checklist

  • Verify the visible label or title still produces a clear accessible name.
  • Verify focus remains obvious in every supported state and size.
  • Verify disabled, selected, and error states do not rely on color alone.

Implementation

Tokens and slot vars

This section shows the representative compiled slot variables that the runtime consumes for the selected design system.

root

--dk-checkbox-gap
clamp(0.75rem, 0.6875rem + 0.278vw, 0.938rem)
--dk-checkbox-hit-size
44px
--dk-checkbox-copy-gap
0.22rem
--dk-checkbox-motion-duration
200ms
--dk-motion-duration
200ms

control

--dk-checkbox-bg
#f2f5fb
--dk-checkbox-border
#95989d
--dk-checkbox-border-width
1.5px
--dk-checkbox-size
20px
--dk-checkbox-radius
0.45rem
--dk-checkbox-shadow
none
--dk-checkbox-focus-ring-color
#2072e4

mark

--dk-checkbox-mark-color
#ffffff
--dk-checkbox-mark-size
0.82rem

label

--dk-checkbox-label-color
#16181c
--dk-checkbox-label-size
clamp(1.333rem, 1.2222rem + 0.494vw, 1.667rem)
--dk-checkbox-label-weight
600

description

--dk-checkbox-description-color
#16181c
--dk-checkbox-description-size
0.8125rem

error

--dk-checkbox-error-color
#cc272e
--dk-checkbox-error-size
0.8125rem

Implementation notes

  • Checkbox remains native-input backed so indeterminate state and accessibility stay honest.

Implementation checklist

  • Use the public component API first and only drop to lower-level primitives when the component contract genuinely does not fit.
  • Keep theme overrides token-driven so proofs and recipes stay meaningful.
  • Verify the shipped examples and proof fixtures still represent the real product scenario you are implementing.

Examples

Copy-paste examples

Each example is intentionally practical, grouped by starter, common pattern, and edge-case coverage.

Examples
3
Depth
baseline

Starter

1 example

starter

Starter: one independent choice

A single checkbox with label and description.

Copy snippet

<Checkbox label="Send notes" description="Share the update with the team." checked={true} />

Common patterns

1 example

common

Common: aggregate selection

Use the mixed state when some child items are selected.

Copy snippet

<Checkbox label="Select all" indeterminate={true} />

Edge cases

1 example

edge

Edge: unavailable choice

Disabled state stays visible without pretending the option disappeared.

Copy snippet

<Checkbox label="Enable automation" disabled={true} />

Verification

Curated proof fixtures

Proofs stay visible in the docs so the system shows what it can guarantee, not just what it can render.

default (size=sm)

pass

size=sm

  • Contrast: 76.6 Lc
  • Target: 44px
  • Layout: 269 / 240, 320
  • Helper: 2/2

default (size=md)

pass

size=md

  • Contrast: 76.6 Lc
  • Target: 44px
  • Layout: 269 / 240, 320
  • Helper: 2/2

default (size=lg)

pass

size=lg

  • Contrast: 76.6 Lc
  • Target: 44px
  • Layout: 269 / 240, 320
  • Helper: 2/2

checked (size=sm)

pass

size=sm

  • Contrast: 76.6 Lc
  • Target: 44px
  • Layout: 269 / 240, 320
  • Helper: 2/2

checked (size=md)

pass

size=md

  • Contrast: 76.6 Lc
  • Target: 44px
  • Layout: 269 / 240, 320
  • Helper: 2/2

checked (size=lg)

pass

size=lg

  • Contrast: 76.6 Lc
  • Target: 44px
  • Layout: 269 / 240, 320
  • Helper: 2/2

indeterminate (size=sm)

pass

size=sm

  • Contrast: 76.6 Lc
  • Target: 44px
  • Layout: 269 / 240, 320
  • Helper: 2/2

indeterminate (size=md)

pass

size=md

  • Contrast: 76.6 Lc
  • Target: 44px
  • Layout: 269 / 240, 320
  • Helper: 2/2

indeterminate (size=lg)

pass

size=lg

  • Contrast: 76.6 Lc
  • Target: 44px
  • Layout: 269 / 240, 320
  • Helper: 2/2