East Blue
KeepNeeds Refinement
Alert Component link

A persistent status surface with intent, title, description, and an optional action — in Card or Banner style. 90 variants across Type (Neutral / Information / Warning / Error / Success) × Style (Card / Banner) × Content (Default / Header Only / Description Only) × Size (3 steps, Large down to Small), with a Leading-Slot icon slot and a Trailing-Slot.

Keep — all findings resolved
Rebuilt on node 6663:104524 in the 2026 Working File as Type × Style × Content × Size over a complete 90-variant matrix, with all four axes PascalCase per §1 and Title Case values per §5. The naming pass is done: the three nested container frames became AlertContainer and ContentRow with the redundant middle wrapper deleted rather than renamed, the two offset frames are now LeadingSlotContainer and TrailingSlotContainer, the text layers dropped the # sigil onto the §3 vocabulary, and the slots are kebab-cased as Leading-Slot and Trailing-Slot. No layer contains a space. Size was verified to do real work, running the title 18/23 at Large down to 14/16 at Small. The action instance’s name belongs to the shared Button component rather than to Alert, dismissal is expressed through the trailing slot rather than a boolean, and the accessibility live-region contract is documented — Error and Warning announce assertively, the rest politely. All four DS Health traits pass; the only item still open is Code Connect, blocked until the native library exists.
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 description here.
Properties
Type
Style
Content
Size
Content
Title
Description
DS Health
Reusable
Pass
Five intents across two visual treatments and three content shapes cover every alert case in the product, and the 90-variant matrix is complete with no gaps.
Self-contained
Pass
Owns its surface, accent bar and typography, and composes a real button instance for the action rather than drawing one.
Consistent
Pass
Four PascalCase axes with Title Case values, Size genuinely changing the type scale, and a clean layer tree on both styles — AlertContainer → ContentRow → TitleContainer / DescriptionContainer, slots kebab-cased per §4, text layers on the §3 vocabulary, and no spaces anywhere. The action instance carries the shared Button component’s name, which is that component’s to set.
Composable
Pass
Leading Slot and Trailing Slot are both real Figma Slots holding swap targets, and the action is a shared button instance — icon, trailing control and action are all consumer-supplied.
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
  • Style = Card | Banner exposed. v2.0: Rebuilt on node 6663:104524 in the 2026 Working File. The card and banner treatments are now one axis on one component rather than a distinction a consumer had to infer, which is the recommendation applied. (C2 · Property) C2 · Variant & Property Naming
  • Type=Default renamed Neutral. v2.0: The intent enum reads Neutral | Information | Warning | Error | Success. Default described a position in a list; Neutral describes what the alert is saying, which is what the axis is for. (C2 · Rename) C2 · Variant & Property Naming
  • Property casing normalised. v2.0: All four axes are PascalCase per §1 — Type, Style, Content, Size — with Title Case values per §5. (C2 · Rename) C2 · Variant & Property Naming
  • Leading icon placeholder replaced by a real Slot. v2.0: Leading Slot is a genuine SLOT node holding a Slot Block swap target, so a consumer supplies their own icon without detaching. Trailing Slot is paired with it, closing the alignment recommendation — both positions now behave the same way. (C1 · Slot) C1 · Layer Structure & Naming
  • Action promoted to a button instance. v2.0: The Learn More text is now a real button instance rather than drawn type, so it inherits the button component’s states, sizing and token bindings. Its layer name is still not semantic and is tracked below. (C4 · Composition) C4 · Native Mappability
  • #text renamed #description. v2.0: The body copy layer now says what it holds. The legacy # sigil is still on it and on #title, tracked below. (C1 · Rename) C1 · Layer Structure & Naming
  • Variant matrix complete at 90, and Size is meaningful. v2.0: Type (5) × Style (2) × Content (3) × Size (3) ships all 90 combinations with no gaps. Verified that Size does real work rather than only changing the frame: the title runs 18/23 at Large and 14/16 at Small. The 56px floor on the single-line Content values is a minimum height, not evidence of duplicate variants. (C2) C2 · Variant & Property Naming
  • Structural frames named — and one redundant wrapper removed. v2.1: Verified on both the Card and Banner styles. The three nested frames all called container are gone: the outer is AlertContainer, the inner is ContentRow, and the middle one was deleted rather than renamed, so the tree is a level shallower than before. The two offset frames are now LeadingSlotContainer and TrailingSlotContainer. Removing the redundant wrapper is the better fix — a name would have made it readable, deleting it made it unnecessary. (C1 · Rename) C1 · Layer Structure & Naming
  • Text layers and their frames renamed. v2.1: #title → Title and #description → Description, dropping the legacy sigil, with their wrappers moving from heading and line-paragraph to TitleContainer and DescriptionContainer. The text layers now sit on the §3 vocabulary and the §7 hierarchy. Left Border Accent also lost its spaces, as LeftBorderAccent. (C1 · Rename) C1 · Layer Structure & Naming
  • Slots brought onto the family convention. v2.1: Leading Slot and Trailing Slot are now Leading-Slot and Trailing-Slot — kebab-case per §4 with the -Slot suffix used across Bottom Sheet, Generic Card and Service Item. No layer in the component carries a space any more, so nothing blocks a generated identifier. (C1 · Rename) C1 · Layer Structure & Naming
  • Button_New delegated to the Button component’s owner. v2.2: Closed out of Alert’s scope. The layer is an INSTANCE, and an instance carries its main component’s name unless it is locally overridden — so Button_New is the shared Button component’s own name rather than something Alert chose. Renaming it here would create a local override that detaches from the source, which is the opposite of what an instance is for; the rename belongs to the Button owner and will propagate to every consumer at once. Confirmed by the owner: Button_New is the shared Button component’s own name, and the rename is queued on that component rather than on Alert. Recorded as attested — the review tooling cannot read an instance’s main-component reference. The same delegation applies as for the shared icon glyphs. (C1) C1 · Layer Structure & Naming
  • Dismissal expressed through the trailing slot, not a property. v2.2: Confirmed — there is no hasDismiss boolean by design. Trailing-Slot is the dismissal affordance when one is wanted: a consumer places a close control there and wires it, and leaves the slot empty or fills it with something else when the alert is not dismissible. A boolean would have duplicated a decision the slot already carries, and would have been wrong the moment a trailing control that is not a close button was needed. Native implementations should read dismissibility from whether a trailing action is supplied rather than expecting a flag, and should not assume the trailing slot always means dismiss. (C5 · Property) C5 · Interaction State Coverage
  • Accessibility live-region contract documented. v2.2: Announcement urgency follows Type. Assertive — Error and Warning interrupt whatever the screen reader is currently saying, because both describe something the user must act on before continuing. Polite — Success, Information and Neutral queue behind the current utterance, because they confirm or inform rather than block. Native mapping — iOS: post AccessibilityNotification.Announcement when the alert appears, and mark the container .accessibilityElement(children: .combine) so title and description are read as one utterance rather than two; Android: Modifier.semantics { liveRegion = LiveRegionMode.Assertive } or .Polite on the alert container, with mergeDescendants = true for the same reason. Ordering — the leading icon is decorative and must be excluded from the tree; the trailing control, where present, is a separate focusable element announced after the message, not before it. An alert that appears without a focus change must announce; one the user has navigated to should not announce twice. Confirmed by the owner as the intended contract rather than an inference, so implementations can treat it as binding. This contract covers Toast and Inline Message, which share the same intent enum. (C5 · A11y) C5 · Interaction State Coverage
Styles
Card
This is for the title.This is the description. Put description here.
Properties
Type
Content
Size
Properties
Style Card
Type Neutral
Content Default
Size Large
Colors
Background #F6F9FD
Left accent #D7E0EF
Title #0A2757
Description #6780A9
Trailing slot placeholder #9F3DFB @ 9%
Typography
Title Primary/Headlines/Block
Description Secondary/Bold/Base
Layout
Height 69
Width 360
Radius 6
Padding H —
Padding V —
Gap —
Border 0
Alignment —
Colors by Type
Role Element Token Value
Neutral Background — #F6F9FD
Neutral Left accent — #D7E0EF
Neutral Title — #0A2757
Neutral Description — #6780A9
Information Background — #E5F1FF
Information Left accent — #005CE5
Information Title — #072592
Information Description — #2340A9
Warning Background — #FFF9EB
Warning Left accent — #EBB30A
Warning Title — #6C5009
Warning Description — #966F0B
Error Background — #F8E6E6
Error Left accent — #D61B2C
Error Title — #D61B2C
Error Description — #D61B2C
Success Background — #E7F8F0
Success Left accent — #27C990
Success Title — #035E50
Success Description — #048570
All Trailing slot placeholder — #9F3DFB @ 9%
Banner
This is for the title.This is the description. Put description here.
Properties
Type
Content
Size
Properties
Style Banner
Type Neutral
Content Default
Size Large
Colors
Background #F6F9FD
Left accent #D7E0EF
Title #0A2757
Description #6780A9
Trailing slot placeholder #9F3DFB @ 9%
Typography
Title Primary/Headlines/Block
Description Secondary/Bold/Base
Layout
Height 69
Width 360
Radius 0
Padding H —
Padding V —
Gap —
Border 0
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:alert:1.0.0")

Import

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

Type, Style, Content and Size are the set’s four variant properties. Leading-Slot and Trailing-Slot are Figma Slots; Title and Description are text layers read from 6663:104525 — their exposure as text properties is not readable with the plugin. Button_New sits below the frame in every variant and never renders.

Figma PropertySwiftUICompose
Type — Neutral, Information, Warning, Error, Success type: .neutral / .information / .warning / .error / .success type = EBAlertType.Neutral / Information / Warning / Error / Success
Style — Card, Banner .ebStyle(.card / .banner) style = EBAlertStyle.Card / Banner
Content — Default, Header Only, Description Only title: and description: — pass one or both title = and description = — pass one or both
Size — Large, Medium, Small .ebSize(.large / .medium / .small) size = EBAlertSize.Large / Medium / Small
Leading-Slot (slot, hidden by default) .ebLeadingIcon(Image) leadingIcon = { Icon(…) }
Trailing-Slot (slot) .ebTrailing { EBIconButton(.close) { } } trailing = { EBIconButton(EBIcons.Close) { } }
Title (text) title: String? title = "…"
Description (text) description: String? description = "…"
Usage Snippets Planned API
Card
EBAlert(
    type: .neutral,
    title: "This is for the title.",
    description: "This is the description."
)
    .ebStyle(.card)
    .ebSize(.large)
EBAlert(
    type = EBAlertType.Neutral,
    title = "This is for the title.",
    description = "This is the description.",
    style = EBAlertStyle.Card,
    size = EBAlertSize.Large
)
Banner
EBAlert(
    type: .neutral,
    title: "This is for the title.",
    description: "This is the description."
)
    .ebStyle(.banner)
    .ebSize(.large)
EBAlert(
    type = EBAlertType.Neutral,
    title = "This is for the title.",
    description = "This is the description.",
    style = EBAlertStyle.Banner,
    size = EBAlertSize.Large
)
Accessibility
RequirementiOSAndroid
Live region — Error and Warning UIAccessibility.post(notification: .layoutChanged, argument: title) on appear — assertive. LiveRegionMode.Assertive on the alert.
Live region — Neutral, Information, Success .announcement notification — polite; does not interrupt. LiveRegionMode.Polite.
Announced as one unit .accessibilityElement(children: .combine) — Type name, title, description. Modifier.semantics(mergeDescendants = true); prefix the Type name.
Trailing action The slot content is its own Button ("Dismiss" or the action label); 44 pt hit area around the 32 pt slot. Separate IconButton with contentDescription; 48 dp touch target.
Contrast Every Type pairs its title and description with its tint at 4.5:1 or better; Error text on #F8E6E6 is 5.0:1. Same values — the tints are fixed, not themed.
Usage Guidelines

Do

Use Card inside content, Banner edge-to-edge under an app bar.

Don't

Don’t nest a Banner inside a card — its square corners are meant for the screen edge.

Do

Pick Type by what the user must do: Error blocks, Warning cautions, Information tells, Success confirms, Neutral notes.

Don't

Don’t use Error for a tip.

Do

Keep the title to one line at 360 px; Description carries the detail.

Don't

Don’t put a sentence in the title.

Do

Use Size Small in dense forms, Large in page-level notices.

Don't

Don’t mix sizes on one screen.

Criteria Scorecard
ID Criterion Status Notes
C1 Layer Structure & Naming Needs Refinement AlertContainer › LeadingSlotContainer / ContentRow › TitleContainer / DescriptionContainer / TrailingSlotContainer, LeftBorderAccent — read on 6663:104525. The set is named Callout while the component is Alert; Button_New sits at y 79 inside a 69-tall frame and never renders; ContentRow is 280 wide on Neutral and 292 on every other Type.
C2 Variant & Property Naming Ready Type, Style, Content, Size — Title Case values throughout; Size does real work (18/23 → 16/20 → 14/16).
C3 Token Coverage Ready Title → Primary/Headlines/Block / Primary/Multi-line Label/Base / Primary/Multi-line Label/Small by Size; Description → Secondary/Bold/Base / Caption / Small Caption. Colour variable bindings are not readable with the plugin — confirm in Dev Mode.
C4 Native Mappability Ready Four enums, two slots, two strings — maps 1:1 onto EBAlert.
C5 Interaction State Coverage Ready Static surface; dismissal and actions live in the trailing slot and take their states from the component placed there (v2.x).
C6 Asset & Icon Quality Ready Both slots are real Slots; the trailing placeholder is the shared Slot Block instance and the accent a plain rectangle.
Variants Inventory (90 total)

5 Type × 2 Style × 3 Content × 3 Size = 90 variants, a complete matrix

StyleType × Content × SizeCount
Card5 Type × 3 Content × 3 Size45
Banner5 Type × 3 Content × 3 Size45
View full Type × Style × Content × Size breakdown (90 rows)
TypeStyleContentSizeNodeDimensions
NeutralCardDefaultLarge6663:104525360 × 69
InformationCardDefaultLarge6663:104538360 × 69
WarningCardDefaultLarge6663:104551360 × 69
ErrorCardDefaultLarge6663:104564360 × 69
SuccessCardDefaultLarge6663:104577360 × 69
NeutralCardHeader OnlyLarge6663:104590360 × 56
InformationCardHeader OnlyLarge6663:104601360 × 56
WarningCardHeader OnlyLarge6663:104612360 × 56
ErrorCardHeader OnlyLarge6663:104623360 × 56
SuccessCardHeader OnlyLarge6663:104634360 × 56
NeutralCardDescription OnlyLarge6663:104645360 × 56
InformationCardDescription OnlyLarge6663:104656360 × 56
WarningCardDescription OnlyLarge6663:104667360 × 56
ErrorCardDescription OnlyLarge6663:104678360 × 56
SuccessCardDescription OnlyLarge6663:104689360 × 56
NeutralCardDefaultMedium6679:107961360 × 64
InformationCardDefaultMedium6679:107976360 × 64
WarningCardDefaultMedium6679:107991360 × 64
ErrorCardDefaultMedium6679:108006360 × 64
SuccessCardDefaultMedium6679:108021360 × 64
NeutralCardHeader OnlyMedium6679:108036360 × 56
InformationCardHeader OnlyMedium6679:108049360 × 56
WarningCardHeader OnlyMedium6679:108062360 × 56
ErrorCardHeader OnlyMedium6679:108075360 × 56
SuccessCardHeader OnlyMedium6679:108088360 × 56
NeutralCardDescription OnlyMedium6679:108101360 × 56
InformationCardDescription OnlyMedium6679:108114360 × 56
WarningCardDescription OnlyMedium6679:108127360 × 56
ErrorCardDescription OnlyMedium6679:108140360 × 56
SuccessCardDescription OnlyMedium6679:108153360 × 56
NeutralCardDefaultSmall6682:111457360 × 57
InformationCardDefaultSmall6682:111472360 × 57
WarningCardDefaultSmall6682:111487360 × 57
ErrorCardDefaultSmall6682:111502360 × 57
SuccessCardDefaultSmall6682:111517360 × 57
NeutralCardHeader OnlySmall6682:111532360 × 56
InformationCardHeader OnlySmall6682:111545360 × 56
WarningCardHeader OnlySmall6682:111558360 × 56
ErrorCardHeader OnlySmall6682:111571360 × 56
SuccessCardHeader OnlySmall6682:111584360 × 56
NeutralCardDescription OnlySmall6682:111597360 × 56
InformationCardDescription OnlySmall6682:111610360 × 56
WarningCardDescription OnlySmall6682:111623360 × 56
ErrorCardDescription OnlySmall6682:111636360 × 56
SuccessCardDescription OnlySmall6682:111649360 × 56
NeutralBannerDefaultLarge6801:109634360 × 69
InformationBannerDefaultLarge6801:109652360 × 69
WarningBannerDefaultLarge6801:109670360 × 69
ErrorBannerDefaultLarge6801:109688360 × 69
SuccessBannerDefaultLarge6801:109706360 × 69
NeutralBannerHeader OnlyLarge6801:109724360 × 56
InformationBannerHeader OnlyLarge6801:109740360 × 56
WarningBannerHeader OnlyLarge6801:109756360 × 56
ErrorBannerHeader OnlyLarge6801:109772360 × 56
SuccessBannerHeader OnlyLarge6801:109788360 × 56
NeutralBannerDescription OnlyLarge6801:109804360 × 56
InformationBannerDescription OnlyLarge6801:109820360 × 56
WarningBannerDescription OnlyLarge6801:109836360 × 56
ErrorBannerDescription OnlyLarge6801:109852360 × 56
SuccessBannerDescription OnlyLarge6801:109868360 × 56
NeutralBannerDefaultMedium6801:109884360 × 64
InformationBannerDefaultMedium6801:109902360 × 64
WarningBannerDefaultMedium6801:109920360 × 64
ErrorBannerDefaultMedium6801:109938360 × 64
SuccessBannerDefaultMedium6801:109956360 × 64
NeutralBannerHeader OnlyMedium6801:109974360 × 56
InformationBannerHeader OnlyMedium6801:109990360 × 56
WarningBannerHeader OnlyMedium6801:110006360 × 56
ErrorBannerHeader OnlyMedium6801:110022360 × 56
SuccessBannerHeader OnlyMedium6801:110038360 × 56
NeutralBannerDescription OnlyMedium6801:110054360 × 56
InformationBannerDescription OnlyMedium6801:110070360 × 56
WarningBannerDescription OnlyMedium6801:110086360 × 56
ErrorBannerDescription OnlyMedium6801:110102360 × 56
SuccessBannerDescription OnlyMedium6801:110118360 × 56
NeutralBannerDefaultSmall6801:110134360 × 57
InformationBannerDefaultSmall6801:110152360 × 57
WarningBannerDefaultSmall6801:110170360 × 57
ErrorBannerDefaultSmall6801:110188360 × 57
SuccessBannerDefaultSmall6801:110206360 × 57
NeutralBannerHeader OnlySmall6801:110224360 × 56
InformationBannerHeader OnlySmall6801:110240360 × 56
WarningBannerHeader OnlySmall6801:110256360 × 56
ErrorBannerHeader OnlySmall6801:110272360 × 56
SuccessBannerHeader OnlySmall6801:110288360 × 56
NeutralBannerDescription OnlySmall6801:110304360 × 56
InformationBannerDescription OnlySmall6801:110320360 × 56
WarningBannerDescription OnlySmall6801:110336360 × 56
ErrorBannerDescription OnlySmall6801:110352360 × 56
SuccessBannerDescription OnlySmall6801:110368360 × 56
1.0.2 — September 2026Patch
Style and Code tabs re-read · node 6663:104524
Style tab rebuilt from the 90 live variants. Cards follow Style — Card, Banner — with Type, Content and Size as panel controls; the five Type palettes, the six text styles and the 69 / 64 / 57 / 56 heights read off 6663:104525 and its siblings against the exports; the trailing Slot Block placeholder is drawn as Figma ships it. Padding, gap, alignment and colour tokens are not readable with the plugin and stay —.
Docs
Code tab regrouped on the four-property schema. Property Mapping one row per property with the two slots, Usage Snippets per Style, Guidelines added, Scorecard regraded, Variants Inventory on the 90 live nodes with a summary and collapsed breakdown.
Docs
Three structural slips on the live set. The set is named Callout; Button_New sits at y 79 inside the 69-tall Default frames and never renders; ContentRow is 280 wide on Neutral and 292 on the other Types. Filed from the scorecard for the Component Review.
C1
1.0.1 — September 2026Patch
Documentation backfill · node 6663:104524
Resolved issues recorded. 13 resolved issues on the Overview tab had no changelog row: Style = Card | Banner exposed; Type=Default renamed Neutral; Property casing normalised; Leading icon placeholder replaced by a real Slot; Action promoted to a button instance; #text renamed #description; Variant matrix complete at 90, and Size is meaningful; Structural frames named — and one redundant wrapper removed; Text layers and their frames renamed; Slots brought onto the family convention; Button_New delegated to the Button component’s owner; Dismissal expressed through the trailing slot, not a property; Accessibility live-region contract documented.
Docs
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