Inputs

Generated from DESIGN_SYSTEM.md

Rules

A checkbox marks an item as selected (in a set, in a form to be submitted); a switch flips a state that takes effect immediately โ€” auto-reply on, a connector enabled, a consent granted. HIG and Material draw the same line.

PlatformComponent
Web<Switch> from @yroun/ui (checked / onCheckedChange / disabled / label or ariaLabel) โ€” brand fill on, zinc track off, white thumb, role="switch" + aria-checked
iOSSwiftUI Toggle with .tint(AppTheme.Colors.brandPrimary)
AndroidMaterial 3 Switch, colorScheme.primary
  • One switch, no size or color variants โ€” variants are how the fragmentation this ended starts over.
  • label renders the visible text as part of the same control (clicking it toggles); pass ariaLabel only when no visible label sits with it.
  • Review heuristic: a new type="checkbox" whose handler mutates server state immediately (not on form submit) is a switch wearing the wrong control โ€” rejected.

Pills โ€” four roles, one discipline

Rounded tinted surfaces serve FOUR distinct roles. Every pill on any surface must be one of these, via its named utility โ€” never a hand-rolled variant:

RoleUtility (web)DifferentiatorInteractive?
Actionbtn btn-filled / btn btn-tinted + a size (see Buttons)44pt min height on touch, size from btn-sm/md/lgโœ… tap = do something
Filter chipchip-filter (+ chip-filter-active)min-h-9, text-xs, borderedโœ… tap = narrow a list
Option cardoption-card (+ option-card-active)full-width rounded-2xl tile, title + descriptionโœ… tap = pick one of N
Status badgebadge-blue / badge-neutral / badge-featuredtiny (text-[11px]), no hover, no min-heightโŒ read-only label

Rule 1 โ€” utilities are complete by default. Every utility above renders correctly bare. Active/selected variants carry the FULL base shape so both standalone and composed usage render identically. Call-site utilities still override the baked defaults when a context truly differs.

Rule 2 โ€” one state, one signal. A state already carried by an icon/shape (a check circle, a filled dot) does NOT also get a badge. Duplicated signals read as clutter and make the static badge look like a stray button.

Rule 3 โ€” status is never dressed as an action. Size is the separator: badges stay tiny with no hover/press states; anything 44pt-tall and tinted reads as tappable and must actually be tappable.

Live specimens

SwitchA switch takes effect at once; a checkbox waits for a submit.
Input and textareainput-base: interactive border at rest, brand border and ring on focus.
CheckboxMarks items for a later submit; an 18px box inside a 44px hit area.
Pills: four rolesFilter chips narrow a list, badges only label, option cards pick one of N. Actions are buttons.
chip-filter ยท chip-filter-active
badge-blue ยท badge-neutral
ProDraft
status-pill-ok ยท -warn ยท -danger
LiveDelayedFailed
option-card ยท option-card-active