Alert

A message that stays on the page: a status, a warning, a banner across the top of a view. The kit adds a neutral type and a three-level emphasis.

Usage

When to reach for Alert, what each of its axes is for, and the decisions it leaves to you.

When to use

An Alert is a message that stays on the page: a status the reader can come back to, a warning attached to the thing it is about, a banner across the top of a view. It is part of the layout, not an event that happens to it.
  • The message belongs to a region of the page, and it is still true the next time the reader looks at it.
  • The reader may need to act on it, so the text has to sit still long enough to be read, copied or linked out of.
  • The condition has an end: a form that now validates, a quota that has been raised, a plan that has been upgraded.
Use something else when
  • The message is short-lived and about an action that just happened. That is message for a one-line confirmation and notification for something with a title, a body and a place to go. Both are called from code and dismiss themselves, and an Alert does neither.
  • The message is the page: an empty state, a 404, a payment that failed and left nothing else to show. That is Result, which is sized and centered for a whole viewport.
  • The message belongs to one field. Form's own validation output sits under the input it is about, where an Alert would only repeat it further away.
  • The reader has to answer before anything else can happen. That is a Modal, because an Alert blocks nothing.

Type, and what a status is allowed to mean

type is the status axis: success, info, warning, error, plus a neutral default. It decides the color and the icon, and tells a screen reader nothing, so the words matter more than the value.
  • error means something is broken and the reader cannot proceed. Reserve it. An error that turns out to be an inconvenience teaches readers to skip the red one.
  • warning means it still works, and something will go wrong later: an expiring key, a quota at 90%, a deprecated setting.
  • success confirms a state, not an action. A saved record is a message, and a verified domain that stays verified is an Alert.
  • info is the default and it is also the drawer everything gets swept into. If a page has four info alerts, three of them are probably body copy.
  • default is a neutral alert for content with no status, a bordered surface with no status color. With showIcon it shows the info icon in a neutral color, so pass your own icon when that drawing is wrong for the case. With emphasis="strong" it inverts with the light or dark theme.
Leaving type off gives you info, except under banner, where it defaults to warning.

The emphasis scale

emphasis works alongside type: the type says which status, the emphasis says how loudly. Each of the three values is a complete look.
  • subtle swaps the status tint for a neutral fill and keeps the icon, title and description in their own colors. Use it for a stack of alerts where the row of tinted backgrounds is louder than any single message in it.
  • default keeps the tinted look and adds no classes, so your className styles it without a fight.
  • strong fills the alert with its status color and recolors the title, description, icon and close button to read on it. Use one per view at most. A page with two strong alerts has none.
strong also gives any <a> inside it the alert's text color and an underline. On a saturated fill no link color stays readable, so the underline is what marks it as a link.

Variant changes the border

variant takes outlined (the default) and filled. Filled drops the border, and both keep the same light tint. For a solid fill, use emphasis="strong".
  • Pick one per surface and keep it. Mixing outlined and filled down one page reads as two components, not two weights.
  • filled suits an alert sitting inside a card or a panel, where the container already draws the edge.
  • subtle and strong never show a border, whatever variant says, so use emphasis="default" when you want the border. Switching emphasis never changes the alert's size.
  • Set it once on ConfigProvider if the whole product wants filled alerts.

Title, description, icon and action

title on its own is the compact alert: one line, everything centered against it. Adding description switches to the taller layout, top-aligns the parts and grows the icon.
  • Keep the title to a sentence that is true on its own. The description is where the cause, the number and the next step go.
  • icon needs showIcon. A custom icon renders only when showIcon is set. On a strong alert it takes the alert's text color, like the default icon. Under banner, showIcon defaults to on.
  • action is the slot on the trailing side, for the one thing the reader can do about the message: retry, upgrade, dismiss for good. Keep it to one control, or two at most.
  • An action that navigates away from the page it is explaining is usually a link inside the description instead. The slot is for acting on the alert, not for leaving it.
  • Line up the icons with a wrapping title. With no description, the icon, action and close button center on the whole title. When the title wraps to several lines, align them with the first line instead: classNames={{ root: "items-start", icon: "mt-xxs", close: "mt-xxs" }}.

Closable, and the two callbacks

closable adds a real <button> to the trailing edge, and the alert hides itself when it is clicked. The object form takes closeIcon, onClose, afterClose, and any aria-* attributes you put on it, which is how the button gets a name.
  • closable.onClose fires on the click, before anything animates. If you only need to know it closed, this is enough.
  • Remove a closed alert in afterClose. closable.afterClose fires once the closing animation ends. If you take the alert out of your state in onClose, the animation is cut short.
  • Only make it closable if dismissing it is harmless. A warning the reader still has to act on should not be one click from gone, and if the same alert comes back on the next render, the close button was a lie.
  • A dismissal that should stick needs somewhere to stick. The alert remembers nothing across a remount, so persist the flag yourself.
banner is the page-wide form: no border, square corners and no bottom margin, so the alert sits flush against the edges of whatever it is pinned to.
  • It changes two defaults with it: type becomes warning and showIcon becomes on, both only when you have not set them yourself.
  • Reach for it at the top of a viewport or a layout region, full bleed. A banner indented inside a content column reads as a bug.
  • One banner at a time. A stack of them pushes the page down and turns the real content into the thing below the fold.
  • The squared corners are the tell that this is a system-level message. Use the ordinary rounded alert for anything scoped to one card or one form.

ErrorBoundary

Import Alert.ErrorBoundary from antd. The kit's Alert does not include it, so write import { Alert as AntdAlert } from "antd". A boundary keeps its error until it remounts, so give it a new key to reset it. React still logs the caught error to the console.

Restyling it

Reach for the semantic keys before a descendant selector: root, icon, section, title, description, actions, close. A part with a key keeps its name across versions, and a part reached by class name may not.
strong keeps its fill over your classes. A background class in className does not override emphasis="strong", and a text color class only wins in light mode. To color an alert yourself, leave emphasis at default.
  • emphasis="default" adds no classes, so yours always apply. Pick it when the fill has to be yours.
  • emphasis="subtle" gives way to your background and text classes too.
  • emphasis="strong" always keeps its fill over a bg-* class. A text-* class wins in light mode and loses in dark mode.
  • Use theme colors, not literals. The neutral default type at strong inverts between modes with no dark: rule, because its fill and text colors already invert with the theme.