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

PropTypeDescription
childrenReactNodeOne copy of the line. It is repeated to fill the width, so put the gap (padding) inside.
durationnumberdefault 40Seconds for one copy of the line to pass; the speed stays the same on every screen width.
openbooleandefault trueShown or put away by the parent; closing slides it up and closes its row.
onDismiss() => voidAdds 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.
hideOnScrollbooleandefault truePut the strip away while scrolling down and bring it back on the way up.
containerRefObject<HTMLElement | null>default the pageFollow a scrolling box instead of the page.
classNamestringExtra classes on the root (default bg-primary text-primary-foreground).

Installation

npx shadcn@latest add https://purrfectui.com/r/announce-strip.json

How 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.

0