Skip to main content
Version: Next

NumberTicker

NumberTicker animates a numeric value from a starting point to a target value with formatting, reduced-motion handling, and imperative playback controls. It wraps the ui-number-ticker custom element from @editora/ui-core.

Import

import { NumberTicker } from '@editora/ui-react';
// or subpath
import { NumberTicker } from '@editora/ui-react/NumberTicker';

Basic Usage

<NumberTicker
value={128420}
from={120000}
duration={1400}
formatStyle="currency"
currency="USD"
size="xl"
/>

KPI Card

<div style={{ display: 'grid', gap: 10 }}>
<div style={{ fontSize: 12, letterSpacing: '0.1em', textTransform: 'uppercase' }}>
Monthly revenue
</div>

<NumberTicker
value={128420}
from={120000}
duration={1400}
formatStyle="currency"
currency="USD"
tone="brand"
size="xl"
/>

<div>Recognized this month</div>
</div>

Signed Delta

<NumberTicker
value={12.4}
from={9.1}
duration={1100}
fractionDigits={1}
prefix="+"
suffix="%"
tone="success"
size="lg"
/>

Compact Usage Metric

<NumberTicker
value={8421}
from={7900}
duration={1200}
notation="compact"
tone="info"
size="lg"
/>

Odometer Style

<NumberTicker
value={128420}
from={120000}
duration={1600}
easing="spring"
animation="odometer"
stagger={20}
formatStyle="currency"
currency="USD"
tone="brand"
size="xl"
/>

Start When Visible

<NumberTicker
value={98.6}
from={92}
duration={1400}
easing="overshoot"
trigger="visible"
visibilityThreshold={0.55}
fractionDigits={1}
suffix="%"
tone="success"
size="xl"
/>

Custom Formatter

<NumberTicker
value={8421}
from={7900}
notation="compact"
animation="odometer"
formatter={(value, context) => `${context.intl} weekly seats`}
/>

Imperative API

const ref = React.useRef<HTMLElement & {
play(): void;
pause(): void;
refresh(): void;
finish(): void;
}>(null);

<>
<button onClick={() => ref.current?.pause()}>Pause</button>
<button onClick={() => ref.current?.play()}>Play</button>
<button onClick={() => ref.current?.refresh()}>Refresh</button>
<button onClick={() => ref.current?.finish()}>Finish</button>

<NumberTicker ref={ref} value={184} from={240} tone="danger" />
</>

Props

NumberTicker

PropTypeDefaultDescription
valuenumber | string0Target number to animate toward
fromnumber | string0Starting number used on first render and refresh()
durationnumber | string1200msAnimation duration. Numeric values are treated as milliseconds
delaynumber | string0msDelay before the ticker starts
easing'linear' | 'ease-in' | 'ease-out' | 'ease-in-out' | 'spring' | 'bounce' | 'overshoot''ease-out'Motion easing curve
animation'interpolate' | 'odometer''interpolate'Standard value interpolation or per-digit rolling presentation
trigger'immediate' | 'visible''immediate'Starts immediately or waits until the ticker is visible
visibilityThresholdnumber | string0.4Intersection ratio required when trigger="visible"
staggernumber | string0msDelay applied between odometer digits
staggerFrom'start' | 'end' | 'center''start'Direction used to calculate digit stagger timing
localestringruntime localeLocale passed to Intl.NumberFormat
formatStyle'decimal' | 'currency''decimal'Number formatting style
currencystring'USD' when currency style is usedISO currency code
currencyDisplay'symbol' | 'narrowSymbol' | 'code' | 'name''symbol'Currency display mode
notation'standard' | 'compact''standard'Standard or compact number notation
compactDisplay'short' | 'long''short'Compact display style
fractionDigitsnumber | stringinferred from the input valueFixed number of decimal places
useGroupingbooleantrueEnables thousands grouping
signDisplay'auto' | 'always' | 'exceptZero' | 'never''auto'Sign rendering behavior
prefixstringLiteral text rendered before the formatted number
suffixstringLiteral text rendered after the formatted number
tone'brand' | 'neutral' | 'info' | 'success' | 'warning' | 'danger''brand'Accent color tone
size'sm' | 'md' | 'lg' | 'xl' | '1' | '2' | '3' | '4''md'Typography scale preset
align'start' | 'center' | 'end' | 'left' | 'right''start'Horizontal alignment
fontSizenumber | stringDirect font-size override
fontWeightnumber | string780Direct font-weight override
letterSpacingnumber | stringpreset valueDirect tracking override
colorstringDirect text color override
tabularbooleantrueKeeps digits width-stable with tabular numerals
monospacebooleanfalseUses a monospace font stack
pausedbooleanfalsePauses the current ticker
pauseOnHoverbooleanfalsePauses while hovered
pauseOnFocusbooleanfalsePauses while focus is inside the component
formatter(value, context) => stringReact-only formatter callback for product-specific final text

Notes

  • refresh() restarts the ticker from from to value.
  • finish() snaps to the final value immediately.
  • Reduced-motion users get the final formatted value without the counting animation.
  • notation="compact" is useful for large KPI surfaces like 8.4K, 2.5M, and similar summaries.
  • animation="odometer" is best for short numbers and high-visibility hero metrics where per-digit motion adds character.
  • trigger="visible" is useful on long dashboards so counters do not finish animating before the user reaches them.