Components / Feedback
AnnouncementBar
A top banner that rotates messages, counts down, and collapses smoothly when dismissed.
Install
npx shadcn@latest add https://irisui.dev/r/announcement-bar.jsonimport { AnnouncementBar } from "@/components/iris/announcement-bar/announcement-bar";Preview
AnnouncementBar
A slim bar for the top of a page that rotates messages, can count down to a deadline, and collapses smoothly when dismissed.
When to use
- Site-wide product news, promotions, and events with a call to action.
- Time-boxed campaigns that need a live countdown ("Ends in 2d 05:59:58").
- Not for problems tied to a section of the page: use
Alert. Not for confirmations of an action: useToast.
Usage
import { AnnouncementBar } from "@/components/iris/announcement-bar/announcement-bar";
h(AnnouncementBar, {
id: "first-month-free",
controls: true,
messages: [
{
id: "pg18",
message: "Postgres 18 is now first class on every plan.",
action: { label: "Read the changelog", href: "/changelog" },
},
{
id: "trial",
message: "Your first month on any plan is free.",
action: { label: "View plans", href: "/pricing" },
countdown: { to: "2026-10-31T23:59:00Z", label: "Ends in" },
},
],
});
Props
| Prop | Type | Default | Description |
|---|---|---|---|
messages |
{ id, message: ReactNode, action?: { label, href?, onClick? }, countdown?: { to, label? } }[] |
— | Required. One or more announcements. |
id |
string |
— | Remembers dismissal in localStorage; change it to show a new campaign again. |
open / defaultOpen / onOpenChange |
boolean / boolean / (open) => void |
— / true / — |
Controlled or uncontrolled visibility. |
index / defaultIndex / onIndexChange |
number / number / (i) => void |
— / 0 / — |
Visible message. |
interval |
number |
6000 |
Milliseconds per message. |
autoPlay |
boolean |
true |
Rotate automatically; pauses on hover, focus, or a hidden tab, and is off under reduced motion. |
controls |
boolean |
false |
Adds previous, next, and a pause ring when there are several messages. |
dismissible |
boolean |
true |
Shows the close button. |
tone |
"neutral" | "inverted" |
"neutral" |
Muted surface, or a high-contrast inverted bar. |
onAction |
(announcement) => void |
— | Called when a call to action is used. |
onCountdownEnd |
(announcement) => void |
— | Called when a message's countdown reaches zero. |
label |
string |
"Announcements" |
Accessible name of the region. |
className |
string |
— | Extra class. |
clearAnnouncementDismissal(id) (Iris.clearAnnouncementDismissal) forgets a dismissal remembered under that id, so the bar shows again on its next mount (for example from a "Show announcements" setting or in tests).
Notes
- Renders a labelled region. The message is
aria-live="polite"only while rotation is stopped (paused, hovered, focused, or a single message), so auto-rotation never chatters. Controls are labelled "Previous announcement", "Next announcement", and pause/play. - Each new message rises in while the bar springs to its height; dismissing collapses the height so the page eases up.
- Reads
--hover/--ink(neutral) or--ink/--page(inverted),--line,--ink-2,--text-sm,--tracking-body.