A generic surface card used to group content into a tappable unit — header, body slot, and optional footer.
iconSize to semantic values (XL / L / M / S). Replace the icon placeholder with a swappable Avatar / Icon slot via instance swap. Replace the raster chevron with a vector. Add a pressed state — this is clearly a tappable row but only Default + skeleton are modeled today.Generic Card stacks vertically into a scrolling list — product catalogs, service menus, transaction history detail screens. Icon size tightens as the density of the list increases.
Heading Goes Here
Label:Description goes here
Label:Description goes here
LabeliconSize values is a lot. Tag uses Badge (good) and bottom pill uses Badge (good) — composition is correct where it happens.| State | iOS | Android | Figma Property | Notes |
|---|---|---|---|---|
| Default | Yes | Yes | state=Default | Normal row — all content visible, chevron shown when hasChevron. |
| Skeleton (loading) | Yes | Yes | state=skeleton | Loading pattern — gray rounded placeholders where each content slot would render. Kudos for shipping this as a first-class variant. |
| Pressed | N/A | N/A | Not built | Tappable row (has chevron) — needs a pressed state with background tint for tap feedback. |
| Disabled | N/A | N/A | Not built | For temporarily-unavailable services (e.g. maintenance). Typically dimmed label + muted icon. |
-
iconSizeuses 6 numeric values.64 / 52 / 46 / 40 / 32 / 24is too granular — consumers can't tell when to pick 46 vs 40. Collapse to 3–4 semantic sizes (XL / L / M / S) with fixed pixel values behind the scenes. C2 · Variant & Property Naming - Icon slot is a hardcoded placeholder circle. Not an Avatar or Icon instance — blocks swappable composition. Designers can't drop in a brand icon, illustration, or Avatar without detaching. C6 · Asset & Icon Quality
- Chevron is a raster image. Ships as a PNG (
shape_full) rather than a vector glyph — blurs at large render sizes and blocks token-based tinting. C6 · Asset & Icon Quality - No pressed / disabled states. Has a chevron, so clearly tappable — but only Default + skeleton states are built. Pressed tint and disabled appearance are standard row affordances. C5 · Interaction State Coverage
- Code Connect mappings not registered. Blocked until iconSize collapse + icon-slot adoption land. C7 · Code Connect Linkability
- Collapse
iconSizeto semantic sizes.xl (64) / l (52) / m (40) / s (32)— drops 6 numeric values to 4 meaningful ones. (46 and 24 can be retired or mapped to the nearest semantic size.) Matches how Avatar sizes are named elsewhere. Rename - Replace the icon placeholder with a Figma Slot. Accept an Avatar instance (for person/brand rows) or an Icon instance (for service rows). Native maps to
@ViewBuilder(SwiftUI) or@Composableslot (Compose) via Code Connect. Slot - Convert the chevron to a vector. Replace the raster
shape_fullwith a vector path — token-bindable color and crisp at any scale. Asset - Add pressed + disabled states. Pressed: subtle bg tint on the whole row. Disabled: muted label + icon opacity. Rows are tappable and need both. State
- Document the skeleton pattern as a DS convention. Generic Card's skeleton variant is exactly the pattern other row/card components should follow. Call it out in the guidelines so the same loading treatment spreads consistently. Docs
- See sibling: Generic Transaction Card. Similar "card row" primitive — the two could share a common schema once both are cleaned up. Family
Full-featured row: icon + blurb with tag, heading, 2 description lines, bottom badge, chevron.
Heading Goes Here
Label:Description goes here
Label:Description goes here
LabelTappable list-style card with leading icon, heading, description, optional blurb + tag.
| Role | Token | Default |
|---|---|---|
| Surface | card-list/color/bg | #FFFFFF |
| Border | card-list/color/border | #E5EBF4 |
| Title | card-list/color/label-header | #0A2757 |
| Description | card-list/color/description | #445C85 |
| Label | card-list/color/label | #90A8D0 |
| Blurb | card-list/color/label-blurb | #005CE5 |
| Icon | card-list/color/icon | #005CE5 |
| Badge bg | badge/information/light/background | #E5F1FF |
| Badge label | badge/information/light/label | #005CE5 |
The loading pattern for the card. Every content slot becomes a rounded rectangle placeholder in neutral gray. Use while awaiting data.
Loading state — every content slot is a rounded rectangle in neutral grey on the card surface.
| Role | Token | Default |
|---|---|---|
| Skeleton bg | main/skeleton/bg | #EEF2F9 |
| Surface bg | main/card/bg | #FFFFFF |
| Figma Property | SwiftUI | Compose |
|---|---|---|
iconSize: 64 | 52 | 46 | 40 | 32 | 24 | size: xl | l | m | s | .controlSize(.large) etc. |
| (drawn circle) | leadingMedia: Avatar | Icon (slot) | leadingMedia: EBLeadingMedia? |
| (hardcoded text) | heading: String | heading: String |
hasBlurb | blurb?: String | blurb: String? |
hasTag | tag?: Badge (instance) | tag: EBBadge? |
hasSubtitle | (derived: shown if blurb or tag present) | — |
| (hardcoded "Description goes here") | descriptions: [LabelValue] | descriptions: [EBLabelValue] |
has2ndDescription | (derived: up to N rows rendered) | — |
hasBadge | badge?: Badge (instance) | badge: EBBadge? |
hasChevron | showChevron: Bool = true | showChevron: Bool = true |
state: Default | skeleton | loading: Bool | loading: Bool |
| (not modeled) | onTap?: () -> Void | onTap: (() -> Void)? |
| Requirement | iOS | Android |
|---|---|---|
| Row as a button | Whole row wrapped in Button with combined accessibilityLabel (heading + blurb + tag). | Modifier.clickable { onTap() }.semantics(mergeDescendants = true) on the row. |
| Combined announcement | "Send Money Abroad, PROMO, New, Free for first transfer, Same day, Recommended" — VoiceOver reads top-to-bottom. | Same reading order — TalkBack follows composition. |
| Loading state | Announce "Loading" once on mount; suppress per-placeholder announcements. | Apply contentDescription = "Loading" to the skeleton container. |
| Min touch target | 146 px row height ≫ 44 pt ✓ | 146 dp ≫ 48 dp ✓ |
| ID | Criterion | Status | Notes |
|---|---|---|---|
| C1 | Layer Structure & Naming | Ready | Clean container / content / chevron hierarchy. Tag and bottom pill are Badge instances. |
| C2 | Variant & Property Naming | Needs Refinement | 6 numeric iconSize values — collapse to semantic scale. |
| C3 | Token Coverage | Ready | All colors bound to main/card-list/color/* + Badge tokens. |
| C4 | Native Mappability | Needs Refinement | Maps cleanly to a row composable once icon slot + chevron are fixed. |
| C5 | Interaction State Coverage | Needs Refinement | Default + skeleton built. Missing pressed + disabled for a tappable row. |
| C6 | Asset & Icon Quality | Needs Refinement | Icon placeholder isn't an instance; chevron is a raster. |
| C7 | Code Connect Linkability | Not Mapped | Blocked until iconSize rename and icon slot adoption land. |
iconSize (6) × state (2) = 12 variants. The 6 boolean slot props (hasBlurb, hasTag, hasSubtitle, has2ndDescription, hasBadge, hasChevron) toggle content independently and don't multiply the variant count.
| iconSize | Default node | Skeleton node | Dimensions |
|---|---|---|---|
| 64 | 18482:35807 | 18482:35832 | 360 × 146 |
| 52 | 18482:35843 | 18482:35868 | 360 × 146 |
| 46 | 18482:35879 | 18482:35904 | 360 × 146 |
| 40 | 18482:35915 | 18482:35940 | 360 × 146 |
| 32 | 18482:35951 | 18482:35976 | 360 × 146 |
| 24 | 18482:35987 | 18482:36012 | 360 × 146 |