Alert
A message that stays on the page with the content it is about.
In Brand expressive
See it live
npm run storybookWhen to use it
In Brand expressive: A sign-up that did not go through, and how to recover, on the page. Not for confirmations; toast does that.
- Use it when: People need to read a standing notice or how to recover, on this page, tied to what they are doing.
- Not when: A short confirmation that can go away by itself, or one notice for the whole site.
Instead:
- Toast: Short, non-blocking, goes away.
- Dialog: Needs an answer before going on.
- Site banner: One full-width notice for the whole site.
Variants
What each variant is for in any design system, then what Brand expressive decided and why. Each sample is the live story with that variant set.
defaultvariantNot used in Brand expressiveWhat it is for
A notice that stays on the page: information or a heads-up.
In Brand expressive
Alerts here only report a sign-up that did not go through; confirmations go in a toast.
destructivevariantUsed in Brand expressiveWhat it is for
Something failed or will be lost, and people must act to recover.
In Brand expressive
A sign-up that did not go through: plain first, then how to recover, with a word beside the color.
How Brand expressive uses it
Why it works this way
Alert 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 Alert, and what would move if it changed.
tasks.q21The answer
One action: sign up.
2So Alert
- –does not use default: Alerts here only report a sign-up that did not go through; confirmations go in a toast.
Input group: block-start Input group: block-end Toggle: lg3If it changed
and 2 answers that follow from it: Three, Only what today's screens use.
voice.count1The answer
Playful in headlines, plain in errors.
2So Alert
- –does not use default: Alerts here only report a sign-up that did not go through; confirmations go in a toast.
- ✓uses destructive: A sign-up that did not go through: plain first, then how to recover, with a word beside the color.
Badge: danger Toast: neutral Toast: danger3If it changed
No other answer follows from it.
accessibility.count1The answer
Color and word.
2So Alert
- ✓uses destructive: A sign-up that did not go through: plain first, then how to recover, with a word beside the color.
Badge: neutral Badge: success Badge: warning3If it changed
No other answer follows from it.
outcomes.q21The answer
A bland page is the costly mistake.
2So Alert
- ✓uses destructive: A sign-up that did not go through: plain first, then how to recover, with a word beside the color.
Button: secondary Button: danger Item: muted3If it changed
and 1 answer that follow from it: One per moment.
Words
- Headlines are short and bold. Three to six words.
- Verbs that move: Join, Try, Go.
- Playful in headlines, plain in errors.
- Use: Join, Drop, Go, Love. Avoid: Synergy, Leverage, Kindly.
The labels components use, from the voice tokens:
content.action.commit: Gocontent.action.cancel: Not nowcontent.action.destroy: Removecontent.action.retry: Try againcontent.action.empty-action: Explore the drop
See Voice and tone for the whole voice.
Accessibility and keyboard
Test before you ship:
- An error that appears after an action is announced (role alert); a standing note is not. undefined
- The tone also shows as an icon and words, never color alone. undefined
Use it in code
npx open-ds add alert
The component reads only component keys and semantic tokens, so it follows the brand and mode on <html>.
Tokens it reads
Alert reads 15 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 Alert's tokens to change Alert alone.
Brand expressive 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 |
|---|---|---|
| Alert | ||
| Gap y | component.alert.gap-ycomponent-spacing-map.hairlinevar(--alert-gap-y) | space.2:0.125rem |
| Corner | component.alert.radiusradius.containervar(--alert-radius) | radius.24:1.5rem |
| Padding, left and right | component.alert.padding-xspace.inset.containervar(--alert-padding-x) | space.32:2rem |
| Padding, top and bottom | component.alert.padding-ycomponent-spacing-map.x3var(--alert-padding-y) | space.24:1.5rem |
| Text size | component.alert.font-sizetype.body.font-sizevar(--alert-font-size) | font.size.17:1.0625rem |
| Gap x | component.alert.gap-xcomponent-spacing-map.x3var(--alert-gap-x) | space.24:1.5rem |
| Icon size | component.alert.icon-sizesize.iconvar(--alert-icon-size) | size.20:1.25rem |
| Default | ||
| Fill Changes with theme | component.alert.default.backgroundcolor.surface.defaultvar(--alert-default-background) | Lighttaupe.light.0:#FFFFFFDarktaupe.dark.50:#1F1411 |
| Text Changes with theme | component.alert.default.labelcolor.text.primaryvar(--alert-default-label) | Lighttaupe.light.900:#1F1411Darktaupe.dark.900:#FFF8F3 |
| Destructive | ||
| Fill Changes with theme | component.alert.destructive.backgroundcolor.surface.defaultvar(--alert-destructive-background) | Lighttaupe.light.0:#FFFFFFDarktaupe.dark.50:#1F1411 |
| Text Changes with theme | component.alert.destructive.labelcolor.status.dangervar(--alert-destructive-label) | Lightred.light.600:#C42B2BDarkred.dark.600:#F28B8B |
| Title | ||
| Weight | component.alert.title.font-weighttype.label.font-weightvar(--alert-title-font-weight) | font.weight.700:700 |
| Description | ||
| Gap | component.alert.description.gapspace.gap.tightvar(--alert-description-gap) | space.8:0.5rem |
| Text size | component.alert.description.font-sizetype.body.font-sizevar(--alert-description-font-size) | font.size.17:1.0625rem |
| Text Changes with theme | component.alert.description.labelcolor.text.mutedvar(--alert-description-label) | Lighttaupe.light.600:#6B544ADarktaupe.dark.400:#B5988A |
| From the system | ||
| Edge Changes with theme | color.border.default straight from the system, through --border | Lighttaupe.light.200 · #F2DCCFDarktaupe.dark.100 · #33241F |