ngx-digit-flow

May 15, 2026 ยท View on GitHub

Individual digit animations for Angular. Each digit has a vertical reel (0-9) that scrolls to the new value when the number changes - slot-machine / odometer style.

Built on Web Animations API + CSS @property. No animation libraries. SSR-safe. Signals-first.

Website: ngx-digit-flow.ayangabryl.com

npm license

Install

npm install ngx-digit-flow

Quick start

Import the standalone component and bind it to a number.

import { Component, signal } from '@angular/core';
import { DigitFlowComponent } from 'ngx-digit-flow';

@Component({
  selector: 'app-price',
  imports: [DigitFlowComponent],
  template: `
    <ngx-digit-flow [value]="price()" [format]="{ style: 'currency', currency: 'USD' }" />
  `,
})
export class PriceComponent {
  price = signal(182.5);
}

AI skill

Install the ngx-digit-flow skill so your AI assistant knows the full API and can wire it into your components:

npx skills add https://github.com/ayangabryl/ngx-digit-flow --skill ngx-digit-flow

Works with Claude Code and any agent that supports the Agent Skills format.

Usage

import { DigitFlowComponent } from 'ngx-digit-flow';

@Component({
  imports: [DigitFlowComponent],
  template: `<ngx-digit-flow
    [value]="price()"
    [format]="{ style: 'currency', currency: 'USD' }"
  />`,
})
export class PriceComponent {
  price = signal(182.5);
}

API

Inputs

InputTypeDefaultDescription
valuenumberrequiredThe number to display and animate
formatIntl.NumberFormatOptions{}Options forwarded to Intl.NumberFormat
localesstring | string[]undefinedBCP 47 locale string(s), including localized digit glyphs
prefixstring''Text prepended before the number
suffixstring''Text appended after the number
animatedbooleantrueSet false to disable all animation
durationnumber900Spin + FLIP animation duration in ms
opacityDurationnumber450Fade duration for appearing/disappearing elements
transformTimingDigitFlowTimingduration + flipEasingFull WAAPI timing for layout/FLIP animations
spinTimingDigitFlowTimingtransformTimingFull WAAPI timing for digit spin animations
opacityTimingDigitFlowTimingopacityDurationFull WAAPI timing for fade animations
spinEasingDigitFlowEasingspringNamed preset (spring, default, overshoot) or CSS easing for digit spin
flipEasingDigitFlowEasingspringNamed preset (spring, default, overshoot) or CSS easing for layout motion
trendnumber | (oldValue, value) => numberautoControls digit path: 1 counts up, -1 counts down, 0 per-digit local, or custom
continuousbooleanfalseVisually ticks through intermediate values by looping unchanged lower-place digits
digitsRecord<number, { max?: number }>{}Configure digit reel ranges by decimal position
respectMotionPreferencebooleantrueDisable animations when the user prefers reduced motion
staggernumber0Delay in ms between entering/exiting presence animations
colorOnIncreasestringundefinedCSS color flashed when value increases
colorOnDecreasestringundefinedCSS color flashed when value decreases

Outputs

OutputPayloadDescription
animationsStartvoidFires when a batch of animations begins
animationsFinishvoidFires when all in-flight animations settle

Examples

Currency

<ngx-digit-flow
  [value]="revenue()"
  [format]="{ style: 'currency', currency: 'USD' }"
  [duration]="600"
/>

Compact notation (K / M / B)

<ngx-digit-flow [value]="views()" [format]="{ notation: 'compact', maximumFractionDigits: 1 }" />

Percentage

<ngx-digit-flow [value]="progress()" [format]="{ style: 'percent', maximumFractionDigits: 1 }" />

Localized digits

<ngx-digit-flow [value]="12345" locales="ar-EG" />

Forced digit path

<ngx-digit-flow [value]="value()" [trend]="-1" />

Score counter

score = signal(0);
<ngx-digit-flow [value]="score()" [duration]="500" />
<button (click)="score.update(v => v - 1)">-</button>
<button (click)="score.update(v => v + 1)">+</button>

Group directive (coordinate related counters)

import { DigitFlowGroupDirective } from 'ngx-digit-flow';
<div ngxDigitFlowGroup>
  <ngx-digit-flow [value]="hours" />
  <span>:</span>
  <ngx-digit-flow [value]="minutes" />
  <span>:</span>
  <ngx-digit-flow [value]="seconds" />
</div>

Use ngxDigitFlowGroup when separate numbers form one visual unit. The directive batches their pre-update snapshots so unchanged siblings can still animate layout shifts caused by another value changing.

Browser support

Requires CSS mod() and @property: Chrome 125+, Safari 15.4+, Firefox 118+.

prefers-reduced-motion is respected automatically - no extra code needed.

Contributing

See CONTRIBUTING.md.

License

MIT - see LICENSE.