Skip to main content

Alert

A message that stays on the page with the content it is about.

In Brand expressive

See it live​

Start Storybook to see it live: npm run storybook

When 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 expressive
Start Storybook to see it live

What it is for

A notice that stays on the page: information or a heads-up.

✓A note people should read but need not fix.
✕Something failed and must be fixed.

In Brand expressive

Alerts here only report a sign-up that did not go through; confirmations go in a toast.

destructivevariantUsed in Brand expressive
Start Storybook to see it live

What it is for

Something failed or will be lost, and people must act to recover.

✓An error, with what went wrong and how to fix it.
✕A plain note dressed as danger for emphasis.

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​

An error message
Use color.status.danger and a short sentence
Not The brand magenta
Errors must not look like the brand.

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.

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

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.
It also shapes Input group: block-start Input group: block-end Toggle: lg
3If it changed
1
Alert decision would reopen

and 2 answers that follow from it: Three, Only what today's screens use.

How many tones does it use?voice.count
1The answer
One per moment

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.
It also shapes Badge: danger Toast: neutral Toast: danger
3If it changed
2
Alert decisions would reopen

No other answer follows from it.

How many signals carry each meaning?accessibility.count
1The answer
Two: color and word

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.
It also shapes Badge: neutral Badge: success Badge: warning
3If it changed
1
Alert decision would reopen

No other answer follows from it.

What is a costly mistake?outcomes.q2
1The answer
Looking off-brand

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.
It also shapes Button: secondary Button: danger Item: muted
3If it changed
2
Alert decisions would reopen

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: Go
  • content.action.cancel: Not now
  • content.action.destroy: Remove
  • content.action.retry: Try again
  • content.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.

Changes with theme

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.

PartIts token and the semantic it aliasesValue
Alert
Gap ycomponent.alert.gap-ycomponent-spacing-map.hairlinevar(--alert-gap-y)space.2:0.125rem
Cornercomponent.alert.radiusradius.containervar(--alert-radius)radius.24:1.5rem
Padding, left and rightcomponent.alert.padding-xspace.inset.containervar(--alert-padding-x)space.32:2rem
Padding, top and bottomcomponent.alert.padding-ycomponent-spacing-map.x3var(--alert-padding-y)space.24:1.5rem
Text sizecomponent.alert.font-sizetype.body.font-sizevar(--alert-font-size)font.size.17:1.0625rem
Gap xcomponent.alert.gap-xcomponent-spacing-map.x3var(--alert-gap-x)space.24:1.5rem
Icon sizecomponent.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
Weightcomponent.alert.title.font-weighttype.label.font-weightvar(--alert-title-font-weight)font.weight.700:700
Description
Gapcomponent.alert.description.gapspace.gap.tightvar(--alert-description-gap)space.8:0.5rem
Text sizecomponent.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