East Blue
KeepNeeds Refinement
Action Row Component link

A tappable list row with a leading asset slot, label and description, and a trailing chevron with optional counter. Merges the former Action List, Action List with Counter and Action List with Description.

Keep — all findings resolved
Rebuilt on node 4628:19843 in the 2026 Working File and renamed Action Row, merging the three former Action List siblings into TrailingContent (2) × State (4) × Density (2) = 16 variants, plus a hasDescription boolean. Interaction states now exist where there were none, the leading asset and counter are real Figma Slots, and layer and property naming matches the conventions the rest of the family settled on. All four DS Health traits pass; the only item still open is Code Connect, blocked until the native library exists.
In Context

Action-list rows stack inside Settings / Profile / Help menus. A typical screen mixes variants with/without description and with/without trailing counter.

Settings View 3
Live Preview

Label

description

CTA
Properties
TrailingContent
State
Density
hasDescription
Content
Label
Description
CTA label
Count
DS Health
Reusable
Pass
Used across Settings, Help Center, Profile, Wallet sub-screens. Covers the main action-list row patterns.
Self-contained
Pass
Carries its own surface, dividers and state colors, and composes a chevron and counter from library instances. Nothing external required to render a complete row.
Consistent
Pass
TrailingContent, State and Density are orthogonal, Density is used exactly as §1 defines it, hasDescription carries the correct verb prefix, and TrailingContent matches View Only Field for the same concept. Every addressable layer is semantically named; the skeleton loader keeps working names by design.
Composable
Pass
Asset Slot and Counter Slot are real Figma Slots, and the chevron and counter come from library instances — teams drop in content without detaching. Stacks cleanly into lists.
Behavior
State iOS Android Figma Property Notes
Default Yes Yes State=Default Baseline row. Label in Neutral Dark (or Brand Blue on the Counter variant).
Disabled Yes Yes State=Disabled Label → #C2CFE5, chevron → #9BC5FD, CTA → #9BC5FD, counter bg stays #EEF2F9 but label → #C2CFE5.
Loading Yes Yes State=Loading Icon becomes a neutral ring; label + trailing become 16 px pill placeholders filled with #EEF2F9.
Pressed N/A N/A Not built Action rows are tap targets — a pressed state (row tint + possibly label darken) is a baseline expectation for native.
Focused N/A N/A Not built TV / keyboard focus ring not defined. Android a11y also relies on it.
Issues
  • Three Action List components merged into Action Row. v2.0: Rebuilt on node 4628:19843 in the 2026 Working File and renamed Action Row. Action List, Action List with Counter and Action List with Description are now one set: the counter is a Trailing=Counter value, and the description is part of the row rather than a separate component. Confirmed as a permanent merge by the component owner. (C4 · Family) C4 · Native Mappability
  • Variant matrix is orthogonal and complete. v2.0: Trailing (CTA · Counter) × State (Default · Pressed · Disabled · Loading) × Density (Compact · Expanded) = 16 variants, all authored. Density is used exactly as §1 defines it — adjusting row height and padding, 56px against 64px — rather than gating content. (C2 · Property) C2 · Variant & Property Naming
  • Interaction states added. v2.0: State now covers Default, Pressed, Disabled and Loading, where the original components had no state coverage at all. Pressed carries its own #F6F9FD surface. (C5) C5 · Interaction State Coverage
  • Leading asset and counter are real Figma Slots. v2.0: Asset Slot and Counter Slot are SLOT nodes, and the chevron and counter are library instances. Teams can drop in real content without detaching — the composition pattern the rest of the family has converged on. (C6 · Slot) C6 · Asset & Icon Quality
  • Frame naming aligned to the family. v2.1: The two frames both called Container are now Row and TrailingGroup, and the spaced names are hyphenated to match the convention Toast, Upload File and Section Header settled on — Asset-Slot, Counter-Slot, Text-Container, Icon-Container, Bottom-Stroke. (C1) C1 · Layer Structure & Naming
  • Trailing renamed to TrailingContent. v2.1: The axis now carries the same name View Only Field uses for the same concept, satisfying §6 on consistent terminology. Any future component with a trailing area has one name to adopt rather than a choice between two. (C2 · Family) C2 · Variant & Property Naming
  • Text and action layer naming completed. v2.2: #label → Label and #blurb → Description, mapping onto §3 — the content is supporting text beneath a label rather than the promotional summary Blurb denotes. leading icon → Leading-Icon and Action Button → Action-Button complete the hyphenated convention. (C1) C1 · Layer Structure & Naming
  • hasDescription boolean added. v2.3: Confirmed by the component owner — a hasDescription boolean now toggles the description line, restoring the label-only row the original Action List provided. Implemented as a boolean component property rather than a fourth variant axis, so the matrix stays at 16 rather than doubling. Not independently verifiable from the assessment tooling, which cannot read component property definitions. (C2 · Property) C2 · Variant & Property Naming
  • Nested Wrapper collision resolved. v2.3: The Wrapper frame nested inside another Wrapper in the Loading variants is now Skeleton-Trailing, naming what it actually holds. (C1) C1 · Layer Structure & Naming
  • Skeleton loader retained as authored. v2.3: Closed by owner decision — the Loading variants keep their skeleton geometry as built, including the repeated trailing icon and line rectangle names. These are internal placeholder shapes with no property surface and no override target, so their names never reach a consumer or a Code Connect mapping — the same reasoning applied to View Only Field's wrapper frames. (C1) C1 · Layer Structure & Naming
Recommendations
  • Record State=Loading under the existing State/Status exception. Loading is a process status rather than an interaction state, the same shape as Error on the form fields. It falls under the exception already documented for that family rather than needing its own justification. Docs
Variants
CTA

Label

description

CTA
Properties
State
Density
hasDescription
Properties
TrailingContent CTA
State Default
Density Compact
hasDescription True
Colors
Background #FFFFFF
Bottom stroke #D7E0EF
Asset placeholder #D7E0EF
Label #0A2757
Description #6780A9
CTA label #005CE5
Chevron #005CE5
Loading placeholders #EEF2F9
Typography
Label Primary/Label/Base
Description Primary/Multi-line Label/Light/Fine
Layout
Height 56
Width 360
Radius 0
Padding H —
Padding V —
Gap —
Border 1 · bottom
Alignment —
Colors by TrailingContent and State
Role Element Token Value
CTA · Default Background — #FFFFFF
CTA · Default Bottom stroke — #D7E0EF
CTA · Default Asset placeholder — #D7E0EF
CTA · Default Label — #0A2757
CTA · Default Description — #6780A9
CTA · Default CTA label — #005CE5
CTA · Default Chevron — #005CE5
CTA · Pressed Background — #F6F9FD
CTA · Disabled Asset placeholder — #EEF2F9
CTA · Disabled Label — #C2CFE5
CTA · Disabled Description — #C2CFE5
CTA · Disabled CTA label — #9BC5FD
CTA · Disabled Chevron — #9BC5FD
Counter · Default Background — #FFFFFF
Counter · Default Bottom stroke — #D7E0EF
Counter · Default Asset placeholder — #D7E0EF
Counter · Default Label — #0A2757
Counter · Default Description — #90A8D0
Counter · Default Chevron — #005CE5
Counter · Default Counter background — #EEF2F9
Counter · Default Counter value — #072592
Counter · Pressed Background — #F6F9FD
Counter · Disabled Asset placeholder — #EEF2F9
Counter · Disabled Label — #C2CFE5
Counter · Disabled Description — #C2CFE5
Counter · Disabled Chevron — #9BC5FD
Counter · Disabled Counter value — #C2CFE5
Loading Asset placeholder — #EEF2F9
Loading Placeholder bars — #EEF2F9
Counter

Label

description

0
Properties
State
Density
hasDescription
Properties
TrailingContent Counter
State Default
Density Compact
hasDescription True
Colors
Background #FFFFFF
Bottom stroke #D7E0EF
Asset placeholder #D7E0EF
Label #0A2757
Description #90A8D0
Chevron #005CE5
Counter background #EEF2F9
Counter value #072592
Loading placeholders #EEF2F9
Typography
Label Primary/Label/Base
Description Primary/Multi-line Label/Light/Fine
Layout
Height 56
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:action-list:1.0.0")

Import

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

TrailingContent, State and Density are the set’s three variant properties; hasDescription is the boolean the rebuild added. Asset-Slot, Leading-Slot (the CTA) and Counter-Slot are Figma Slots. Label and Description are text layers read from 4628:19844; whether they are exposed on the property panel, and the boolean’s default, are not readable with the plugin.

Figma PropertySwiftUICompose
TrailingContent — CTA, Counter .ebTrailing(.cta("…") / .counter(0)) trailing = EBActionRowTrailing.Cta("…") / Counter(0)
State — Default, Pressed, Disabled, Loading .disabled(true) · .ebLoading(true) · Pressed is the platform touch-down enabled = false · isLoading = true · Pressed from interactionSource
Density — Compact, Expanded .ebDensity(.compact / .expanded) density = EBActionRowDensity.Compact / Expanded
hasDescription — True, False description: present or nil description = "…" or null
Asset-Slot (slot) .ebLeadingAsset(Image) leadingAsset = { Icon(…) }
Leading-Slot (slot) .ebTrailing(.cta("CTA")) — the CTA text button EBActionRowTrailing.Cta("CTA")
Counter-Slot (slot) .ebTrailing(.counter(0)) EBActionRowTrailing.Counter(0)
Label (text) EBActionRow("Label", …) label = "…"
Description (text) description: String? description = "…"
Usage Snippets Planned API
CTA
EBActionRow("Label", description: "description")
    .ebLeadingAsset(Image("placeholder"))
    .ebTrailing(.cta("CTA"))
    .ebDensity(.compact)
EBActionRow(
    label = "Label",
    description = "description",
    leadingAsset = { Icon(…) },
    trailing = EBActionRowTrailing.Cta("CTA"),
    density = EBActionRowDensity.Compact
)
Counter
EBActionRow("Label", description: "description")
    .ebLeadingAsset(Image("placeholder"))
    .ebTrailing(.counter(0))
    .ebDensity(.compact)
EBActionRow(
    label = "Label",
    description = "description",
    leadingAsset = { Icon(…) },
    trailing = EBActionRowTrailing.Counter(0),
    density = EBActionRowDensity.Compact
)
Accessibility
RequirementiOSAndroid
Row as a button Whole row in Button; accessibilityLabel combines label and description. Modifier.clickable { onTap() }.semantics(mergeDescendants = true) on the row.
CTA as a second action The CTA is its own Button inside the row — two accessibility elements, not one. Separate TextButton with its own onClick; do not merge it into the row.
Counter value .accessibilityValue("3 items") on the row — a bare number is ambiguous. stateDescription = "3 items" on the row.
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 56 pt row ≥ 44 pt; 64 pt when Expanded. 56 dp row ≥ 48 dp; 64 dp when Expanded.
Usage Guidelines

Do

Use CTA when the row carries a second action beside the tap, and keep it to one word.

Don't

Don’t use CTA to repeat what tapping the row already does.

Do

Use Counter for unread or pending counts; the pill is 24 px and takes up to two digits.

Don't

Don’t put text or a status word in the Counter.

Do

Use Expanded in Settings and Profile menus, Compact inside dense lists.

Don't

Don’t mix Compact and Expanded rows in one list.

Do

Turn hasDescription off when the label says everything.

Don't

Don’t leave the Description as filler under a self-explanatory label.

Criteria Scorecard
ID Criterion Status Notes
C1 Layer Structure & Naming Needs Refinement Wrapper › Row › Asset-Slot, Text-Container, TrailingGroup on 4628:19844. Loading variants are a separate Wrapper + Action-Button structure, and 4649:16639 (CTA · Loading · Expanded) is 56 tall where every other Expanded variant is 64.
C2 Variant & Property Naming Ready TrailingContent, State, Density with Title Case values; hasDescription is a real boolean.
C3 Token Coverage Needs Refinement Label resolves to Primary/Label/Base, Description to Primary/Multi-line Label/Light/Fine. Description is #6780A9 on the CTA variants and #90A8D0 on the Counter variants — one binding is wrong. Colour variable bindings are not readable with the plugin.
C4 Native Mappability Ready Three enums, one boolean, three slots and two text values — maps 1:1 onto EBActionRow.
C5 Interaction State Coverage Ready Default, Pressed, Disabled and Loading built for both TrailingContent values and both densities.
C6 Asset & Icon Quality Ready Chevron Right is a vector instance; the CTA is a Leading instance and the counter a Counter instance, each inside a Slot.
Variants Inventory (16 total)

2 TrailingContent × 4 State × 2 Density = 16 variants; hasDescription is a boolean and does not multiply the count

TrailingContentState × DensityCount
CTADefault, Pressed, Disabled, Loading × Compact, Expanded8
CounterDefault, Pressed, Disabled, Loading × Compact, Expanded8
View full TrailingContent × State × Density breakdown (16 rows)
TrailingContentStateDensityNodeDimensions
CTADefaultCompact4628:19844360 × 56
CTADefaultExpanded4628:19857360 × 64
CTAPressedCompact4628:20022360 × 56
CTAPressedExpanded4628:19870360 × 64
CTADisabledCompact4628:19939360 × 56
CTADisabledExpanded4628:19952360 × 64
CTALoadingCompact4649:16649360 × 56
CTALoadingExpanded4649:16639360 × 56
CounterDefaultCompact4628:19883360 × 56
CounterDefaultExpanded4628:19911360 × 64
CounterPressedCompact4628:19897360 × 56
CounterPressedExpanded4628:19925360 × 64
CounterDisabledCompact4628:19965360 × 56
CounterDisabledExpanded4628:19979360 × 64
CounterLoadingCompact4628:20010360 × 56
CounterLoadingExpanded4628:20016360 × 64
1.0.2 — September 2026Patch
Style and Code tabs re-read · node 4628:19843
Style tab rebuilt from the 16 live variants. Cards follow TrailingContent — CTA, Counter — with State, Density and hasDescription as panel controls; colours, text styles and the 56 / 64 heights read off 4628:19844, 4628:19883 and the state variants. Padding, gap, alignment and colour tokens are not readable with the plugin and stay —; the row height with hasDescription off could not be read either.
Docs
Code tab regrouped on the TrailingContent × State × Density schema. Installation on the Action List family coordinates, Property Mapping one row per property with the three slots, Usage Snippets and Guidelines added, Scorecard regraded, Variants Inventory moved from the three sibling nodes to the 16 live nodes.
Docs
Description colour differs by TrailingContent. #6780A9 on the CTA variants, #90A8D0 on the Counter variants (4628:19844 vs 4628:19883). One binding is off. Filed from the scorecard for the Component Review.
C3
One Expanded variant is Compact-height. 4649:16639 (CTA · Loading · Expanded) is 360 × 56; every other Expanded variant is 64. Filed from the scorecard for the Component Review.
C1
1.0.1 — September 2026Patch
Documentation backfill · node 4628:19843
Resolved issues recorded. 10 resolved issues on the Overview tab had no changelog row: Three Action List components merged into Action Row; Variant matrix is orthogonal and complete; Interaction states added; Leading asset and counter are real Figma Slots; Frame naming aligned to the family; Trailing renamed to TrailingContent; Text and action layer naming completed; hasDescription boolean added; Nested Wrapper collision resolved; Skeleton loader retained as authored.
Docs
1.0.0 — April 2026Major
Initial Assessment · nodes 18577:14545, 18577:14637, 18577:14604
Verdict: Restructure — Collapse 3 sibling components into one slot-driven List row. Reconcile label typography. Add Pressed state. Open
Architecture
C1 — 3 siblings for 1 pattern — Description and Counter are additive features, not different components. Open
C1
C1 — Spacer annotations leak — _space_2 / _space_16 are authoring artifacts exported as opacity-0 layers. Open
C1
C2 — Divergent label typography — Semibold 16 Neutral vs. Bold 18 Brand across siblings. Same family must read as one. Open
C2
C4 — Trailing baked per sibling — Replace CTA / Counter / Chevron booleans with a single trailing enum. Open
C4
C5 — Missing Pressed state — Action rows are the primary nav tap target. Open
C5
C6 — Placeholder icon — Leading is a gray #C2C6CF circle. Adopt a Figma Slot. Open
C6
C7 — Code Connect — Blocked on consolidation. Open
C7
Tokens ✓ — Colors / paddings / radii all bound to main/action-list/*. Noted
Praise