Announce strip
A thin announcement strip whose line loops seamlessly; it slides away as you scroll down or dismiss it.
Behaviour
- Two identical halves of the track move by exactly -50% with the Web Animations API: transform only, seamless, no layout reads per frame.
- Copies are added to fill the width (ResizeObserver), so a short line never leaves a gap; a resize carries on from where the line was.
- RTL pages run it the other way.
- Pauses off screen, under the mouse and while the close button has focus; on touch a tap pauses it and another tap resumes.
- Scrolling down 48px past the top slides it up and closes its row so the header takes its place; scrolling up 48px brings it back.
- Screen readers and Tab get the line once; the repeats are inert, and a closed strip is inert.
- Reduced motion: the line stands still and wraps so all of it is readable; the strip fades out without sliding and its row closes once the fade ends.
Props
| Prop | Type | Description |
|---|---|---|
| children | ReactNode | One copy of the line. It is repeated to fill the width, so put the gap (padding) inside. |
| duration | numberdefault 40 | Seconds for one copy of the line to pass; the speed stays the same on every screen width. |
| open | booleandefault true | Shown or put away by the parent; closing slides it up and closes its row. |
| onDismiss | () => void | Adds a close button on the right that calls this. Move focus somewhere sensible in it (e.g. the header nav), since the button goes inert. |
| hideOnScroll | booleandefault true | Put the strip away while scrolling down and bring it back on the way up. |
| container | RefObject<HTMLElement | null>default the page | Follow a scrolling box instead of the page. |
| className | string | Extra classes on the root (default bg-primary text-primary-foreground). |
Installation
npx shadcn@latest add https://purrfectui.com/r/announce-strip.jsonHow to use
import { AnnounceStrip } from "@/components/ui/announce-strip";
const [open, setOpen] = useState(true);
<header className="sticky top-0 z-50">
<AnnounceStrip open={open} onDismiss={() => setOpen(false)}>
<span className="px-4 py-1.5">Built for the Agent Harness Hackathon</span>
</AnnounceStrip>
<nav>...</nav>
</header>Source code
Loading…
Credits
Ported from bountydesk.vaibhav.quest.
License
MIT. Copy it into your project and change it as you like.