A transaction-summary card with merchant info, amount, date, and tappable detail surface.
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).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).
Juan Dela Cruz
type enum. Heading uses Semibold 600 while Generic Card uses Bold 700 — inconsistent across the card family.type and live with its fixed slot composition. A slot-based API would let them mix freely (e.g. avatar + reference).| 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. |
-
typeenum hides 5 structurally different layouts. Same anti-pattern as Alert'sFull Widthboolean.default/more information/with avatar/no amountare 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 amountandmore informationdescribe absence, not role. Value names should describe what the variant IS, not what it lacks.no amountbecomes "swap amount for a trailing badge";more informationbecomes "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
- Replace
typewith 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 (
#E0E6F2fill, 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
EBRowprimitive with variants for "with subtitle" (Generic Card) and "with metadata + amount" (Generic Transaction Card). Family
The baseline transaction row. Leading label, mid-row badge + date metadata, trailing amount. 78 px tall.
Label
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 |
Adds a 32 × 32 Avatar at the leading edge (instance-swapped from the Avatar component). Used for person-to-person transactions.
Label
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 |
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
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 |
| Figma Property | SwiftUI | Compose |
|---|---|---|
| (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)? |
| Requirement | iOS | Android |
|---|---|---|
| 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. |
| 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. |
type is a single enum with 5 values, each a structurally different layout.
| # | Node | type | Layout | Dimensions |
|---|---|---|---|---|
| 1 | 18482:35754 | default | label · badge · date · amount | 360 × 78 |
| 2 | 18482:35765 | more information | label · date · amount · menu (⋯) | 360 × 76 |
| 3 | 18482:35776 | with avatar | avatar · label · badge · date · amount | 360 × 84 |
| 4 | 18482:35789 | no amount | label · reference · trailing badge | 360 × 76 |
| 5 | 18482:35797 | skeleton loader | loading placeholders | 360 × 81 |
type enum (5 layouts) with slot-based composition. Align heading weight with Generic Card. Add pressed state. OpenFull Width. Split into leadingMedia, badge, trailing, loading. Openno amount / more information describe what's missing. Semantic slot names replace them. Open