KeepNeeds Refinement
Checkbox Component link

A selection control for binary and partial choices. 33 variants across isSelected (true/false/indeterminate) × State (Default/Pressed/Focused/Disabled/Error) × Size (Small/Medium/Large). Code Connect registration pending.

In Context

Contexts are illustrative. Final screens will reference actual GCash patterns.

Live Preview
Properties
isSelected
State
Size
DS Health
Reusable
Partial
All 5 interaction states and indeterminate defined across 3 sizes (C5 resolved). Checkbox is icon-only by design — CheckboxItem compound component provides label + description pairing.
Self-contained
Pass
Checkmark is a separable icon-check child layer (C6 resolved). All 5 interaction states and indeterminate defined across 3 sizes (C5 resolved). Carries its own visual states and token bindings.
Consistent
Pass
Token naming follows DS convention (main/checkbox/color/...). isSelected uses true/false/indeterminate. All property values follow boolean and enum standards (C2 resolved).
Composable
Partial
Nests in form layouts, list rows, and select-all patterns. Indeterminate state defined. CheckboxItem compound component wraps Checkbox + Label + Description for accessible form groups.
Behavior
State iOS Android Figma Property Notes
Unchecked Yes Yes isSelected=false Border-only container. 3 sizes.
Checked Yes Yes isSelected=true Blue fill + separable icon-check layer.
Indeterminate Yes Yes isSelected=indeterminate Blue fill + icon-indeterminate dash.
Disabled Yes Yes State=Disabled 40% opacity. Checked: #9BC5FD fill.
Pressed Yes Yes State=Pressed Unchecked: #EBF2FF bg. Checked: #0F57C8.
Focused Yes Yes State=Focused Blue #1972F9 border stroke.
Error Yes Yes State=Error Red border / red #D81E1E fill.
Resolved Issues
  • isSelected=Yes/No renamed to isSelected=true/false in Figma — now maps correctly to Swift Bool and Kotlin Boolean C2 Fixed
  • Checkmark rebuilt as a separable icon-check child layer inside each checked container — engineers can now tint, swap, and reference it via Code Connect C6 Fixed
  • Added 27 new variants — State (Pressed/Focused/Disabled/Error) × isSelected (true/false) × Size, plus isSelected=indeterminate per size with icon-indeterminate dash layer. 6 → 33 total variants C5 Fixed
Open Issues
  • Code Connect mappings not registered. All structural blockers resolved — registration can now proceed against the 33-variant isSelected × State × Size schema. C7 · Code Connect Linkability
Design Recommendations
  • CheckboxItem compound component created. Composes Checkbox + Label (Proxima Soft Bold) + Description (BarkAda Medium). 4 variants: isSelected (true/false) × Size (Small 14px label / Medium 18px label). Node: 17734:161220. Created Docs
Variants
Unchecked
DES DEV

Empty container with border stroke. Represents a deselected option.

Properties
State
Size
Properties
isSelected false
State Default
Size Medium
Colors
Border #D7E0EF
Layout
Size 20 × 20px
Corner radius 4px (radius-1)
Border width 2px
Hit target 44 × 44 (mobile)
Typography
icon-only control
Colors by State

All interaction states now have defined colors. Token paths follow main/checkbox/color/{state}/{role} convention.

Role Token TokenDEFAULTPRESSEDDISABLEDERROR
Unchecked Border unselected/border #D7E0EF #1972F9 #D7E0EF #D81E1E
Unchecked Container bg unselected/bg #EBF2FF
Checked Container bg selected/bg #1972F9 #0F57C8 #9BC5FD #D81E1E
Checked Checkmark selected/icon-check #FFFFFF #FFFFFF #FFFFFF #FFFFFF
Indeterminate Container bg indeterminate/bg #1972F9
Indeterminate Dash icon indeterminate/icon #FFFFFF
Focused Border focused/border #1972F9 (all isSelected values)
Checked
DES DEV

Filled container with white checkmark. Represents a selected option. Checkmark is rendered via a separable <code>icon-check</code> child layer.

Properties
State
Size
Properties
isSelected true
State Default
Size Medium
Colors
Container bg #1972F9
Checkmark #FFFFFF
Layout
Size 20 × 20px
Corner radius 4px (radius-1)
Border width None (filled)
Hit target 44 × 44 (mobile)
Typography
icon-only control
Installation Planned API

iOS — Swift Package Manager

// In Xcode: File → Add Package Dependencies
"https://github.com/AY-Org/eb-ds-ios"

// Or in Package.swift:
.package(
    url: "https://github.com/AY-Org/eb-ds-ios",
    from: "2.0.0"
)

Android — Gradle (Kotlin DSL)

// build.gradle.kts (app)
dependencies {
    implementation("com.eastblue.ds:checkbox:2.0.0")
}

Import

import EastBlueDS  // SwiftUI
import com.eastblue.ds.checkbox.*  // Compose

Package not yet published. These are the planned distribution paths. API shape is final — native implementation is pending.

Property Mapping
Figma PropertySwiftUICompose
isSelected isOn: Binding<Bool> checked: Boolean
isSelected = indeterminate toggleIndeterminate TriStateCheckbox
Size .controlSize() size = EBCheckboxSize.*
State = Disabled .disabled(true) enabled = false
State = Pressed interactionSource
State = Focused .focused() interactionSource
State = Error .ebError(true) isError = true
SwiftUI
ios/Components/Checkbox/EBCheckbox.swift
Jetpack Compose
android/components/checkbox/EBCheckbox.kt
Usage Snippets Planned API
Unchecked
// Unchecked (default state)
EBCheckbox(isOn: $isSelected)
    .controlSize(.regular)

// Small size
EBCheckbox(isOn: $isSelected)
    .controlSize(.mini)
// Unchecked (default state)
EBCheckbox(
    checked = false,
    onCheckedChange = { isSelected = it },
    size = EBCheckboxSize.Medium
)

// Small size
EBCheckbox(
    checked = false,
    onCheckedChange = { isSelected = it },
    size = EBCheckboxSize.Small
)
Checked
// Checked (selected state)
EBCheckbox(isOn: .constant(true))
    .controlSize(.regular)

// Bound to state
@State private var isChecked = true
EBCheckbox(isOn: $isChecked)
    .controlSize(.large)
// Checked (selected state)
EBCheckbox(
    checked = true,
    onCheckedChange = { isSelected = it },
    size = EBCheckboxSize.Medium
)

// Bound to state
var isChecked by remember { mutableStateOf(true) }
EBCheckbox(
    checked = isChecked,
    onCheckedChange = { isChecked = it }
)
Indeterminate
// Indeterminate (partial selection)
EBCheckbox(isOn: $isSelected)
    .controlSize(.regular)
    .toggleIndeterminate(true)
// Indeterminate (partial selection)
TriStateCheckbox(
    state = ToggleableState.Indeterminate,
    onClick = { /* cycle state */ },
    modifier = Modifier.size(EBCheckboxSize.Medium)
)
Disabled
// Disabled unchecked
EBCheckbox(isOn: $isSelected)
    .controlSize(.regular)
    .disabled(true)

// Disabled checked
EBCheckbox(isOn: .constant(true))
    .controlSize(.regular)
    .disabled(true)
// Disabled unchecked
EBCheckbox(
    checked = false,
    onCheckedChange = {},
    enabled = false,
    size = EBCheckboxSize.Medium
)

// Disabled checked
EBCheckbox(
    checked = true,
    onCheckedChange = {},
    enabled = false,
    size = EBCheckboxSize.Medium
)
Error
// Error state (form validation)
EBCheckbox(isOn: $isSelected)
    .controlSize(.regular)
    .ebError(true)
// Error state (form validation)
EBCheckbox(
    checked = false,
    onCheckedChange = { isSelected = it },
    isError = true,
    size = EBCheckboxSize.Medium
)
Accessibility
RequirementiOSAndroid
Minimum touch target 44 x 44 pt 48 x 48 dp
Accessibility label .accessibilityLabel("Accept terms") semantics { contentDescription = "Accept terms" }
Checked state announcement VoiceOver reads "checked" / "unchecked" automatically via Toggle TalkBack reads state automatically via Checkbox semantics
Indeterminate toggleIndeterminate reads "mixed" TriStateCheckbox reads "partially checked"
Usage Guidelines

Do

Pair with a visible label adjacent to the checkbox. Checkboxes must always have associated text.

Don't

Use for a single binary toggle — use Switch/Toggle instead. Checkboxes are for multi-select scenarios.

Do

Use for multi-select scenarios — forms, filter lists, settings, and select-all patterns.

Don't

Use a standalone Checkbox without an accessible label. Pair with CheckboxItem or an adjacent text label for form use.

Do

Expand touch area via padding when using Small (16px) size — minimum touch target is 44pt / 48dp.

Don't

Omit an accessible label. Use .accessibilityLabel / contentDescription when no visible label is present.

Criteria Scorecard
ID Criterion Status Notes
C1 Layer Structure & Naming Ready Root frame named container. Simple, semantic hierarchy. No generic layer names.
C2 Variant & Property Naming Ready isSelected now uses true/false — corrected in Figma. Maps directly to Swift Bool / Kotlin Boolean. indeterminate property is a C5 concern (missing state variant).
C3 Token Coverage Ready All states have defined color values. Default, Pressed, Disabled, Error, Focused, and Indeterminate containers use distinct fills/strokes. Separable icon-check and icon-indeterminate layers present.
C4 Native Mappability Ready Maps to Toggle(.checkbox) / Checkbox. Indeterminate maps to TriStateCheckbox. Label pairing via CheckboxItem compound component.
C5 Interaction State Coverage Ready All 5 interaction states defined (Default, Pressed, Focused, Disabled, Error) × isSelected (true/false) × 3 sizes. Indeterminate added as isSelected=indeterminate with icon-indeterminate dash layer. 33 total variants.
C6 Asset & Icon Quality Ready Checkmark rebuilt as a separable icon-check child vector layer inside each checked container. Can be tinted via selected/icon-check token and swapped natively.
C7 Code Connect Linkability Needs Refinement All structural blockers resolved (C2, C5, C6). Ready for CLI mapping registration. No mappings registered yet.
Code Connect
Aspect Status Notes
Property naming Ready isSelected=true/false — maps directly to Swift Bool and Kotlin Boolean
Icon/asset quality Ready icon-check is now a named, separable child layer — can be mapped to a native icon slot via Code Connect
State coverage Ready All interaction states defined — Default, Pressed, Focused, Disabled, Error, plus Indeterminate
Usage descriptions Ready All 33 variants have usage descriptions attached in Figma
Native component file Needs Refinement EBCheckbox.swift / EBCheckbox.kt not yet created
Variants Inventory (33 total)

5 State × 3 isSelected × 3 Size = 45 theoretical. isSelected=indeterminate only ships State=Default, so actual count is (5 × 2 × 3) + (1 × 1 × 3) = 33 variants.

isSelectedStatesSizesCount
falseDefault, Pressed, Focused, Disabled, ErrorSmall, Medium, Large15
trueDefault, Pressed, Focused, Disabled, ErrorSmall, Medium, Large15
indeterminateDefault onlySmall, Medium, Large3
1.5.0 — March 2026Minor
Compound Component + Cleanup · node 17734:161220
CheckboxItem compound component created — 4 variants: isSelected (true/false) × Size (Small/Medium). Each contains a real Checkbox instance + Label (Proxima Soft Bold, 14px/18px) + Description (BarkAda Medium, 12px). Wraps atomic Checkbox with label pairing for accessible form use. Created
New Component
Variant property order reordered — Naming changed from isSelected=X, Size=Y, State=Z to State=X, isSelected=Y, Size=Z. State is now the first property axis in the component set. Section renamed from "Claude Testing" to "Checkbox". Updated
Cleanup
1.4.0 — March 2026Minor
C5 Fix · node 17143:2464
All interaction states added — Added 27 new variants covering State (Pressed/Focused/Disabled/Error) × isSelected (true/false) × Size (Small/Medium/Large). Variants 6 → 33. Colors: Pressed uses light blue fill + blue border (unchecked) / #0F57C8 (checked); Focused uses blue border; Disabled uses 40% opacity; Error uses red border / #D81E1E fill. Fixed
C5 Resolved
Indeterminate state added — Added isSelected=indeterminate variants for Small, Medium, and Large. Each contains a blue container frame with a named icon-indeterminate horizontal dash child layer. Maps to ToggleableState.Indeterminate (Android) and toggleIndeterminate (iOS). Fixed
C5 Indeterminate
1.3.0 — March 2026Minor
C6 Fix · node 17143:2464
Checkmark rebuilt as separable vector layer — Deleted the flattened boolean-op containers from all 3 isSelected=true variants. Created clean blue container frames (4px radius) with a named icon-check child vector inside each. Engineers can now tint via selected/icon-check token and map to a native icon slot. Nodes: 17721:962 (Small), 17721:963 (Medium), 17721:964 (Large). Fixed
C6 Resolved
1.2.0 — March 2026Minor
C2 Fix · node 17143:2464
Boolean property renamed in Figma — All 6 variants renamed from isSelected=Yes/No to isSelected=true/false. Now maps directly to Swift Bool and Kotlin Boolean for Code Connect. C2 criterion resolved. Fixed
C2 Resolved
1.1.0 — March 2026Minor
Assessment Rebuild · node 17143:2464
Full 4-tab assessment built — Overview, Style, Code, and Changelog tabs. Interactive live preview with size and state controls. Spec cards for Unchecked and Checked appearances. Full criteria scorecard and Code Connect readiness table. Updated
Documentation
Property name corrected — Existing assessment incorrectly referenced isChecked. Figma metadata confirms the property is isSelected. All documentation updated. Fixed
C2 Note
1.0.0 — March 2026Major
Initial Assessment · node 17143:2464
Component assessed — 6 variants documented across isSelected (Yes/No) x Size (Small 16px / Medium 20px / Large 24px). Token audit found 7 variables defined. Documented
Initial
Flattened checkmark icon — Checked containers had no child layers. The white checkmark was a boolean operation baked into the container frame. Cannot be extracted, tinted, or swapped as a component instance. Hard C6 blocker. Fixed in v1.3.0
C6 Resolved
Missing interaction states — Only checked/unchecked defined. No disabled, pressed, focused, indeterminate, or error state variants. Checkboxes require all of these for production form use. Fixed in v1.4.0
C5 Resolved
Boolean property uses Yes/NoisSelected=Yes/No instead of true/false. Incompatible with Swift Bool and Kotlin Boolean for Code Connect mapping. Fixed in v1.2.0
C2 Resolved
Code Connect mappings — Usage descriptions attached per variant. Was blocked by C2 and C6 (both resolved). Pending C5 (missing states) before complete CLI mapping. No CLI mappings registered yet. Open
C7 Open