Alert
An inline status message with an icon, a status tint, an optional action, and an optional dismiss.
Alert puts a message about the page or form in place, where it stays until the thing it describes changes or a person dismisses it. It has four statuses that each draw their own icon on a muted fill, a title and a description that are both optional, one action, and a dismiss button. It is the persistent sibling of Toaster, which is gone after a few seconds.
New export
CSV is available from settings.
Changes saved
Your profile is up to date.
Plan ends in 3 days
Renew to keep the workspace.
Could not save
Check the connection and try again.
Usage
import { Alert, AlertAction } from '@/components/ui/alert';
<Alert variant="success" title="Saved" description="Your changes are live." />Four statuses
variant picks the status: info, the default, success, warning, and destructive.
Each one paints a 20px Phosphor fill icon in the status color on the status tint (bg-tone-tint), and the text stays in text-fg and text-fg-muted. The four icons are
different shapes, so the status does not depend on color alone. In dark the icon keeps the
same status color and the fill deepens to a 16% mix of that hue, so the roles do not
invert and a warning is still yellow on a dark yellow ground.
title and description are plain strings and either can be left off. A title alone suits a
short notice and a description alone suits a confirmation like "File uploaded."
Session ends in five minutes.
File uploaded.
Dismissing
onDismiss adds a ghost icon button in the top right corner, named by dismissLabel. Alert
does not hide itself when it is clicked, because the parent owns visibility, so set a flag in
the handler and stop rendering the alert. Focus moves on to the next control first. Click the X to hide this one, and restore it with the link.
Maintenance window
The system is offline Sunday 2–4 AM UTC.
One action beside the text
action takes one control after the text, centered on it and ahead of the dismiss button, for
a verb the alert is about, such as changing what it describes. Keep it to one, and send a
second choice to a Dialog.
Pass an AlertAction, a small Button in one of two
variants. secondary, the default, is a tinted fill, and ghost is ink only, for a quieter
verb. Either way the alert sets its tone, so the button draws in the alert's hue by taking
tone="inherit", and the dismiss button does the same. Filled and outline buttons are left out on
purpose, since a solid fill competes with the alert itself.
Template: Spring newsletter
Two columns, hero image, and a footer.
Domain verified
Mail from ramson.tech now passes SPF and DKIM.
Sender domain is unverified
41 recipients bounced
<Alert
variant="info"
title="Template: Spring newsletter"
action={<AlertAction onClick={openPicker}>Change</AlertAction>}
/>Props
Alert takes every <div> attribute, plus these.
| Prop | Type | Default | What it does |
|---|---|---|---|
variant | "info" | "success" | "warning" | "destructive" | "info" | The status. It sets the icon, the icon color, and the muted fill. |
title | string | A bold line in text-fg, rendered as an <h4>. | |
description | string | A line of text-fg-muted under the title, with a 4px gap when both are set. | |
action | ReactNode | One AlertAction, centered on the text and ahead of the dismiss button. | |
onDismiss | () => void | Renders the dismiss button and calls this when it is pressed. | |
dismissLabel | string | "Dismiss" | The dismiss button's name, for a translated one. |
AlertAction takes every Button prop except size, which
is fixed at sm, and variant is "secondary" (the default) or "ghost".
Accessibility
warninganddestructivearerole="alert", so a screen reader announces them as soon as they are added, without moving focus.infoandsuccessarerole="status", which waits for a pause. Passroleto change either, since your props are spread after it. An alert that is already on the page when it loads is usually not announced at all.- The icon is
aria-hidden, and the status is not named anywhere else, so write the title or description to say what happened. The shapes differ, so the status also survives forced colors, where the fills are replaced. - The title is an
<h4>and the description is a<p>. Nothing ties them together witharia-labelledbyoraria-describedby, and the heading level is fixed, so an alert placed under an<h2>skips a level in the outline. - The dismiss button is a native button named "Dismiss", or
dismissLabel. It is 36px square, and 44px square on a touch screen. When it has focus, dismissing moves focus to the next control after the alert, or the one before it at the end of the page, so focus does not fall to the page when the alert unmounts. - The action is a native Button, so Enter and Space press it, and it keeps the 44px touch height. Its focus ring is the usual contrast ring.
- The action and dismiss ink mix the status hue into the page ink at 48%, which keeps them readable on the status tint in every look. Check them again if you retune a status color.
- Nothing in Alert animates, and it appears and goes without a transition.
When to use something else
- Toaster for the result of something a person just did, like "Saved". It disappears on its own and does not take space in the layout.
- Dialog or Alert dialog when the message needs an answer before the person can go on. An alert never blocks.
- Empty state when a region has no content, rather than a message about content that is there.
- A Field's error text for a problem with one input. Field ties it to the control.
Install
shadcn add @gesso/alert