Action-list row with a 32px leading icon, label, trailing chevron, and a trailing Counter pill.
4628:19843), where the trailing counter is now a Trailing=Counter value. Assessment for this pattern lives on the Action Row page.Used where a row needs to surface a pending count alongside the action — inbox folders, notification categories, or settings entries with outstanding items.
| State | iOS | Android | Figma Property | Notes |
|---|---|---|---|---|
| Default | Yes | Yes | State=Default | Brand-blue label, brand-blue chevron, filled Counter pill (#072592 on #EEF2F9). |
| Disabled | Yes | Yes | State=Disabled | Muted label (#C2CFE5), muted chevron (#9BC5FD), empty Counter pill. |
| Loading | Yes | Yes | State=Loading | Avatar circle, long label skeleton, trailing 46 × 16 strip. The strip doesn't actually match the Counter pill shape — see open issue. |
| Pressed / Focused | N/A | N/A | Not modeled | No pressed / focused variants on the row. Inherited gap — same issue as base Transaction row. |
- Merged into Action Row. v2.0: Confirmed by the component owner — this no longer exists as a standalone component. It is merged into Action Row (node
4628:19843), where the trailing counter is now aTrailing=Countervalue. This page is kept as a pointer; all assessment for this pattern lives on Action Row. (Family) C4 · Native Mappability
360 × 56. 32 px icon, brand-blue label, chevron, trailing 24 × 24 filled Counter pill.
| Role | Token | Default | Disabled | Loading |
|---|---|---|---|---|
| Row bg | main/action-list/color/default/bg | #FFFFFF | #FFFFFF | #FFFFFF |
| Label | main/action-list/color/default/label-brand | #005CE5 | – | – |
| Label (disabled) | main/action-list/color/disabled/label | – | #C2CFE5 | – |
| Chevron | main/action-list/color/default/chevron | #005CE5 | #9BC5FD | – |
| Counter bg | main/counter/color/filled/bg | #EEF2F9 | #EEF2F9 | – |
| Counter label (filled) | main/counter/color/filled/label | #072592 | – | – |
| Counter label (empty) | main/counter/color/empty/label | – | #C2CFE5 | – |
| Skeleton bar | bg/color-bg-strong | – | – | #EEF2F9 |
| Row shadow | Depth/D0 | drop-shadow(0 1 3 0 #E8EEF2C9) |
360 × 64. Same composition; 15 px vertical padding vs 11 px on Compact.
| Role | Token | Value |
|---|---|---|
| Row width | — | 360px |
| Row height (Compact) | — | 56px |
| Row height (Expanded) | — | 64px |
| Row padding H | space/space-12 | 12px |
| Row padding V (Compact) | — | 11px |
| Row padding V (Expanded) | — | 15px |
| Icon → label gap | space/space-12 | 12px |
| Label → trailing gap | space/space-16 | 16px |
| Icon size | — | 32 × 32 |
| Chevron size | — | 32 × 32 |
| Counter size | — | 24 × 24 (min) · hugs digits |
| Counter pad H | space/space-8 | 8px |
| Counter radius | radius/radius-round | pill (99999) |
| Row radius | radius/radius-2 | 6px |
Muted label, muted chevron, empty Counter pill.
| Role | Token | Spec |
|---|---|---|
| Label | Primary/Label/Large | Proxima Soft Bold · 18 / 18 · +0.25 |
| Counter | Primary/Label/Small | Proxima Soft Bold · 14 / 14 · +0.25 |
Expanded height + Disabled tokens.
Avatar circle + label line + 46 × 16 trailing strip. Strip shape doesn't match the Counter pill.
Same skeleton with 16 px padding.
iOS — Swift Package Manager
// In Xcode: File → Add Package Dependencies "https://github.com/AY-Org/eb-ds-ios" import EBDesignSystem
Android — Gradle (Kotlin DSL)
dependencies { implementation("com.eastblue.ds:list:1.0.0") } import com.eastblue.ds.components.EBListItemTransaction
| Figma Property | SwiftUI | Compose |
|---|---|---|
| (separate component) | trailing Slot on base row | @ViewBuilder trailing |
| Density | density (renamed) | density: .compact | .expanded |
| State | state (renamed) | state: .default | .disabled | .loading |
| icon (bool) | leading Slot | @ViewBuilder leading |
| label | label | label: String |
| chevron (bool) | chevron | chevron: Bool = true |
| counter (bool) | derived from trailing slot | — |
// Default — Compact density, trailing Counter EBListItemTransaction(label: "Notifications") { EBAvatar(initials: "N") } trailing: { EBCounter(count: unreadCount) } // Expanded density EBListItemTransaction(label: "Promos") { EBAvatar(initials: "P") } trailing: { EBCounter(count: 2) } .density(.expanded) // Disabled row — counter stays in empty state EBListItemTransaction(label: "Archive") { EBAvatar(initials: "A") } trailing: { EBCounter(count: 0) } .disabled(true) // Loading — trailing slot omitted; skeleton fills EBListItemTransaction.loading()
// Default — Compact density, trailing Counter EBListItemTransaction( label = "Notifications", leading = { EBAvatar(initials = "N") }, trailing = { EBCounter(count = unreadCount) } ) // Expanded density EBListItemTransaction( label = "Promos", density = EBListDensity.Expanded, leading = { EBAvatar(initials = "P") }, trailing = { EBCounter(count = 2) } ) // Disabled row EBListItemTransaction( label = "Archive", enabled = false, leading = { EBAvatar(initials = "A") }, trailing = { EBCounter(count = 0) } ) // Loading — trailing slot omitted; skeleton fills EBListItemTransaction(state = EBListState.Loading)
| Requirement | iOS | Android |
|---|---|---|
| Row role | Wrap in Button / NavigationLink for tappable semantics | Apply Modifier.clickable(...) + Role.Button |
| Counter label | Compose accessibility label: "Notifications, 5 unread" — don't let VoiceOver read the digit alone | Merge into row: contentDescription = "Notifications, 5 unread" |
| Disabled | .disabled(true) — drops from hit-testing + dims label/chevron/counter | enabled = false on clickable modifier |
| Loading | Announce "Loading"; hide skeleton children from a11y tree | Modifier.semantics { liveRegion = Polite } + hide skeletons |
| Chevron | Decorative — .accessibilityHidden(true) | contentDescription = null |
| ID | Criterion | Status | Notes |
|---|---|---|---|
| C1 | Layer Structure & Naming | Requires Rework | Sibling duplicates the base Transaction row matrix. Consolidate via trailing slot. |
| C2 | Variant & Property Naming | Needs Refinement | Density/State PascalCase mismatches lowercase Counter and most of DS. |
| C3 | Token Coverage | Ready | All colors + spacing bound. Uses main/action-list/* + main/counter/*. |
| C4 | Native Mappability | Needs Refinement | HStack/Row maps cleanly. Loading skeleton's 46 × 16 trailing strip doesn't match a Counter pill. |
| C5 | Interaction State Coverage | Needs Refinement | No pressed / focused variants — inherited from base row. |
| C6 | Asset & Icon Quality | Ready | Chevron is a vector instance; icon is a swap placeholder — same pattern as other List Items. |
| C7 | Code Connect Linkability | Not Mapped | Do not wire this sibling — map the base row with trailing slot after consolidation. |
Density (2) × State (3) = 6 variants. Identical matrix to the base Transaction row.
| # | Density | State | Node ID | Dimensions |
|---|---|---|---|---|
| 1 | Compact | Default | 18577:14638 | 360 × 56 |
| 2 | Expanded | Default | 18577:14647 | 360 × 64 |
| 3 | Compact | Disabled | 18577:14656 | 360 × 56 |
| 4 | Expanded | Disabled | 18577:14665 | 360 × 64 |
| 5 | Compact | Loading | 18577:14674 | 360 × 56 |
| 6 | Expanded | Loading | 18577:14679 | 360 × 64 |
Density/State mismatch lowercase state on composed Counter. Open