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.
Contexts are illustrative. Final screens will reference actual GCash patterns.
CheckboxItem compound component provides label + description pairing.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.main/checkbox/color/...). isSelected uses true/false/indeterminate. All property values follow boolean and enum standards (C2 resolved).CheckboxItem compound component wraps Checkbox + Label + Description for accessible form groups.| 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. |
-
isSelected=Yes/Norenamed toisSelected=true/falsein Figma — now maps correctly to SwiftBooland KotlinBooleanC2 Fixed - Checkmark rebuilt as a separable
icon-checkchild 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=indeterminateper size withicon-indeterminatedash layer. 6 → 33 total variants C5 Fixed
- Code Connect mappings not registered. All structural blockers resolved — registration can now proceed against the 33-variant
isSelected × State × Sizeschema. C7 · Code Connect Linkability
-
CheckboxItemcompound 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
Empty container with border stroke. Represents a deselected option.
All interaction states now have defined colors. Token paths follow main/checkbox/color/{state}/{role} convention.
| Role | Token | Token | DEFAULT | PRESSED | DISABLED | ERROR |
|---|---|---|---|---|---|---|
| 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) |
Filled container with white checkmark. Represents a selected option. Checkmark is rendered via a separable <code>icon-check</code> child layer.
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.
| Figma Property | SwiftUI | Compose |
|---|---|---|
| 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 |
// 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 (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 (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 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 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 )
| Requirement | iOS | Android |
|---|---|---|
| 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" |
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.
| 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. |
| 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 |
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.
| isSelected | States | Sizes | Count |
|---|---|---|---|
| false | Default, Pressed, Focused, Disabled, Error | Small, Medium, Large | 15 |
| true | Default, Pressed, Focused, Disabled, Error | Small, Medium, Large | 15 |
| indeterminate | Default only | Small, Medium, Large | 3 |
Proxima Soft Bold, 14px/18px) + Description (BarkAda Medium, 12px). Wraps atomic Checkbox with label pairing for accessible form use.
CreatedisSelected=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#0F57C8 (checked); Focused uses blue border; Disabled uses 40% opacity; Error uses red border / #D81E1E fill.
FixedisSelected=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).
FixedisSelected=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).
FixedisSelected=Yes/No to isSelected=true/false. Now maps directly to Swift Bool and Kotlin Boolean for Code Connect. C2 criterion resolved.
FixedisChecked. Figma metadata confirms the property is isSelected. All documentation updated.
FixedisSelected=Yes/No instead of true/false. Incompatible with Swift Bool and Kotlin Boolean for Code Connect mapping.
Fixed in v1.2.0