RestructureNeeds Refinement
Generic Transaction Card Component link

A transaction-summary card with merchant info, amount, date, and tappable detail surface.

Restructure — type enum hides 5 different layouts
The five type values are visually distinct layouts, not variants of the same pattern. Replace the enum with slot-based composition (leadingMedia?, badge?, trailing = amount | menu | reference, loading). Same fix pattern as Alert's Full Width. Also align heading weight with Generic Card (both should use Bold, not Semibold).
In Context

Transaction-history rows stack vertically in the Activity / Transactions screen. Different rows use different variants depending on the context (recipient avatar, reference number, action menu).

Live Preview

Juan Dela Cruz

SentApr 14, 2026, 10:24 AM
PHP 1,500.00
Content
label
badge
date / meta
amount
reference
avatar initials
Properties
type
DS Health
Reusable
Pass
Solid transaction-row primitive — covers the main patterns seen in Activity screens.
Self-contained
Pass
Owns tokens, composes Avatar + Badge correctly. Good structure internally.
Consistent
Warn
5 structurally different layouts hidden behind one type enum. Heading uses Semibold 600 while Generic Card uses Bold 700 — inconsistent across the card family.
Composable
Partial
Today consumers must pick a type and live with its fixed slot composition. A slot-based API would let them mix freely (e.g. avatar + reference).
Behavior
State iOS Android Figma Property Notes
Default Yes Yes type=default Label + badge + date + amount. The baseline transaction row.
With avatar Yes Yes type=with avatar Adds a 32 × 32 Avatar at the leading edge. Used for person-to-person transactions.
More information Yes Yes type=more information Replaces the badge with an overflow menu button (⋯). Used when a row has context-menu actions.
No amount Yes Yes type=no amount Swaps the amount for a trailing badge; swaps date for a reference number. Used for confirmations without monetary value.
Skeleton loader Yes Yes type=skeleton loader Loading placeholder pattern. Worth documenting alongside Generic Card's skeleton as a DS-wide convention.
Pressed N/A N/A Not built Rows typically drill into transaction detail — need pressed tint for tap feedback.
Open Issues
  • type enum hides 5 structurally different layouts. Same anti-pattern as Alert's Full Width boolean. default / more information / with avatar / no amount are not variants of one pattern — they're four different slot compositions. Replace with a slot-based API (leadingMedia, badge, trailing, loading). C1 · Layer Structure & Naming
  • no amount and more information describe absence, not role. Value names should describe what the variant IS, not what it lacks. no amount becomes "swap amount for a trailing badge"; more information becomes "show action menu." Once slot-based, the enum disappears entirely. C2 · Variant & Property Naming
  • Heading uses Semibold (600) while Generic Card uses Bold (700). Inconsistent title weight across the card family. Standardize — either both Bold or both Semibold. C2 · Variant & Property Naming
  • No pressed / disabled states. Transaction rows drill into a detail screen on tap — need pressed tint. Also disabled state for pending/failed transactions that can't be reopened. C5 · Interaction State Coverage
  • Code Connect mappings not registered. Blocked on the slot restructure. C7 · Code Connect Linkability
Design Recommendations
  • Replace type with slot-based props. leadingMedia?: Avatar | Icon | none, badge?: Badge, metadata: String, trailing: amount | menu | badge | reference, loading: Bool. Eliminates the 5-type union and lets consumers compose any valid row without editing the master. Property
  • Align heading weight with Generic Card. Pick one (Bold 700 is more common across the DS) and apply it to both components. Card family should read as one system, not two dialects. Family
  • Promote skeleton to a cross-family convention. Generic Card + Generic Transaction Card both ship skeletons — document the pattern (#E0E6F2 fill, rounded rect placeholders, no spinner) as the DS loading standard so future card/row primitives follow the same treatment. Docs
  • Add pressed + disabled states. Pressed: subtle bg tint across the whole row. Disabled: muted label + amount opacity. State
  • Reconcile with Generic Card. The two share ~80 % of the "row with leading / trailing / meta" shape. Consider a shared EBRow primitive with variants for "with subtitle" (Generic Card) and "with metadata + amount" (Generic Transaction Card). Family
Styles
Default — label + badge + date + amount
DES DEV

The baseline transaction row. Leading label, mid-row badge + date metadata, trailing amount. 78 px tall.

Label

LabelDate XX, XXXX, Time (AM,PM)
PHP XX.XX
Properties
Type
Properties
Type default
Variant Label + badge + date + amount
Layout avatar-leading + meta-right
Colors
Surface #FFFFFF
Border #E5EBF4
Title #0A2757
Amount #0A2757
Metadata #6780A9
Icon #005CE5
Badge bg #E5F1FF
Badge label #005CE5
Layout
Width 360
Padding 16 24 18 22
Content gap 6
Meta-row gap 8
Bottom border 1 px
Typography
Label (title) Proxima Soft Semibold · 18 / 18 · +0.25
Amount Proxima Soft Semibold · 18 / 18 · +0.25
Metadata (date) BarkAda Semibold · 12 / 18 · +0
Badge label Proxima Soft Bold · 12 / 12 · +0.5
Composed sub-components
Badge Badge · Information · Light
Avatar (in "with avatar") Avatar · dark-initials · 32 px
Heading weight Uses Semibold 600 — inconsistent with Generic Card's Bold 700 (flagged)
Default — Colors

List-style transaction row with leading icon, title, amount, and a metadata strip.

Role Token Default
Surface card-list/color/bg #FFFFFF
Border card-list/color/border #E5EBF4
Title card-list/color/label-header #0A2757
Amount card-list/color/label-amount #0A2757
Metadata card-list/color/label-metadata #6780A9
Icon card-list/color/icon #005CE5
Badge bg badge/information/light/background #E5F1FF
Badge label badge/information/light/label #005CE5
With avatar
DES DEV

Adds a 32 × 32 Avatar at the leading edge (instance-swapped from the Avatar component). Used for person-to-person transactions.

G

Label

LabelDate XX, XXXX, Time (AM,PM)
XXX.XX
Properties
Type
Properties
Type with-avatar
Leading slot Avatar
Has badge Yes
Has amount Yes
Colors
Surface bg #FFFFFF
Title color #0A2757
Date color #3C4A5C
Amount color #0A2757
Layout
Min height 72
Padding 16
Corner radius 12
Avatar size 40 × 40
Gap 12
Typography
Title style Body/Medium · Bold
Date style Caption/Regular
Amount style Body/Medium · Bold
With Avatar — Colors

Same transaction palette as Default; Avatar component replaces the leading icon.

Role Token Default
Surface main/transaction-card/bg #FFFFFF
Title main/transaction-card/title #0A2757
Date main/transaction-card/date #3C4A5C
Amount main/transaction-card/amount #0A2757
No amount
DES DEV

Used for non-monetary confirmations (KYC acknowledgments, voucher redemptions). Swaps amount for a trailing badge and the date row for a reference number.

Label

Reference No: GC123456789876543

Label
Properties
Type
Properties
Type no-amount
Leading slot Icon
Has badge No
Has amount No
Colors
Surface bg #FFFFFF
Title color #0A2757
Date color #3C4A5C
Layout
Min height 72
Padding 16
Corner radius 12
Icon size 24 × 24
Gap 12
Typography
Title style Body/Medium · Bold
Date style Caption/Regular
Skeleton — Colors

Loading state — every content slot is a rounded grey rectangle on the card surface.

Role Token Default
Skeleton bg main/skeleton/bg #EEF2F9
Surface bg main/card/bg #FFFFFF
Property Mapping
Figma PropertySwiftUICompose
(hardcoded) label: String label: String
(hardcoded) metadata?: String metadata: String?
type=with avatar leadingMedia?: Avatar (slot) leadingMedia: EBAvatar?
(drawn) badge?: Badge (slot) badge: EBBadge?
type=default/with avatar trailing = .amount(String) trailing: EBRowTrailing
type=more information trailing = .menu(() -> Void) 同上
type=no amount trailing = .badge(Badge) + metadata = reference 同上
type=skeleton loader loading: Bool loading: Bool
(not modeled) onTap?: () -> Void onTap: (() -> Void)?
Accessibility
RequirementiOSAndroid
Row as button Whole row in Button with combined label (person + amount + date). Modifier.clickable { onTap() }.semantics(mergeDescendants = true).
Currency announcement "Juan Dela Cruz, Sent, 1,500 pesos, April 14 10:24 AM" — use localized currency formatter, not raw "PHP 1,500.00". Same — announce via contentDescription with currency formatter applied.
Reference number Spell out long reference numbers for clarity: "GC 1 2 3 4..." — avoid run-together digits. Same.
Loading Announce "Loading transactions" once on mount. contentDescription = "Loading" on skeleton container.
Criteria Scorecard
ID Criterion Status Notes
C1 Layer Structure & Naming Requires Rework type enum hides 5 layouts — restructure to slot-based.
C2 Variant & Property Naming Requires Rework Absence-based value names; heading weight inconsistent with Generic Card.
C3 Token Coverage Ready Colors bound to main/card-list/color/*.
C4 Native Mappability Needs Refinement Maps cleanly once slots replace the type enum.
C5 Interaction State Coverage Needs Refinement No pressed / disabled. Skeleton ✓.
C6 Asset & Icon Quality Ready Avatar + Badge composed correctly as instances.
C7 Code Connect Linkability Not Mapped Blocked on restructure.
Variants Inventory (5 total)

type is a single enum with 5 values, each a structurally different layout.

#NodetypeLayoutDimensions
118482:35754defaultlabel · badge · date · amount360 × 78
218482:35765more informationlabel · date · amount · menu (⋯)360 × 76
318482:35776with avataravatar · label · badge · date · amount360 × 84
418482:35789no amountlabel · reference · trailing badge360 × 76
518482:35797skeleton loaderloading placeholders360 × 81
1.0.0 — April 2026Major
Initial Assessment · node 18482:35753
Verdict: Restructure — Replace type enum (5 layouts) with slot-based composition. Align heading weight with Generic Card. Add pressed state. Open
Architecture
C1 — Type enum hides layouts — Same anti-pattern as Alert's Full Width. Split into leadingMedia, badge, trailing, loading. Open
C1
C2 — Absence-based namesno amount / more information describe what's missing. Semantic slot names replace them. Open
C2
C2 — Heading weight inconsistency — Semibold 600 vs Generic Card's Bold 700. Standardize across card family. Open
C2
C5 — Pressed state — Transaction rows drill into detail on tap; needs tap feedback. Open
C5
Skeleton pattern ✓ — First-class loading variant, matches Generic Card. Adopt as DS-wide convention. Noted
Praise
C7 — Code Connect — Blocked on restructure. Open
C7