The 32×32 selectable day cell rendered inside the Date Picker calendar grid.
Picker Cell with kind: day | month | year + state: default | today | selected | range-middle | prev-next | disabled. Also note: at 32×32 the cell is below WCAG's 44×44 minimum touch target (A11y).The cell is an instance inside Date Picker - Group (Type=Date). 42 cells are rendered across 6 rows × 7 columns. A sibling weekday-header row also instance-swaps this component, which is one of the reasons C1 flags the layer-naming convention.
Month and Year Picker - Item exists at 100×32 doing nearly the same job.main/date-picker/day/*. However, Range (Middle) uses absolutely-positioned sibling rectangles (Range highlight start, Range highlight end) to spill the range strip into adjacent cells — this is row-level geometry leaking into a cell-level component.Type mixes display roles (Default, Today, Prev/Next) with selection state (Selected, Range Middle) on one axis. Disabled exists only on Default and Today — Selected, Range (Middle), and Prev/Next have no Disabled variant. Value Range (Middle) uses parentheses/space in a variant name.DatePicker(.graphical) and Material 3 DatePicker render their own cells. Even if kept as a visual reference, it duplicates Month and Year Picker - Item at a different size instead of being one Picker Cell with a kind axis.| State | iOS | Android | Figma Property | Notes |
|---|---|---|---|---|
| Default | Yes | Yes | Type=Default, State=Enabled | Plain day number on white. No ring, no fill. #0A2757 label. |
| Today | Yes | Yes | Type=Today, State=Enabled | 1.5px blue ring, blue label. Native equivalent: todayDateBorderColor on Material 3. |
| Selected | Yes | Yes | Type=Selected, State=Enabled | Solid blue fill (#005CE5), white bold label. Only exists as Enabled — no Disabled form. |
| Range (Middle) | Yes | Yes | Type=Range (Middle), State=Enabled | Weakest-info bg (#E5F1FF), bold blue label. Ships with extraLeft/extraRight booleans that bleed the strip into adjacent cells. |
| Prev/Next | Yes | Yes | Type=Prev/Next, State=Enabled | Greyed label (#C2CFE5) for days spilling over from the adjacent month. Not a true Disabled — the day is still conceptually pickable, just visually dimmed. |
| Disabled (Default/Today) | Yes | Yes | Type={Default|Today}, State=Disabled | Label drops to #9BC5FD (Today) or #C2CFE5 (Default). Disabled missing on Selected, Range, and Prev/Next. |
| Pressed / Focused / Hover | No | No | — | Not defined on any Type. Native pickers supply these automatically. |
| Today + Selected | No | No | — | Not defined. Unclear which presentation wins when today is also the selected date. |
| Touch target | N/A | N/A | — | Below WCAG minimum 44×44. Native pickers enforce their own hit areas, but any custom wrapper would need to extend the tap area beyond the visual cell. |
- Sibling duplication with Month and Year Picker - Item. The two components are the same selectable-cell primitive at different pixel sizes (32×32 vs 100×32) with overlapping state semantics (Default, Today, Selected). Maintaining them as siblings doubles the variant surface and forces the Group panel to decide which cell to instance-swap based on the current view. C1 · Layer Structure & Naming
- Range continuity is drawn per-cell, not at the row. The
Range (Middle)variant includes two absolutely-positioned siblings (Range highlight start,Range highlight end) that spill 28–34% beyond the cell bounds to visually connect with neighbours. Range continuity is row-level geometry; modelling it on the cell produces per-cell decoration with leak. C1 · Layer Structure & Naming -
Typeaxis mixes display role with selection state. Default, Today, and Prev/Next describe what the cell is; Selected and Range (Middle) describe what the user has done. These belong on two axes (roleandselection), not one. The current shape produces invalid combinations (e.g. you can't express "Today that is also Selected"). C2 · Variant & Property Naming - Variant value
Range (Middle)uses punctuation and whitespace. Rename torange-middle(or, after the axis-split,selection = range-middle). Current value generatestype="Range (Middle)"in code-connect output, which is awkward to match on. C2 · Variant & Property Naming - Cell has no 1:1 native primitive. Both SwiftUI
DatePicker(.graphical)and Material 3DatePickerrender their own day cells and don't accept a custom cell view. This Figma component is therefore a reference spec, not a mappable component — should be marked as such or merged into the Picker Cell family. C4 · Native Mappability - Disabled coverage incomplete. The
Stateaxis nominally supports Disabled, but Disabled variants exist only on Default and Today. Selected, Range (Middle), and Prev/Next have no Disabled form — unreachable if the user picks a selected date then the parent toggles disabled. C5 · Interaction State Coverage - No Pressed, Hover, or Focused variants. Tap feedback (iOS ripple / Android state layer) and keyboard focus ring are not defined. Native pickers supply these automatically, but any custom overlay or wrapper has no tokens to apply. C5 · Interaction State Coverage
- Today + Selected collision is unresolved. There is no variant for the common case of today being the currently-selected date. The design team should decide which presentation wins (ring + fill, fill-only, or a hybrid) and publish a variant. C5 · Interaction State Coverage
- Selection emphasis pattern not shared with Month/Year cells. Selected on this cell is a solid fill; Selected on Month and Year Picker - Item is a 1px ring. The two selection treatments drift — should be one token-driven "selection emphasis" applied consistently per
kind. C6 · Asset & Icon Quality - Code Connect mappings not registered. Blocked by the native-pickers-own-it direction (C4) and by the pending Picker Cell family unification (C1). Map only once the unified component exists and the wrapper surface is confirmed. C7 · Code Connect Linkability
- Family — Consolidate Date Picker - Item + Month and Year Picker - Item into ONE
Picker Cell. Both are selectable cells with identical state semantics (Default / Today / Selected / Disabled); only pixel size (32×32 vs 100×32) and typography differ. Proposed schema:kind = day | month | year+state = default | today | selected | range-middle | prev-next | disabled. Collapses 10 sibling variants across two components into one component with two clean axes. A single nativePickerCellcomposable renders the correct typography perkind. Family - Property — Split
Typeintorole+selection(after consolidation). Within the unified Picker Cell, separate display role (default | today | prev-next) from selection state (none | selected | range-start | range-middle | range-end). Lets designers express "Today that is also Selected" and fixes the current invalid combinations. Property - Rename
Range (Middle)torange-middle. Remove parentheses and whitespace from the variant value. Cleaner code-connect output and matches the kebab-case used by other DS enums. Rename - State — Add Pressed, Focused, and Today+Selected variants. Extend the state axis with Pressed and Focused (needed for any custom wrapper rendering tap / keyboard affordances), and publish a decision variant for the common "today is also selected" case. State
- State — Complete Disabled coverage across all Types. The
Stateaxis currently only exists on Default and Today. Publish Disabled variants for Selected, Range (Middle), and Prev/Next so the axis is rectangular — no missing cells in the variant matrix. State - Composition — Move range-strip continuity from the cell to the row. Remove the absolutely-positioned
Range highlight start/Range highlight endsiblings from the cell. Render the range strip as a row-level decoration behind the cells (a full-width rectangle between range-start and range-end). Keeps the cell component self-contained. Composition - Token — Share a selection-emphasis token across Picker Cell kinds. Create
main/picker-cell/selection/*tokens that resolve to either "fill" or "ring" based onkind, so day/month/year selection treatments stay intentionally consistent rather than drifting. Token - A11y — Flag the 32×32 touch target. Below WCAG 2.5.5 minimum 44×44. If a custom wrapper is ever built, extend the hit area beyond the visual cell (add transparent padding). Document this on the component so consumers don't accidentally ship the tight target outside the native picker context. A11y
- Docs — Mark as reference, not a production component. Given that both platforms render their own day cells inside the native
DatePicker, this cell is a visual reference for the token-styled wrapper, not a component developers rebuild. Add a description banner and a_referenceprefix once the Picker Cell family unification lands. Docs
32×32 day cell rendered inside the calendar grid. Flip Type and State to walk through every variant.
All cell colors are bound to tokens. Selected uses the main/date-picker/day/color/selected/* scope; Default/Today borrow main/date-picker/day/color/unselected/* plus primary text/border tokens for the ring and label. Range (Middle) reuses the shared bg/color-bg-info-weakest rather than a picker-scoped token.
| Role | Token | Token | ENABLED | DISABLED |
|---|---|---|---|---|
| Default | bg | main/date-picker/day/color/unselected/bg | #FFFFFF | #FFFFFF |
| Default | label | main/date-picker/day/color/unselected/label | #0A2757 | #C2CFE5 (text/color-text-disabled) |
| Today | bg | main/date-picker/day/color/unselected/bg | #FFFFFF | #FFFFFF |
| Today | ring | border/color-border-primary | #005CE5 (1.5px) | #9BC5FD (border/color-border-primary-disabled) |
| Today | label | text/color-text-primary | #005CE5 | #9BC5FD (text/color-text-primary-disabled) |
| Selected | bg | main/date-picker/day/color/selected/bg | #005CE5 | – |
| Selected | label | main/date-picker/day/color/selected/label | #FFFFFF | – |
| Range (Middle) | bg | bg/color-bg-info-weakest | #E5F1FF | – |
| Range (Middle) | label | text/color-text-primary | #005CE5 (bold) | – |
| Prev/Next | bg | main/date-picker/day/color/unselected/bg | #FFFFFF | – |
| Prev/Next | label | text/color-text-disabled | #C2CFE5 | – |
| Figma Property | SwiftUI | Compose |
|---|---|---|
| Type=Default | (default rendering) | dayContentColor |
| Type=Today | .accentColor / automatic Today ring | todayDateBorderColor |
| Type=Selected | .tint (via selection binding) | selectedDayContainerColor / selectedDayContentColor |
| Type=Range (Middle) | (no direct API — requires custom calendar) | dayInSelectionRangeContainerColor |
| Type=Prev/Next | (automatic dimming) | (automatic dimming via dayContentColor) |
| State=Disabled | in: Date... range parameter | selectableDates |
| extraLeft / extraRight | — | — |
| Requirement | iOS | Android |
|---|---|---|
| Touch target (44 × 44 min) | Figma cell is 32 × 32 — native picker extends hit area | Figma cell is 32 × 32 — native picker extends hit area |
| Screen reader label | VoiceOver: "Friday, 5 March, Today" (from DatePicker) | TalkBack: "5 March 2026, Today" (from Material 3) |
| Selected announcement | "Selected" trait added automatically | "Selected" state added automatically |
| Focus ring | System focus ring on iPad / hw keyboard | System focus indicator on D-Pad / hw keyboard |
| Disabled announcement | "Dimmed" trait when outside in: range | "Disabled" state when outside selectableDates |
| Dynamic Type / font scaling | Automatic | Automatic |
Do
Treat this cell as a visual reference for how the native picker should look in GCash theme — colors, ring thickness, radius, and label weight.
Don't
Don't ship a standalone EBDatePickerItem composable. Native pickers render their own cells; a custom cell composable has no slot to plug into.
Do
If you genuinely need a custom cell (e.g. event dots, legend markers), merge with Month and Year Picker - Item into a unified PickerCell(kind:, state:) and compose it inside a custom calendar grid.
Don't
Don't maintain Date Picker - Item and Month and Year Picker - Item as siblings — they're the same primitive at different sizes.
Do
Rely on the native picker for locale-aware firstDayOfWeek, leap-year handling, VoiceOver / TalkBack, and minDate/maxDate enforcement.
Don't
Don't draw disabled days manually. Pass an in: range (SwiftUI) or selectableDates (Compose) and let the platform style them.
| ID | Criterion | Status | Notes |
|---|---|---|---|
| C1 | Layer Structure & Naming | Requires Rework | Sibling-duplication with Month and Year Picker - Item. Range continuity modelled with absolute-positioned siblings that spill beyond cell bounds. |
| C2 | Variant & Property Naming | Requires Rework | Type mixes display role with selection state on one axis. Value Range (Middle) uses punctuation/whitespace. |
| C3 | Token Coverage | Ready | All colors, spacing, radius, and typography are token-bound (main/date-picker/day/* + primary text/border tokens). |
| C4 | Native Mappability | Requires Rework | Native pickers own the day cell and don't accept a custom cell view. Reference-only unless merged into a custom PickerCell. |
| C5 | Interaction State Coverage | Requires Rework | Disabled missing on Selected, Range (Middle), Prev/Next. No Pressed, Hover, Focused. Today + Selected collision unresolved. |
| C6 | Asset & Icon Quality | Needs Refinement | No raster assets — cell is pure geometry + text. But selection emphasis (fill vs ring) drifts from Month and Year Picker - Item; should be one token-driven pattern. |
| C7 | Code Connect Linkability | Not Mapped | Blocked by C4 (native owns it) and by the pending Picker Cell family unification. |
| Aspect | Status | Notes |
|---|---|---|
| Property naming | Requires Rework | Split Type into role + selection; rename Range (Middle) to range-middle. |
| Family unification | Requires Rework | Merge with Month and Year Picker - Item into PickerCell with kind: day | month | year. |
| Native component file | Not Mapped | No standalone composable — native DatePicker renders cells. Only materialize EBPickerCell if a custom calendar grid is ever built. |
| Range continuity | Requires Rework | Move Range highlight start/end geometry from the cell up to the row before mapping. |
| Recommendation | Consolidate | Merge into PickerCell, mark as reference spec for the native picker's day cell. |
5 Type × 2 State would produce 10 variants, but only 7 are published — Selected, Range (Middle), and Prev/Next exist only with State=Enabled.
| Type | State | Dimensions | Emphasis | Node ID |
|---|---|---|---|---|
| Default | Enabled | 32 × 32 | none | 12874:42181 |
| Default | Disabled | 32 × 32 | dim label | 13948:3888 |
| Today | Enabled | 32 × 32 | 1.5px blue ring | 13944:5633 |
| Today | Disabled | 32 × 32 | 1.5px primary-disabled ring | 13948:3891 |
| Selected | Enabled | 32 × 32 | solid blue fill, white label | 12874:42183 |
| Range (Middle) | Enabled | 32 × 32 | weakest-info fill, bold blue label, extraLeft/extraRight booleans | 13944:5637 |
| Prev/Next | Enabled | 32 × 32 | dim label only | 13944:5653 |
Type × State. 32×32 pill cell with token-bound colors, spacing, radius, and typography.
DocumentedPicker Cell with kind: day | month | year.
OpenRange highlight start and Range highlight end are absolute-positioned siblings that spill beyond the cell. Should be row-level geometry.
OpenType mixes role and selection — Default/Today/Prev-Next are display roles; Selected/Range (Middle) are selection states. Split into role + selection.
OpenRange (Middle) needs cleanup — Rename to range-middle for clean code-connect output.
OpenDatePicker renders its own cells on both platforms. Reference-only unless a custom calendar grid is built.
Openkind.
Open