Toast
A short message that confirms an action and goes away.
In Dense data
See it live
npm run storybookWhen 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 dataWhat it is for
A plain confirmation.
In Dense data
A plain confirmation: Filters cleared.
successtoneUsed in Dense dataWhat it is for
Confirms that something people care about worked.
In Dense data
A short confirmation with the count: 12 alerts exported.
dangertoneUsed in Dense dataWhat it is for
Something failed in the background.
In Dense data
A background failure: name the record, then the fix.
How Dense data uses it
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.
voice.values1The answer
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.
Alert: destructive3If it changed
No other answer follows from it.
tasks.q21The answer
The same actions repeat many times an hour.
2So Toast
- ✓uses success: A short confirmation with the count: 12 alerts exported.
Button: ghost Input group: inline-end Sidebar: default Alert: default Toggle: default3If it changed
and 11 answers that follow from it: Time on task, All day, Three, and 8 more.
voice.lands1The answer
Errors and empty tables are where words decide the next action.
2So Toast
- ✓uses danger: A background failure: name the record, then the fix.
Empty: default3If it changed
No other answer follows from it.
outcomes.q21The answer
Acting on the wrong row is the costly error.
2So Toast
- ✓uses danger: A background failure: name the record, then the fix.
Button: primary Button: secondary Button: danger Alert: default Alert: destructive3If it changed
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: Savecontent.action.cancel: Cancelcontent.action.destroy: Deletecontent.action.retry: Retrycontent.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.
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.
| Part | Its token and the semantic it aliases | Value |
|---|---|---|
| Shared | ||
| Overlay background Changes with theme | component.overlay.backgroundcolor.surface.raisedvar(--overlay-background) | Lightslate.light.0:#FFFFFFDarkslate.dark.100:#262D38 |
| Overlay radius | component.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 | ||
| Gap | component.toast.gapspace.gap.defaultvar(--toast-gap) | space.8:0.5rem |
| Padding | component.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 width | component.toast.border-widthborder-width.defaultvar(--toast-border-width) | border-width.1:1px |
| Gap 2 | component.toast.gap-2space.gap.tightvar(--toast-gap-2) | space.4:0.25rem |
| Weight | component.toast.font-weighttype.label.font-weightvar(--toast-font-weight) | font.weight.500:500 |
| Text size | component.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 2 | component.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 |