Animated Number
Count-up/down number animation with formatting options.
<arc-animated-number>Overview
AnimatedNumber transitions between numeric values using requestAnimationFrame with an ease-out-expo curve, the "counting up" effect seen in dashboards, stat cards, and hero metrics. When the value attribute changes, the component interpolates from the current displayed number to the new target over the specified duration.
The ease-out-expo easing produces a fast start that decelerates toward the target, which draws attention to the final number. Duration defaults to 1000ms. Use 500ms for small increments in real-time dashboards and 2000ms for hero reveals on landing pages.
Formatting is built in: prefix and suffix strings wrap the number (e.g. "$" and "K"), and decimals controls fixed decimal places. The format property switches between number, currency, and percent modes, each powered by Intl.NumberFormat for locale-aware formatting: thousands separators, decimal marks, and grouping all follow the configured locale. The default locale is en-US, but you can pass any BCP 47 tag (e.g. de-DE, ja-JP) for international formatting. The animation respects prefers-reduced-motion by snapping directly to the target value without animation.
Guidelines
When to use
- Use in dashboard stat cards and hero metrics
- Set decimals="2" for currency values and decimals="0" for counts
- Use prefix="$" or suffix="%" for contextual formatting
- Keep duration under 2000ms; longer animations feel sluggish
- Combine with ValueCard or Stat for metric displays
When not to use
- Do not animate more than 4-5 numbers simultaneously; it becomes distracting
- Do not use for rapidly changing real-time values, because the animations queue up and feel laggy
- Do not set duration below 200ms, where the animation becomes imperceptible
- Do not animate between extremely different magnitudes (1 to 1,000,000), where the counting is meaningless
- Do not use for static numbers that never change. Add animation only when values update
Features
- Count-up/down animation using requestAnimationFrame
- Ease-out-expo easing
- Configurable duration
- Prefix and suffix strings for currency, units, and labels
- Fixed decimal place control via decimals attribute
- Intl.NumberFormat-powered formatting with currency, percent, and number modes
- Configurable locale for international number formatting
- Respects `prefers-reduced-motion` by snapping to final value
Preview
Usage
<!-- Revenue counter -->
<arc-animated-number value="12847" prefix="$" duration="1500"></arc-animated-number>
<!-- Percentage with decimals -->
<arc-animated-number value="94.7" suffix="%" decimals="1"></arc-animated-number>
<!-- User count -->
<arc-animated-number value="3200" suffix=" users"></arc-animated-number>import { AnimatedNumber } from '@arclux/arc-ui-react';
function Dashboard({ revenue, percentage, users }) {
return (
<div>
<AnimatedNumber value={revenue} prefix="$" duration={1500} />
<AnimatedNumber value={percentage} suffix="%" decimals={1} />
<AnimatedNumber value={users} suffix=" users" />
</div>
);
}<script setup>
import { ref, onMounted } from 'vue';
import { AnimatedNumber } from '@arclux/arc-ui-vue';
const revenue = ref(0);
onMounted(() => { revenue.value = 12847; });
</script>
<template>
<AnimatedNumber :value="revenue" prefix="$" :duration="1500" />
</template><script>
import { AnimatedNumber } from '@arclux/arc-ui-svelte';
import { onMount } from 'svelte';
let value = 0;
onMount(() => { value = 12847; });
</script>
<AnimatedNumber {value} prefix="$" duration={1500} />import { Component, OnInit } from '@angular/core';
import { AnimatedNumber } from '@arclux/arc-ui-angular';
@Component({
imports: [AnimatedNumber],
template: `<arc-animated-number [value]="revenue" prefix="$" [duration]="1500" />`,
})
export class DashboardComponent implements OnInit {
revenue = 0;
ngOnInit() { this.revenue = 12847; }
}import { AnimatedNumber } from '@arclux/arc-ui-solid';
import { createSignal, onMount } from 'solid-js';
const [revenue, setRevenue] = createSignal(0);
onMount(() => setRevenue(12847));
<AnimatedNumber value={revenue()} prefix="$" duration={1500} />import { AnimatedNumber } from '@arclux/arc-ui-preact';
import { useState, useEffect } from 'preact/hooks';
const [revenue, setRevenue] = useState(0);
useEffect(() => { setRevenue(12847); }, []);
<AnimatedNumber value={revenue} prefix="$" duration={1500} /><!-- Auto-generated by @arclux/prism — do not edit manually -->
<!-- arc-animated-number — requires animated-number.css + tokens.css (or arc-ui.css) -->
<span class="arc-animated-number">
<span class="value"
role="status"
aria-live="polite"
>_format Value</span>
</span><!-- Auto-generated by @arclux/prism — do not edit manually -->
<!-- arc-animated-number — self-contained, no external CSS needed -->
<span class="arc-animated-number" style="display: inline-block; font-family: 'JetBrains Mono', ui-monospace, monospace; font-variant-numeric: tabular-nums">
<span style="white-space: nowrap"
role="status"
aria-live="polite"
>_format Value</span>
</span>API
valuenumber0- Target number to animate to
prefixstring''- String prepended before the number (e.g., "$")
suffixstring''- String appended after the number (e.g., "%")
decimalsnumber0- Number of fixed decimal places
localestring'en-US'- BCP 47 locale tag passed to Intl.NumberFormat for locale-aware number formatting (thousands separators, decimal marks).
durationnumber1000- Animation duration in milliseconds
format'number' | 'currency' | 'percent''number'- Controls how the number is formatted using Intl.NumberFormat. Use currency with a prefix like $ or percent with a suffix like %.