Charts & metrics
Animated Number Morph
Independent column digit rolling physics for metrics and financial dashboards
detent-animated-number
Port status
- Catalog status
- implemented
- Origin
- upstream
- Phase
- 4
- Wave
- phase-4-cinematic
- Group
- Charts & metrics
5.0 KB gzip for the class module · inlines the shared spring
Variants
Each digit is its own ten-row column, so only the columns whose digit changes roll and the number never jitters
sideways; 12,450 groups automatically and the compact line abbreviates to 1.2M. The whole
string is announced once through aria-label, and the columns are hidden from assistive technology. Move
the slider to write the documented value property; with prefers-reduced-motion: reduce the
new value appears immediately.
The component dispatches no events; this demo reports its own property writes.
Recorded states
reduced motionrecorded state; no settercompletedrecorded state; no setter
Usage
Import
import '/components/animated-number/define.js';
// or register it yourself
import { DetentAnimatedNumber } from '/components/animated-number/animated-number.js';
Attributes
compactdampingdecimalsmassprefixstiffnesssuffixuse-groupingvalue
Properties
No properties are recorded for this component.
Slots
No slots are recorded for this component.
Events
No events are recorded for this component.
Example
Runnable example: site/examples/animated-number.ts. The snippet below is generated from the catalogued attributes.
<detent-animated-number
compact
damping="22"
decimals="0"
mass="0.6"
prefix=""
stiffness="170"
suffix=""
use-grouping
value="0"
></detent-animated-number>
Source
The pinned upstream source for this row:
src/components/ui/AnimatedNumber.tsxsha256 d85afdf7095a…
Native files
The native module and its artifacts:
src/components/animated-number/animated-number.tssrc/components/animated-number/styles.csssrc/components/animated-number/define.tsdocs/components/animated-number.mdsite/examples/animated-number.tstests/browser/animated-number.spec.tsevidence/components/animated-number.md
API
Boolean attributes follow HTML presence semantics: present means true, absent means false, and disabled="false" still means disabled.
Attributes
| Attribute | Property | Type | Default | Notes |
|---|---|---|---|---|
compact | compact | boolean | false | Presence semantics: present means true, absent means false. |
damping | damping | number | 22 | Kebab-case attribute; camelCase property. |
decimals | decimals | number | 0 | Kebab-case attribute; camelCase property. |
mass | mass | number | 0.6 | Kebab-case attribute; camelCase property. |
prefix | prefix | string | '' | Kebab-case attribute; camelCase property. |
stiffness | stiffness | number | 170 | Kebab-case attribute; camelCase property. |
suffix | suffix | string | '' | Kebab-case attribute; camelCase property. |
use-grouping | useGrouping | boolean | true | Presence semantics: present means true, absent means false. |
value | value | number | 0 | Kebab-case attribute; camelCase property. |
Properties
No property-only values are recorded for this component.
Events
No custom events are recorded for this component.
Slots
No slots are recorded for this component.
CSS customisation
- Framer Motion springs/AnimatePresence ported to CSS transitions, WAAPI or the shared rAF spring helper.
- React state/hooks replaced by element-owned state with pre-upgrade property preservation.
- Controlled/uncontrolled React pair maps to initial-value attributes plus owned state and change events.
- Colour defaults to the page text token instead of the hard-coded #FAFAFA (about 1.05:1 on white), with --detent-animated-number-color as the knob.
- The accessible name lives on role=img with prefix, suffix and digits aria-hidden; upstream labelled a bare span.
- mass is pinned to the top-level source default 0.6 (the inner DigitColumn default 0.8 never applies because the parent always passes mass).
- The locale stays en-US because the row records no locale prop.
- A digit column is replaced only when its kind changes (digit to separator), mirroring upstream key={index-kind}.
- useGrouping (default true) is reflected and the property is the opt-out; use-grouping="false" resolves to true (PC-3.2).
- prefix shadows the getter-only Element.prefix, so a pre-upgrade prefix assignment is not preserved; use the attribute.
What it does
A number whose digits roll into place in fixed-width columns, with thousands separators. Formatting supports compact notation (1.2M) and fixed decimals.
Upstream behaviour
- Independent digit column spring animation preventing layout jitter
- Automatic thousand grouping (e.g. 12,450) and fixed decimal formatting
- Compact notation support for large values (1.2M, 45K)
- Configurable prefixes, suffixes, and spring stiffness parameters
- Full accessibility with aria-label text narration
Differences from upstream
- Framer Motion springs/AnimatePresence ported to CSS transitions, WAAPI or the shared rAF spring helper.
- React state/hooks replaced by element-owned state with pre-upgrade property preservation.
- Controlled/uncontrolled React pair maps to initial-value attributes plus owned state and change events.
- Colour defaults to the page text token instead of the hard-coded #FAFAFA (about 1.05:1 on white), with --detent-animated-number-color as the knob.
- The accessible name lives on role=img with prefix, suffix and digits aria-hidden; upstream labelled a bare span.
- mass is pinned to the top-level source default 0.6 (the inner DigitColumn default 0.8 never applies because the parent always passes mass).
- The locale stays en-US because the row records no locale prop.
- A digit column is replaced only when its kind changes (digit to separator), mirroring upstream key={index-kind}.
- useGrouping (default true) is reflected and the property is the opt-out; use-grouping="false" resolves to true (PC-3.2).
- prefix shadows the getter-only Element.prefix, so a pre-upgrade prefix assignment is not preserved; use the attribute.