crucıble

Ledger

The atomic KPI stat card, animated in three beats: the value rolls up on odometer digit drums, the sparkline scores itself in, and the delta badge stamps down last with one crisp X-flip. Live updates re-roll only the digits that changed — a meter, not a poster.

motionfree

Installation

CLI

npx shadcn@latest add @crucible/ledger

Manual — install dependencies, then copy the source

npm install motion

Props

PropTypeDefaultDescription
labelstringKPI label rendered above the value, e.g. "Monthly revenue".
valuenumberThe metric. Changing it after the initial choreography is a live update: only the digits that changed re-roll (unchanged drums hold still), the badge re-stamps with a short tick, and no full re-choreography runs.
formatLedgerFormat"number"How the value is formatted. percent follows Intl: pass 0.246 for "24.6%".
currencystring"USD"ISO 4217 currency code used when format is currency.
localestring"en-US"BCP 47 locale for all number formatting.
decimalsnumber0 (number), 2 (currency), 1 (percent)Decimal places on the value.
deltanumberChange figure shown in the badge (percent points, e.g. 12.4 → "▴ 12.4%"). Omit for no badge.
deltaDirectionLedgerDirectionBadge direction override; inferred from the sign of delta when omitted.
deltaDecimalsnumber1Decimal places on the delta figure.
sparklinenumber[]Trend points for the sparkline, any numeric range. Omit for no sparkline. New arrays swap in without redrawing.
sparklinePropsOmit<ScriberProps, "data">Advanced pass-through to the underlying Scriber (variant, colors, strokeWidth…).
triggerLedgerTrigger"in-view"What starts the three-beat choreography: entering the viewport, mounting, or the first value change.
delaynumber0Seconds the whole choreography is shifted by — set delay={i * 0.15} across a row of ledgers to sequence a metrics strip.
staggernumber0.75Seconds between beat starts (value → sparkline → badge).
valueDurationnumber1.4Seconds the value takes to roll up (beat one).
sparklineDurationnumber1.2Seconds the sparkline takes to draw (beat two).
badgeDurationnumber0.5Seconds the badge flip takes to land (beat three).
sizeLedgerSize"md"Overall scale of the card.
colorsLedgerColorsDelta badge hues — the only color on the card.
pausedbooleanfalseRender the finished card with no animation at all.
Also accepts all props of Omit<React.ComponentPropsWithoutRef<"div">, "children">they pass through to the underlying element.

Honors prefers-reduced-motion with a designed static fallback, and passes className through.