Skip to main content

Alert

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

In Dense data

See it live​

Start Storybook to see it live: npm run storybook

When to use it​

In Dense data: A problem that stays on the page.

  • 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 Dense data decided and why. Each sample is the live story with that variant set.

defaultvariantNot used in Dense data
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 Dense data

Alerts here are for problems that stay on the page; news goes in a toast or a badge.

destructivevariantUsed in Dense data
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 Dense data

A record that was not saved or an action that failed: name the record, then the fix, with an icon.

How Dense data uses it​

An error message
Use color.status.danger with an icon
Not color.status.warning
Red always means fix this, and the icon says it without color.

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.

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

Acting on the wrong row is the costly error.

2So Alert
  • –does not use default: Alerts here are for problems that stay on the page; news goes in a toast or a badge.
  • ✓uses destructive: A record that was not saved or an action that failed: name the record, then the fix, with an icon.
It also shapes Button: primary Button: secondary Button: danger Toast: danger
3If it changed
2
Alert decisions would reopen

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

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

The same actions repeat many times an hour.

2So Alert
  • –does not use default: Alerts here are for problems that stay on the page; news goes in a toast or a badge.
It also shapes Button: ghost Input group: inline-end Sidebar: default Toast: success Toggle: default
3If it changed
1
Alert decision would reopen

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

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

Many statuses share one table; color alone is not enough.

2So Alert
  • ✓uses destructive: A record that was not saved or an action that failed: name the record, then the fix, with an icon.
It also shapes Badge: neutral Badge: info Badge: success Badge: warning Badge: danger
3If it changed
1
Alert decision would reopen

No other answer follows from it.

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

Experts want short labels and short messages.

2So Alert
  • ✓uses destructive: A record that was not saved or an action that failed: name the record, then the fix, with an icon.
It also shapes Toast: neutral Toast: success Toast: danger
3If it changed
1
Alert decision would reopen

No other answer follows from it.

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:

  • 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

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
Alert
Gap ycomponent.alert.gap-ycomponent-spacing-map.hairlinevar(--alert-gap-y)space.2:0.125rem
Cornercomponent.alert.radiusradius.containervar(--alert-radius)radius.4:0.25rem
Padding, left and rightcomponent.alert.padding-xspace.inset.containervar(--alert-padding-x)space.16:1rem
Padding, top and bottomcomponent.alert.padding-ycomponent-spacing-map.x3var(--alert-padding-y)space.12:0.75rem
Text sizecomponent.alert.font-sizetype.body.font-sizevar(--alert-font-size)font.size.14:0.875rem
Gap xcomponent.alert.gap-xcomponent-spacing-map.x3var(--alert-gap-x)space.12:0.75rem
Icon sizecomponent.alert.icon-sizesize.iconvar(--alert-icon-size)size.16:1rem
Default
Fill
Changes with theme
component.alert.default.backgroundcolor.surface.defaultvar(--alert-default-background)Lightslate.light.0:#FFFFFFDarkslate.dark.50:#161B23
Text
Changes with theme
component.alert.default.labelcolor.text.primaryvar(--alert-default-label)Lightslate.light.900:#161B23Darkslate.dark.900:#F7F8FA
Destructive
Fill
Changes with theme
component.alert.destructive.backgroundcolor.surface.defaultvar(--alert-destructive-background)Lightslate.light.0:#FFFFFFDarkslate.dark.50:#161B23
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.500:500
Description
Gapcomponent.alert.description.gapspace.gap.tightvar(--alert-description-gap)space.4:0.25rem
Text sizecomponent.alert.description.font-sizetype.body.font-sizevar(--alert-description-font-size)font.size.14:0.875rem
Text
Changes with theme
component.alert.description.labelcolor.text.mutedvar(--alert-description-label)Lightslate.light.600:#535D6DDarkslate.dark.400:#969FAD
From the system
Edge
Changes with theme
color.border.default
straight from the system, through --border
Lightslate.light.200 · #DDE2EADarkslate.dark.100 · #262D38