FixNeeds Refinement
Generic Card Component link

A generic surface card used to group content into a tappable unit — header, body slot, and optional footer.

Fix — collapse iconSize, swap placeholders to slots, ship the pressed state
Rename 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.
In Context

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.

Live Preview
BlurbTag

Heading Goes Here

Label:Description goes here

Label:Description goes here

Label
Content
blurb
tag
heading
description
badge
Properties
iconSize
state
Slots
hasSubtitle
hasBlurb
hasTag
has2ndDesc
hasBadge
hasChevron
DS Health
Reusable
Pass
Solid general-purpose list-row card. Works across catalogs, services, transaction history, and detail-screen rows.
Self-contained
Partial
Owns colors, typography, spacing tokens. But the icon is drawn (placeholder circle) not instanced, and the chevron ships as a raster.
Consistent
Partial
6 numeric iconSize values is a lot. Tag uses Badge (good) and bottom pill uses Badge (good) — composition is correct where it happens.
Composable
Pass
Stacks cleanly into a scrollable list. Skeleton state is a first-class variant — rare and worth highlighting as a DS convention.
Behavior
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.
Open Issues
  • iconSize uses 6 numeric values. 64 / 52 / 46 / 40 / 32 / 24 is 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
Design Recommendations
  • Collapse iconSize to 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 @Composable slot (Compose) via Code Connect. Slot
  • Convert the chevron to a vector. Replace the raster shape_full with 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
Variants
Default — iconSize=64
DES DEV

Full-featured row: icon + blurb with tag, heading, 2 description lines, bottom badge, chevron.

BlurbTag

Heading Goes Here

Label:Description goes here

Label:Description goes here

Label
Properties
iconSize
state
Slots
hasSubtitle
hasBadge
hasChevron
Properties
iconSize 64
state Default
Layout icon-leading + content-right
Colors
Surface #FFFFFF
Border #E5EBF4
Title #0A2757
Description #445C85
Label #90A8D0
Blurb #005CE5
Icon #005CE5
Badge bg #E5F1FF
Badge label #005CE5
Layout
Width × Height 360 × 146
Padding 16 24 16 12
Gap (icon ↔ content) 24px
Gap (content ↔ chevron) 24px
Bottom border 1px
Icon size 64 × 64
Chevron size 32 × 32
Typography
Heading Proxima Soft Bold · 18 / 23 · +0.25
Blurb Proxima Soft Bold · 14 / 14 · +0.25
Description BarkAda Semibold · 12 / 18 · +0
Tag label Proxima Soft Bold · 12 / 12 · +0.5
Badge label Proxima Soft Bold · 12 / 12 · +0.5
Composed sub-components
Tag Badge · Negative · Heavy
Bottom pill Badge · Information · Light
Icon (today) Drawn placeholder
Icon (proposed) Avatar / Icon slot
Default — Colors

Tappable 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
Skeleton — loading state
DES DEV

The loading pattern for the card. Every content slot becomes a rounded rectangle placeholder in neutral gray. Use while awaiting data.

Properties
iconSize
state
Slots
hasSubtitle
hasBadge
hasChevron
Properties
iconSize 64
state Skeleton
Colors
Skeleton bg #EEF2F9
Surface bg #FFFFFF
Layout
Min height 88px
Padding 16px
Corner radius 12px
Icon placeholder 64 × 64
Bar 1 size 120 × 14
Bar 2 size 180 × 10
Typography
N/A No text in skeleton state
Skeleton — Colors

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
Property Mapping
Figma PropertySwiftUICompose
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)?
Accessibility
RequirementiOSAndroid
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 ✓
Criteria Scorecard
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.
Variants Inventory (12 total)

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.

iconSizeDefault nodeSkeleton nodeDimensions
6418482:3580718482:35832360 × 146
5218482:3584318482:35868360 × 146
4618482:3587918482:35904360 × 146
4018482:3591518482:35940360 × 146
3218482:3595118482:35976360 × 146
2418482:3598718482:36012360 × 146
1.0.0 — April 2026Major
Initial Assessment · node 18482:35806
Verdict: Fix — Collapse iconSize to semantic scale, swap icon placeholder for a slot, vectorize the chevron, add pressed state. Open
Schema
Skeleton pattern acknowledged — First-class loading variant is rare and valuable. Adopt this pattern across the card/row family. Noted
Praise
C2 — iconSize collapse — 6 numeric values → 4 semantic sizes (xl/l/m/s). Open
C2
C6 — Icon slot + vector chevron — Adopt Figma Slot for leading media; vectorize chevron. Open
C6
C5 — Pressed / disabled — Tappable row needs both. Open
C5
C7 — Code Connect — Blocked on above. Open
C7