ConsolidateRequires Rework
Toast - With Button Component link

A toast variant with a trailing action button used for undo or in-flight confirmations.

Consolidate — fold into the base Toast
Remove this component from the family. Base Toast picks up action?: EBToastAction (label + callback) and supportingText?: String (the 10/15 BarkAda second line). Align width with base Toast (312 vs. 330 today) and swap the deprecated Button - Small/XS for Button - XSmall. Covers the "Undo / Retry / View" use cases and collapses two components into one.
In Context

The actionable toast appears after reversible operations — "Transfer sent · Undo", "Message failed · Retry", "Photo uploaded · View". The action button sits right-aligned, tappable without dismissing the toast. Auto-dismiss is suppressed while an action is present.

Live Preview

Add label here

Add description here.

Label
Properties
Type
Description
DS Health
Reusable
Partial
Drops into reversible-action moments (Undo, Retry, View). But the narrow axis set (no error, no pending, no icon) means it can't replace the base Toast for most feedback moments — consumers pick the wrong component half the time.
Self-contained
Warn
Embeds the .[DEPRECATED] Button - Small/XS instance (scheduled for deletion). When that source is removed, this component breaks. Owns its surface tokens, but its action surface is borrowed from a deprecated source.
Consistent
Fail
Exists as a parallel component for what should be a property on Toast. type=default|light here vs. base Toast's type=default|pending|error and theme=default|light|dark — same axis name, incompatible value sets. Width is 330; base Toast is 312.
Composable
Warn
The action is baked in as a fixed Button instance — consumers can't swap it for a text-only link, an icon button, or disable/load it. A real slot would let consumers compose the action they need.
Behavior
State iOS Android Figma Property Notes
Action tap Yes Yes Button instance embedded The deprecated Button - Small/XS is the action surface. Only one fixed appearance; consumers can't disable or show a loading spinner on the action.
Whole-container tap N/A N/A Root is a <button> in some variants The default, description=no variant wraps the whole toast in a button element, overlapping the inner action — tap target is unclear.
Auto-dismiss when action present N/A N/A Not annotated Toasts with actions should stay visible until the action is taken or explicitly dismissed. Not spec'd.
Action loading / disabled state N/A N/A Not modeled "Retry" actions often need a loading state after tap. No provision in the component.
A11y — action label N/A N/A Text "Label" The default text in the instance is literally "Label". Needs a content contract and an accessibility label override.
Open Issues
  • Separate component for a button slot that should be a prop on the base Toast. Material's Snackbar, SwiftUI's .alert(actions:), and every other mature DS handle this as an optional action parameter — not a sibling record. Maintaining two components doubles the surface area of every future change and invites drift (different widths, different type sets). C1 · Layer Structure & Naming
  • Axis names + values drift from the base Toast. Base Toast exposes type = default | pending | error + theme = default | light | dark. This sibling exposes type = default | light — same axis name, narrower value set, collides on meaning. Consumers wiring Code Connect can't treat them as the same prop. C2 · Variant & Property Naming
  • description=yes|no is a slot + sizing flag bundled into a string. When description is present, vertical padding grows from 8 to 12 and a 4 px gap is inserted below the label. The trigger should be the presence of supporting-text content (supportingText?: String), not a hard-coded variant. C2 · Variant & Property Naming
  • Action surface uses the deprecated Button - Small/XS. The embedded Button instance (node 21:164490) is marked DEPRECATED in Figma, slated for deletion. When that source is removed, every variant of this toast breaks. Must re-link to Button - XSmall. C4 · Native Mappability
  • No icon axis at all. Base Toast has With Icon = yes | no. This sibling drops the axis entirely — you can't have an actionable toast with a leading checkmark or error glyph. Merging into Toast recovers the icon automatically. C6 · Asset & Icon Quality
  • Whole-container tap overlaps the action button. The default, description=no variant wraps the entire toast in a <button> element, while the inner action is also a button — two conflicting tap targets stacked. Behavior is undefined when the user taps the non-action area. C5 · Interaction State Coverage
  • Action has no states. No pressed, disabled, or loading state on the action. "Retry" actions commonly need a spinner after tap; destructive "Undo" often needs to grey out during processing. Not modeled. C5 · Interaction State Coverage
  • Width 330 vs. base Toast 312. Inconsistent with the base Toast's fixed width. A single consolidated component picks one width (recommend 312, matching the rest of the family). C1 · Layer Structure & Naming
  • Code Connect mappings not registered. Blocked on consolidation — there should be no separate Code Connect entry; the action slot maps to the base Toast's action parameter. C7 · Code Connect Linkability
Design Recommendations
  • Consolidate into the base Toast. Remove Toast - With Button from the family. Base Toast picks up two new optional slots: supportingText?: String (the 10/15 BarkAda second line) and action?: EBToastAction (label + callback, with optional loading and disabled states). One component, covers every use case today and the ones this sibling misses (actionable error, actionable with icon). Family
  • Migrate the action surface to Button - XSmall. The embedded Button - Small/XS is marked deprecated in Figma. Rebind the action instance to the canonical Button - XSmall before the deprecated source is deleted — otherwise every variant breaks. Composition
  • Replace description=yes|no with a supporting-text slot. Promote the second text line to an optional content slot. The padding and gap changes follow from the slot being populated — no duplicate variants required. Slot
  • Normalize width to 312. Match the base Toast. One width across the family. Property
  • Define the action's state contract. Spec pressed / disabled / loading states on the action slot so "Retry" and "Undo" flows can reflect processing state. State
  • Resolve the whole-container tap conflict. Decide: either the toast is dismiss-on-tap (drop the action as the only interactive surface), or the action owns the only tappable region. Pick one and drop the root <button> wrapper from the other variants. State
  • Document auto-dismiss suppression when an action is present. A toast with an action stays visible until the user taps the action or explicitly dismisses. Call this out as a usage note. Docs
  • Document the A11y announcement mapping. Action label feeds accessibilityLabel (iOS) / contentDescription (Android). Live region polite for neutral, assertive if consolidated into a destructive Toast. A11y
Types
Default
DES DEV

Confirms a reversible action that the user might want to undo right away — "Removed from favorites", "Transfer sent". Pairs a label and optional description with a trailing action button.

Add label here

Add description here.

Label
Properties
Theme
Description
Properties
Theme default
Description yes
Colors
Background #0A2757
Label #FFFFFF
Description #F6F9FDCC
Button label #005CE5
Button bg #FFFFFF
Layout
Width 330
Padding 16 × 12
Corner radius 8
Button height 24
Typography
Label Proxima Soft Bold · 14 / 16 · +0.25
Description BarkAda Medium · 10 / 15
Button Proxima Soft Bold · 14 / 14 · +0.25
Default — Colors by Theme

Default toast with a trailing action button. Theme axis flips surface + label between Dark and Light.

Role Token Theme · DarkTheme · Light
Surface bg toast/color/{theme}/bg #0A2757 #FFFFFF
Border toast/color/{theme}/border #E5EBF4 #E5EBF4
Label toast/color/{theme}/label #FFFFFF #0A2757
Description toast/color/{theme}/description #F6F9FD @ 80% #445C85
Action label toast/color/{theme}/action #9BC5FD #005CE5
Property Mapping

This component collapses into the base Toast. Figma properties map to the consolidated Toast API, not to a standalone EBToastWithButton.

Figma PropertySwiftUICompose
Type: default | light theme: light | dark (shared with Toast) .ebToastTheme(.dark)
Description: yes | no supportingText?: String (slot) supportingText: String?
(embedded Button - Small/XS — deprecated) action?: ToastAction (slot) action: EBToastAction?
(implicit label text) message: String message: String
(no icon axis) leadingIcon?: Icon (inherited from Toast) leadingIcon: Image?
Accessibility
RequirementiOSAndroid
Action label Action passes accessibilityLabel through to the inner Button. Default: the visible label. Action passes contentDescription to the inner Button. Default: the visible label.
Live region Polite announcement; use the Toast's appearance to decide (destructive → assertive). LiveRegionMode.Polite by default; assertive for destructive.
Suppress auto-dismiss When action is non-nil, host overlay keeps the toast on screen until the action is tapped or the user swipes. SnackbarDuration.Indefinite when an action is present.
Action loading state Swap label for a ProgressView; keep the button reachable for VoiceOver (don't disable mid-announcement). Swap label for a CircularProgressIndicator; set enabled = false after the state is announced.
Tap target Action button must have a ≥ 44 × 44 hit area; the 24 px pill extends via .contentShape if visual size is smaller. Action button must have a ≥ 48 dp touch target; use Modifier.minimumInteractiveComponentSize().
Criteria Scorecard
ID Criterion Status Notes
C1 Layer Structure & Naming Requires Rework Separate component for a property slot. Consolidate into base Toast; normalize width from 330 to 312.
C2 Variant & Property Naming Requires Rework type values drift from base Toast; description=yes|no should be a content slot.
C3 Token Coverage Ready Surface, label, description, border tokens all bound via main/toast/color/{default|light}/*. Action uses comp/button-v1/default/*.
C4 Native Mappability Requires Rework Action surface uses the deprecated Button - Small/XS; maps cleanly to Snackbar's action slot once migrated.
C5 Interaction State Coverage Requires Rework No action states (pressed / disabled / loading); whole-container tap overlaps the inner action.
C6 Asset & Icon Quality Requires Rework No leading-icon axis at all — consolidation recovers it from base Toast.
C7 Code Connect Linkability Not Mapped Blocked on consolidation — no standalone Code Connect entry; action maps to base Toast's action parameter.
Variants Inventory (4 total)

Axes: Type (2) × Description (2) = 4 variants. Flat matrix — no collapsed axes, no illegal combinations. Every variant embeds the deprecated .[DEPRECATED] Button - Small/XS instance.

#NodeTypeDescriptionDimensionsNotes
1813:31117defaultyes330 × 74Root is a <button> element
227:53213lightyes330 × 74Root is a <div> element
3813:31125defaultno330 × 41Root is a <button> element (tap conflict)
427:53225lightno330 × 41Root is a <div> element
1.0.0 — April 2026Major
Initial Assessment · node 27:53205
Verdict: Consolidate — Fold into the base Toast. Action becomes an optional slot; supporting text becomes an optional content slot. Remove this sibling from the family. Open
Family
C1 — Duplicate component — Exists to add an action slot to Toast. Collapse into base Toast with action?: EBToastAction. Width drifts from base (330 vs. 312). Open
C1
C2 — Axis drifttype=default|light here vs. type=default|pending|error + theme=default|light|dark on base Toast. description=yes|no should be supportingText?: String. Open
C2
C4 — Deprecated Button embedded — Action surface uses .[DEPRECATED] Button - Small/XS (node 21:164490), slated for deletion Aug 22, 2025. Rebind to Button - XSmall before migration. Open
C4
C5 — Tap conflict + missing action statesdescription=no variants wrap the root in a <button> overlapping the inner action. No pressed/disabled/loading states for the action. Open
C5
C6 — No icon axis — Silently drops the With Icon axis that base Toast exposes. Consolidation recovers it. Open
C6
C7 — Code Connect — Blocked on family consolidation. No standalone entry expected. Open
C7