KQ-1856 · PACE/BOARD

Pace Board

A display that swaps one value for the next with real motion: the new value arrives fast from the side on a spring between flick and recoil set by its overshoot, runs past its rest and on the way back is caught like a detent — locked, with a short judder — while the old one accelerates away stretching from its trailing edge. Both carry a horizontal motion blur in proportion to their own speed, an SVG blur in x only that is switched off at rest, so the faster a value moves the more it smears. Values cycle from a list or follow a live number, optionally swapping only the characters that changed; a cycling board pauses on hover, and with keyboard focus Space pauses and resumes it while Left, Right, Home and End step through it.

KQ-1856 · PACE/BOARD

Gaugeworks · Ride telemetry

Built for teamsSpace pauses or resumes; Left and Right step through.

1,284 riders on course right now

teams · 1 of 4 · every 2.4 s

Install

One command — the source lands in your repo. Or copy it from the Code tab.

$ pnpm dlx shadcn@latest add @kinetiq/pace-board

Props

values
readonly string[]
default —
Words to cycle through, one at a time.
value
string | number
default —
A live value: every change swaps it in; numbers go through `format`. Wins over `values`.
format
(value: number) => string
default grouped thousands
Formats a number `value`.
index / defaultIndex
number
default 0
The shown entry of `values`, controlled or not.
onIndexChange
(index: number) => void
default —
Fires from the timer, key or click that moved it, with the new index.
interval
number
default 2400
Time each entry holds before the next swaps in, ms.
blur
number
default 0.6
Motion-blur strength, 0 (none) to 1 (a heavy smear at speed).
overshoot
number
default 0.5
How far a new value runs past its rest before it locks, and how hard it judders, 0 to 1.
speed
number
default 1
Spring speed, 0.5 (unhurried) to 2 (snappy).
travel
number
default 0.9
How far a new value comes from, in widths of its window.
from
"right" | "left" | "auto"
default "right"
The side new values arrive from; auto brings rising numbers from the right and falling ones from the left. Stepping back reverses it.
swap
"word" | "chars"
default "word"
Swap the whole value, or only the characters that changed, each in its own window.
stagger
number
default 28
Time between characters in chars mode, ms, starting on the side the motion comes from.
trigger
"mount" | "inView" | "manual"
default "inView"
When `values` start cycling: at mount, the first time it is seen, or never (keys, clicks and `index` only).
paused
boolean
default false
Stop cycling; live values still swap.
onPausedChange
(paused: boolean) => void
default —
Fires when Space pauses or resumes the cycle.
progress
boolean
default false
Draw a hairline under the value that fills until the next swap.
reserve
string
default —
A sample whose width is always kept, so a growing number never shifts the layout.
align
"start" | "center" | "end"
default "start"
Where the value sits in its kept width.
as
React.ElementType
default "span"
The element to render.
label
string
default —
Read before the value by assistive technology; names a cycling board.
live
"off" | "polite"
default "off"
Announce each new value politely; off by default so a cycling board never chatters.
onSwap
(text: string) => void
default —
Fires as a swap starts, with the new text.
className
string
default —
Font size, weight and colour inherit; style it like text.