A 2D grid of icon-and-label tiles used for top-level service navigation.
"by 4") instead of integers (C2). Service Item only ships an active color set — no pressed/disabled tokens (C5). Code Connect mappings not yet registered (C7).Contexts are illustrative. Final screens will reference actual GCash patterns. Menu Grid sits on the dashboard as the primary service shortcut surface — typically Row=2, Column=4 (8 services) on the home screen.
"by 4") instead of clean integer enums. Should be rows: 4 / columns: 4 for native parity. C217787:1700). Service Item is a separate canonical component — icon and label are easily overridable per cell.| State | iOS | Android | Figma Property | Notes |
|---|---|---|---|---|
| Default | Yes | Yes | Row × Column | Active state only — uses dashboard/service-item/color/active/{icon,label} |
| Pressed | N/A | N/A | — | No pressed token defined for Service Item. Native may need to derive from icon brand color. C5 |
| Disabled | N/A | N/A | — | No disabled token defined. C5 |
- Variant values use pseudo-numeric strings.
Row="by 4",Column="by 4"can't map cleanly to native ints or enums. Should be plain integers (rows: 4,columns: 4). C2 · Variant & Property Naming - Service Item only defines an
activecolor set. Nopressedordisabledtokens exist — engineers must invent these colors on native. C5 · Interaction State Coverage - Code Connect mappings not registered. Blocked until the variant explosion and token gaps are addressed. C7 · Code Connect Linkability
- Replace the 20-variant matrix with two integer props.
rowsandcolumnsas ints. Variant explosion is a Figma-only construct; native uses a lazy grid that takes any int. Could collapse to ~1–2 variants. Property - Add
pressedanddisabledcolor tokens. Extenddashboard/service-item/color/*so all states are documented at the token layer, not improvised in code. Token - Promote Service Item to a first-class DS component. It's currently a child of Menu Grid but is reused independently across other surfaces. Publishing it standalone (same pattern as Avatar + Avatar Group) makes reuse explicit. Family
The default dashboard layout — 2 rows × 4 columns = 8 services. Used on the home dashboard for primary service shortcuts.
EBMenuGrid(items: services, columns: 4) Service Item ships only the active color set. Pressed and disabled are not yet defined at the token layer — see C5 in the Open Issues.
| Role | Token | Value |
|---|---|---|
| Container bg | bg/color-bg-main | #FFFFFF |
| Service icon | dashboard/service-item/color/active/icon | #005CE5 |
| Service label | dashboard/service-item/color/active/label | #072592 |
| Border (weak) | border/color-border-weak | #E5EBF4 |
Expanded grid for "All Services" sheets — 4 rows × 4 columns = 16 services. Used on category pages or full-list views.
EBMenuGrid(items: services, columns: 4) | Role | Token | Value |
|---|---|---|
| Container width | — | 336px (fixed) |
| Padding (horizontal) | space/space-8 | 8px |
| Padding (top) | space/space-10 | 10px |
| Padding (bottom) | space/space-6 | 6px |
| Cell gap (row & col) | space/space-4 | 4px |
| Bottom radius | radius/radius-2 | 6px |
| Service Item min-width | — | 64px |
| Service Item icon container | — | 40 × 40 |
| Icon padding | space/space-4 | 4px |
| Icon → label gap | space/space-6 | 6px |
Maximum density — 5 rows × 5 columns = 25 services. Use sparingly; label legibility tightens at this density.
EBMenuGrid(items: services, columns: 4) | Role | Token |
|---|---|
| DS text style | Primary/Label/Fine |
| Font | Proxima Soft |
| Weight | 700 (Bold) |
| Size | 12px |
| Line height | 12px |
| Tracking | +0.5 |
| Alignment | center |
iOS — Swift Package Manager
// In Xcode: File → Add Package Dependencies "https://github.com/AY-Org/eb-ds-ios"
Android — Gradle (Kotlin DSL)
dependencies { implementation("com.eastblue.ds:menu-grid:1.0.0") }
| Figma Property | SwiftUI | Compose |
|---|---|---|
| Row="by N" | rows: Int | rows: Int |
| Column="by N" | columns: Int | columns: Int |
| Service Item (instance) | items: [EBServiceItem] | items: List<EBServiceItem> |
// Default dashboard grid — 2 rows × 4 columns EBMenuGrid(columns: 4, items: services) // Service Item child EBServiceItem( icon: Image("send-money"), label: "Send Money", action: { /* tap */ } )
// Default dashboard grid — 2 rows × 4 columns EBMenuGrid( columns = 4, items = services ) // Service Item child EBServiceItem( icon = painterResource(R.drawable.send_money), label = "Send Money", onClick = { /* tap */ } )
| Requirement | iOS | Android |
|---|---|---|
| Tap target | Service Item is 64+ px wide × ~64 px tall — meets HIG 44pt minimum | Meets Material 48dp minimum |
| Accessibility label | .accessibilityLabel(label) on each item | contentDescription = label |
| Grid semantics | Container exposes grid traits via LazyVGrid | LazyVerticalGrid announces row/column position |
| Disabled state | Currently undefined — needs token + .disabled(true) handling | Currently undefined — needs token + enabled = false |
Do
Use Row=2 × Column=4 for the primary dashboard surface — 8 services is the established home pattern.
Don't
Use Row=5 × Column=5 unless density is essential — 25 cells reduces label legibility.
Do
Pair Menu Grid with a section heading or container card so users understand the grouping.
Don't
Mix icon styles within a single grid — keep all Service Item icons in the same vector style.
| ID | Criterion | Status | Notes |
|---|---|---|---|
| C1 | Layer Structure & Naming | Ready | Semantic names: Service Item, icon-container, Label. No Frame/Group debris. |
| C2 | Variant & Property Naming | Requires Rework | Property values are pseudo-numeric strings ("by 4") instead of integers. Native takes Int. |
| C3 | Token Coverage | Ready | All colors, spacing, radii, and typography bound to tokens. |
| C4 | Native Mappability | Needs Refinement | Maps to LazyVGrid / LazyVerticalGrid. The 20-variant matrix is Figma-only — native uses one component with two int props. |
| C5 | Interaction State Coverage | Requires Rework | Only active token defined. No pressed or disabled color tokens for Service Item. |
| C6 | Asset & Icon Quality | Ready | Icon container is a vector instance, token-bound color. |
| C7 | Code Connect Linkability | Needs Refinement | No CLI mappings registered yet. |
4 Row × 5 Column = 20 variants. All variants share the same 336px container, 4×4 cell gap, and Service Item child.
| Row | Columns | Cell range | Count |
|---|---|---|---|
| by 2 | by 1, 2, 3, 4, 5 | 2 – 10 | 5 |
| by 3 | by 1, 2, 3, 4, 5 | 3 – 15 | 5 |
| by 4 | by 1, 2, 3, 4, 5 | 4 – 20 | 5 |
| by 5 | by 1, 2, 3, 4, 5 | 5 – 25 | 5 |
Row="by 4", Column="by 4". Native takes Int; the string prefix forces parsing.
Opendashboard/service-item/color/active/{icon,label} defined. Other states must be improvised.
Open