Alert
An inline, semantic message: a filled icon disc, a title, an optional description, and either a dismiss button or an action cluster on the right. Only the disc takes the variant colour — the card and the copy stay neutral by design, so a column of mixed alerts reads as one calm list rather than five banners competing for the same attention. The disc is decoration a screen reader never reaches, so the variant also emits one visually-hidden word — "Error", "Warning", "Success", "Information" — ahead of the title, which is what keeps severity alive when colour is not. Each one arrives on the panel spring, rising 8px through a short blur, because an alert has just happened rather than having always been there. One thing on this page is not what ships: every specimen below is rendered with role="note". The component defaults to role="alert", which is an assertive live region, and fourteen of those on one route would announce themselves all at once to a reader who had only opened the page.
import { Alert, AlertTitle, AlertDescription, Button } from "@pestoui/core"Semantic variants
All five, title-only and stacked, so the discs can be compared directly. default and info share a bare i, success takes a check, warning a bare !, destructive a cross. On screen, severity is carried by a 20px circle and nothing else — no tinted card, no coloured border, no coloured copy — which is what lets five of them sit in one column without the page turning into a warning label. It cannot be carried by colour alone, though, so each variant also announces itself: the fourth one is read as "Warning: 82% of this month's run credits are used", and the word is in an sr-only span, so it moves nothing. default announces nothing at all — plain ink is the absence of a severity rather than one of the five.
Title only, or title and description
AlertDescription is optional, and adding one changes the geometry rather than just the height: the card flips from items-center to items-start, so the × sits level with the first line instead of floating beside the middle of a two-line block — measured on the specimen further down that has both, it is 13px from the card's top and 38.5px from its bottom. An action cluster is the exception and opts out with self-center, staying at 19.75px from each edge. What does not change is the disc. It sits in a box exactly one line of the title tall and centres itself in that, so it lands on the first line of the title in both forms — measured on the two specimens below, the gap between the disc's centre and the title's line-box centre is 0px in each. There is no longer a separate nudge for the description case; there used to be, and being a 2px step standing in for a 1.25px gap it left the two forms three-quarters of a pixel apart. Use the short one when the title already says the whole thing; a description that only restates it costs a line and adds nothing.
Dismiss and actions
onDismiss renders the × button at the trailing edge and fires when it is pressed; action takes a right-aligned cluster, normally one or two Buttons, and centres it against the card whether or not a description is present. The two are independent, so an alert can carry both — the third one does, and the actions sit inboard of the dismiss. Keep the cluster to sm buttons: an alert is a line of content, not a toolbar.
A different glyph, or no disc at all
icon replaces what the variant would have put inside the disc while keeping the disc itself, so a Sparkles on the default variant still arrives in the ink-filled circle. Passing null removes the disc outright and the copy takes the full width — and with nothing left to colour, variant stops having any visible effect on that alert, which is the honest signal that a disc-less alert is a quiet notice rather than a severity. It is still announced as one: the severity word is keyed to the variant and not to the disc, so dropping the circle cannot quietly take the severity away from the readers who never had it in the first place. Make it quiet for everyone with severityLabel={null}.
Rewording or silencing the announcement
These two are pixel-for-pixel ordinary alerts — the difference is only audible. severityLabel replaces the word the variant would have announced, which is where a translation goes, or a phrase more specific than "Error"; severityLabel={null} removes it, for the case where the title already carries the severity in its own words and hearing "Error: Card declined" is one word too many. Silencing is the exception, not the pattern: with it gone, a screen reader is back to a destructive alert and a success alert reading as the same sentence.
Props
Pesto UI · 117 documented components