KeepNeeds Refinement
Alert Component link

A persistent status surface with intent, title, description, and an optional action — in Card or Banner style. 30 variants across Type (Neutral / Information / Warning / Error / Success) × Style (Card / Banner) × Content (Default / Header Only / Description Only), with a Leading Container icon slot and a Dismiss Container slot.

Rebuilt — explicit Style, slots, and intent enum
The rebuild resolved every structural issue: Style=Card / Banner is now an explicit axis (was hidden behind a Full Width boolean), the yes/no booleans collapsed into a clean Type × Style × Content matrix, Type=Default became Neutral, the left icon is a swappable Leading Container slot, and a dismiss slot plus a real action-button instance shipped. v2.1 finished the naming — #text#description across all 20 description nodes, and Trailing ElementDismiss Container across all 30 variants. Only the A11y live-region docs and Code Connect remain.
In Context

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.

Live Preview

This is for the title.

This is the description. Put the description here.

Content
title
description
Properties
Type
Full Width
Left Icon
Right Icon
Description
DS Health
Reusable
Pass
Generic notification primitive — drops into forms, detail screens, and flows across the app.
Self-contained
Pass
Owns its colors, spacing, and typography tokens across all five intents and both styles. The action is now a real button instance (with its own states) rather than drawn in-place.
Consistent
Pass
Three Title Case enums — Type × Style × Content — a complete 30-variant matrix, and Type=Default renamed Neutral. Internal naming now matches: the description node is #description, and the paired slots read Leading Container / Dismiss Container.
Composable
Pass
A swappable Leading Container icon slot in both styles, a Dismiss Container holding a Content slot, and an action-button instance — consumers compose an icon, an action, and a dismiss without editing the master.
Behavior
State iOS Android Figma Property Notes
Intent Yes Yes Type=Neutral / Information / Warning / Error / Success Five intents drive background, border/accent, and icon color. Neutral is the no-charge appearance (renamed from the old Default).
Card style Yes Yes Style=Card Bordered rounded card (radius 4) with a leading icon slot, action button, and trailing dismiss slot.
Banner style Yes Yes Style=Banner Flat inline surface with a 6px Left Border Accent instead of a full border.
Content composition Yes Yes Content=Default / Header Only / Description Only Default shows title + description; the other two drop one. Composes with every Type and Style.
Action tap Yes Yes Button instance The "Learn more" action is a real button instance with its own states, plus a chevron slot — no longer drawn in-place.
Dismiss Yes Yes Dismiss Container (Content slot) The trailing slot carries the dismiss / close affordance.
A11y announcement N/A N/A Not annotated Error alerts should announce as role="alert" / LiveRegion.Assertive, informational as role="status" / LiveRegion.Polite. Still to document.
Issues
  • A11y live-region mapping not documented. Error alerts should announce assertively, informational alerts politely. Not yet annotated on the component, so engineers have no spec for the correct roles. C7 · Code Connect Linkability
  • Code Connect mappings not registered. Structure and naming are settled enough to register. Blocked only on the SwiftUI / Compose mappings being wired and the native component existing — snippets remain a Planned API. C7 · Code Connect Linkability
  • v2.0: Boolean properties eliminated — the old yes/no Full Width / Left Icon / Right Icon / Description booleans (with the No/no casing bug) collapsed into a clean Type × Style × Content enum matrix. (C2)
  • v2.0: The Card-vs-Banner distinction is now an explicit Style axis rather than being hidden behind a Full Width boolean — Card is the bordered accent surface, Banner the flat inline strip with a left accent. (C1)
  • v2.0: Type=Default renamed Neutral — no longer conflated with "the default/unset value", and consistent with the semantic siblings. (C2)
  • v2.0: Left-icon placeholder replaced with a real Leading Container SLOT (32 × 32) in both Card and Banner, so consumers swap in any DS icon. (C6)
  • v2.0: Dismiss contract added — a Trailing Element wrapping a Content slot carries the close affordance, covering the previously-missing dismissable pattern. (C5)
  • v2.0: The "Learn more" action is now a real button instance (with a chevron slot) rather than drawn text + chevron, so it carries its own states and its copy is swappable. (C5)
  • v2.1: Description text node renamed #text#description across all 20 variants that carry one — Card and Banner, Default and Description Only. Verified by a full text-node rescan with zero #text remaining. (C2)
  • v2.1: Trailing dismiss wrapper renamed Trailing ElementDismiss Container across all 30 variants, pairing cleanly with Leading Container. Dismiss was chosen over Trailing Container deliberately: the nested Button_New already exposes its own Trailing Container slot, so reusing that name would have put two identically-named layers in one variant. (C2)
  • v2.1: Component moved into the Sticker Sheets v2 library; the assessment now points at the canonical node rather than the 2026 Working File. (C1)
  • v2.1: The Button_New action instance is intentional — reviewed and confirmed. It is a real Button component slotted into the Alert, not a placeholder or copy-paste artifact, so its name belongs to that component rather than to Alert. Not an Alert defect. (C1)
Recommendations
  • Document the A11y live-region mapping. Spell out assertive for error, polite for informational, so engineers wire role="alert" / role="status" correctly. A11y
  • Register Code Connect mapping to EBAlert. Wire Type, Style, and Content to the SwiftUI / Compose API, and map the Leading Container and trailing dismiss slots to native content slots. Docs
  • Normalize boolean values and casing. v2.0: Applied — the yes/no booleans are gone entirely, replaced by three Title Case enums. The No/no casing bug no longer exists. Rename
  • Expose style = banner | card. v2.0: Applied — Style=Card / Banner is a real axis; the layout difference is no longer hidden behind width. Property
  • Rename Type=Default to Neutral. v2.0: Applied. Rename
  • Replace the left-icon placeholder with a swappable Icon slot. v2.0: Applied — Leading Container SLOT in both styles. Slot
  • Add a dismissable variant. v2.0: Applied — the Trailing Element / Content slot carries the dismiss affordance. State
  • Promote the Learn More action to a button instance. v2.0: Applied — it is now a real button instance with its own states, rather than drawn in-place. (Naming cleanup pending — see the Button_New open issue.) Composition
  • Rename #text#description. v2.1: Applied — all 20 description nodes, verified by rescan. Rename
  • Align the paired slot names. v2.1: Applied as Leading Container / Dismiss Container — avoiding a collision with the Button's own nested Trailing Container slot. Rename
  • Give the action button a semantic name. v2.1: Reviewed and closed as not needed — Button_New is a real Button component slotted into the Alert, so the name is owned by that component. Rename
Styles
Banner
DES DEV

Flat inline banner. 360 wide, 12 × 16 padding, 4px radius, soft shadow. Optional left icon, right icon, and description.

This is for the title.
This is the description.
Properties
Type
Properties
Style Banner
Type Information
Colors
Background #E5F1FF
Title #072592
Description #072592
Icon / accent #2340A9
Layout
Width 360px
Padding 12 × 16
Corner radius 4px (radius-1)
Gap (icon ↔ content) 8px
Right icon 24 × 24
Typography
Title style Primary/Multi-line Label/Base
Title font Proxima Soft Bold
Title size 16 / 20
Description font BarkAda Semibold
Description size 12 / 18
Colors by Type

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 TokenValue
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
Accent Card
DES DEV

Card with a 6px left-border accent. Always ships a right icon + Learn More action + description. Title is larger (18 / 23) than the banner.

This is for the title.
This is the description. Put the description here.
Learn More
Properties
Type
Properties
Style Accent Card
Type Information
Colors
Surface #FFFFFF
Border accent #2340A9
Title #072592
Description #072592
Action link #005CE5
Layout
Width 328px
Padding 16 × 16
Corner radius 6px (radius-2)
Left accent 6px solid
Gap (title ↔ desc) 4px
Typography
Title style Primary/Headlines/Block
Title font Proxima Soft Bold
Title size 18 / 23
Description BarkAda Semibold · 12 / 18
Action label Proxima Soft Bold · 14 / 20
Property Mapping
Figma PropertySwiftUICompose
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)?
Accessibility
RequirementiOSAndroid
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.
Criteria Scorecard
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.
Variants Inventory (20 total)

Type (5) × layout combos = 20 built variants out of 24 × 5 = 80 theoretical combinations.

GroupCountAxes
Accent card4fullWidth=No, L=no, R=yes, desc=yes · Information / Warning / Error / Success
Banner — right icon, desc5fullWidth=yes, L=no, R=yes, desc=yes · all 5 types
Banner — left icon, desc5fullWidth=yes, L=yes, R=no, desc=yes · all 5 types
Banner — left icon, no desc5fullWidth=yes, L=yes, R=no, desc=no · all 5 types
Default — full width, no icons, with desc1fullWidth=yes, L=no, R=no, desc=yes · Default only
1.0.0 — April 2026Major
Initial Assessment · node 18444:2012
Verdict: Fix — Normalize booleans, replace placeholder left-icon with a real Slot, split the two layouts explicitly, and add a dismiss contract. Open
Schema
C2 — Property naming — Four booleans on yes/no with inconsistent casing; Type=Default mixes with semantic types. Open
C2
C1 — Two layouts, one component — Banner + accent card hidden behind fullWidth. Rename to style or split. Open
C1
C6 — Left-icon placeholder — 24 × 24 icon-placeholder circle; adopt Figma Slots. Open
C6
C5 — State coverage — No dismiss; Learn More isn't a real button. Open
C5
C7 — Code Connect — Blocked on schema cleanup. Open
C7