East Blue
KeepNeeds Refinement
Toast Component link

A transient bottom-anchored message for confirmations and inline alerts, with optional leading icon, description and trailing action. Auto-dismisses after a short delay.

Keep — documentation gaps only
Rebuilt on node 4915:25141 in the 2026 Working File as Appearance × Theme × Size × three has* booleans, authored as a sparse 22-variant set. The family restructure is complete: Toast and Toast - With Button are merged, the overloaded theme axis is split, every variant value follows §5, layer naming is clean, and the description and trailing action are real Figma Slots composing shared components. All four DS Health traits pass. What remains is documentation — the dismiss and auto-duration contract, the native primitive mapping, and the a11y live-region behaviour.
In Context

Toasts float over the app screen — not inline with content. Success toasts confirm completed actions ("Transfer sent"), pending toasts acknowledge background work ("Uploading…"), and error toasts surface failures that don't block the flow. They auto-dismiss after ~3 seconds unless swiped.

Live Preview

Add the popup message here

Properties
Appearance
Theme
Size
hasLeadingIcon
hasTrailingAction
hasDescription
Content
Title
Description
Action label
DS Health
Reusable
Pass
Drops into any transient-feedback moment — transfers, uploads, validation errors. Not tied to a specific screen.
Self-contained
Pass
Owns its colors and typography, composes a shared Subtext Message for the description and a Button - XSmall for the action, and each Appearance carries its own icon instance from the library. Nothing external required to render.
Consistent
Pass
Appearance and Theme are separate axes, Size uses the standard MD | SM scale, the three has* booleans carry correct verb prefixes and are genuine Figma booleans, and every variant value is Title Cased per §5.
Composable
Pass
The trailing action is an addon SLOT holding a Button - XSmall instance — addon being §4's canonical name for this pattern — and the description is a content SLOT carrying a shared Subtext Message. The separate Toast - With Button sibling is retired.
Behavior
State iOS Android Figma Property Notes
Show / auto-dismiss Yes Yes Not modeled Toasts appear on a host overlay and auto-dismiss after a duration (~3s short, ~5s long). Host-screen concern — no visual state variant needed.
Swipe to dismiss N/A N/A Not annotated Standard gesture on both platforms. Not called out in the component spec.
Tap to dismiss N/A N/A Not annotated Pending variants already wrap the container in a button element in the Figma code — but no interaction callback is documented.
Pending spinner animation N/A N/A Gray circle Pending icon is a static gray circle (icon-placeholder) — should be an animated spinner (ProgressView / CircularProgressIndicator).
A11y announcement N/A N/A Not annotated Error toasts should announce as assertive; default/pending as polite. Not spec'd.
Issues
  • Toast and Toast - With Button consolidated. v2.0: Rebuilt on node 4915:25141 in the 2026 Working File. The two components that modelled one primitive are now a single set — the trailing button is a hasTrailingAction boolean rather than a separate component. Confirmed as a permanent merge by the component owner. (C4 · Family) C4 · Native Mappability
  • theme axis split into Appearance and Theme. v2.0: The overloaded axis that mixed status with light/dark is now Appearance (default · destructive · pending) × Theme (dark · light), exactly as recommended. Semantic meaning and visual mode are independent. (C2 · Property) C2 · Variant & Property Naming
  • Large Label replaced by a real Size axis. v2.0: The content flag masquerading as a size is now Size = base | sm. Value naming still needs work — see open issues — but the axis itself is correct. (C2 · Rename) C2 · Variant & Property Naming
  • Boolean values normalised. v2.0: hasLeadingIcon, hasTrailingAction and hasDescription use true/false rather than yes/no strings, and all three carry the correct has verb prefix per §2. (C2 · Rename) C2 · Variant & Property Naming
  • Action slot added. v2.0: The trailing action is an addon SLOT holding a Button - XSmall instance — and addon is the canonical name §4 gives for exactly this pattern. Consumers can swap the button without detaching. (Slot) C6 · Asset & Icon Quality
  • Description composed from the shared Subtext Message. v2.0: The description is a content SLOT carrying a shared Subtext Message instance, matching Text Area, Upload File and View Only Field. Copy changes propagate from one source. (Composition) C1 · Layer Structure & Naming
  • Size and Theme values aligned to the standard sets. v2.1: Size = base | sm → MD | SM, matching §5's XS · SM · MD · LG · XL scale and the values Amount Text Field and View Only Field use. Theme is now Dark | Light in Title Case per §5. (C2 · Rename) C2 · Variant & Property Naming
  • Booleans confirmed as real Figma booleans. v2.1: hasLeadingIcon, hasTrailingAction and hasDescription now render True/False capitalised, matching every genuine Figma boolean elsewhere in the file. They map directly to Swift Bool and Kotlin Boolean. (C2) C2 · Variant & Property Naming
  • Layer naming completed. v2.2: container → ToastRow, the two sibling offset frames → LeadingIcon and TextContent, text-container → TextGroup, and #content → Title. The two anonymous slots also gained names — Text-Slot for the description and Component-Slot for the trailing action. (C1) C1 · Layer Structure & Naming
  • Pending placeholder replaced with a real icon. v2.2: The icon-placeholder rectangle is gone. LeadingIcon now holds an Information instance from the icon library — chosen by the owner over a spinner, so Pending reads as an informational notice rather than an in-flight progress state. Each Appearance carries its own icon instance, which keeps glyph and semantic meaning in step and removes the need for a leading-icon slot. (C6 · Asset) C6 · Asset & Icon Quality
  • All variant values Title Cased. v2.3: Appearance=pending → Pending, the last value the casing sweep had missed. Every one of the 22 variant names now conforms to §5 — Appearance = Default | Destructive | Pending, Theme = Dark | Light, Size = MD | SM, and three has* booleans on True | False. (C2 · Rename) C2 · Variant & Property Naming
  • Dismiss and auto-duration contract documented. v2.4: Documented. Auto-hide — 4 seconds by default; 8 seconds when hasTrailingAction=True, since the user needs time to read the message and reach the action. Appearance=Pending does not auto-hide at all: it represents an in-flight operation and is replaced by a Default or Destructive toast when that operation resolves. Dismissal — a horizontal swipe in either direction dismisses. Tapping the toast body does nothing; only the trailing action is a tap target, and triggering it dismisses the toast. Stacking — one toast at a time; a new message replaces the current one rather than queueing behind it. Durations follow Material 3 Snackbar convention (4s short, longer when an action is present) rather than a product measurement, so they are a starting contract — say the word if product has specific numbers and I will amend. (C5 · Docs) C5 · Interaction State Coverage
  • Native mapping and a11y live region documented. v2.4: Documented. iOS — there is no system toast; build a custom view presented through a ViewModifier over the root, anchored to the bottom safe area. Android — Material 3 Snackbar with SnackbarHost covers the Default and Destructive appearances and maps hasTrailingAction onto its action slot, though the Pending appearance and the Theme axis need a custom composable. Accessibility — a transient message that is never focused must be announced, not merely rendered. On iOS post an AccessibilityNotification.Announcement with the message text; on Android set Modifier.semantics { liveRegion = LiveRegionMode.Polite }, raised to Assertive for Appearance=Destructive so an error interrupts rather than queues. The trailing action carries its own label; the leading icon is decorative and should be hidden from the accessibility tree. (C4 · A11y · Docs) C4 · Native Mappability
Types
Default

Add the popup message here

Properties
Theme
Size
hasLeadingIcon
hasTrailingAction
hasDescription
Properties
Appearance Default
Theme Dark
Size MD
hasLeadingIcon True
hasTrailingAction False
hasDescription False
Colors
Background #0A2757
Border #E5EBF4
Title #FFFFFF
Leading icon #FFFFFF
Description #F6F9FD @ 72%
Action background #FFFFFF
Action label #005CE5
Typography
Title Primary/Label/Light/Small
Layout
Height 38
Width 312
Radius 8
Padding H —
Padding V —
Gap —
Border 1
Alignment —
Colors by Appearance and Theme
Role Element Token Value
Default · Dark Background — #0A2757
Default · Light Background — #FFFFFF
Default · Dark Border — #E5EBF4
Default · Dark Title — #FFFFFF
Default · Light Title — #0A2757
Default · Dark Leading icon — #FFFFFF
Default · Light Leading icon — #0A2757
Default · Dark Description — #F6F9FD @ 72%
Default · Light Description — #6780A9
Default · Dark Action background — #FFFFFF
Default · Light Action background — #005CE5
Default · Dark Action label — #005CE5
Default · Light Action label — #FFFFFF
Destructive · Dark Background — #D61B2C
Destructive · Dark Border — #F4C7C9
Destructive · Dark Title — #FFFFFF
Destructive · Dark Leading icon — #FFFFFF
Destructive · Dark Description — #F6F9FD @ 80%
Destructive · Dark Action background — None
Destructive · Dark Action label — #FFFFFF
Pending · Dark Background — #0A2757
Pending · Light Background — #FFFFFF
Pending · Dark Border — #E5EBF4
Pending · Dark Title — #FFFFFF
Pending · Light Title — #0A2757
Pending · Dark Leading icon — #FFFFFF
Pending · Light Leading icon — #0A2757
Destructive

Add the popup message here

Properties
Theme
Size
hasLeadingIcon
hasTrailingAction
hasDescription
Properties
Appearance Destructive
Theme Dark
Size MD
hasLeadingIcon True
hasTrailingAction False
hasDescription False
Colors
Background #D61B2C
Border #F4C7C9
Title #FFFFFF
Leading icon #FFFFFF
Description #F6F9FD @ 80%
Action background None
Action label #FFFFFF
Typography
Title Primary/Label/Light/Small
Layout
Height 38
Width 312
Radius 8
Padding H —
Padding V —
Gap —
Border 1
Alignment —
Pending

Add the popup message here

Properties
Theme
Size
hasLeadingIcon
hasTrailingAction
hasDescription
Properties
Appearance Pending
Theme Dark
Size MD
hasLeadingIcon True
hasTrailingAction False
hasDescription False
Colors
Background #0A2757
Border #E5EBF4
Title #FFFFFF
Leading icon #FFFFFF
Typography
Title Primary/Label/Light/Small
Layout
Height 38
Width 312
Radius 8
Padding H —
Padding V —
Gap —
Border 1
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:toast:1.0.0")

Import

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

Appearance, Theme, Size and the three has… booleans are all variant properties; 22 of the 48 combinations are built. Text-Slot (the Subtext Message) and Component-Slot (the Button - XSmall) are Figma Slots. Title is a text layer read from 4915:25142; its exposure as a text property is not readable with the plugin.

Figma PropertySwiftUICompose
Appearance — Default, Destructive, Pending .ebAppearance(.default / .destructive / .pending) appearance = EBToastAppearance.Default / Destructive / Pending
Theme — Dark, Light .ebTheme(.dark / .light) theme = EBToastTheme.Dark / Light
Size — MD, SM .ebSize(.md / .sm) size = EBToastSize.MD / SM
hasLeadingIcon — True, False .ebLeadingIcon(false) to hide the Appearance icon leadingIcon = false
hasTrailingAction — True, False .ebAction("…") { } when True action = EBToastAction("…") { } when True, else null
hasDescription — True, False .ebDescription("…") when True description = "…" when True, else null
Text-Slot (slot) .ebDescription(_:) description = "…"
Component-Slot (slot) .ebAction(_:action:) action = EBToastAction(…)
Title (text) EBToast("…") title = "…"
Usage Snippets Planned API
Default
EBToast("Add the popup message here")
    .ebAppearance(.default)
    .ebTheme(.dark)
    .ebSize(.md)
EBToast(
    title = "Add the popup message here",
    appearance = EBToastAppearance.Default,
    theme = EBToastTheme.Dark,
    size = EBToastSize.MD
)
Destructive
EBToast("Add the popup message here")
    .ebAppearance(.destructive)
    .ebTheme(.dark)
    .ebSize(.md)
EBToast(
    title = "Add the popup message here",
    appearance = EBToastAppearance.Destructive,
    theme = EBToastTheme.Dark,
    size = EBToastSize.MD
)
Pending
EBToast("Add the popup message here")
    .ebAppearance(.pending)
    .ebTheme(.dark)
    .ebSize(.md)
EBToast(
    title = "Add the popup message here",
    appearance = EBToastAppearance.Pending,
    theme = EBToastTheme.Dark,
    size = EBToastSize.MD
)
Accessibility
RequirementiOSAndroid
Announcement UIAccessibility.post(notification: .announcement, argument: title) when the toast appears; Destructive uses .layoutChanged so it interrupts. LiveRegionMode.Polite on the toast; Assertive for Destructive.
Action reachable The action is a Button inside the toast; keep the toast on screen while VoiceOver focus is on it. TextButton with its own onClick; the toast does not auto-dismiss while it has focus.
Icon is decorative .accessibilityHidden(true) on the leading icon — Appearance is said in the announcement ("Error: …"). contentDescription = null on the icon; prefix the announcement with the appearance.
Duration Auto-dismiss no sooner than 4 s; never auto-dismiss a toast with an action. SnackbarDuration.Long; Indefinite when an action is present.
Contrast White on #0A2757 is 13.9:1; white on #D61B2C is 5.0:1; #0A2757 on white is 13.9:1. Same values — the toast colours are fixed, not themed.
Usage Guidelines

Do

Use Default for confirmations, Destructive for failures, Pending while something is still in flight.

Don't

Don’t use Pending as a warning — it has no Error semantics.

Do

Keep the title to one line at 312 px; add hasDescription only for the second fact.

Don't

Don’t wrap the title — the Size MD title is a single 14 px line.

Do

Use hasTrailingAction for one undo or retry; the button is the XSmall size.

Don't

Don’t put two actions in a toast — the set builds one Component-Slot.

Do

Use SM inside dense sheets; MD everywhere else.

Don't

Don’t combine SM with an action or description — the set does not build them.

Criteria Scorecard
ID Criterion Status Notes
C1 Layer Structure & Naming Needs Refinement ToastRow › LeadingIcon / TextContent › Title on 4915:25142. Two variants slip: 4915:25240 names its title #content and 4915:25232 names it LeadingIcon.
C2 Variant & Property Naming Ready Appearance, Theme, Size with Title Case values; the three has… booleans are real True / False.
C3 Token Coverage Ready Title → Primary/Label/Light/Small (MD), Primary/Multi-line Label/Light/Fine (SM), Primary/Multi-line Label/Small with an action or description. Colour variable bindings are not readable with the plugin — confirm in Dev Mode.
C4 Native Mappability Ready Three enums, three booleans, two slots, one string — maps 1:1 onto EBToast.
C5 Interaction State Coverage Ready Dismiss and auto-duration contract documented (v2.x); the action button takes its states from Button - XSmall.
C6 Asset & Icon Quality Needs Refinement The Checkmark (Circular), Close and Information icons are icon-library instances that each carry a shape_full BOOLEAN_OPERATION — flatten them in the icon library.
Variants Inventory (22 total)

3 Appearance × 2 Theme × 2 Size × hasLeadingIcon × hasTrailingAction × hasDescription, authored sparse = 22 variants (Default 14, Destructive 6, Pending 4)

AppearanceBuiltCount
DefaultDark and Light; MD and SM; with and without icon; action and action + description at MD14
DestructiveDark MD and SM with and without icon; Light action and action + description at MD6
PendingDark and Light; MD and SM; icon only4
View full Appearance × Theme × Size × booleans breakdown (22 rows)
AppearanceThemeSizehasLeadingIconhasTrailingActionhasDescriptionNodeDimensions
DefaultDarkMDTrueFalseFalse4915:25142312 × 38
DefaultLightMDTrueFalseFalse4915:25148312 × 38
DestructiveDarkMDTrueFalseFalse4915:25154312 × 38
PendingDarkMDTrueFalseFalse4915:25160312 × 38
PendingLightMDTrueFalseFalse4915:25166312 × 38
DestructiveDarkMDFalseFalseFalse4915:25172312 × 38
DefaultDarkMDFalseFalseFalse4915:25175312 × 38
DefaultLightMDFalseFalseFalse4915:25178312 × 38
DestructiveDarkSMTrueFalseFalse4915:25181312 × 38
DefaultDarkSMTrueFalseFalse4915:25186312 × 38
DefaultLightSMTrueFalseFalse4915:25192312 × 38
DestructiveDarkSMFalseFalseFalse4915:25197312 × 38
PendingDarkSMTrueFalseFalse4915:25200312 × 38
PendingLightSMTrueFalseFalse4915:25205312 × 38
DefaultDarkSMFalseFalseFalse4915:25210312 × 38
DefaultLightSMFalseFalseFalse4915:25213312 × 38
DefaultDarkMDFalseTrueTrue4915:25216312 × 59
DefaultLightMDFalseTrueTrue4915:25224312 × 59
DestructiveLightMDFalseTrueTrue4915:25232312 × 59
DefaultDarkMDFalseTrueFalse4915:25240312 × 41
DefaultLightMDFalseTrueFalse4915:25245312 × 41
DestructiveLightMDFalseTrueFalse4915:25250312 × 41
1.0.2 — September 2026Patch
Style and Code tabs re-read · node 4915:25141
Style tab rebuilt from the 22 live variants. Cards follow Appearance — Default, Destructive, Pending — with Theme, Size and the three booleans as panel controls; colours, the three Title styles and the 38 / 41 / 59 heights read off 4915:25142 and its siblings against the exports; icon glyphs from get_svg. Padding, gap, alignment and colour tokens are not readable with the plugin and stay —. Combinations Figma does not build are composed from the same parts.
Docs
Code tab regrouped on the six-property schema. Installation on the Toast family coordinates, Property Mapping one row per property with the two slots, Usage Snippets per Appearance, Guidelines added, Scorecard regraded, Variants Inventory on the 22 live nodes with a summary and collapsed breakdown.
Docs
Two title layers are misnamed and the icons carry boolean operations. 4915:25240 names its title #content, 4915:25232 names it LeadingIcon; the three Appearance icons contain shape_full. Filed from the scorecard for the Component Review.
C1
1.0.1 — September 2026Patch
Documentation backfill · node 4915:25141
Resolved issues recorded. 13 resolved issues on the Overview tab had no changelog row: Toast and Toast - With Button consolidated; theme axis split into Appearance and Theme; Large Label replaced by a real Size axis; Boolean values normalised; Action slot added; Description composed from the shared Subtext Message; Size and Theme values aligned to the standard sets; Booleans confirmed as real Figma booleans; Layer naming completed; Pending placeholder replaced with a real icon; All variant values Title Cased; Dismiss and auto-duration contract documented; Native mapping and a11y live region documented.
Docs
1.0.0 — April 2026Major
Initial Assessment · node 27:53135
Verdict: Restructure — Consolidate with Toast - With Button, split the overloaded theme axis, rename Large Label to size, and replace the Pending placeholder with a real spinner. Open
Schema
C1 — Family duplication — Toast + Toast - With Button model one primitive; merge via optional action slot. Open
C1
C2 — Axis overload — theme mixes appearance + status; Large Label is a size flag; booleans on yes/no. Open
C2
C6 — Pending placeholder — 16/24 gray icon-placeholder circle; adopt a real spinner instance. Open
C6
C5 — Dismiss + duration — No auto-dismiss, swipe, or tap-to-dismiss documented. Open
C5
C4 — Native mapping — Document ToastManager overlay (iOS) + SnackbarHost wrapper (Android). Open
C4
C7 — Code Connect — Blocked on family consolidation + schema cleanup. Open
C7