Ticker
A news ticker for React: a band of short items that scrolls across the top of a screen without end, stops when pointed at, and stands still for reduced motion.
Install
# once per project: where @zzzui items come frompnpm dlx shadcn@latest registry add @zzzui=https://zzzui.catforest.dev/r/{name}.jsonpnpm dlx shadcn@latest add @zzzui/tickerExamples
Notices on a harbour board
- Live
- Ferry Lumen leaves pier 306:40
- Crane B back in service+2
- Fog over the outer mole40 m
- Night shift signs off18
- Berth 9 cleared for the Ostra07:15
import { Ticker, TickerItem, TickerLive, TickerValue,} from "@/components/zero/ticker";const notices = [ { line: "Ferry Lumen leaves pier 3", value: "06:40" }, { line: "Crane B back in service", value: "+2" }, { line: "Fog over the outer mole", value: "40 m" }, { line: "Night shift signs off", value: "18" }, { line: "Berth 9 cleared for the Ostra", value: "07:15" },];export default function TickerHarbour() { return ( <Ticker aria-label="Harbour notices" duration={40} className="w-full"> <TickerLive /> {notices.map((notice) => ( <TickerItem key={notice.line}> {notice.line} <TickerValue>{notice.value}</TickerValue> </TickerItem> ))} </Ticker> );}Behaviour
The items are written twice and the row is moved by half its width, so the loop has no seam. The second copy is aria-hidden and inert: screen readers hear each item once, and Tab does not visit it twice.
It stops while the pointer is over it or focus is inside, so a link in an item can be read and followed. Under reduced motion it does not move at all; the band scrolls sideways by hand instead. duration is one full pass in seconds: give a longer list more time, so it reads at the same speed.
Name it with aria-label; it is a section, so it shows up among the page's landmarks.
Props
Ticker
| Prop | Type | Default | Description |
|---|---|---|---|
| duration | number | 80 | Seconds for one full pass. |
| aria-label | string | — | What the band carries. |
TickerItem / TickerValue / TickerLive
| Prop | Type | Default | Description |
|---|---|---|---|
| children | ReactNode | TickerLive: "Live" | An item's line (links inside are styled), the value after it, or the live mark's word. |