components / switch

Switch

Track/thumb toggle for clear on/off states with motion-gated proofs and touch-target guarantees.

Overview

What it is

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

  • Switch expresses binary system state as on or off rather than selected or not selected.
  • Use it when the control changes a persistent setting or availability mode.

Aliases

toggle

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 Switch when the interaction should feel deliberate, documented, and reusable across product surfaces.
  • If the scenario is more specialized than the current Switch contract, prefer a simpler component or build a dedicated workflow on top of the lower-level DK primitives.

Do

  • Keep the Switch 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 Switch behind decorative copy or overloaded surface treatments.
  • Do not stretch Switch 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 Switch for immediate on/off system state such as enabled features or publishing state.
  • Use the description to clarify what being on actually means in product language.

Usage

When not to use

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

  • Do not use Switch for form checklists or consent flows; use Checkbox instead.
  • Do not use Switch when the change should not happen until a form is submitted.

Anti-patterns

  • Using Switch 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 switch 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.

toggle shell

track

Carries the on/off background state.

moving indicator

thumb

Shows the binary position of the switch.

visible label

label

Names the system state being toggled.

supporting copy

description

Optional explanation of the toggle effect.

API

Public interface

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

Props

NameTypeDefaultDescription
checkedbooleanfalseControlled on/off state.
labelstringVisible switch label.
descriptionstringSupporting explanation of the toggle effect.
disabledbooleanfalseDisables the switch.
namestringNative form field name.
idstringOptional explicit id.
size'sm' | 'md''md'Chooses the switch size recipe.
onChange(detail: { value: string | undefined }) => voidCallback fired when the switch value 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
defaultSwitch 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: Switch uses one structural recipe and varies by size.

Sizes

  • sm: Compact switch
  • md: Default switch size

States

  • off: Default off position.
  • on: Enabled on position.
  • disabled: Semantically disabled and visually inactive.

Accessibility

Accessibility contract

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

Semantics

  • Uses switch semantics for an on/off stateful control.

Keyboard

  • Supports native focus and Space activation behavior.

Screen readers

  • Visible label and description explain what the on/off state means.

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-switch-gap
clamp(0.75rem, 0.6875rem + 0.278vw, 0.938rem)
--dk-switch-hit-size
44px
--dk-motion-duration
200ms

track

--dk-switch-track-bg
#95989d
--dk-switch-track-width
42px
--dk-switch-track-height
24px
--dk-switch-track-radius
999px
--dk-switch-thumb-offset
2px
--dk-switch-focus-ring-color
#2072e4

thumb

--dk-switch-thumb-bg
#f2f5fb
--dk-switch-thumb-size
20px

label

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

description

--dk-switch-description-color
#16181c
--dk-switch-description-size
clamp(0.75rem, 0.6875rem + 0.278vw, 0.938rem)

Implementation notes

  • Switch is for immediate system state. If the user is selecting among options, use a selection component instead.

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: enabled feature

A basic on/off setting.

Copy snippet

<Switch label="Auto publish" description="Ship after checks pass." checked={true} />

Common patterns

1 example

common

Common: compact inspector toggle

Smaller switch for dense inspector layouts.

Copy snippet

<Switch size="sm" label="Quiet mode" checked={false} />

Edge cases

1 example

edge

Edge: unavailable system state

Disabled switches should explain why elsewhere in the UI.

Copy snippet

<Switch label="Live sync" 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: 53.9 Lc
  • Target: 44px
  • Motion: 200ms

default (size=md)

pass

size=md

  • Contrast: 53.9 Lc
  • Target: 44px
  • Motion: 200ms

default (size=lg)

pass

size=lg

  • Contrast: 53.9 Lc
  • Target: 44px
  • Motion: 200ms

checked (size=sm)

pass

size=sm

  • Contrast: 76.6 Lc
  • Target: 44px
  • Motion: 200ms

checked (size=md)

pass

size=md

  • Contrast: 76.6 Lc
  • Target: 44px
  • Motion: 200ms

checked (size=lg)

pass

size=lg

  • Contrast: 76.6 Lc
  • Target: 44px
  • Motion: 200ms