East Blue
KeepNeeds Refinement
Generic Transaction Card Component link

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

Keep — all findings resolved
Rebuilt on node 5488:32955 in the 2026 Working File. The type enum that packed five layouts into one axis is replaced by real Leading-Slot and Trailing-Slot nodes; the single state axis is split into State = Default | Pressed | Disabled beside Status = Default | Read | Skeleton per §6, so read-and-pressed is expressible; the heading weight matches Generic Card at Proxima Soft Bold 18/23; and pressed and disabled both ship. Naming is complete across every variant including the skeleton — no offset frames, no # sigil, no spaces, no duplicate names, and slots kebab-cased per §4. The label overflow is resolved, with the 270px LabelAmountRow budget honoured as 172 + 98. All four DS Health traits pass; the only item still open is Code Connect, blocked until the native library exists.
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
G

Label

XXX.XX
LabelDate XX, XXXX, Time (AM,PM)
Properties
Status
State
Content
Label
Badge
Date
Amount
Avatar initials
DS Health
Reusable
Pass
A generic transaction row — the leading and trailing slots let it carry an avatar, an icon or nothing, so one component covers the layouts the old type enum needed five variants for.
Self-contained
Pass
Owns its surface, border and typography across all five states, and composes shared Avatar and Badge instances rather than redrawing them.
Consistent
Pass
State and Status are separate PascalCase properties with Title Case values per §1 and §5, following the §6 split. Layer naming is clean across all five variants including the skeleton: slots kebab-cased per §4, text layers on the §3 vocabulary, every frame named for what it holds, and no duplicates, sigils, spaces or offset frames left anywhere.
Composable
Pass
leadingElement and trailingElement are both real Figma Slots, and the avatar, badge and trailing icon are all shared instances — the composition problem the previous assessment raised is solved.
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.
Issues
  • type enum replaced by slot-based composition. v2.0: Rebuilt on node 5488:32955 in the 2026 Working File. The axis that packed five structurally different layouts into one enum is gone — the leading and trailing positions are now real SLOT nodes, so an avatar, an icon or nothing at all is the consumer’s choice rather than a variant. The set drops from a layout enum to five states. This is the headline recommendation applied. (C2 · Property) C2 · Variant & Property Naming
  • no amount and more information values retired. v2.0: Both described what was absent rather than what the card was for, and both are gone with the enum that carried them. (C2 · Rename) C2 · Variant & Property Naming
  • Heading weight aligned with Generic Card. v2.0: The label is now Proxima Soft Bold 700 at 18/23, matching Generic Card’s Title exactly. The two cards sit next to each other in lists, so a Semibold/Bold split between them read as an error rather than a distinction. (C3) C3 · Token Coverage
  • Pressed and disabled states added. v2.0: state=pressed fills the surface #F6F9FD and state=disabled ships alongside it, closing the missing-states finding. The card is a primary tap target in transaction lists, so touch-down feedback was the most-felt gap. (C5) C5 · Interaction State Coverage
  • Axis split into State and Status. v2.1: Verified on the live node. State = Default | Pressed | Disabled now sits beside Status = Default | Read | Skeleton, so interaction, content status and loading are three separate concerns rather than five values competing for one axis. Read-and-pressed is expressible, which in a transaction list is the common case. Both properties are PascalCase per §1 with Title Case values per §5, matching the split Generic Card made and the rule in §6. (C2 · Property) C2 · Variant & Property Naming
  • Slots brought onto the family convention. v2.1: ⤷ leadingElement and ⤷ trailingElement are now Leading-Slot and Trailing-Slot — the literal arrow character is gone and both follow §4 kebab-case with the -Slot suffix used across Bottom Sheet, Alert and Generic Card. (C1 · Rename) C1 · Layer Structure & Naming
  • The three offset frames named, and the typo fixed. v2.1: offset → BadgeContainer, offset → AmountContainer, and the misspelled amout-offset → Amount. A new LabelAmountRow now holds the label and amount columns as an explicit 270px row — 172 + 98 — so the horizontal structure is declared rather than implied by position. (C1 · Rename) C1 · Layer Structure & Naming
  • Legacy sigil dropped and frames moved to PascalCase. v2.1: #label → Label, #date → Date, #amount → Amount, on the §3 vocabulary. The frames follow — container → CardContainer, content-container → ContentContainer, transaction-detail → TransactionDetail — and the space in leading element is closed as LeadingElement. (C1 · Rename) C1 · Layer Structure & Naming
  • Label overflow resolved. v2.2: Re-measured on the live node — Label (5488:32986) is now 172px, matching TransactionDetail exactly rather than running 33px past it. The LabelAmountRow budget of 270px is now honoured on both sides: 172 for the label column, 98 for the amount. Nothing overlaps, and a native implementation reading these bounds gets one consistent answer instead of two. (C4) C4 · Native Mappability
  • Skeleton brought onto the shared vocabulary. v2.2: The inner layers are renamed to match the default variant — transaction-detail → TransactionDetail, the last offset frame → BadgeContainer, and tag / header / badge → Tag / Header / Badge. No frame in the component is named offset any more, and the skeleton no longer needs a second vocabulary to read. (C1 · Rename) C1 · Layer Structure & Naming
  • Amount duplication resolved. v2.2: The trailing column now reads AmountRow → AmountContainer → Amount — three distinct names across three levels, with the text layer keeping the §3 vocabulary name and the wrappers describing what they hold. (C1 · Rename) C1 · Layer Structure & Naming
Styles
Default
G

Label

XXX.XX
LabelDate XX, XXXX, Time (AM,PM)
Properties
State
Properties
Status Default
State Default
Colors
Background #FFFFFF
Border #E5EBF4
Label #0A2757
Amount #0A2757
Date #6780A9
Badge background #E5F1FF
Badge label #005CE5
Avatar background #005CE5
Avatar initials #FFFFFF
Avatar border #E5EBF4
Trailing icon #005CE5
Typography
Label Primary/Headlines/Block
Amount Primary/Headlines/Block
Date Secondary/Bold/Caption
Layout
Height 82
Width 360
Radius 0
Padding H —
Padding V —
Gap —
Border 1 · bottom
Alignment —
Colors by Status
Role Element Token Value
Default Background — #FFFFFF
Default Border — #E5EBF4
Default Label — #0A2757
Default Amount — #0A2757
Default Date — #6780A9
Default Badge background — #E5F1FF
Default Badge label — #005CE5
Default Avatar background — #005CE5
Default Avatar initials — #FFFFFF
Default Avatar border — #E5EBF4
Default Trailing icon — #005CE5
Default · Pressed Background — #F6F9FD
Default · Disabled Label — #C2CFE5
Default · Disabled Amount — #C2CFE5
Default · Disabled Date — #C2CFE5
Default · Disabled Badge background — #D7E0EF
Default · Disabled Badge label — #FFFFFF
Default · Disabled Avatar background — #9BC5FD
Default · Disabled Avatar initials — #F6F9FD @ 72%
Default · Disabled Avatar border — #F6F9FD @ 72%
Default · Disabled Trailing icon — #9BC5FD
Read Amount — #90A8D0
Skeleton Background — #FFFFFF
Skeleton Border — #E5EBF4
Skeleton Placeholder bars — #EEF2F9
Skeleton Leading placeholder — #EEF2F9
Read
G

Label

XXX.XX
LabelDate XX, XXXX, Time (AM,PM)
Properties
Status Read
State Default
Colors
Background #FFFFFF
Border #E5EBF4
Label #0A2757
Amount #90A8D0
Date #6780A9
Badge background #E5F1FF
Badge label #005CE5
Avatar background #005CE5
Avatar initials #FFFFFF
Avatar border #E5EBF4
Trailing icon #005CE5
Typography
Label Primary/Headlines/Block
Amount Primary/Headlines/Block
Date Secondary/Bold/Caption
Layout
Height 82
Width 360
Radius 0
Padding H —
Padding V —
Gap —
Border 1 · bottom
Alignment —
Skeleton
Properties
Status Skeleton
State Default
Colors
Background #FFFFFF
Border #E5EBF4
Placeholder bars #EEF2F9
Leading placeholder #EEF2F9
Typography
Layout
Height 79
Width 360
Radius 0
Padding H —
Padding V —
Gap —
Border 1 · bottom
Alignment —
Installation Planned API

iOS — Swift Package Manager

.package(url: "https://github.com/AY-Org/eb-ds-ios", from: "1.0.0")

Android — Gradle (Kotlin DSL)

implementation("com.eastblue.ds:card:1.0.0")

Import

import EastBlueDS
import com.eastblue.ds.card.*
Property Mapping

State and Status are the set’s two variant properties. Leading-Slot and Trailing-Slot are Figma Slots. Label, Amount, Date and the Badge are read from the layer tree of 5488:32979; whether they are exposed on the property panel is not readable with the plugin.

Figma PropertySwiftUICompose
State — Default, Pressed, Disabled .disabled(true) for Disabled · Pressed is the platform touch-down enabled = false for Disabled · Pressed from interactionSource
Status — Default, Read, Skeleton .ebStatus(.read) · loading: true status = EBTransactionStatus.Read · isLoading = true
Leading-Slot (slot) leading: EBTransactionLeading — .avatar("G") leading: @Composable (() -> Unit)?
Trailing-Slot (slot) trailing: EBTransactionTrailing — .menu trailing = EBTransactionTrailing.Menu
Label (text) title: String title = "…"
Amount (text) amount: String amount = "…"
Date (text) date: String date = "…"
Badge (nested Badge instance) badge: EBBadge badge = EBBadge("Label", EBBadgeIntent.Information)
Usage Snippets Planned API
Default
EBTransactionCard(
    title: "Label",
    amount: "XXX.XX",
    date: "Date XX, XXXX, Time (AM,PM)",
    badge: EBBadge("Label", intent: .information),
    leading: .avatar("G"),
    trailing: .menu
)
EBTransactionCard(
    title = "Label",
    amount = "XXX.XX",
    date = "Date XX, XXXX, Time (AM,PM)",
    badge = EBBadge("Label", EBBadgeIntent.Information),
    leading = { EBAvatar(initials = "G") },
    trailing = EBTransactionTrailing.Menu
)
Read
EBTransactionCard(
    title: "Label",
    amount: "XXX.XX",
    date: "Date XX, XXXX, Time (AM,PM)",
    badge: EBBadge("Label", intent: .information),
    leading: .avatar("G"),
    trailing: .menu
)
.ebStatus(.read)
EBTransactionCard(
    title = "Label",
    amount = "XXX.XX",
    date = "Date XX, XXXX, Time (AM,PM)",
    badge = EBBadge("Label", EBBadgeIntent.Information),
    leading = { EBAvatar(initials = "G") },
    trailing = EBTransactionTrailing.Menu,
    status = EBTransactionStatus.Read
)
Skeleton
EBTransactionCard(loading: true)
EBTransactionCard(isLoading = true)
Accessibility
RequirementiOSAndroid
Row as a button Whole row in Button; one accessibilityLabel combining label, badge, amount and date. Modifier.clickable { onTap() }.semantics(mergeDescendants = true) on the row.
Amount announcement Pass the amount through the localized currency formatter, not the raw string. contentDescription carries the formatted amount.
Read status .accessibilityValue("Read") when Status is Read — the grey amount alone is not announced. stateDescription = "Read" in the row semantics.
Disabled .disabled(true) adds the .notEnabled trait. enabled = false sets the disabled semantics.
Loading Announce "Loading" once; .accessibilityHidden(true) on the placeholder bars. contentDescription = "Loading" on the skeleton container; placeholders cleared with clearAndSetSemantics.
Minimum target 82 pt row ≥ 44 pt. 82 dp row ≥ 48 dp.
Usage Guidelines

Do

Use Status Read once the user has opened the transaction.

Don't

Don’t use Read as a disabled look — Disabled is a State value.

Do

Keep the label to one line inside its 172 px column.

Don't

Don’t let a long counterparty name push the amount out of its 98 px column.

Do

Fill Leading-Slot with an Avatar or a merchant icon that identifies the counterparty.

Don't

Don’t put a second text layer or a badge in the slot.

Do

Show one Skeleton row per expected transaction while the list loads.

Don't

Don’t use Skeleton for a refresh of a single amount.

Criteria Scorecard
ID Criterion Status Notes
C1 Layer Structure & Naming Ready PascalCase frames, Leading-Slot / Trailing-Slot named slots, no offset frames — read on 5488:32979.
C2 Variant & Property Naming Ready State and Status split, Title Case values, no absence-based names.
C3 Token Coverage Ready Label and Amount resolve to Primary/Headlines/Block, Date to Secondary/Bold/Caption. Colour variable bindings are not readable with the plugin — confirm in Dev Mode.
C4 Native Mappability Ready Two enums, two slots, four text values — maps 1:1 onto EBTransactionCard.
C5 Interaction State Coverage Ready Default, Pressed and Disabled built; Read and Skeleton exist at State Default only.
C6 Asset & Icon Quality Needs Refinement Avatar and Badge are instances. The Trailing-Slot icon (Others) carries a shape_full BOOLEAN_OPERATION — flatten it in the icon library.
Variants Inventory (5 total)

3 State × 3 Status, with Read and Skeleton built at State Default only = 5 variants

StateStatusNodeDimensions
DefaultDefault5488:32979360 × 82
PressedDefault5492:33839360 × 82
DisabledDefault5492:33889360 × 82
DefaultRead5501:38441360 × 82
DefaultSkeleton5488:33001360 × 79
1.0.2 — September 2026Patch
Style and Code tabs re-read · node 5488:32955
Style tab rebuilt from the five live variants. Cards follow Status — Default, Read, Skeleton — with State as a panel control; colours, text styles and the 82 / 79 heights read off 5488:32979, 5501:38441 and 5488:33001. Padding, gap, alignment and colour tokens are not readable with the plugin and stay —.
Docs
Code tab regrouped on the State × Status schema. Property Mapping is one row per property, Usage Snippets and Guidelines added, Scorecard regraded, Variants Inventory moved from the five type nodes to the five live nodes.
Docs
Trailing-Slot icon carries a BOOLEAN_OPERATION. The Others icon on 5488:32979 contains shape_full; flatten it in the icon library. Filed from the scorecard for the Component Review.
C6
1.0.1 — September 2026Patch
Documentation backfill · node 5488:32955
Resolved issues recorded. 11 resolved issues on the Overview tab had no changelog row: type enum replaced by slot-based composition; no amount and more information values retired; Heading weight aligned with Generic Card; Pressed and disabled states added; Axis split into State and Status; Slots brought onto the family convention; The three offset frames named, and the typo fixed; Legacy sigil dropped and frames moved to PascalCase; Label overflow resolved; Skeleton brought onto the shared vocabulary; Amount duplication resolved.
Docs
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 names — no 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