Alert Banner
FreeDismissible alert banners in 5 semantic variants and multiple display styles.
</>sv-alert-banner alertbannerfeedback
import { SvAlertBannerComponent } from '@styloviz/alert-banner';Demo & usage
Basic usage
Usage example — open the gallery for the full interactive demo.
An interactive demo for this component lives in the gallery.
Open live demoMore examples
With actions
example.htmlAngular
8 lines
<!-- No autoDismissMs here, and it would be ignored if there were: a banner with actions must not remove itself while the user is aiming at one of them. Same for variant="danger". --> <sv-alert-banner variant="success" message="Changes published." [actions]="bannerActions" (actionClick)="onAction($event)" />
Auto-dismiss, where it is allowed
example.htmlAngular
7 lines
<!-- Allowed: no actions, and not a danger banner. The countdown pauses while the pointer or the keyboard focus is over the banner (WCAG 2.2.1). --> <sv-alert-banner variant="success" message="Saved." [autoDismissMs]="5000" />
Two pinned banners that do not know about each other
example.htmlAngular
22 lines
<!-- The shell renders one, the route renders the other. They used to get byte-identical "fixed top-0 left-0 right-0 z-50" and paint on top of each other, so one was simply never seen. Now the higher priority takes the edge and the other is stacked below it. --> <sv-alert-banner position="top-fixed" [priority]="10" variant="danger" message="Read-only until 21:00 UTC" /> <sv-alert-banner position="top-fixed" variant="info" message="Your trial ends in 3 days" /> <!-- And two copies of the SAME notice are one notice: the later registration renders nothing. Give it a key when the wording differs but the subject does not. --> <sv-alert-banner position="top-fixed" dedupeKey="maintenance" message="Maintenance in progress" />
Announcement bar (full-bleed top strip)
alertStyle="announcement" with position="top-fixed" renders a centered, edge-to-edge promo bar with an inline CTA and dismiss.
example.htmlAngular
7 lines
<sv-alert-banner alertStyle="announcement" position="top-fixed" variant="info" title="New:" message="Styloviz 2.0 is here." [actions]="[{ id: 'learn', label: 'Learn more' }]" />
When to use
- Communicating a persistent, page-level status or message (info, success, warning, error).
- You need an inline banner the user can act on or dismiss.
- For transient confirmations, use a Toast; for blocking decisions, a Confirm Dialog.
Async states
None — this component has nothing to load, so it has no loading, empty or error state to drive.
Inputs
| Name | Type | Default | Description |
|---|---|---|---|
| title | string | '' | Bold heading line. Leave empty to render body-only. |
| message | string | '' | Main alert message text. |
| variant | AlertVariant | 'info' | Semantic color. |
| alertStyle | AlertStyle | 'soft' | Visual treatment. |
| size | AlertSize | 'md' | Size controls padding and text scale. |
| position | AlertPosition | 'inline' | Positioning mode. - `inline` — block element in document flow (default) - `top-fixed` — fixed to viewport top, full width - `bottom-fixed` — fixed to viewport bottom, full width - `top-sticky` — sticky inside its scroll container |
| showIcon | boolean | true | Show the leading icon. |
| icon | string | '' | Icon-library NAME overriding the default variant icon — e.g. `'bell'`. Leave empty to use the built-in icon for the current variant. BREAKING (icon sweep): was `iconPath`, a raw `<path d="…">`. `iconViewBox` is GONE — it only existed because a raw path might not be 24-box. |
| actions | AlertAction[] | [] | Up to 2 action buttons rendered inline. Each button emits its `id` via `actionClick`. |
| dismissible | boolean | true | Show the × close button. |
| autoDismissMs | number | 0 | Auto-dismiss after N milliseconds. Set to 0 to disable auto-dismiss. |
| priority | number | 0 | Stack weight for a pinned banner: higher sits against the edge. |
| dedupeKey | string | null | undefined | undefined | Identity for suppressing a duplicate pinned banner. | Value | Meaning | |-----------|------------------------------------------------------------| | omitted | derive from variant + style + title + message | | a string | suppress on that, whatever the text | | `null` | never suppress | A SUPPRESSED BANNER RENDERS NOTHING — no count, unlike a deduplicated toast. A toast reports an EVENT, so "it happened eleven times" is information; a banner reports a STATE, and "your trial expires ×2" is not a thing that can be true. |
| customClass | string | '' | Additional CSS classes merged on the root element. |
Outputs
| Event | Payload type | Description |
|---|---|---|
| dismissed | void | Emitted after the alert finishes its close animation. |
| actionClick | string | Emitted when an action button is clicked, carrying the action `id`. |
Customization & theming
- Five semantic variants.
- Soft, solid and bordered styles.
- Optional icon and action buttons.
- Priority stacking for pinned banners: `[priority]` decides which gets the edge and the rest are offset by the measured height of the ones above them — `top` for a top-pinned banner, `bottom` for a bottom-pinned one, and `top-sticky` is a stack of its own because it scrolls with its container. Coordinated through a root service, because the banners on a page do not share a parent.
- Duplicate suppression: a pinned banner identical to one already on screen renders nothing. Key it with `dedupeKey`, or `null` to opt out.
- Auto-dismiss is REFUSED for a `danger` banner and for any banner with `actions`: a state the user has to know about does not stop being true after a few seconds, and a control cannot be used if it disappears while being aimed at. Everything else keeps its countdown, paused while the pointer is over it OR focus is inside it. The rule, stated: only a short, informational message the user needs to do nothing about may time out. The component enforces it three ways — the countdown is refused when projected content holds a link, button or field (not only for `actions`), and it is never shorter than the text takes to read (`readingTimeMs`: title + message length × `SV_ALERT_READING_MS_PER_CHAR`, 60 ms per character), so `effectiveAutoDismissMs` reports what actually runs.
- A full-bleed `announcement` style: a centered, gradient top bar with an inline CTA and dismiss — pair with `position="top-fixed"`.
Best practices
- Do: Match `variant` to severity so color reinforces the message.
- Do: Keep the message actionable — say what happened and what to do next.
- Don't: Don't auto-dismiss errors the user must read and act on.
- Do: Set `priority` when two pinned banners can be on screen at once — higher takes the edge and the rest stack below it, in registration order among equals. Without it two `top-fixed` banners painted on top of each other and one was never seen.
- Tip: A pinned banner whose variant, style, title and message match one already on screen renders nothing; `dedupeKey` keys that on a subject instead of the wording, and `[dedupeKey]="null"` opts out. Inline banners are never suppressed — two identical ones are usually feedback about two different fields.
Accessibility
- Announces through the kit's single live region (`SvLiveAnnouncer`), assertively for `danger` and politely for everything else — including `warning`, because `assertive` cuts a screen reader off mid-word and a warning you are not blocked by does not earn that.
- ⚠️ The banner itself is NO LONGER a live region. It used to carry `aria-live` and `role="alert"` on its own root, which means the region was inserted complete, with its text already inside it — the arrangement assistive technology is least likely to announce, because AT watches an EXISTING region for changes. The visible root keeps `role="status"` so you can still find it and reach its actions.
- The same message is not repeated when the host re-renders the banner, which is what the shared announcer's deduplication is for.
- Dismiss control is a labelled button, the auto-dismiss timer pauses on hover/focus (WCAG 2.2.1), and dismissing with the close button leaves focus in the region the banner was removed from rather than on `<body>`.
Feedback on Alert Banner
Spotted a gap in this page, or something that didn't work as described? Comments are GitHub Discussions in the public styloviz/community repo, so posting needs a GitHub account.