Announcement Banner
A dismissible one-line announcement — the full-width inverse page-top band.
- Status
- Since
0.3.0- Accessibility pattern
- ARIA status region (opt-in)
Last updated
Install
Add Announcement Banner from the VegaStack registry. The CLI verifies the item's integrity hash before writing it.
pnpm dlx shadcn@latest add @vegastack/announcement-bannerThe same command installs the registry items it composes: @vegastack/icon-button.
Usage
<AnnouncementBanner dismissable action={<a href="/changelog">Read more</a>}>
Workflows now orchestrate revenue agents.
</AnnouncementBanner>When to use
AnnouncementBanner is the one full-width inverse strip that spans the top of a page (foreground
fill, on-background text, centered copy). For an in-content notice or a plan/trial row, use
Alert with variant="strip" — a compact single-line ribbon with an
icon, message, and action — rather than a second banner component.
Live announcements
A page-top band that exists at load is chrome, so it carries no live role — announcing it would
compete with the page's own heading for the first thing a screen reader user hears. Pass live
only for a banner that mounts (or re-words) after the page has settled; it then becomes a polite
role="status" region.
Examples
Dismissal
Uncontrolled by default (the banner removes itself). Pass onDismiss to own it — persist the
choice and stop rendering; the button then only notifies.
API Reference
| Prop | Type | Default | Description |
|---|---|---|---|
action | React.ReactNode | — | Action slot rendered after the message (a link or small Button). |
dismissable | boolean | false | Show the dismiss button; the banner removes itself unless onDismiss is
given (controlled dismissal — persist it and stop rendering the banner). |
dismissLabel | string | 'Dismiss announcement' | Accessible name for the dismiss control. |
live | boolean | false | Mark this strip as a runtime announcement — mounted (or re-worded) after the page settled.
Only then does it become a polite role="status" live region. The default is deliberately NO
live role: a page-top band that is in the DOM at load is chrome, and announcing it competes
with the page's own heading for the first thing a screen reader user hears (D23). |
onDismiss | (() => void) | — | Called when dismissal is controlled by the host. |
Data attributes and CSS variables on AnnouncementBanner
| Attribute | Values |
|---|---|
data-live | "" |
data-slot | "announcement-banner" | "announcement-banner-action" | "announcement-banner-dismiss" |
Accessibility
- The banner carries no live role at load. With
liveit is a polite status region, so keep its message brief and avoid continuously changing content. - The dismiss control has a caller-overridable accessible name and a minimum 24px hit area.
- A composed action must keep visible link or button text; dismissal is never the only way to continue.
| Key | Action |
|---|---|
| Tab | Move to the optional action and dismiss control. |
| Enter / Space | Activate the focused button. |
| Contract | States tested |
|---|---|
| Behaviour | default, open |
| Accessibility | labeled, status-announcement, semantic-html |
| Visual | default, hover |