Alert
Inline status message with tone-driven live region semantics. Stateless resolveAlert helper: no open/close controller, no queue. Use for persistent or in-flow notices, not transient toasts.
Usage
import { Alert } from "@sometic/react/overlay";
export function Example() {
return <Alert tone="info">Profile saved.</Alert>;
}import { Alert } from "@sometic/react/overlay";
export function Example(): JSX.Element {
return <Alert tone="info">Profile saved.</Alert>;
}<script type="module">
import { registerOverlayElements } from "@sometic/elements/overlay";
registerOverlayElements();
</script>
<sometic-alert tone="warning">Check your connection.</sometic-alert>Vue
<script setup>
import { Alert } from "@sometic/vue/overlay";
</script>
<template>
<Alert tone="success">Profile saved.</Alert>
</template>How it works
- Engine (
@sometic/dom/alert):resolveAlert({ tone, live, …styleable })picks defaults (tone→"info";live→"assertive"when tone is"danger", else"polite"). Setsrole(statusvsalert),aria-live,aria-atomic="true",data-tone,data-slot="root". - Adapters: React/Vue render a
divwith resolved attributes and children / default slot. ReactAlertPropsexposestoneplus native div attrs; styling maps from resolve when you call the engine directly withclasses/unstyled. - Custom element:
sometic-alertobservestone,live,shadow, applies resolved attributes onto the host, and keeps light-DOM children as the message.
No dismiss controller: compose your own close button if needed.
Anatomy
| Part | data-slot | Role |
|---|---|---|
| Root | root | Status/alert live region |
| Tone | Default live | Role |
|---|---|---|
info | polite | status |
success | polite | status |
warning | polite | status |
danger | assertive | alert |
Props / attributes
React AlertProps
HTMLAttributes<HTMLDivElement> plus:
| Prop | Type | Default | Description |
|---|---|---|---|
tone | "info" | "success" | "warning" | "danger" | "info" | Visual + default live mapping |
children | ReactNode | , | Message content |
| Native attrs | div HTML attrs | , | Forwarded (className / style merge with resolve) |
Engine-only (DOM / custom wiring): explicit live: "polite" | "assertive", plus StyleableProps for slot root (unstyled, classes, styles, cssVariables, defaults, variants, merge).
Vue
tone (default "info"). Default slot is the message. No emit surface.
Custom element (sometic-alert)
Observed: tone, live, shadow. Children are the message. Setting live overrides the tone default mapping.
Events / callbacks
None. Presentational / live-region only.
Controlled vs uncontrolled
N/A. Mount or unmount to show/hide. Changing tone / live remaps role and aria-live. Keep the element mounted while the condition is true so polite announcements are not lost to a flash remount.
Form participation
N/A. Often placed beside fields for server or form-level errors. Prefer Field error text for single-control messages when possible. For submit-wide failures, keep one assertive Alert near the form actions rather than duplicating the same message on every field.
Accessibility
- Prefer assertive only for critical errors (
dangerdefault, or explicitlive="assertive"on CE /resolveAlert). - Do not spam remounts; each insertion may re-announce.
- Keep meaningful text; decorative icons should be
aria-hiddenwhen the text already explains the status. - Not a dialog: no focus trap, no required focus move. Do not steal focus on mount unless product UX explicitly needs it.
- Keyboard: content is static; interactive children (links/buttons) participate in normal tab order.
Styling
Unstyled by default beyond your theme. Useful selectors:
[data-slot="root"][data-tone="info"|"success"|"warning"|"danger"][role="status"],[role="alert"]
<Alert tone="danger" className="banner banner--danger">
Payment failed. Try another card.
</Alert>Edge cases
- Tone change remaps role/live; verify announcements when swapping from info → danger.
- Forced polite danger, call
resolveAlert({ tone: "danger", live: "polite" })in custom DOM wiring, or setlive="polite"on the CE. - Multiple alerts, fine; avoid assertive storms on the same page update.
- SSR, resolve is pure; register
sometic-alertonly in the browser. - Dismiss, compose a button yourself; Alert has no open state.
Performance notes
Pure resolve, ideal for static banners and SSR-friendly markup. Prefer Alert over Toast when the message should remain visible in layout without a queue. There are no timers, portals, or announcer subscriptions on this path.
When to use / When not
Use for inline or persistent notices (form banners, page status, inline success).
Do not use for:
- Timed ephemeral messages, Toast.
- Modal confirms or blocking flows, Dialog.
- Per-field validation copy that belongs in Field error slots.
FAQ
Toast vs Alert? Toast is queued/ephemeral with announcer helpers. Alert is inline and stays in the document flow.
Can I force polite danger? Yes on CE via live="polite", or resolveAlert({ tone: "danger", live: "polite" }) in DOM wiring. React’s public prop surface is tone (+ HTML attrs).
Dismiss button? Compose yourself; Alert has no open/close API.
Multiple alerts on one page? Allowed. Prefer polite tones unless the failure is critical.
Does React expose live? Not as a first-class prop; use the CE live attribute or call resolveAlert directly for custom hosts.
Shadow DOM? shadow on the CE isolates styles. Light DOM is default so page CSS reaches the host.
Role mapping? Assertive live ⇒ role="alert"; polite ⇒ role="status". Both set aria-atomic="true".
Children required? Provide accessible text. Empty alerts announce nothing useful.
Form errors? Use Field errors for one control; use Alert for page/section summaries.
Can I pass className on React? Yes. It merges with the resolved root className from resolveAlert.
Bundle tip? Import from @sometic/react/overlay or @sometic/dom/alert.