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
Type
Theme
With Icon
Large 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
  • Code Connect mappings not registered. Blocked — no native library exists yet. C7 · Code Connect Linkability
  • 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 | smMD | 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: containerToastRow, the two sibling offset frames → LeadingIcon and TextContent, text-containerTextGroup, and #contentTitle. 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=pendingPending, 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
DES DEV

Confirms a completed action — transfer sent, settings saved, upload finished. Default theme places a checkmark glyph on a dark navy surface.

Add the popup message here

Properties
Theme
With Icon
Large Label
Properties
Theme dark
With Icon yes
Large Label yes
Colors
Background #0A2757
Label #FFFFFF
Icon #FFFFFF
Layout
Width 312
Padding 12 × 12
Corner radius 8
Icon size 24 × 24
Typography
Font Proxima Soft Semibold
Style Primary/Label/Light/Small
Size 14 / 14 · +0.25
Default — Colors by Theme

Information toast. Theme axis flips surface + label between Dark (navy) and Light (white).

Role Token Theme · DarkTheme · Light
Surface bg main/toast/default/{theme}/bg #0A2757 #FFFFFF
Border main/toast/default/{theme}/border #E5EBF4 #E5EBF4
Label main/toast/default/{theme}/label #FFFFFF #0A2757
Icon main/toast/default/{theme}/icon #FFFFFF #0A2757
Error
DES DEV

Surfaces a failure that needs the user's attention — failed transfer, invalid input, expired session. Red surface with a leading X glyph.

Add the popup message here

Properties
Theme
With Icon
Large Label
Properties
Theme default
With Icon yes
Large Label yes
Colors
Background #D61B2C
Label #FFFFFF
Icon #FFFFFF
Layout
Width 312
Padding 12 × 12
Corner radius 8
Icon size 24 × 24
Typography
Font Proxima Soft Semibold
Style Primary/Label/Light/Small
Size 14 / 14 · +0.25
Error — Colors

Critical/error toast. Single appearance regardless of theme.

Role Token Default
Surface bg main/toast/error/bg #D61B2C
Border main/toast/error/border #F4C7C9
Label main/toast/error/label #FFFFFF
Icon main/toast/error/icon #FFFFFF
Pending
DES DEV

Acknowledges in-flight work the user kicked off — submitting a form, syncing a balance, processing a payment. A spinner glyph signals the action is still running.

Add the popup message here

Properties
Theme
With Icon
Large Label
Properties
Theme dark
With Icon yes
Large Label yes
Colors
Background #0A2757
Label #FFFFFF
Icon #FFC857
Layout
Width 312
Padding 12 × 12
Corner radius 8
Icon size 24 × 24
Typography
Font Proxima Soft Semibold
Style Primary/Label/Light/Small
Size 14 / 14 · +0.25
Pending — Colors by Theme

In-progress / loading state toast. Same surface palette as Default; spinner replaces the static icon.

Role Token Theme · DarkTheme · Light
Surface bg main/toast/pending/{theme}/bg #0A2757 #FFFFFF
Border main/toast/pending/{theme}/border #E5EBF4 #E5EBF4
Label main/toast/pending/{theme}/label #FFFFFF #0A2757
Spinner main/toast/pending/{theme}/spinner #FFFFFF #0A2757
Property Mapping

The proposed schema collapses Toast + Toast - With Button into one API. Action becomes an optional slot, theme splits into appearance + theme, and Large Label becomes size.

Figma PropertySwiftUICompose
Type: default | pending | error appearance: neutral | pending | destructive appearance: EBToastAppearance
Theme: default | light | dark (overloaded) theme: light | dark (neutral + pending only) .ebToastTheme(.dark)
Large Label: yes | no size: small | base .controlSize(.small / .regular)
With Icon: yes | no leadingIcon?: Icon (slot) leadingIcon: Image?
(implicit) message: String message: String
(separate component) action?: ToastAction action: EBToastAction?
(not modeled) duration: short | long duration: EBToastDuration
(not modeled) onDismiss?: () -> Void onDismiss: (() -> Void)?
Accessibility
RequirementiOSAndroid
Live region — error Post UIAccessibility.Notification.announcement with .high priority on present. Modifier.semantics { liveRegion = LiveRegionMode.Assertive } on the Snackbar container.
Live region — neutral / pending Post announcement with default priority. LiveRegionMode.Polite.
Minimum duration Short ≥ 3s, long ≥ 5s; extend for longer messages per iOS HIG. SnackbarDuration.Short / Long (Material 3 defaults).
Action button label Action slot owns its own accessibilityLabel. Action slot owns its own contentDescription.
Dismiss gesture Swipe horizontally to dismiss; respect reduce-motion for the slide-out animation. Swipe to dismiss built into Snackbar; honor TalkBackUserTouchExplorationEnabled to extend duration.
Criteria Scorecard
ID Criterion Status Notes
C1 Layer Structure & Naming Requires Rework Two components for one primitive — consolidate with Toast - With Button.
C2 Variant & Property Naming Requires Rework theme overloaded with status; Large Label is a size flag; booleans on yes/no.
C3 Token Coverage Ready All colors bound to main/toast/color/{mode}/*. Spacing + typography fully tokenized.
C4 Native Mappability Requires Rework No SwiftUI first-party primitive; Compose has Snackbar. Needs documented mapping + ToastManager pattern.
C5 Interaction State Coverage Requires Rework No auto-duration, swipe, or tap-to-dismiss contract; pending has no animation.
C6 Asset & Icon Quality Requires Rework Pending uses icon-placeholder gray circle instead of a real spinner.
C7 Code Connect Linkability Not Mapped Blocked on family consolidation and axis cleanup.
Variants Inventory (16 total)

Effective axes today: Type (3) × Theme (3, coupled to Type) × With Icon (2) × Large Label (2). Built variants collapse the illegal combinations — Error only pairs with theme=default; Pending only pairs with theme=dark | light + with icon=yes. = 16 built variants.

GroupCountAxes
Default / Dark4withIcon=yes/no × largeLabel=yes/no
Default / Light4withIcon=yes/no × largeLabel=yes/no
Error / Default4withIcon=yes/no × largeLabel=yes/no
Pending / Dark2withIcon=yes (forced) × largeLabel=yes/no
Pending / Light2withIcon=yes (forced) × largeLabel=yes/no
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 overloadtheme 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