Alert
A styled, accessible notification banner. Its live-region politeness is derived from the color —
urgent danger / warn render role="alert" (assertive), everything else role="status" (polite) —
so a non-urgent banner isn't announced assertively (override with the live prop). It supports an
optional icon, a title, body text, an actions row, and a dismiss button.
The examples are organised by layer: the class reference is the standalone
@oriui/css layer, and the Framework API is the @oriui/vue component. Every
example is live — flip its code between HTML (the standalone classes, also your htmx / Astro / Svelte /
plain-HTML usage), Vue; HTML is the default.
Classes
An alert is a block class plus single-class token utilities — one class repoints one token; no base class needed. The Vue props in Framework API map 1:1 to these.
| Class | Type | Description |
|---|---|---|
ori-alert | Block | Required base class. The Vue component sets role=alert (danger/warn) or role=status (otherwise); standalone markup picks the role itself. |
ori-variant_* | Style | fill · tonal · outline · text · plain |
ori-color_* | Color | primary · secondary · success · warn · danger · info · surface · background |
ori-size-radius_* | Radius | zero · xs · sm · md · lg · xl · rounded |
ori-font-size_* | Size | xs · sm · md · lg · xl · xxl — scales the body text |
ori-alert__icon · ori-alert__content · ori-alert__title · ori-alert__body · ori-alert__actions · ori-alert__close | Part | internal layout elements |
Like Button, the non-fill variants (the default tonal included) paint the body text with the
AA-safe --ori-color-text tone rather than the raw role — see
Design tokens.
Variants
Five visual styles, all driven by the ori-variant_* utility. tonal is the default.
<div class="ori-alert ori-variant_tonal ori-color_info" role="status">
<div class="ori-alert__content">
<div class="ori-alert__body">Tonal alert</div>
</div>
</div>
<!-- swap the variant: ori-variant_tonal → ori-variant_fill / ori-variant_outline / ori-variant_text / ori-variant_plain -->
Colors
Every semantic role. Use success, warn, danger, and info for status messages.
<!-- swap the color: ori-color_info → ori-color_success / ori-color_warn / ori-color_danger / ori-color_primary -->
<div class="ori-alert ori-variant_tonal ori-color_danger" role="alert">
<div class="ori-alert__content">
<div class="ori-alert__body">Danger</div>
</div>
</div>
Variant and color compose freely — e.g. an outline danger alert:
<div class="ori-alert ori-variant_outline ori-color_danger" role="alert">
<div class="ori-alert__content">
<div class="ori-alert__body">Something went wrong. Please try again.</div>
</div>
</div>
With title
Pass title to add a bold heading above the body text.
<div class="ori-alert ori-variant_tonal ori-color_warn" role="alert">
<div class="ori-alert__content">
<div class="ori-alert__title">Session expired</div>
<div class="ori-alert__body">Please sign in again to continue.</div>
</div>
</div>
With icon
Pass an SVG path to icon to prepend a visual cue.
<div class="ori-alert ori-variant_tonal ori-color_success" role="status">
<div class="ori-alert__icon">
<i class="ori-icon" aria-hidden="true">
<svg viewBox="0 0 24 24"><path d="M9 16.17 4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z" /></svg>
</i>
</div>
<div class="ori-alert__content">
<div class="ori-alert__title">Success</div>
<div class="ori-alert__body">Your profile has been updated.</div>
</div>
</div>
Dismissible
closable adds a close button in the top-right corner. Handle the close event to remove or hide
the alert. The button label defaults to "Dismiss" and is configurable via closeLabel.
<div class="ori-alert ori-variant_tonal ori-color_info" role="status">
<div class="ori-alert__content">
<div class="ori-alert__title">Update available</div>
<div class="ori-alert__body">A new version is ready to install.</div>
</div>
<button type="button" class="ori-alert__close" aria-label="Dismiss">
<!-- close icon -->
</button>
</div>
Sizes
size scales the body text from xs to xxl. The default is md.
<!-- swap the font-size: ori-font-size_md → ori-font-size_xs / ori-font-size_sm / ori-font-size_lg / ori-font-size_xl / ori-font-size_xxl -->
<div class="ori-alert ori-font-size_lg ori-variant_tonal ori-color_info" role="status">
<div class="ori-alert__content">
<div class="ori-alert__body">Large alert</div>
</div>
</div>
Radius
From zero (sharp corners) to rounded (pill). Default is md.
<!-- swap the radius: ori-size-radius_md → ori-size-radius_zero / ori-size-radius_sm / ori-size-radius_lg / ori-size-radius_xl / ori-size-radius_rounded -->
<div class="ori-alert ori-size-radius_rounded ori-variant_tonal ori-color_info" role="status">
<div class="ori-alert__content">
<div class="ori-alert__body">Rounded</div>
</div>
</div>
Common patterns
A form submission result and a persistent banner with actions — the everyday compositions.
<!-- form error banner -->
<div class="ori-alert ori-variant_outline ori-color_danger" role="alert">
<div class="ori-alert__icon">
<i class="ori-icon" aria-hidden="true">
<svg viewBox="0 0 24 24">
<path
d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-2h2v2zm0-4h-2V7h2v6z"
/>
</svg>
</i>
</div>
<div class="ori-alert__content">
<div class="ori-alert__title">Payment failed</div>
<div class="ori-alert__body">Your card was declined. Check your details and try again.</div>
</div>
<button type="button" class="ori-alert__close" aria-label="Dismiss"><!-- icon --></button>
</div>
<!-- alert with actions row -->
<div class="ori-alert ori-variant_tonal ori-color_warn" role="alert">
<div class="ori-alert__content">
<div class="ori-alert__title">New terms of service</div>
<div class="ori-alert__body">We have updated our terms. Please review before continuing.</div>
<div class="ori-alert__actions">
<button class="ori-button ori-variant_tonal ori-color_warn …">Review</button>
<button class="ori-button ori-variant_text ori-color_warn …">Dismiss</button>
</div>
</div>
</div>
Accessibility
The accessibility contract holds across every layer — the standalone classes and the Vue component render the same attributes.
- The live-region politeness is derived from the color so non-urgent content isn't announced
assertively: urgent colors (
danger/warn) renderrole="alert"(aria-live="assertive"— interrupts the screen reader), and everything else (theinfodefault,success, …) rendersrole="status"(aria-live="polite"— announced at the next pause). Override with theliveprop (assertive/polite/off);offremoves the live region entirely (for content that is part of the static page and shouldn't be announced as it appears). - Icons inside the alert are decorative (
aria-hidden="true"on theori-icon); the alert text itself is the accessible announcement. - The dismiss button has an
aria-label(default"Dismiss", configurable viacloseLabel) so its purpose is clear without visible text. - The dismiss button has a visible
:focus-visiblering. No other keyboard interaction is required; the alert itself is not focusable. - For a live announcement, insert (or reveal) the element with its content already in place — some
screen readers announce only content present when the region appears. For content that is part of the
page on load, prefer
live="off"(or a non-urgent color) so it isn't announced as the page renders.
| Key | Action |
|---|---|
Tab | Moves focus to the dismiss button (if present). |
Enter | Activates the focused dismiss button. |
Space | Activates the focused dismiss button. |
Framework API
The props, events, slots, and slots of the Vue component. The standalone CSS layer has no component API — its surface is the classes above. (Svelte bindings are planned.)
Props
| Prop | Type | Default | Description |
|---|---|---|---|
closable | boolean | false | Renders a dismiss button; emit close to remove the alert. |
closeLabel | string | 'Dismiss' | aria-label on the dismiss button. |
color | ThemeColor | 'info' | Semantic role: primary · secondary · success · warn · danger · info · surface · background. |
icon | string | — | SVG path for the leading icon. Use the icon slot for custom markup. |
live | 'assertive' | 'polite' | 'off' | derived | Live-region politeness. Defaults to assertive (role="alert") for danger / warn and polite (role="status") otherwise; off removes the live region. |
radius | RadiusSize | 'md' | Corner radius (zero · xs · sm · md · lg · xl · rounded). |
size | ActionSize | 'md' | Body font scale (xs–xxl). |
text | string | — | Body text. Use the default slot for richer markup. |
title | string | — | Bold heading above the body. Use the title slot for richer markup. |
variant | 'fill' | 'tonal' | 'outline' | 'text' | 'plain' | 'tonal' | Visual style. |
ThemeColor: 'primary' | 'secondary' | 'success' | 'warn' | 'danger' | 'info' | 'surface' | 'background'
ActionSize: 'text' | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'xxl'
RadiusSize: 'zero' | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'rounded'
Events & attributes
| Event | Payload | Description |
|---|---|---|
close | — | Emitted when the dismiss button is clicked. Use it to hide or remove the alert. |
OriAlert does not set inheritAttrs: false, so extra attributes (class, style, data-*, …)
fall through to the root <div> (whose role is alert / status / none per the live rule above).
Slots
| Slot | Description |
|---|---|
default | Body content. Replaces the text prop; renders inside ori-alert__body. |
icon | Custom icon markup. Replaces the icon prop; renders inside ori-alert__icon. |
title | Custom title markup. Replaces the title prop; renders inside ori-alert__title. |
actions | Action controls (buttons, links) rendered in a flex row below the body (ori-alert__actions). Only mounted when the slot is provided. |