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.
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.Action-list rows stack inside Settings / Profile / Help menus. A typical screen mixes variants with/without description and with/without trailing counter.
Label
description
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.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.| 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. |
- Three Action List components merged into Action Row. v2.0: Rebuilt on node
4628:19843in 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 aTrailing=Countervalue, 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.Densityis 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:
Statenow covers Default, Pressed, Disabled and Loading, where the original components had no state coverage at all. Pressed carries its own#F6F9FDsurface. (C5) C5 · Interaction State Coverage - Leading asset and counter are real Figma Slots. v2.0:
Asset SlotandCounter SlotareSLOTnodes, 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
Containerare nowRowandTrailingGroup, 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 -
Trailingrenamed toTrailingContent. 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→Labeland#blurb→Description, mapping onto §3 — the content is supporting text beneath a label rather than the promotional summaryBlurbdenotes.leading icon→Leading-IconandAction Button→Action-Buttoncomplete the hyphenated convention. (C1) C1 · Layer Structure & Naming -
hasDescriptionboolean added. v2.3: Confirmed by the component owner — ahasDescriptionboolean 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
Wrappercollision resolved. v2.3: TheWrapperframe nested inside anotherWrapperin the Loading variants is nowSkeleton-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 iconandlinerectangle 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
- Record
State=Loadingunder the existing State/Status exception.Loadingis a process status rather than an interaction state, the same shape asErroron the form fields. It falls under the exception already documented for that family rather than needing its own justification. Docs
Label
description
| 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 |
Label
description
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.*
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 Property | SwiftUI | Compose |
|---|---|---|
| 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 = "…" |
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
) 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
) | Requirement | iOS | Android |
|---|---|---|
| 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. |
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.
| 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. |
2 TrailingContent × 4 State × 2 Density = 16 variants; hasDescription is a boolean and does not multiply the count
| TrailingContent | State × Density | Count |
|---|---|---|
| CTA | Default, Pressed, Disabled, Loading × Compact, Expanded | 8 |
| Counter | Default, Pressed, Disabled, Loading × Compact, Expanded | 8 |
View full TrailingContent × State × Density breakdown (16 rows)
| TrailingContent | State | Density | Node | Dimensions |
|---|---|---|---|---|
| CTA | Default | Compact | 4628:19844 | 360 × 56 |
| CTA | Default | Expanded | 4628:19857 | 360 × 64 |
| CTA | Pressed | Compact | 4628:20022 | 360 × 56 |
| CTA | Pressed | Expanded | 4628:19870 | 360 × 64 |
| CTA | Disabled | Compact | 4628:19939 | 360 × 56 |
| CTA | Disabled | Expanded | 4628:19952 | 360 × 64 |
| CTA | Loading | Compact | 4649:16649 | 360 × 56 |
| CTA | Loading | Expanded | 4649:16639 | 360 × 56 |
| Counter | Default | Compact | 4628:19883 | 360 × 56 |
| Counter | Default | Expanded | 4628:19911 | 360 × 64 |
| Counter | Pressed | Compact | 4628:19897 | 360 × 56 |
| Counter | Pressed | Expanded | 4628:19925 | 360 × 64 |
| Counter | Disabled | Compact | 4628:19965 | 360 × 56 |
| Counter | Disabled | Expanded | 4628:19979 | 360 × 64 |
| Counter | Loading | Compact | 4628:20010 | 360 × 56 |
| Counter | Loading | Expanded | 4628:20016 | 360 × 64 |
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.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.#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.4649:16639 (CTA · Loading · Expanded) is 360 × 56; every other Expanded variant is 64. Filed from the scorecard for the Component Review.Trailing renamed to TrailingContent; Text and action layer naming completed; hasDescription boolean added; Nested Wrapper collision resolved; Skeleton loader retained as authored.List row. Reconcile label typography. Add Pressed state. Open_space_2 / _space_16 are authoring artifacts exported as opacity-0 layers. Opentrailing enum. Open#C2C6CF circle. Adopt a Figma Slot. Openmain/action-list/*. Noted