Change Highlight

Flashes a live price, count or status once when it changes and keeps an up/down marker, so updates aren't missed.

StopsPrice changed and nobody noticed

Installation

pnpm dlx shadcn@latest add https://bollard-ui.vercel.app/r/change-highlight.json

The files land in your project. They're yours to edit.

Usage

change-highlight-usage.tsx
import { ChangeHighlight, type ChangeValue } from "@/components/ui/change-highlight"

<ChangeHighlight value={at(prices)} format={(v: ChangeValue) => inr.format(Number(v))} announce className="font-medium" />

What it catches

  • Silent live updates to numbers and statuses
  • Whether a move is good or bad, given the direction you mark as good
  • Changes since the last visit, when storageKey is set

Props

ChangeHighlight props
PropTypeDefault
value* (required)

The live value. Numbers get a direction; strings are shown as "changed".

ChangeValue—
format

Formats a value for display, e.g. as currency.

(value: ChangeValue) => stringString
goodDirection

Which way is good news: "up" (default, ▲ green), "down" (▼ green, e.g. latency) or "none".

"up" | "down" | "none""up"
holdMs

How long the arrow and tint stay after a change, in ms.

number3000
storageKey

Turns on "changed since your last visit": the last value you saw is kept in localStorage under this key.

string—
announce

Announce changes to screen readers (politely). Off by default so busy tables don't chatter.

booleanfalse
previousLabel

Templates: `{value}` is filled in.

string"Was {value}"
sinceVisitLabel

Text introducing changes since the last visit.

string"was {value} at your last visit"
dismissLabel

Accessible label for the dismiss button.

string"Mark as seen"
upLabel

Word for an increase.

string"up"
downLabel

Word for a decrease.

string"down"
changedLabel

Word for a non-numeric change.

string"changed"

* required. Also accepts the native props of <span> (className, aria-*, data-*…), passed through to it.

Accessibility

  • Flashes at most once a second and not at all with prefers-reduced-motion
  • Direction is given in words as well as ▲/▼ glyphs and colour
  • The changed value is focusable and described by a role="tooltip" showing the previous value
  • Optional aria-live="polite" announcement (announce prop); dismiss button has an aria-label

Only what the source does. Test with your own screen reader and content before shipping.

Limitations

  • "Since your last visit" is stored in this browser's localStorage, so it doesn't follow the user across devices
  • Screen readers hear changes only when announce is on

Rules

Rules last verified:

Informational. One flash per second stays under the three-flashes-per-second limit. Copied components don't update themselves, so re-check after rule changes (see updating a component).

What it stops

Price changed and nobody noticed

Also known as

live updates · flash · price change · ticker · dashboard · realtime · stock price · crypto

Field type

Dependencies

Pairs well with