Alert
Accessible, unstyled alert and status live-region container.
| Package | @vizejs/ui/alert |
| Maturity | stable |
| Own the source | vize lib pull alert |
| Requires | — |
| Aliases | inline alert, status alert, callout primitive |
| Covers | WAI-ARIA alert role, WAI-ARIA status role, shadcn/ui Alert |
Minimal setup
Use a Vue 3.5+ project with Vue SFC compilation configured (see Vite+ integration).
vp install @vizejs/ui
Add the public import below to <script setup lang="ts">. Components provide behavior without styles; the preview uses optional Paper styles.
import { Alert } from "@vizejs/ui/alert";
Or copy the source into your project with vize lib pull alert (see Source Distribution).
Try it
This is the basic example maintained with the component source, using the public package imports. The preview adds the optional Paper styles.
Open the interactive example · Styling these components

Copy the example
<!-- Polite success status with application-owned dismissal and a labelled heading. -->
<script setup lang="ts">
import { ref, useId } from "vue";
import { Alert } from "@vizejs/ui/alert";
const open = ref(true);
const titleId = useId();
</script>
<template>
<div>
<Alert role="status" variant="success" :open :aria-labelledby="titleId">
<strong :id="titleId">Changes saved</strong>
<p>Your profile was updated.</p>
<button type="button" @click="() => (open = false)">Dismiss</button>
</Alert>
<button v-if="!open" type="button" @click="() => (open = true)">Show message again</button>
</div>
</template>
API
Alert
Source: src/families/feedback/alert/alert.vue
Props
| Prop | Type | Default | Description |
|---|---|---|---|
id |
string |
undefined |
Consumer-owned root id for labels, descriptions, or anchors. |
role |
AlertRole |
"alert" |
Live-region role: alert is assertive, status is polite. |
variant |
AlertVariant |
"info" |
Styling variant mirrored to data-variant; no CSS is emitted. |
open |
boolean |
true |
Whether the alert is visible and announceable. |
atomic |
boolean |
true |
Whether assistive technology should present the whole region on updates. |
ariaLabel |
string |
undefined |
Accessible name when no visible label or aria-labelledby supplies one. |
ariaLabelledby |
string |
undefined |
Space-separated ids that label the alert. |
ariaDescribedby |
string |
undefined |
Space-separated ids that describe the alert. |
Slots
| Slot | Slot props | Description |
|---|---|---|
default |
AlertSlotState |
Renders alert content with current role, variant, and visibility state. |
Exposed
| Member | Type | Description |
|---|---|---|
element |
Readonly<ShallowRef<HTMLDivElement | null>> |
Rendered alert root for composition with application-owned effects. |
Behavior
Normative state x input -> outcome table for alert.vue (@vizejs/ui/alert).
Every row is proven by the named mounted-DOM test in src/families/feedback/alert/alert.test.ts,
runtime conformance in src/conformance/runtime-conformance.test.ts, or compile-only
assertions in src/families/feedback/alert/alert.types.test-d.ts; a row without a passing test is a
contract violation.
| # | State | Input | Outcome | Proven by |
|---|---|---|---|---|
| A1 | open, alert | render | native <div role="alert">, assertive live region, atomic announcements, accessible labelling, and data-state |
renders an assertive alert with labelling, description, variant, and open state |
| A2 | open, status | render | role="status" switches to polite live-region semantics and preserves consumer-owned atomic policy |
switches to a polite status region without forcing atomic announcements |
| A3 | closed | render / Tab | the root remains mounted for hydration stability, carries hidden, mirrors data-state="closed", and is not tabbable |
closed alerts stay mounted but are hidden from user agents |
| A4 | any | slot / exposed state | slot consumers receive the live role, variant, visibility state, and boolean; exposed element is the rendered root |
exposes slot state for application-owned chrome and dismissal |
| A5 | SSR/hydration | isolated requests | server markup is byte-identical per request and hydrates without replacing the root | renders stable, accessible markup across isolated SSR requests; hydration conformance |
| A6 | public types | invalid role/variant | compilation rejects unsupported live-region roles and variants | src/families/feedback/alert/alert.types.test-d.ts |
The primitive intentionally ships no built-in dismiss button. Dismissal chrome
is application-owned and can consume slot state. The component subpath remains
tree-shakable with zero packaged CSS; consumers can separately import
@vizejs/ui/component-alert.css for a restrained visual treatment.