# Announcement Bars

> Five site-wide announcement bars — a rotating one-liner, an action card, a volt bar with email capture, a floating pill and a launch countdown with flipping digits — that slide in and collapse with a height spring when dismissed.

- Collection: Blocks
- Tier: pro
- Docs: https://geturui.com/docs/announcement-bars
- Install: `npx shadcn@latest add @geturui-pro/announcement-bars`
- Dependencies: motion, lucide-react

## Variants

### Slim

One line with a tag and link. Several messages rotate with a blurred crossfade, a progress hairline and previous / next buttons.

Install: `npx shadcn@latest add @geturui-pro/announcement-bars-slim`

| Prop | Type | Default | Description |
|---|---|---|---|
| messages | `{ tag?; text; href?; linkLabel? }[]` | — | One or more messages. |
| interval | `number` | 6000 | Milliseconds per message when rotating. |
| dismissible | `boolean` | true | Shows the dismiss button. |
| open / defaultOpen | `boolean` | true | Shown (controlled / uncontrolled). |
| onOpenChange | `(open: boolean) => void` | — | Called with false when dismissed. |
| className | `string` | — | Classes for the outer element. |

### With actions

Title, supporting line, secondary and primary buttons and a dismiss, as a contained card or full width; stacks on narrow screens.

Install: `npx shadcn@latest add @geturui-pro/announcement-bars-actions`

```tsx
import { AnnouncementActions } from "@/components/blocks/announcement-bars/actions";

<AnnouncementActions title="Usage-based billing is in beta" onPrimary={() => router.push("/billing")} width="full" />
```

| Prop | Type | Default | Description |
|---|---|---|---|
| title / description | `string` | — | Bold lead and supporting text. |
| icon | `ReactNode` | — | Replaces the sparkle tile. |
| primaryLabel / onPrimary | `string / () => void` | — | Primary action. |
| secondaryLabel / onSecondary | `string / () => void` | — | Secondary action; empty string hides it. |
| width | `"contained" | "full"` | "contained" | Rounded card inside the page width, or edge to edge. |
| open / defaultOpen | `boolean` | true | Shown (controlled / uncontrolled). |
| onOpenChange | `(open: boolean) => void` | — | Called with false when dismissed. |
| className | `string` | — | Classes for the outer element. |

### Brand

Full-width volt bar with inline email capture that validates, shows a spinner and swaps to a confirmation with a blur.

Install: `npx shadcn@latest add @geturui-pro/announcement-bars-brand`

```tsx
import { AnnouncementBrand } from "@/components/blocks/announcement-bars/brand";

<AnnouncementBrand onSubmit={async (email) => { await fetch("/api/launch-list", { method: "POST", body: JSON.stringify({ email }) }); }} />
```

| Prop | Type | Default | Description |
|---|---|---|---|
| title / description | `string` | — | Message copy. |
| placeholder / submitLabel | `string` | — | Field placeholder and button label. |
| onSubmit | `(email: string) => void | Promise<void>` | — | Resolve to confirm; throw an Error to show its message. |
| open / defaultOpen | `boolean` | true | Shown (controlled / uncontrolled). |
| onOpenChange | `(open: boolean) => void` | — | Called with false when dismissed. |
| className | `string` | — | Classes for the outer element. |

### Floating pill

A glass pill pinned to the bottom of the screen that springs up after a delay and drops away with a blur when dismissed.

Install: `npx shadcn@latest add @geturui-pro/announcement-bars-floating`

```tsx
import { AnnouncementFloating } from "@/components/blocks/announcement-bars/floating";

<AnnouncementFloating tag="v3.2" text="Sidebars and legal pages are live." href="/changelog" />
```

| Prop | Type | Default | Description |
|---|---|---|---|
| tag / text / linkLabel / href | `string` | — | Chip, message and link. |
| onLinkClick | `() => void` | — | Called when the link is used. |
| placement | `"fixed" | "absolute"` | "fixed" | Pin to the viewport or to the nearest positioned parent. |
| delay | `number` | 400 | Milliseconds before it rises in. |
| open / defaultOpen | `boolean` | true | Shown (controlled / uncontrolled). |
| onOpenChange | `(open: boolean) => void` | — | Called with false when dismissed. |
| className | `string` | — | Classes for the outer element. |

### Countdown

Launch bar with days, hours, minutes and seconds that flip on springs, a reminder toggle and a live state at zero. Time is only read in effects.

Install: `npx shadcn@latest add @geturui-pro/announcement-bars-countdown`

```tsx
import { AnnouncementCountdown } from "@/components/blocks/announcement-bars/countdown";

<AnnouncementCountdown title="Launch week starts in" target="2026-11-02T16:00:00Z" tone="brand" />
```

| Prop | Type | Default | Description |
|---|---|---|---|
| title | `string` | — | Lead text before the timer. |
| target | `string | number` | — | ISO date or epoch ms to count down to. |
| seconds | `number` | 200478 | Counts down from mount when no target is given. |
| reminderLabel / onReminderChange | `string / (on: boolean) => void` | — | Reminder toggle (aria-pressed). |
| liveLabel / liveHref | `string` | — | Link shown once the timer hits zero. |
| tone | `"default" | "brand"` | "default" | Brand tints the header volt with a faint grid and glow. |
| open / defaultOpen | `boolean` | true | Shown (controlled / uncontrolled). |
| onOpenChange | `(open: boolean) => void` | — | Called with false when dismissed. |
| className | `string` | — | Classes for the outer element. |

## Accessibility

- Every bar is a labelled region with a real dismiss button ("Dismiss announcement").
- The rotator pauses on hover and focus, stops under reduced motion and only announces messages the user steps to.
- Email capture has a hidden label, aria-invalid and an alert for errors; the countdown is a role=timer with a minute-level label.
- Height, slide and digit springs become fades under reduced motion.

## Source

Pro item — send `Authorization: Bearer <registry token>` to include the source.
