Alert
In-flow message block for system feedback — info notes, success confirmations, warnings, and errors. Built-in icon per variant, optional title, dismiss button, and an actions slot for inline retry / view / undo buttons. The ARIA role flips between status (polite) and alert (assertive) based on the variant's urgency.
Usage
import { Alert, Button } from '@bwo-ui/react';
<Alert variant="info" title="Heads up">
This is an informational message.
</Alert>
<Alert
variant="warning"
title="Unsaved changes"
actions={
<>
<Button size="sm" variant="primary">Save</Button>
<Button size="sm" variant="ghost">Discard</Button>
</>
}
>
You have edits that haven't been published yet.
</Alert>
<Alert variant="success" onDismiss={() => setShown(false)}>
Your changes have been published.
</Alert>Variants
Four semantic variants drive both the colour treatment and the default icon. Choose based on the user's next action and the urgency of the situation:
info— neutral information the user should know about. Polite ARIA (role="status").success— a confirmation that an action completed. Polite ARIA.warning— caution, soft-blocking, or about to expire. Urgent ARIA (role="alert").error— failure, blocking issue, or recoverable problem. Urgent ARIA.
<Alert variant="info" title="Heads up">A neutral note about the system.</Alert>
<Alert variant="success" title="Published">Your post is now live.</Alert>
<Alert variant="warning" title="Approaching limit">You have used 92 % of your storage.</Alert>
<Alert variant="error" title="Couldn't connect">Check your network and try again.</Alert>Appearance
Three visual treatments for the same variant:
soft— tinted background with coloured text (the default). Reads as a gentle in-flow message; safe choice when there's lots of other content nearby.solid— full-colour background with white text. Use sparingly for the loudest hero / banner positions (top of page, post-launch announcement).outline— transparent surface with a coloured border. Quiet and dense; works well in compact admin tables where soft tints would feel busy.
appearance = softappearance = solidappearance = outline<Alert appearance="soft" variant="info" title="Info" />
<Alert appearance="solid" variant="info" title="Info" />
<Alert appearance="outline" variant="info" title="Info" />Actions
The actions prop renders a flex row of buttons below the body. Use it whenever the alert offers a remedy — Retry, View details, Save now, Roll back. Pair the primary action with a ghost dismiss button so users have a quick escape hatch.
<Alert
variant="error"
title="Couldn't load activity"
actions={
<>
<Button size="sm" variant="primary">Retry</Button>
<Button size="sm" variant="ghost">Open status page</Button>
</>
}
onDismiss={() => setShown(false)}
>
The dashboard data hasn't reached us. Network error 503.
</Alert>Dismissible
Pass an onDismiss callback to render the × button. The component doesn't manage its own visibility — you're responsible for removing the alert from the tree. This keeps unmount animations / list reflow under your control.
const [visible, setVisible] = useState(true);
{visible && (
<Alert
variant="success"
title="Plan upgraded"
onDismiss={() => setVisible(false)}
>
You now have unlimited builds and Boogie Pro features.
</Alert>
)}Custom icon
Override the variant's default icon by passing your own icon node. Any inline SVG works — the alert clones the variant colour onto currentColor, so the icon will pick it up automatically.
<Alert
variant="info"
icon={<SparkleIcon />}
title="What's new"
>
We just shipped IconButton parity, Card footer alignment, and the new Avatar group.
</Alert>Compact / inline
Skip the title for a tighter, single-line alert — useful for help tips, trial expiry nudges, or transient errors at the top of a form. Children render as the alert's description directly.
<Alert variant="info">Tip — press ⌘K from anywhere to open the command bar.</Alert>
<Alert variant="warning">Your trial expires in 3 days.</Alert>
<Alert variant="error" appearance="outline">
Unable to save — your session has expired. Sign in again to retry.
</Alert>Banner / hero alert
For top-of-page announcement banners — release notes, scheduled maintenance, migration prompts — combine appearance="solid" with a custom icon and action buttons. Make sure the dismiss handler persists the choice (e.g. in localStorage) so the banner doesn't reappear after a page reload.
Toast — all from-scratch, zero new dependencies.<Alert
variant="info"
appearance="solid"
icon={<SparkleIcon />}
title="bwo-ui 0.5 is coming"
actions={
<>
<Button size="sm" variant="ghost">Read the changelog</Button>
<Button size="sm" variant="ghost">Migrate</Button>
</>
}
onDismiss={dismissBanner}
>
Date pickers, command palettes, and a redesigned Toast — all from-scratch, zero new deps.
</Alert>Accessibility
- The component picks the right ARIA role automatically:
info/successrender asrole="status"witharia-live="polite";warning/errorrender asrole="alert"witharia-live="assertive". Polite announcements wait for a pause; assertive ones interrupt — pick the right urgency. - Override with the
urgentprop when the variant's default doesn't match (e.g. a success message after a long-running deploy might warrant an interrupt;urgent). - The default and custom icons are rendered
aria-hidden— they're a visual reinforcement of the variant, not the source of truth. Make sure the title or body still conveys the state in text. - The dismiss button carries
aria-label="Dismiss". If the alert is unique on the page, that's fine; if you render several at once (e.g. a list of notifications), set a more specific label viaaria-label="Dismiss \"Plan upgraded\""using a wrapping element if needed. - Don't leave critical errors as the only feedback. If an action failed and the user can't see the alert (e.g. it appeared below the fold), pair it with another channel — a disabled save button, a banner near the action, or a toast.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
variant | 'info' | 'success' | 'warning' | 'error' | 'info' | Tone — drives icon, colour, and the default ARIA role (`status` for info/success, `alert` for warning/error). |
appearance | 'soft' | 'solid' | 'outline' | 'soft' | `soft` (tinted bg + coloured text, default), `solid` (full-colour bg + white text), `outline` (transparent bg + coloured border). |
title | ReactNode | — | Short headline above the body. |
icon | ReactNode | — | Override the variant default icon. Renders `aria-hidden`; inherits the variant colour via `currentColor`. |
actions | ReactNode | — | Flex row of action buttons rendered below the body — Retry, View details, etc. |
onDismiss | () => void | — | When provided, renders an × button. The component does not manage its own visibility — caller hides the alert. |
urgent | boolean | — | Override the auto-derived ARIA urgency. Defaults to `true` for warning/error, `false` for info/success. |
radius | 'none' | 'sm' | 'md' | 'lg' | 'pill' | — | Corner radius preset. Omit to inherit the global default (6 px). |
…rest | HTMLAttributes<HTMLDivElement> | — | Native div attributes are forwarded — `style`, `id`, `className`. |