Alert
An inline feedback banner on the shared intent scale, with an optional heading and dismiss button. Announcement semantics are opt-in, and the Form error summary is built from one.
Import
import { Alert } from "@hyzer-labs/ui"Demo
Alert vs Banner
Alert for an inline message that sits next to the thing it describes. For a
solid, full-width announcement at page level, one you can pin to the top or bottom, use Banner instead.The intent vocabulary plus the neutral default. The Form error summary renders as intent="danger" automatically.
Course note
League night
Doubles signup
Course closed
High winds
Round saved
Cart friendly
<Alert title="Course note">Hole 7 tee pads were resurfaced this week.</Alert>
<Alert intent="danger" title="Course closed">Lightning in the area. Clear the course now.</Alert>
<Alert intent="warning" title="High winds">Gusts over 30mph expected after 2pm.</Alert>
<Alert intent="success" title="Round saved">Your scorecard was synced to the league.</Alert>The leading icon slot is decorative, rendered aria-hidden.
Pair it with a glyph that matches the intent, and make sure the title or body already
says the same thing in words.
Round saved
Course closed
<Alert intent="success" title="Round saved">
{#snippet icon()}<IconCircleCheck />{/snippet}
Your scorecard was synced to the league.
</Alert>
<Alert intent="danger" title="Course closed">
{#snippet icon()}<IconTriangleAlert />{/snippet}
Lightning in the area. Clear the course now.
</Alert>The shared Rounded scale maps 1:1 to the --hz-radius-* tokens.
The default is 'md'.
Course note
Course note
Course note
Course note
Course note
<!-- rounded="none" -->
<Alert rounded="none" title="Course note">Hole 7 tee pads were resurfaced this week.</Alert>
<!-- rounded="sm" -->
<Alert rounded="sm" title="Course note">Hole 7 tee pads were resurfaced this week.</Alert>
<!-- rounded="md" (default) -->
<Alert title="Course note">Hole 7 tee pads were resurfaced this week.</Alert>
<!-- rounded="lg" -->
<Alert rounded="lg" title="Course note">Hole 7 tee pads were resurfaced this week.</Alert>
<!-- rounded="full" -->
<Alert rounded="full" title="Course note">Hole 7 tee pads were resurfaced this week.</Alert>Same contract as Badge chips: onDismiss renders the button, you own the
visibility state. Give the button a specific dismissLabel.
High winds
let weatherVisible = $state(true);
{#if weatherVisible}
<Alert
intent="warning"
title="High winds"
dismissLabel="Dismiss weather notice"
onDismiss={() => (weatherVisible = false)}
>
Gusts over 30mph expected after 2pm. Expect flippy discs to flip more.
</Alert>
{/if}Announcement is opt-in. An Alert rendered with the page is just content, but one
inserted after an action should carry role="status" so screen readers hear it.
Click the button below: the alert appears and announces politely.
let saved = $state(false);
<Button onclick={save}>Save round</Button>
{#if saved}
<!-- role="status" = polite announcement; use role="alert" sparingly -->
<Alert intent="success" role="status">Round saved to the league.</Alert>
{/if}Props
| Name | Type | Default | Note |
|---|---|---|---|
children | Snippet | — | Required. The alert body. |
title | string | Snippet | — | Optional heading; labels the alert via aria-labelledby. |
headingLevel | 2 | 3 | 4 | 5 | 6 | 3 | An alert is nearly always a callout inside a section rather than a section of its own, so the default keeps it below your page headings. Raise or lower it to match the surrounding document. |
intent | Intent | 'neutral' | See Foundation → Colors & Intent. |
rounded | 'none' | 'sm' | 'md' | 'lg' | 'full' | 'md' | The shared Rounded scale — 1:1 with the --hz-radius-* tokens. |
icon | Snippet | — | Decorative; rendered aria-hidden. |
onDismiss | () => void | — | Renders the dismiss button. Visibility is your state — the Alert never hides itself. |
dismissLabel | string | 'Dismiss' | |
class | string | — | Merged after the hz-alert class. |
Theme hooks
What this component promises your CSS. The reference theme styles exactly these — from @layer hz-theme, so your unlayered rules win. See Styling Components for the how.
Root class: .hz-alert
Data attributes
| Hook | Values | Styles |
|---|---|---|
data-intent | 'neutral' | any registered intent | Drives the accent bar, tint, and title colour. Spans the intent registry, so an intent you register lands here too. |
data-rounded | 'none' | 'sm' | 'md' | 'lg' | 'full' | 1:1 with the --hz-radius-* scale. Default md. |
data-dismissible | present when dismissible | Marks the dismissible form. Always stamped so you can target it, though the reference theme ships no rule for it. |
Custom properties
| Hook | Values | Styles |
|---|---|---|
--hz-alert-tint | <percentage> — 10% light, 22% dark | How strongly the intent colour mixes into the surface. Retuning it means re-checking the soft pairings on Contrast & Accessibility. |
--hz-alert-border-width | <length> — default var(--hz-border-width-heavy) | Thickness of the inline-start accent bar. Defaults to the heaviest border-width token; override with any length or a lighter token. |
Part classes
| Hook | Values | Styles |
|---|---|---|
.hz-alert-icon | child element | The intent icon. |
.hz-alert-body | child element | Title and content wrapper. |
.hz-alert-title | child element | The heading, at your headingLevel. |
.hz-alert-content | child element | The message body. |
.hz-alert-dismiss | child element | The dismiss button. |
Accessibility
A statically rendered Alert is plain content: no role, no live region. The optional title names it via aria-labelledby.
For alerts inserted after load, pass role="status" (polite) or role="alert" (assertive, use sparingly) via the rest props. A live role on static content is dead weight, so it's never a default.
The dismiss button is a real labeled <button>. Dismissal is your state change, so consider where focus should land.
There is deliberately no Toast component. A timed self-dismissing overlay is hard to make accessible. Under WCAG 2.2.1 the timing has to be adjustable, extendable, or pausable. A message that vanishes on its own often goes unannounced as well. The library prefers dismissal the reader chooses, so content never disappears out from under them. An inline Alert with role="status" covers the need accessibly.
References: APG Alert pattern · MDN: alert role