A persistent in-flow status banner with intent (info, success, warning, danger), title, description, and optional CTA.
style = banner | card (or split into two components) so the two layouts aren't hidden behind a fullWidth boolean. Add a dismiss contract while you're in there.Alerts sit inline in forms, payment flows, and detail screens to communicate status, validation, or supplementary guidance. The accent-card style is often used for onboarding tips; the banner style is used for transient validation.
yes/no strings with inconsistent casing (No vs no). Type=Default mixes a neutral appearance into an otherwise-semantic set.| State | iOS | Android | Figma Property | Notes |
|---|---|---|---|---|
| Show / hide | Yes | Yes | Not modeled | Alerts fade/slide in on mount. Host-screen concern, not component state. |
| Action tap (Learn More) | N/A | N/A | No button | Learn More text + chevron is a drawn element — no pressed state. Should be a Text Button instance. |
| Dismiss (X close) | N/A | N/A | Not built | Dismissable alerts need an X button + onDismiss callback. Not modeled today. |
| A11y announcement | N/A | N/A | Not annotated | Error alerts should announce as role="alert" / LiveRegion.Assertive. Informational use role="status" / LiveRegion.Polite. |
- Boolean properties use
yes/nostrings.Full Width,Left Icon,Right Icon,Description— andFull Widthhas inconsistent casing (Noon the non-full-width Information variant,noelsewhere). Blocks direct SwiftBool/ KotlinBooleanmapping. C2 · Variant & Property Naming - Two layouts hidden behind
Full Width. Non-full-width variants are accent cards (left border + Learn More action); full-width variants are flat banners. The axis name describes the width, not the real structural difference. Either split into two components or rename tostyle = banner | card. C1 · Layer Structure & Naming -
Type=Defaultmixes with semantic types. Default is a neutral appearance; Information / Warning / Error / Success are semantic statuses. Mixing them in one enum blurs the mental model. Rename toNeutralor put it on a separate axis. C2 · Variant & Property Naming - Left-icon slot is a placeholder circle. 24 × 24 gray
icon-placeholder— not swappable via instance-swap. Consumers can't drop in a real Icon from the DS icon library. C6 · Asset & Icon Quality - No dismiss / close state. Dismissable alerts are a standard pattern (X button on the right,
onDismisscallback). Not modeled in any of the 20 variants. C5 · Interaction State Coverage - Learn More action is drawn in-place. Text + chevron aren't a real Text Button instance — no pressed or disabled state coverage, can't swap in "Try again", "View details", etc. without editing the master. C5 · Interaction State Coverage
- Code Connect mappings not registered. Blocked until schema cleanup and slot adoption land. C7 · Code Connect Linkability
- Normalize boolean values and casing.
Full Width/Left Icon/Right Icon/Description→true/false. Eliminates theNo/nocasing bug. Rename - Expose
style = banner | card. Makes the real difference explicit:cardhas the left-border accent + action link,banneris the flat inline surface. Either this, or split into two components (AlertBanner+AlertCard). Property - Rename
Type=DefaulttoNeutral. Disambiguates from "the default / unset value" and matches the semantic naming of its siblings. Rename - Replace the left-icon placeholder with a swappable Icon slot. Adopt Figma Slots so product teams can drop in any Icon from the DS library without editing the master. Slot
- Add a dismissable variant with an X icon on the right and an
onDismisscallback contract. Pairs with a default timeout for transient alerts. State - Promote the Learn More action to a Text Button slot. Gains pressed / disabled states automatically, and lets consumers swap copy ("View details", "Try again", "Undo") without editing the master. Same pattern Button will have once trailing slots ship. Composition
- Document the A11y live-region mapping. Error alerts should announce as assertive; informational alerts as polite. Spell this out in the component spec so engineers wire the right roles. A11y
Flat inline banner. 360 wide, 12 × 16 padding, 4px radius, soft shadow. Optional left icon, right icon, and description.
Each type ships its own bg, title, description, and icon tokens. Accent-card style adds a border-accent token matching the icon color.
| Role | Token | Token | Value |
|---|---|---|---|
| Information | bg | main/alert/color/information/bg | #E5F1FF |
| — | title | main/alert/color/information/label-title | #072592 |
| — | description | main/alert/color/information/description | #072592 @ 80% |
| — | icon / accent | main/alert/color/information/icon | #2340A9 |
| Warning | bg | main/alert/color/warning/bg | #FFF9EB |
| — | title | main/alert/color/warning/label-title | #6C5009 |
| — | description | main/alert/color/warning/description | #6C5009 @ 80% |
| — | icon / accent | main/alert/color/warning/icon | #966F0B |
| Error | bg | main/alert/color/error/bg | #FEECEB |
| — | title | main/alert/color/error/label-title | #5F1410 |
| — | description | main/alert/color/error/description | #5F1410 @ 80% |
| — | icon / accent | main/alert/color/error/icon | #B0231C |
| Success | bg | main/alert/color/success/bg | #E4F7ED |
| — | title | main/alert/color/success/label-title | #0B3E23 |
| — | description | main/alert/color/success/description | #0B3E23 @ 80% |
| — | icon / accent | main/alert/color/success/icon | #188A47 |
| Neutral | bg | main/alert/color/neutral/bg | #F4F6FA |
| — | title | main/alert/color/neutral/label-title | #0A2757 |
| — | description | main/alert/color/neutral/description | #0A2757 @ 80% |
| — | icon / accent | main/alert/color/neutral/icon | #6780A9 |
Card with a 6px left-border accent. Always ships a right icon + Learn More action + description. Title is larger (18 / 23) than the banner.
| Figma Property | SwiftUI | Compose |
|---|---|---|
Type: Default | Information | Warning | Error | Success | type: neutral | information | warning | error | success | type: EBAlertType |
Full Width: yes | No | style: banner | card | .ebAlertStyle(.banner) modifier |
Left Icon: yes | no | leadingIcon?: Icon (slot) | leadingIcon: Image? |
Right Icon: yes | no | trailingIcon?: Icon (slot, auto for semantic types) | trailingIcon: Image? |
Description: yes | no | description?: String | description: String? |
| (implicit) | title: String | title: String |
| (not modeled) | action?: TextButton (card only) | action: EBTextButton? |
| (not modeled) | onDismiss?: () -> Void | onDismiss: (() -> Void)? |
| Requirement | iOS | Android |
|---|---|---|
| Live region — error | Post UIAccessibility.Notification.announcement with .high priority on mount. | Modifier.semantics { liveRegion = LiveRegionMode.Assertive } on the container. |
| Live region — info / success | Post announcement with default priority. | LiveRegionMode.Polite on the container. |
| Action label | Text Button inside action slot owns its own label + hint. | Text Button inside action slot owns its own contentDescription. |
| Dismiss button | Icon Button with accessibilityLabel: "Dismiss". | Icon Button with contentDescription = "Dismiss". |
| Color contrast | All title/description colors on their type-surface tested to ≥4.5:1. Verified in variable defs. | Same ratios apply. |
| ID | Criterion | Status | Notes |
|---|---|---|---|
| C1 | Layer Structure & Naming | Needs Refinement | Two layouts (banner + card) hidden behind Full Width — rename to style or split. |
| C2 | Variant & Property Naming | Requires Rework | Booleans yes/no with inconsistent casing; Type=Default mixes with semantic types. |
| C3 | Token Coverage | Ready | All 5 types fully tokenized under main/alert/color/*. |
| C4 | Native Mappability | Needs Refinement | Maps cleanly to a custom EBAlert view / composable once schema cleans up. |
| C5 | Interaction State Coverage | Needs Refinement | No dismiss state; Learn More isn't a real button — no pressed coverage. |
| C6 | Asset & Icon Quality | Needs Refinement | Left-icon slot is a placeholder circle — adopt a Figma Slot. |
| C7 | Code Connect Linkability | Not Mapped | Blocked until schema cleanup + slot adoption land. |
Type (5) × layout combos = 20 built variants out of 24 × 5 = 80 theoretical combinations.
| Group | Count | Axes |
|---|---|---|
| Accent card | 4 | fullWidth=No, L=no, R=yes, desc=yes · Information / Warning / Error / Success |
| Banner — right icon, desc | 5 | fullWidth=yes, L=no, R=yes, desc=yes · all 5 types |
| Banner — left icon, desc | 5 | fullWidth=yes, L=yes, R=no, desc=yes · all 5 types |
| Banner — left icon, no desc | 5 | fullWidth=yes, L=yes, R=no, desc=no · all 5 types |
| Default — full width, no icons, with desc | 1 | fullWidth=yes, L=no, R=no, desc=yes · Default only |
yes/no with inconsistent casing; Type=Default mixes with semantic types. OpenfullWidth. Rename to style or split. Openicon-placeholder circle; adopt Figma Slots. Open