Checkbox
Square selection mark at md (20) or sm (16), with the icon-set check, on default or inverse surfaces.
checkboxOpen in Figma ↗A binary selection control for forms and lists, available in square (multi-select) and circular (radio-style) shapes.
Use for: Form fields, settings screens, and list items where the user needs to select one or more options. Use the square shape (radio=false) when multiple items can be selected simultaneously. Use the circular shape (radio=true) when the checkbox needs to feel softer or less rigid in context — note this is still a checkbox that allows multi-select, not a true radio button.
Not for: Mutually exclusive single-select choices where only one option can be active — use a switcher or a true radio input pattern instead.
Choosing: Use size=md (20×20px) for standard forms, settings, and main content areas. Use size=sm (16×16px) for dense layouts, compact lists, or inline use. Set inverse=false on light or neutral backgrounds. Set inverse=true on midnight or brand red surfaces. Set selected=true to show a checked state — brand red fill with white checkmark. Set disabled=true to make the control non-interactive; a selected disabled checkbox renders with desaturated grey fill.
Rules: Always pair with a visible label — do not use the checkbox alone without accompanying text. Do not use radio=true to imply single-select behaviour; its shape is cosmetic. Do not mix radio=true and radio=false within the same list.
import SwiftUI import EandTokens // V1.2 checkbox: md 20 / sm 16, radius 4, 1.5pt off ring; on = brand fill with the icon-set // check (12pt in a 16pt box). Every state is a color/mark token — disabled is a colour. // radio=yes draws the same mark as a circle. struct CheckboxView: View { let label: String; @Binding var on: Bool var body: some View { HStack(spacing: EandSpacing.sm) { CheckboxMark(on: on) Text(label).font(.system(size: EandTypography.bodyMd.size)) .foregroundColor(EandColor.textDefaultDefault) } .onTapGesture { on.toggle() } } } struct CheckboxMark: View { let on: Bool var body: some View { RoundedRectangle(cornerRadius: EandRadius.radius1) .fill(on ? EandColor.markDefaultSurfaceSelected : .clear) .overlay { if !on { RoundedRectangle(cornerRadius: EandRadius.radius1) .strokeBorder(EandColor.markDefaultBorderDefault, lineWidth: EandBorder.md) } } .overlay { if on { Image(systemName: "checkmark").font(.system(size: EandIcon.sm - 2, weight: .bold)) .foregroundColor(EandColor.markDefaultIconSelected) } } .frame(width: EandCheckbox.md, height: EandCheckbox.md) } }
When to use
- Use for independent options the user can combine, or for a single opt-in.
- Use ConsentCheckbox when the label carries legal links, such as Terms and Privacy Policy.
- Don't use for one choice out of several — that is Radio. For a setting that takes effect at once, use the Switcher.
radio draws the circular checkbox from the same Figma set: a filled circle with a tick, on
the same tokens. For the ring-and-dot control, use Radio. Pass inverse on
brand-red and midnight surfaces.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
inverse? | boolean | — | Inverse color scheme for dark (midnight/brand) surfaces (Figma color-scheme=inverse). |
label? | ReactNode | — | |
radio? | boolean | — | Render as a radio (single-selection) — a circle instead of a square. Same mark,
colors and states (Figma radio (single selection)=yes, node 27685:5017). |
size? | 'md' | 'sm' | md | Control size — md 20×20 (default) or sm 16×16 (Figma V1.1 size axis). |
Design
Figma source: checkbox — etisalat Consumer App DSL V1.2
md20 andsm16 (checkbox/md·sm),border-radius/1(4); unchecked boxes have a 1.5px (border/md) border.- The tick is the icon set's
check-filled: 12px in a 16px box atmd, 8px in 12px atsm. - Every state binds
mark/{default,inverse}/{surface,icon,border}/*. Disabled is a colour, not opacity. - The label is
body/md,spacing/smfrom the box, intext/default/default; inverse usestext/default/inverse-subtle.