Skip to main content

Toast

A short message that confirms an action and goes away.

In Dense data

See it live​

Start Storybook to see it live: npm run storybook

When to use it​

In Dense data: Confirms a saved change.

  • Use it when: Saved, sent, exported: something people should notice without stopping.
  • Not when: A failure people must understand (alert or dialog), or a notice that stays (alert).

Instead:

Variants​

What each variant is for in any design system, then what Dense data decided and why. Each sample is the live story with that variant set.

neutraltoneUsed in Dense data
Start Storybook to see it live

What it is for

A plain confirmation.

✓Something changed: cleared, copied, moved.
✕Something failed.

In Dense data

A plain confirmation: Filters cleared.

successtoneUsed in Dense data
Start Storybook to see it live

What it is for

Confirms that something people care about worked.

✓Exported, paid, joined.
✕A routine change that needs no celebration.

In Dense data

A short confirmation with the count: 12 alerts exported.

dangertoneUsed in Dense data
Start Storybook to see it live

What it is for

Something failed in the background.

✓What failed and how to fix it, when it can wait for people's attention.
✕A failure that blocks the task: use an alert or a dialog.

In Dense data

A background failure: name the record, then the fix.

How Dense data uses it​

The words of an error
Use Name the record, then the fix. Flat and specific.
Not "Oops" or a vague apology
Experts act on the message; the record and the fix are all they need. Example: “Alert ALR-2042 not saved. Threshold must be between 0 and 100.”
A success message
Use A short confirmation with the count
Not Celebration
Confirm and get out of the way; the next task is waiting. Example: “12 alerts exported.”

Why it works this way​

Toast looks the way it does because of 4 answers about this product. Each card is one answer, in three steps: the answer, what it decided for Toast, and what would move if it changed.

How does it sound?voice.values
1The answer
Terse

Experts want short labels and short messages.

2So Toast
  • ✓uses neutral: A plain confirmation: Filters cleared.
  • ✓uses success: A short confirmation with the count: 12 alerts exported.
  • ✓uses danger: A background failure: name the record, then the fix.
It also shapes Alert: destructive
3If it changed
3
Toast decisions would reopen

No other answer follows from it.

How often do people repeat actions?tasks.q2
1The answer
Constantly

The same actions repeat many times an hour.

2So Toast
  • ✓uses success: A short confirmation with the count: 12 alerts exported.
It also shapes Button: ghost Input group: inline-end Sidebar: default Alert: default Toggle: default
3If it changed
1
Toast decision would reopen

and 11 answers that follow from it: Time on task, All day, Three, and 8 more.

Where do the words matter most?voice.lands
1The answer
Errors and empty states

Errors and empty tables are where words decide the next action.

2So Toast
  • ✓uses danger: A background failure: name the record, then the fix.
It also shapes Empty: default
3If it changed
1
Toast decision would reopen

No other answer follows from it.

What is a costly mistake?outcomes.q2
1The answer
Acting on the wrong record

Acting on the wrong row is the costly error.

2So Toast
  • ✓uses danger: A background failure: name the record, then the fix.
It also shapes Button: primary Button: secondary Button: danger Alert: default Alert: destructive
3If it changed
1
Toast decision would reopen

and 2 answers that follow from it: Status in tables, Errors and empty states.

Words​

  • Lead with the object, then the state: "Alert 2041 contained."
  • Use numbers, not words for numbers.
  • One verb per button. No "please", no exclamation marks.
  • Use: Investigate, Filter, Assign, Escalated, Resolved. Avoid: Oops, Awesome, Please, Simply.

The labels components use, from the voice tokens:

  • content.action.commit: Save
  • content.action.cancel: Cancel
  • content.action.destroy: Delete
  • content.action.retry: Retry
  • content.action.empty-action: Change filters

See Voice and tone for the whole voice.

Accessibility and keyboard​

Test before you ship:

  • It is announced politely without taking focus, and stays long enough to read. undefined
  • Nothing people must act on lives only in a toast. undefined

Use it in code​

npx open-ds add toast

The component reads only component keys and semantic tokens, so it follows the brand and mode on <html>.

Tokens it reads​

Toast reads 17 tokens of its own, each an alias of a semantic token. Each row is one part: its own token, the semantic it aliases, and the value it ends at. Change a semantic and every component that reads it follows; override one of Toast's tokens to change Toast alone.

Changes with theme

Dense data decides what changes when you switch theme. Here a switch changes colors only, so the marked rows differ between light and dark; everything else holds steady.

PartIts token and the semantic it aliasesValue
Shared
Overlay background
Changes with theme
component.overlay.backgroundcolor.surface.raisedvar(--overlay-background)Lightslate.light.0:#FFFFFFDarkslate.dark.100:#262D38
Overlay radiuscomponent.overlay.radiusradius.containervar(--overlay-radius)radius.4:0.25rem
Overlay shadow
Changes with theme
component.overlay.shadowelevation.overlayvar(--overlay-shadow)Lightshadow.overlay:0px 8px 24px 0px #0D111729Darkshadow.overlay-dark:0px 8px 24px 0px #00000080
Toast
Gapcomponent.toast.gapspace.gap.defaultvar(--toast-gap)space.8:0.5rem
Paddingcomponent.toast.paddingspace.inset.containervar(--toast-padding)space.16:1rem
Text
Changes with theme
component.toast.labelcolor.text.primaryvar(--toast-label)Lightslate.light.900:#161B23Darkslate.dark.900:#F7F8FA
Border widthcomponent.toast.border-widthborder-width.defaultvar(--toast-border-width)border-width.1:1px
Gap 2component.toast.gap-2space.gap.tightvar(--toast-gap-2)space.4:0.25rem
Weightcomponent.toast.font-weighttype.label.font-weightvar(--toast-font-weight)font.weight.500:500
Text sizecomponent.toast.font-sizetype.body.font-sizevar(--toast-font-size)font.size.14:0.875rem
Label 2
Changes with theme
component.toast.label-2color.text.secondaryvar(--toast-label-2)Lightslate.light.700:#3D4655Darkslate.dark.500:#C4CBD6
Font size 2component.toast.font-size-2type.caption.font-sizevar(--toast-font-size-2)font.size.12:0.75rem
Neutral
Border
Changes with theme
component.toast.neutral.bordercolor.border.defaultvar(--toast-neutral-border)Lightslate.light.200:#DDE2EADarkslate.dark.100:#262D38
Success
Border
Changes with theme
component.toast.success.bordercolor.border.defaultvar(--toast-success-border)Lightslate.light.200:#DDE2EADarkslate.dark.100:#262D38
Border 2
Changes with theme
component.toast.success.border-2color.status.successvar(--toast-success-border-2)Lightgreen.light.600:#1F7A3ADarkgreen.dark.600:#5CC283
Danger
Border
Changes with theme
component.toast.danger.bordercolor.border.defaultvar(--toast-danger-border)Lightslate.light.200:#DDE2EADarkslate.dark.100:#262D38
Border 2
Changes with theme
component.toast.danger.border-2color.status.dangervar(--toast-danger-border-2)Lightred.light.600:#C42B2BDarkred.dark.600:#F28B8B