@ngstarter-ui/components 21.0.11 → 21.0.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3,7 +3,7 @@
3
3
  "generatedBy": "scripts/generate-ai-metadata.mjs",
4
4
  "package": "@ngstarter-ui/components",
5
5
  "description": "AI-readable registry for NgStarter UI Angular secondary entry points.",
6
- "componentCount": 121,
6
+ "componentCount": 122,
7
7
  "conventions": {
8
8
  "importPattern": "@ngstarter-ui/components/<component>",
9
9
  "selectorPrefix": "ngs",
@@ -93,10 +93,11 @@
93
93
  "Do not make ordinary table rows, labels, descriptions, sidebar items, or status text bold to imitate a screenshot."
94
94
  ],
95
95
  "styling": {
96
- "template": "Use TailwindCSS utility classes for layout, responsive behavior, sizing, spacing, flex, grid, alignment, and routine margins/padding such as mt-10 and p-6 instead of custom margin-top: 2.5rem and padding: 1.5rem in SCSS.",
96
+ "template": "Treat TailwindCSS utility classes in templates as the primary styling surface for layout, responsive behavior, sizing, spacing, flex, grid, alignment, and routine margins/padding such as mt-10 and p-6 instead of custom margin-top: 2.5rem and padding: 1.5rem in SCSS.",
97
97
  "localScss": [
98
98
  "Start local SCSS files that use Tailwind tokens with @reference 'tailwindcss';",
99
99
  "Use --spacing(N) for spacing values in local SCSS.",
100
+ "Use local SCSS for CSS custom property/token overrides, especially --ngs-* component variables, and necessary component selector overrides. Do not move routine layout, spacing, sizing, flex/grid, or alignment styling from templates into SCSS.",
100
101
  "Override NgStarter components through component or directive selectors such as ngs-card, ngs-navigation, ngs-form-field, table[ngs-table], button[ngsButton], and button[ngsIconButton]."
101
102
  ],
102
103
  "globalStyles": "Use CSS custom properties and theme tokens, especially --ngs-* variables, for global visual customization."
@@ -3426,6 +3427,109 @@
3426
3427
  ],
3427
3428
  "example": "inject(Dialog).open(MyDialogComponent, { data })"
3428
3429
  },
3430
+ {
3431
+ "name": "digit-roller",
3432
+ "title": "Digit Roller",
3433
+ "overviewName": "Digit Roller",
3434
+ "category": "components",
3435
+ "package": "@ngstarter-ui/components",
3436
+ "importPath": "@ngstarter-ui/components/digit-roller",
3437
+ "publicApi": "projects/components/digit-roller/public-api.ts",
3438
+ "sourceRoot": "projects/components/digit-roller/src",
3439
+ "docsPath": "/components/digit-roller",
3440
+ "docsOverviewSource": "projects/docs/src/app/components/digit-roller/overview/overview.html",
3441
+ "purpose": "The NgStarter Angular Digit Roller component animates individual digits in formatted numbers with a slot-machine style reel effect.",
3442
+ "useWhen": "Choose Digit Roller when the workflow matches examples such as Number Sizes, Social Actions, Progress Bar, Gauge, Digit roller dashboard.",
3443
+ "exampleTopics": [
3444
+ "Number Sizes",
3445
+ "Social Actions",
3446
+ "Progress Bar",
3447
+ "Gauge",
3448
+ "Digit roller dashboard",
3449
+ "Digit roller social actions",
3450
+ "Digit roller progress bar",
3451
+ "Digit roller gauge"
3452
+ ],
3453
+ "minimalExample": "<div class=\"grid gap-4\" ngsDigitRollerGroup>\n @for (example of examples; track example.label) {\n <div class=\"grid gap-4 rounded-lg border border-neutral-200 bg-white p-5 md:grid-cols-[160px_minmax(0,1fr)] md:items-center\">\n <div>\n <p class=\"font-medium text-neutral-900\">{{ example.label }}</p>\n <p class=\"mt-1 text-sm leading-6 text-neutral-500\">{{ example.description }}</p>\n </div>\n <div class=\"flex min-w-0 flex-wrap items-baseline gap-2\">\n <ngs-digit-roller\n [class]=\"example.className\"\n [value]=\"example.value()\"\n [format]=\"example.format\"\n [prefix]=\"example.prefix ?? ''\"\n [continuous]=\"example.continuous ?? false\"\n [duration]=\"example.duration ?? 900\"\n [stagger]=\"example.stagger ?? 0\"\n spinEasing=\"spring\"\n />\n @if (example.unit) {\n <span class=\"text-sm text-neutral-500\">{{ example.unit }}</span>\n }\n </div>\n </div>\n }\n</div>",
3454
+ "exampleFiles": [
3455
+ {
3456
+ "name": "digit-roller-dashboard-example",
3457
+ "title": "Digit roller dashboard",
3458
+ "file": "projects/docs/src/app/components/digit-roller/_examples/digit-roller-dashboard-example/digit-roller-dashboard-example.html",
3459
+ "source": "<div class=\"grid gap-4\" ngsDigitRollerGroup>\n @for (example of examples; track example.label) {\n <div class=\"grid gap-4 rounded-lg border border-neutral-200 bg-white p-5 md:grid-cols-[160px_minmax(0,1fr)] md:items-center\">\n <div>\n <p class=\"font-medium text-neutral-900\">{{ example.label }}</p>\n <p class=\"mt-1 text-sm leading-6 text-neutral-500\">{{ example.description }}</p>\n </div>\n <div class=\"flex min-w-0 flex-wrap items-baseline gap-2\">\n <ngs-digit-roller\n [class]=\"example.className\"\n [value]=\"example.value()\"\n [format]=\"example.format\"\n [prefix]=\"example.prefix ?? ''\"\n [continuous]=\"example.continuous ?? false\"\n [duration]=\"example.duration ?? 900\"\n [stagger]=\"example.stagger ?? 0\"\n spinEasing=\"spring\"\n />\n @if (example.unit) {\n <span class=\"text-sm text-neutral-500\">{{ example.unit }}</span>\n }\n </div>\n </div>\n }\n</div>"
3460
+ },
3461
+ {
3462
+ "name": "digit-roller-gauge-example",
3463
+ "title": "Digit roller gauge",
3464
+ "file": "projects/docs/src/app/components/digit-roller/_examples/digit-roller-gauge-example/digit-roller-gauge-example.html",
3465
+ "source": "<div class=\"grid gap-6 rounded-lg border border-neutral-200 bg-white p-6 sm:grid-cols-[auto_minmax(0,1fr)] sm:items-center\" ngsDigitRollerGroup>\n <ngs-gauge class=\"size-28\" [value]=\"score()\" [radius]=\"50\" [strokeWidth]=\"8\">\n <ngs-gauge-value>\n <ngs-digit-roller\n class=\"text-xl font-bold leading-none text-primary\"\n [value]=\"score()\"\n [format]=\"integerFormat\"\n suffix=\"%\"\n [continuous]=\"true\"\n [stagger]=\"12\"\n />\n </ngs-gauge-value>\n </ngs-gauge>\n <div>\n <p class=\"text-sm font-medium text-neutral-900\">Health score</p>\n <p class=\"mt-1 text-sm leading-6 text-neutral-500\">\n The same value drives the gauge arc and the animated number in the center.\n </p>\n </div>\n</div>"
3466
+ },
3467
+ {
3468
+ "name": "digit-roller-progress-bar-example",
3469
+ "title": "Digit roller progress bar",
3470
+ "file": "projects/docs/src/app/components/digit-roller/_examples/digit-roller-progress-bar-example/digit-roller-progress-bar-example.html",
3471
+ "source": "<div class=\"grid gap-4 rounded-lg border border-neutral-200 bg-white p-5\" ngsDigitRollerGroup>\n <div class=\"flex items-end justify-between gap-4\">\n <div>\n <p class=\"text-sm font-medium text-neutral-900\">Deployment progress</p>\n <p class=\"mt-1 flex flex-wrap items-baseline gap-1 text-sm text-neutral-500\">\n <ngs-digit-roller [value]=\"remaining()\" [format]=\"integerFormat\"/>\n <span>steps remaining</span>\n </p>\n </div>\n <ngs-digit-roller\n class=\"text-2xl font-bold leading-none text-primary\"\n [value]=\"progress() / 100\"\n [format]=\"percentFormat\"\n [continuous]=\"true\"\n [stagger]=\"14\"\n />\n </div>\n <ngs-progress-bar [value]=\"progress()\"/>\n</div>"
3472
+ }
3473
+ ],
3474
+ "previewAsset": "projects/components/digit-roller/preview.svg",
3475
+ "selectors": [
3476
+ "[ngsDigitRollerGroup]",
3477
+ "ngs-digit-roller"
3478
+ ],
3479
+ "exportedSymbols": [
3480
+ "canAnimateDigitRoller",
3481
+ "DIGIT_ROLLER_EMPTY_FORMATTED",
3482
+ "DIGIT_ROLLER_GROUP",
3483
+ "DigitRoller",
3484
+ "DigitRollerCapabilityOptions",
3485
+ "DigitRollerDigitConfig",
3486
+ "DigitRollerDigits",
3487
+ "DigitRollerEasing",
3488
+ "DigitRollerFormattedNumber",
3489
+ "DigitRollerGlyph",
3490
+ "DigitRollerGroupCoordinator",
3491
+ "DigitRollerGroupDirective",
3492
+ "DigitRollerGroupMember",
3493
+ "DigitRollerNumberPart",
3494
+ "DigitRollerTiming",
3495
+ "DigitRollerTrend",
3496
+ "formatDigitRollerValue",
3497
+ "getDigitRollerGlyphs",
3498
+ "resetDigitRollerCapabilityCache"
3499
+ ],
3500
+ "inputs": [
3501
+ "animated",
3502
+ "colorOnDecrease",
3503
+ "colorOnIncrease",
3504
+ "continuous",
3505
+ "digits",
3506
+ "duration",
3507
+ "flipEasing",
3508
+ "format",
3509
+ "locales",
3510
+ "opacityDuration",
3511
+ "opacityTiming",
3512
+ "prefix",
3513
+ "respectMotionPreference",
3514
+ "spinEasing",
3515
+ "spinTiming",
3516
+ "stagger",
3517
+ "suffix",
3518
+ "transformTiming",
3519
+ "trend",
3520
+ "value"
3521
+ ],
3522
+ "outputs": [
3523
+ "animationsFinish",
3524
+ "animationsStart"
3525
+ ],
3526
+ "cssTokens": [
3527
+ "--ngs-digit-roller-mask-height",
3528
+ "--ngs-digit-roller-mask-width",
3529
+ "--ngs-digit-roller-min-digit-width"
3530
+ ],
3531
+ "example": null
3532
+ },
3429
3533
  {
3430
3534
  "name": "divider",
3431
3535
  "title": "Divider",
@@ -0,0 +1,748 @@
1
+ import { isPlatformBrowser } from '@angular/common';
2
+ import * as i0 from '@angular/core';
3
+ import { InjectionToken, input, output, signal, computed, inject, PLATFORM_ID, ElementRef, DestroyRef, effect, untracked, afterEveryRender, ChangeDetectionStrategy, ViewEncapsulation, Component, contentChildren, forwardRef, Directive } from '@angular/core';
4
+
5
+ let staticCapable;
6
+ let prefersReducedMotion;
7
+ function isStaticallyCapable() {
8
+ if (staticCapable !== undefined) {
9
+ return staticCapable;
10
+ }
11
+ staticCapable =
12
+ typeof window !== 'undefined' &&
13
+ typeof window.CSS !== 'undefined' &&
14
+ typeof window.Element !== 'undefined' &&
15
+ typeof window.Element.prototype.animate === 'function' &&
16
+ typeof window.CSS.registerProperty === 'function' &&
17
+ window.CSS.supports('width', 'calc(mod(2, 10) * 1px)') &&
18
+ supportsLinearEasing();
19
+ return staticCapable;
20
+ }
21
+ function getPrefersReducedMotion() {
22
+ if (prefersReducedMotion !== undefined) {
23
+ return prefersReducedMotion;
24
+ }
25
+ if (typeof window === 'undefined' || !window.matchMedia) {
26
+ return false;
27
+ }
28
+ const mediaQuery = window.matchMedia('(prefers-reduced-motion: reduce)');
29
+ prefersReducedMotion = mediaQuery.matches;
30
+ if (typeof mediaQuery.addEventListener === 'function') {
31
+ mediaQuery.addEventListener('change', (event) => {
32
+ prefersReducedMotion = event.matches;
33
+ });
34
+ }
35
+ return prefersReducedMotion;
36
+ }
37
+ function resetDigitRollerCapabilityCache() {
38
+ staticCapable = undefined;
39
+ prefersReducedMotion = undefined;
40
+ }
41
+ function canAnimateDigitRoller(options = {}) {
42
+ if (!isStaticallyCapable()) {
43
+ return false;
44
+ }
45
+ return options.respectMotionPreference === false || !getPrefersReducedMotion();
46
+ }
47
+ function supportsLinearEasing() {
48
+ try {
49
+ document.createElement('div').animate({ opacity: 0 }, { easing: 'linear(0, 1)' });
50
+ return true;
51
+ }
52
+ catch {
53
+ return false;
54
+ }
55
+ }
56
+
57
+ const PRE_TYPES = new Set(['currency', 'literal', 'minusSign', 'plusSign', 'nan', 'infinity']);
58
+ const POST_TYPES = new Set(['percentSign', 'unit']);
59
+ const formatterCache = new Map();
60
+ function getCachedFormatter(locales, options) {
61
+ const key = JSON.stringify(locales) + ':' + JSON.stringify(options);
62
+ let formatter = formatterCache.get(key);
63
+ if (!formatter) {
64
+ formatter = new Intl.NumberFormat(locales, options);
65
+ formatterCache.set(key, formatter);
66
+ }
67
+ return formatter;
68
+ }
69
+ function getDigitRollerGlyphs(locales, options = {}) {
70
+ const formatter = getCachedFormatter(locales, {
71
+ numberingSystem: options.numberingSystem,
72
+ useGrouping: false,
73
+ maximumFractionDigits: 0,
74
+ });
75
+ return Array.from({ length: 10 }, (_, value) => ({
76
+ value,
77
+ glyph: formatter.format(value),
78
+ }));
79
+ }
80
+ function getDigitValueMap(locales, options = {}) {
81
+ return new Map(getDigitRollerGlyphs(locales, options).map(({ glyph, value }) => [glyph, value]));
82
+ }
83
+ function formatDigitRollerValue(value, options = {}, locales, prefix = '', suffix = '') {
84
+ const formatter = getCachedFormatter(locales, options);
85
+ const digitValues = getDigitValueMap(locales, options);
86
+ const parts = formatter.formatToParts(value);
87
+ const pre = [];
88
+ const rawInteger = [];
89
+ const fraction = [];
90
+ const post = [];
91
+ let seenInteger = false;
92
+ let seenDecimal = false;
93
+ for (const part of parts) {
94
+ if (part.type === 'integer' || part.type === 'group') {
95
+ seenInteger = true;
96
+ rawInteger.push(part);
97
+ }
98
+ else if (part.type === 'decimal' || part.type === 'fraction') {
99
+ seenDecimal = true;
100
+ fraction.push({ type: part.type, value: part.value, key: '' });
101
+ }
102
+ else if (!seenInteger && PRE_TYPES.has(part.type)) {
103
+ pre.push({ type: part.type, value: part.value, key: `pre-${pre.length}` });
104
+ }
105
+ else if (seenInteger && POST_TYPES.has(part.type)) {
106
+ post.push({ type: part.type, value: part.value, key: `post-${post.length}` });
107
+ }
108
+ else if (seenDecimal || seenInteger) {
109
+ post.push({ type: part.type, value: part.value, key: `post-${post.length}` });
110
+ }
111
+ else {
112
+ pre.push({ type: part.type, value: part.value, key: `pre-${pre.length}` });
113
+ }
114
+ }
115
+ if (prefix) {
116
+ pre.unshift({ type: 'prefix', value: prefix, key: '__prefix' });
117
+ }
118
+ if (suffix) {
119
+ post.push({ type: 'suffix', value: suffix, key: '__suffix' });
120
+ }
121
+ const splitInteger = [];
122
+ for (const part of rawInteger) {
123
+ if (part.type === 'integer') {
124
+ for (const char of part.value) {
125
+ splitInteger.push({ type: 'integer', value: char });
126
+ }
127
+ }
128
+ else {
129
+ splitInteger.push(part);
130
+ }
131
+ }
132
+ let digitIndex = 0;
133
+ const reversedInteger = [];
134
+ for (let i = splitInteger.length - 1; i >= 0; i--) {
135
+ const part = splitInteger[i];
136
+ if (part.type === 'integer') {
137
+ reversedInteger.push({
138
+ type: 'integer',
139
+ value: part.value,
140
+ key: `i${digitIndex}`,
141
+ numericValue: digitValues.get(part.value) ?? Number(part.value),
142
+ });
143
+ digitIndex++;
144
+ }
145
+ else {
146
+ reversedInteger.push({ type: 'group', value: part.value, key: `g${digitIndex}` });
147
+ }
148
+ }
149
+ let fractionDigitIndex = 0;
150
+ const keyedFraction = [];
151
+ for (const part of fraction) {
152
+ if (part.type === 'fraction') {
153
+ for (const char of part.value) {
154
+ keyedFraction.push({
155
+ type: 'fraction',
156
+ value: char,
157
+ key: `f${++fractionDigitIndex}`,
158
+ numericValue: digitValues.get(char) ?? Number(char),
159
+ });
160
+ }
161
+ }
162
+ else {
163
+ keyedFraction.push({ ...part, key: 'decimal' });
164
+ }
165
+ }
166
+ return { pre, integer: reversedInteger.reverse(), fraction: keyedFraction, post };
167
+ }
168
+
169
+ const DIGIT_ROLLER_GROUP = new InjectionToken('DIGIT_ROLLER_GROUP');
170
+
171
+ const DIGIT_ROLLER_EMPTY_FORMATTED = {
172
+ pre: [],
173
+ integer: [],
174
+ fraction: [],
175
+ post: [],
176
+ };
177
+
178
+ const SPIN_EASING = 'linear(0,.005,.019,.039,.066,.096,.129,.165,.202,.24,.278,.316,.354,.39,.426,.461,' +
179
+ '.494,.526,.557,.586,.614,.64,.665,.689,.711,.731,.751,.769,.786,.802,.817,.831,.844,' +
180
+ '.856,.867,.877,.887,.896,.904,.912,.919,.925,.931,.937,.942,.947,.951,.955,.959,.962,' +
181
+ '.965,.968,.971,.973,.976,.978,.98,.981,.983,.984,.986,.987,.988,.989,.99,.991,.992,' +
182
+ '.992,.993,.994,.994,.995,.995,.996,.996,.9963,.9967,.9969,.9972,.9975,.9977,.9979,' +
183
+ '.9981,.9982,.9984,.9985,.9987,.9988,.9989,1)';
184
+ const EASING_PRESETS = {
185
+ default: SPIN_EASING,
186
+ spring: SPIN_EASING,
187
+ overshoot: 'cubic-bezier(0.34, 1.56, 0.64, 1)',
188
+ };
189
+ class DigitRoller {
190
+ value = input.required(...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
191
+ format = input({}, ...(ngDevMode ? [{ debugName: "format" }] : /* istanbul ignore next */ []));
192
+ locales = input(undefined, ...(ngDevMode ? [{ debugName: "locales" }] : /* istanbul ignore next */ []));
193
+ prefix = input('', ...(ngDevMode ? [{ debugName: "prefix" }] : /* istanbul ignore next */ []));
194
+ suffix = input('', ...(ngDevMode ? [{ debugName: "suffix" }] : /* istanbul ignore next */ []));
195
+ animated = input(true, ...(ngDevMode ? [{ debugName: "animated" }] : /* istanbul ignore next */ []));
196
+ duration = input(undefined, ...(ngDevMode ? [{ debugName: "duration" }] : /* istanbul ignore next */ []));
197
+ opacityDuration = input(undefined, ...(ngDevMode ? [{ debugName: "opacityDuration" }] : /* istanbul ignore next */ []));
198
+ transformTiming = input(undefined, ...(ngDevMode ? [{ debugName: "transformTiming" }] : /* istanbul ignore next */ []));
199
+ spinTiming = input(undefined, ...(ngDevMode ? [{ debugName: "spinTiming" }] : /* istanbul ignore next */ []));
200
+ opacityTiming = input(undefined, ...(ngDevMode ? [{ debugName: "opacityTiming" }] : /* istanbul ignore next */ []));
201
+ spinEasing = input(undefined, ...(ngDevMode ? [{ debugName: "spinEasing" }] : /* istanbul ignore next */ []));
202
+ flipEasing = input(undefined, ...(ngDevMode ? [{ debugName: "flipEasing" }] : /* istanbul ignore next */ []));
203
+ trend = input(undefined, ...(ngDevMode ? [{ debugName: "trend" }] : /* istanbul ignore next */ []));
204
+ continuous = input(false, ...(ngDevMode ? [{ debugName: "continuous" }] : /* istanbul ignore next */ []));
205
+ digits = input({}, ...(ngDevMode ? [{ debugName: "digits" }] : /* istanbul ignore next */ []));
206
+ respectMotionPreference = input(true, ...(ngDevMode ? [{ debugName: "respectMotionPreference" }] : /* istanbul ignore next */ []));
207
+ stagger = input(0, ...(ngDevMode ? [{ debugName: "stagger" }] : /* istanbul ignore next */ []));
208
+ colorOnIncrease = input(undefined, ...(ngDevMode ? [{ debugName: "colorOnIncrease" }] : /* istanbul ignore next */ []));
209
+ colorOnDecrease = input(undefined, ...(ngDevMode ? [{ debugName: "colorOnDecrease" }] : /* istanbul ignore next */ []));
210
+ animationsStart = output();
211
+ animationsFinish = output();
212
+ data = signal(DIGIT_ROLLER_EMPTY_FORMATTED, ...(ngDevMode ? [{ debugName: "data" }] : /* istanbul ignore next */ []));
213
+ digitGlyphs = computed(() => getDigitRollerGlyphs(this.locales(), this.format()), ...(ngDevMode ? [{ debugName: "digitGlyphs" }] : /* istanbul ignore next */ []));
214
+ formattedPlainText = computed(() => new Intl.NumberFormat(this.locales(), this.format()).format(this.value()), ...(ngDevMode ? [{ debugName: "formattedPlainText" }] : /* istanbul ignore next */ []));
215
+ effectiveSettings = computed(() => {
216
+ const duration = this.duration() ?? 900;
217
+ return {
218
+ duration,
219
+ opacityDuration: this.opacityDuration() ?? 450,
220
+ spinEasing: this.resolveEasing(this.spinEasing()),
221
+ flipEasing: this.resolveEasing(this.flipEasing()),
222
+ transformTiming: this.transformTiming(),
223
+ spinTiming: this.spinTiming(),
224
+ opacityTiming: this.opacityTiming(),
225
+ };
226
+ }, ...(ngDevMode ? [{ debugName: "effectiveSettings" }] : /* istanbul ignore next */ []));
227
+ platformId = inject(PLATFORM_ID);
228
+ elementRef = inject(ElementRef);
229
+ destroyRef = inject(DestroyRef);
230
+ group = inject(DIGIT_ROLLER_GROUP, { optional: true });
231
+ prevRects = new Map();
232
+ prevInnerHTML = new Map();
233
+ prevDigitD = new Map();
234
+ prevDigitCurrent = new Map();
235
+ prevDigitValues = new Map();
236
+ prevDigitOrder = [];
237
+ prevNumberLeft = 0;
238
+ prevNumberWidth = 0;
239
+ prevNumericValue = 0;
240
+ animCount = 0;
241
+ pending = false;
242
+ destroyed = false;
243
+ hasRenderedValue = false;
244
+ liveAnimations = [];
245
+ spinCount = new Map();
246
+ animationsFinishAbort;
247
+ pendingCanAnimate = false;
248
+ pendingHostFont = '';
249
+ pendingHostColor = '';
250
+ pendingKeyedEls = [];
251
+ pendingNumberRect = null;
252
+ pendingNumberOffsetWidth = 0;
253
+ isNearViewport = true;
254
+ viewportObserver;
255
+ constructor() {
256
+ this.destroyRef.onDestroy(() => {
257
+ this.destroyed = true;
258
+ this.animationsFinishAbort?.abort();
259
+ this.viewportObserver?.disconnect();
260
+ for (const animation of this.liveAnimations) {
261
+ try {
262
+ animation.cancel();
263
+ }
264
+ catch {
265
+ /* Animation cancellation can throw AbortError in some browsers. */
266
+ }
267
+ }
268
+ this.liveAnimations = [];
269
+ });
270
+ effect(() => {
271
+ const value = this.value();
272
+ const format = this.format();
273
+ const locales = this.locales();
274
+ const prefix = this.prefix();
275
+ const suffix = this.suffix();
276
+ if (!this.hasRenderedValue) {
277
+ untracked(() => this.data.set(formatDigitRollerValue(value, format, locales, prefix, suffix)));
278
+ this.prevNumericValue = value;
279
+ this.hasRenderedValue = true;
280
+ return;
281
+ }
282
+ const canAnimateThisUpdate = isPlatformBrowser(this.platformId) && this.animated() && this.canAnimateNow();
283
+ if (canAnimateThisUpdate) {
284
+ const handledByGroup = this.group?.requestGroupedUpdate(this, () => {
285
+ untracked(() => this.data.set(formatDigitRollerValue(value, format, locales, prefix, suffix)));
286
+ });
287
+ if (handledByGroup) {
288
+ return;
289
+ }
290
+ this.snapshot();
291
+ untracked(() => this.data.set(formatDigitRollerValue(value, format, locales, prefix, suffix)));
292
+ this.pending = true;
293
+ }
294
+ else {
295
+ untracked(() => this.data.set(formatDigitRollerValue(value, format, locales, prefix, suffix)));
296
+ this.prevNumericValue = value;
297
+ }
298
+ });
299
+ if (isPlatformBrowser(this.platformId)) {
300
+ if (typeof IntersectionObserver !== 'undefined') {
301
+ this.viewportObserver = new IntersectionObserver((entries) => {
302
+ this.isNearViewport = entries[entries.length - 1].isIntersecting;
303
+ }, { rootMargin: '240px' });
304
+ this.viewportObserver.observe(this.elementRef.nativeElement);
305
+ }
306
+ afterEveryRender({
307
+ earlyRead: () => {
308
+ if (this.pending) {
309
+ this.readAnimationState();
310
+ }
311
+ },
312
+ write: () => {
313
+ if (this.pending) {
314
+ this.pending = false;
315
+ this.fireAnimations();
316
+ }
317
+ },
318
+ });
319
+ }
320
+ }
321
+ canGroupAnimateNow() {
322
+ return isPlatformBrowser(this.platformId) && this.animated() && this.canAnimateNow();
323
+ }
324
+ prepareGroupedUpdate() {
325
+ this.snapshot();
326
+ }
327
+ queueGroupedAnimation() {
328
+ this.pending = true;
329
+ }
330
+ snapshot() {
331
+ const host = this.elementRef.nativeElement;
332
+ this.prevRects.clear();
333
+ this.prevInnerHTML.clear();
334
+ this.prevDigitD.clear();
335
+ this.prevDigitCurrent.clear();
336
+ this.prevDigitValues.clear();
337
+ this.prevDigitOrder = [];
338
+ const number = host.querySelector('.ngs-digit-roller__number');
339
+ if (number) {
340
+ const numberRect = number.getBoundingClientRect();
341
+ this.prevNumberLeft = numberRect.left;
342
+ this.prevNumberWidth = numberRect.width;
343
+ }
344
+ untracked(() => {
345
+ [...this.data().integer, ...this.data().fraction].forEach((part) => {
346
+ if (part.type === 'integer' || part.type === 'fraction') {
347
+ this.prevDigitValues.set(part.key, this.getPartDigitValue(part));
348
+ this.prevDigitOrder.push(part.key);
349
+ }
350
+ });
351
+ });
352
+ host.querySelectorAll('[data-key]').forEach((element) => {
353
+ const key = element.getAttribute('data-key');
354
+ this.prevRects.set(key, element.getBoundingClientRect());
355
+ this.prevInnerHTML.set(key, element.innerHTML);
356
+ if (element.classList.contains('ngs-digit-roller__digit')) {
357
+ const styles = getComputedStyle(element);
358
+ this.prevDigitD.set(key, styles.getPropertyValue('--_ngs-digit-roller-d').trim() || '0');
359
+ this.prevDigitCurrent.set(key, (element.style.getPropertyValue('--_ngs-digit-roller-current') || '0').trim());
360
+ }
361
+ });
362
+ }
363
+ readAnimationState() {
364
+ if (this.destroyed || !this.canAnimateNow()) {
365
+ this.pendingCanAnimate = false;
366
+ return;
367
+ }
368
+ this.pendingCanAnimate = true;
369
+ const host = this.elementRef.nativeElement;
370
+ const hostStyles = getComputedStyle(host);
371
+ this.pendingHostFont = hostStyles.font;
372
+ this.pendingHostColor = hostStyles.color;
373
+ this.pendingKeyedEls = [];
374
+ host.querySelectorAll('[data-key]').forEach((element) => {
375
+ this.pendingKeyedEls.push({
376
+ el: element,
377
+ key: element.getAttribute('data-key'),
378
+ newRect: element.getBoundingClientRect(),
379
+ });
380
+ });
381
+ const number = host.querySelector('.ngs-digit-roller__number');
382
+ this.pendingNumberRect = number ? number.getBoundingClientRect() : null;
383
+ this.pendingNumberOffsetWidth = number ? number.offsetWidth : 0;
384
+ }
385
+ fireAnimations() {
386
+ if (this.destroyed) {
387
+ return;
388
+ }
389
+ const host = this.elementRef.nativeElement;
390
+ const newNumericValue = untracked(() => this.value());
391
+ if (!this.pendingCanAnimate) {
392
+ this.prevNumericValue = newNumericValue;
393
+ return;
394
+ }
395
+ const settings = this.effectiveSettings();
396
+ const duration = settings.duration;
397
+ const opacityDuration = settings.opacityDuration;
398
+ const trend = this.resolveTrend(this.prevNumericValue, newNumericValue);
399
+ const staggerMs = this.stagger();
400
+ const baseTransformTiming = settings.transformTiming ?? {
401
+ duration,
402
+ easing: settings.flipEasing,
403
+ };
404
+ const spinOptions = {
405
+ ...baseTransformTiming,
406
+ easing: settings.spinEasing,
407
+ ...(settings.spinTiming ?? {}),
408
+ duration: settings.spinTiming?.duration ?? baseTransformTiming.duration,
409
+ fill: 'none',
410
+ composite: 'accumulate',
411
+ };
412
+ const flipOptions = {
413
+ ...baseTransformTiming,
414
+ duration: baseTransformTiming.duration,
415
+ fill: 'none',
416
+ composite: 'accumulate',
417
+ };
418
+ const fadeOptions = {
419
+ duration: opacityDuration,
420
+ easing: 'ease-out',
421
+ fill: 'none',
422
+ composite: 'accumulate',
423
+ ...(settings.opacityTiming ?? {}),
424
+ };
425
+ const continuousStartPosition = this.continuous() && duration > 0 && trend !== 0 ? this.getContinuousStartPosition() : undefined;
426
+ const batch = [];
427
+ const newKeys = new Set();
428
+ let elementIndex = 0;
429
+ const number = host.querySelector('.ngs-digit-roller__number');
430
+ for (const { el, key, newRect } of this.pendingKeyedEls) {
431
+ newKeys.add(key);
432
+ const prevRect = this.prevRects.get(key);
433
+ const staggerDelay = staggerMs > 0 ? elementIndex * staggerMs : 0;
434
+ elementIndex++;
435
+ if (el.classList.contains('ngs-digit-roller__digit')) {
436
+ const digit = this.getDigitValue(key);
437
+ const fromDigit = this.prevDigitValues.has(key) ? this.prevDigitValues.get(key) : 0;
438
+ const rawDelta = this.getTrendDelta(fromDigit, digit, trend, this.getDigitLength(key));
439
+ const digitPosition = this.getDigitPosition(key);
440
+ const isLowerUnchanged = this.continuous() &&
441
+ rawDelta === 0 &&
442
+ continuousStartPosition !== undefined &&
443
+ digitPosition !== undefined &&
444
+ continuousStartPosition >= digitPosition;
445
+ const delta = isLowerUnchanged ? this.getDigitLength(key) * trend : rawDelta;
446
+ if (delta !== 0 && duration > 0) {
447
+ this.incrementSpin(el);
448
+ const animation = el.animate({ '--_ngs-digit-roller-d': [-delta, 0] }, spinOptions);
449
+ batch.push(animation);
450
+ animation.finished.then(() => this.decrementSpin(el)).catch(() => this.decrementSpin(el));
451
+ }
452
+ this.animatePositionOrFade(el, prevRect, newRect, flipOptions, fadeOptions, staggerDelay, batch);
453
+ }
454
+ else {
455
+ this.animatePositionOrFade(el, prevRect, newRect, flipOptions, fadeOptions, staggerDelay, batch);
456
+ }
457
+ }
458
+ let exitIndex = 0;
459
+ this.prevRects.forEach((rect, key) => {
460
+ if (newKeys.has(key)) {
461
+ return;
462
+ }
463
+ const ghost = this.buildGhost(key, rect, this.pendingHostFont, this.pendingHostColor);
464
+ host.appendChild(ghost);
465
+ ghost.style.setProperty('--_ngs-digit-roller-d-opacity', '-0.999');
466
+ const staggerDelay = staggerMs > 0 ? exitIndex * staggerMs : 0;
467
+ exitIndex++;
468
+ const animation = ghost.animate({ '--_ngs-digit-roller-d-opacity': [0.999, 0] }, this.addStaggerDelay(fadeOptions, staggerDelay));
469
+ batch.push(animation);
470
+ animation.finished.then(() => ghost.remove()).catch(() => ghost.remove());
471
+ });
472
+ if (number && this.pendingNumberRect) {
473
+ const rect = this.pendingNumberRect;
474
+ const dx = this.prevNumberLeft - rect.left;
475
+ const width = rect.width || this.pendingNumberOffsetWidth;
476
+ const dWidth = this.prevNumberWidth - width;
477
+ number.style.setProperty('--_ngs-digit-roller-width', String(width || this.prevNumberWidth || 1));
478
+ if (Math.abs(dx) > 0.5 || Math.abs(dWidth) > 0.5) {
479
+ batch.push(number.animate({
480
+ '--_ngs-digit-roller-dx': [`${dx}px`, '0px'],
481
+ '--_ngs-digit-roller-d-width': [dWidth, 0],
482
+ }, flipOptions));
483
+ }
484
+ }
485
+ if (duration > 0) {
486
+ const colorIncrease = this.colorOnIncrease();
487
+ const colorDecrease = this.colorOnDecrease();
488
+ if (trend > 0 && colorIncrease) {
489
+ batch.push(host.animate([{ color: colorIncrease }, { color: '' }], {
490
+ duration: Math.max(duration, 400),
491
+ easing: 'ease-out',
492
+ fill: 'none',
493
+ }));
494
+ }
495
+ else if (trend < 0 && colorDecrease) {
496
+ batch.push(host.animate([{ color: colorDecrease }, { color: '' }], {
497
+ duration: Math.max(duration, 400),
498
+ easing: 'ease-out',
499
+ fill: 'none',
500
+ }));
501
+ }
502
+ }
503
+ this.prevNumericValue = newNumericValue;
504
+ if (batch.length === 0) {
505
+ return;
506
+ }
507
+ this.liveAnimations.push(...batch);
508
+ this.animCount++;
509
+ if (this.animationsFinishAbort) {
510
+ this.animationsFinishAbort.abort();
511
+ }
512
+ else {
513
+ this.animationsStart.emit();
514
+ }
515
+ const finishController = new AbortController();
516
+ this.animationsFinishAbort = finishController;
517
+ Promise.allSettled(batch.map((animation) => animation.finished)).then(() => {
518
+ const batchSet = new Set(batch);
519
+ this.liveAnimations = this.liveAnimations.filter((animation) => !batchSet.has(animation));
520
+ this.animCount--;
521
+ if (this.animCount === 0 && !this.destroyed && this.animationsFinishAbort) {
522
+ this.animationsFinish.emit();
523
+ this.animationsFinishAbort = undefined;
524
+ }
525
+ });
526
+ }
527
+ animatePositionOrFade(element, prevRect, newRect, flipOptions, fadeOptions, staggerDelay, batch) {
528
+ if (prevRect) {
529
+ const dx = prevRect.left - newRect.left;
530
+ if (Math.abs(dx) > 0.5) {
531
+ batch.push(element.animate([{ transform: `translateX(${dx}px)` }, { transform: 'translateX(0)' }], flipOptions));
532
+ }
533
+ }
534
+ else {
535
+ batch.push(element.animate({ '--_ngs-digit-roller-d-opacity': [-0.9999, 0] }, this.addStaggerDelay(fadeOptions, staggerDelay)));
536
+ }
537
+ }
538
+ getDigitValue(key) {
539
+ const part = [...this.data().integer, ...this.data().fraction].find((item) => item.key === key);
540
+ return part ? this.getPartDigitValue(part) : 0;
541
+ }
542
+ getPartDigitValue(part) {
543
+ return part.numericValue ?? Number(part.value);
544
+ }
545
+ resolveTrend(oldValue, newValue) {
546
+ const configured = this.trend();
547
+ const trend = typeof configured === 'function'
548
+ ? configured(oldValue, newValue)
549
+ : (configured ?? Math.sign(newValue - oldValue));
550
+ return Math.sign(trend);
551
+ }
552
+ canAnimateNow() {
553
+ const host = this.elementRef.nativeElement;
554
+ return (canAnimateDigitRoller({ respectMotionPreference: this.respectMotionPreference() }) &&
555
+ this.animated() &&
556
+ host.ownerDocument.visibilityState === 'visible' &&
557
+ this.isHostNearViewport(host));
558
+ }
559
+ isHostNearViewport(host) {
560
+ if (this.viewportObserver) {
561
+ return this.isNearViewport;
562
+ }
563
+ const rect = host.getBoundingClientRect();
564
+ if (rect.width <= 0 || rect.height <= 0) {
565
+ return false;
566
+ }
567
+ const windowRef = host.ownerDocument.defaultView;
568
+ if (!windowRef) {
569
+ return true;
570
+ }
571
+ const margin = 240;
572
+ return (rect.bottom >= -margin &&
573
+ rect.right >= -margin &&
574
+ rect.top <= windowRef.innerHeight + margin &&
575
+ rect.left <= windowRef.innerWidth + margin);
576
+ }
577
+ resolveEasing(easing) {
578
+ return easing ? (EASING_PRESETS[easing] ?? easing) : SPIN_EASING;
579
+ }
580
+ getContinuousStartPosition() {
581
+ const current = new Map();
582
+ const currentOrder = [];
583
+ untracked(() => {
584
+ [...this.data().integer, ...this.data().fraction].forEach((part) => {
585
+ if (part.type === 'integer' || part.type === 'fraction') {
586
+ current.set(part.key, this.getPartDigitValue(part));
587
+ currentOrder.push(part.key);
588
+ }
589
+ });
590
+ });
591
+ const firstChangedPrev = this.prevDigitOrder.find((key) => current.get(key) !== this.prevDigitValues.get(key));
592
+ const firstChangedCurrent = currentOrder.find((key) => current.get(key) !== this.prevDigitValues.get(key));
593
+ const start = Math.max(this.getDigitPosition(firstChangedPrev) ?? -Infinity, this.getDigitPosition(firstChangedCurrent) ?? -Infinity);
594
+ return Number.isFinite(start) ? start : undefined;
595
+ }
596
+ getDigitPosition(key) {
597
+ if (!key) {
598
+ return undefined;
599
+ }
600
+ if (key.startsWith('i')) {
601
+ return Number(key.slice(1));
602
+ }
603
+ if (key.startsWith('f')) {
604
+ return -Number(key.slice(1));
605
+ }
606
+ return undefined;
607
+ }
608
+ getDigitLength(key) {
609
+ if (!key.startsWith('i')) {
610
+ return 10;
611
+ }
612
+ const position = Number(key.slice(1));
613
+ const max = this.digits()[position]?.max;
614
+ return max !== undefined ? max + 1 : 10;
615
+ }
616
+ digitLengthForKey(key) {
617
+ return this.getDigitLength(key);
618
+ }
619
+ digitGlyphsForKey(key) {
620
+ return this.digitGlyphs().slice(0, this.getDigitLength(key));
621
+ }
622
+ addStaggerDelay(options, staggerDelay) {
623
+ const currentDelay = typeof options.delay === 'number' ? options.delay : 0;
624
+ return { ...options, delay: currentDelay + staggerDelay };
625
+ }
626
+ getTrendDelta(from, to, trend, length = 10) {
627
+ const diff = to - from;
628
+ const resolvedTrend = trend || Math.sign(diff);
629
+ if (resolvedTrend > 0 && to < from) {
630
+ return length - from + to;
631
+ }
632
+ if (resolvedTrend < 0 && to > from) {
633
+ return to - length - from;
634
+ }
635
+ return diff;
636
+ }
637
+ incrementSpin(element) {
638
+ const count = (this.spinCount.get(element) ?? 0) + 1;
639
+ this.spinCount.set(element, count);
640
+ if (count === 1) {
641
+ element.classList.add('ngs-digit-roller__digit--spinning');
642
+ }
643
+ }
644
+ decrementSpin(element) {
645
+ const count = Math.max(0, (this.spinCount.get(element) ?? 1) - 1);
646
+ if (count === 0) {
647
+ this.spinCount.delete(element);
648
+ element.classList.remove('ngs-digit-roller__digit--spinning');
649
+ }
650
+ else {
651
+ this.spinCount.set(element, count);
652
+ }
653
+ }
654
+ buildGhost(key, rect, font, color) {
655
+ const ghost = document.createElement('span');
656
+ ghost.style.cssText =
657
+ `position:fixed;left:${rect.left}px;top:${rect.top}px;` +
658
+ `width:${rect.width}px;height:${rect.height}px;` +
659
+ `pointer-events:none;overflow:hidden;display:inline-flex;` +
660
+ `align-items:center;font:${font};color:${color}`;
661
+ ghost.className = 'ngs-digit-roller__ghost';
662
+ const savedHTML = this.prevInnerHTML.get(key);
663
+ if (savedHTML) {
664
+ ghost.innerHTML = savedHTML;
665
+ const savedD = this.prevDigitD.get(key);
666
+ const savedCurrent = this.prevDigitCurrent.get(key);
667
+ if (savedD !== undefined) {
668
+ ghost.style.setProperty('--_ngs-digit-roller-d', savedD);
669
+ }
670
+ if (savedCurrent !== undefined) {
671
+ ghost.style.setProperty('--_ngs-digit-roller-current', savedCurrent);
672
+ }
673
+ ghost.querySelectorAll('[inert]').forEach((element) => {
674
+ element.style.display = 'none';
675
+ });
676
+ }
677
+ return ghost;
678
+ }
679
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: DigitRoller, deps: [], target: i0.ɵɵFactoryTarget.Component });
680
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.4", type: DigitRoller, isStandalone: true, selector: "ngs-digit-roller", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: true, transformFunction: null }, format: { classPropertyName: "format", publicName: "format", isSignal: true, isRequired: false, transformFunction: null }, locales: { classPropertyName: "locales", publicName: "locales", isSignal: true, isRequired: false, transformFunction: null }, prefix: { classPropertyName: "prefix", publicName: "prefix", isSignal: true, isRequired: false, transformFunction: null }, suffix: { classPropertyName: "suffix", publicName: "suffix", isSignal: true, isRequired: false, transformFunction: null }, animated: { classPropertyName: "animated", publicName: "animated", isSignal: true, isRequired: false, transformFunction: null }, duration: { classPropertyName: "duration", publicName: "duration", isSignal: true, isRequired: false, transformFunction: null }, opacityDuration: { classPropertyName: "opacityDuration", publicName: "opacityDuration", isSignal: true, isRequired: false, transformFunction: null }, transformTiming: { classPropertyName: "transformTiming", publicName: "transformTiming", isSignal: true, isRequired: false, transformFunction: null }, spinTiming: { classPropertyName: "spinTiming", publicName: "spinTiming", isSignal: true, isRequired: false, transformFunction: null }, opacityTiming: { classPropertyName: "opacityTiming", publicName: "opacityTiming", isSignal: true, isRequired: false, transformFunction: null }, spinEasing: { classPropertyName: "spinEasing", publicName: "spinEasing", isSignal: true, isRequired: false, transformFunction: null }, flipEasing: { classPropertyName: "flipEasing", publicName: "flipEasing", isSignal: true, isRequired: false, transformFunction: null }, trend: { classPropertyName: "trend", publicName: "trend", isSignal: true, isRequired: false, transformFunction: null }, continuous: { classPropertyName: "continuous", publicName: "continuous", isSignal: true, isRequired: false, transformFunction: null }, digits: { classPropertyName: "digits", publicName: "digits", isSignal: true, isRequired: false, transformFunction: null }, respectMotionPreference: { classPropertyName: "respectMotionPreference", publicName: "respectMotionPreference", isSignal: true, isRequired: false, transformFunction: null }, stagger: { classPropertyName: "stagger", publicName: "stagger", isSignal: true, isRequired: false, transformFunction: null }, colorOnIncrease: { classPropertyName: "colorOnIncrease", publicName: "colorOnIncrease", isSignal: true, isRequired: false, transformFunction: null }, colorOnDecrease: { classPropertyName: "colorOnDecrease", publicName: "colorOnDecrease", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { animationsStart: "animationsStart", animationsFinish: "animationsFinish" }, host: { properties: { "attr.data-animated": "animated()" }, classAttribute: "ngs-digit-roller" }, exportAs: ["ngsDigitRoller"], ngImport: i0, template: "<span class=\"ngs-digit-roller__number\" aria-hidden=\"true\">\n <span class=\"ngs-digit-roller__number-inner\">\n @if (data().pre.length) {\n <span class=\"ngs-digit-roller__section ngs-digit-roller__section--pre\">\n @for (part of data().pre; track part.key) {\n <span class=\"ngs-digit-roller__literal\" [attr.data-key]=\"part.key\">{{ part.value }}</span>\n }\n </span>\n }\n\n <span class=\"ngs-digit-roller__section ngs-digit-roller__section--integer\">\n @for (part of data().integer; track part.key) {\n @if (part.type === 'integer') {\n <span\n class=\"ngs-digit-roller__digit\"\n [attr.data-key]=\"part.key\"\n [style.--_ngs-digit-roller-current]=\"part.numericValue\"\n [style.--_ngs-digit-roller-len]=\"digitLengthForKey(part.key)\"\n >\n @for (digit of digitGlyphsForKey(part.key); track digit.value) {\n <span\n class=\"ngs-digit-roller__digit-number\"\n [style.--_ngs-digit-roller-n]=\"digit.value\"\n [attr.inert]=\"digit.value !== part.numericValue ? '' : null\"\n >\n {{ digit.glyph }}\n </span>\n }\n </span>\n } @else {\n <span class=\"ngs-digit-roller__separator\" [attr.data-key]=\"part.key\">{{ part.value }}</span>\n }\n }\n </span>\n\n @if (data().fraction.length) {\n <span class=\"ngs-digit-roller__section ngs-digit-roller__section--fraction\">\n @for (part of data().fraction; track part.key) {\n @if (part.type === 'fraction') {\n <span\n class=\"ngs-digit-roller__digit\"\n [attr.data-key]=\"part.key\"\n [style.--_ngs-digit-roller-current]=\"part.numericValue\"\n [style.--_ngs-digit-roller-len]=\"digitLengthForKey(part.key)\"\n >\n @for (digit of digitGlyphsForKey(part.key); track digit.value) {\n <span\n class=\"ngs-digit-roller__digit-number\"\n [style.--_ngs-digit-roller-n]=\"digit.value\"\n [attr.inert]=\"digit.value !== part.numericValue ? '' : null\"\n >\n {{ digit.glyph }}\n </span>\n }\n </span>\n } @else {\n <span class=\"ngs-digit-roller__separator\" [attr.data-key]=\"part.key\">{{ part.value }}</span>\n }\n }\n </span>\n }\n\n @if (data().post.length) {\n <span class=\"ngs-digit-roller__section ngs-digit-roller__section--post\">\n @for (part of data().post; track part.key) {\n <span class=\"ngs-digit-roller__literal\" [attr.data-key]=\"part.key\">{{ part.value }}</span>\n }\n </span>\n }\n </span>\n</span>\n\n<span class=\"ngs-digit-roller__sr-only\">{{ formattedPlainText() }}</span>\n", styles: ["@layer properties;@property --_ngs-digit-roller-d{syntax: \"<number>\"; inherits: true; initial-value: 0;}@property --_ngs-digit-roller-d-opacity{syntax: \"<number>\"; inherits: false; initial-value: 0;}@property --_ngs-digit-roller-d-width{syntax: \"<number>\"; inherits: false; initial-value: 0;}@property --_ngs-digit-roller-dx{syntax: \"<length>\"; inherits: true; initial-value: 0px;}ngs-digit-roller{--ngs-digit-roller-mask-height: .25em;--ngs-digit-roller-mask-width: .5em;--ngs-digit-roller-min-digit-width: .6em;display:inline-block;position:relative;direction:ltr;isolation:isolate;line-height:1;white-space:nowrap}ngs-digit-roller .ngs-digit-roller__number{--_ngs-digit-roller-width: 1;--_ngs-digit-roller-scale-x: calc( 1 + var(--_ngs-digit-roller-d-width) / var(--_ngs-digit-roller-width) );--_ngs-digit-roller-half-mask-height: round( nearest, calc(var(--ngs-digit-roller-mask-height) / 2), 1px );--_ngs-digit-roller-resolved-mask-height: calc(var(--_ngs-digit-roller-half-mask-height) * 2);--_ngs-digit-roller-scaled-mask-width: calc( var(--ngs-digit-roller-mask-width) / var(--_ngs-digit-roller-scale-x) );display:inline-block;line-height:1;font-variant-numeric:tabular-nums;font-feature-settings:\"tnum\";position:relative;transform-origin:left top;transform:translate(var(--_ngs-digit-roller-dx)) scaleX(var(--_ngs-digit-roller-scale-x));margin:0 calc(-1 * var(--ngs-digit-roller-mask-width));-webkit-mask-image:linear-gradient(to right,transparent 0,#000 var(--_ngs-digit-roller-scaled-mask-width),#000 calc(100% - var(--_ngs-digit-roller-scaled-mask-width)),transparent 100%),linear-gradient(to bottom,transparent 0,#000 var(--_ngs-digit-roller-resolved-mask-height),#000 calc(100% - var(--_ngs-digit-roller-resolved-mask-height)),transparent 100%),radial-gradient(at bottom right,#000 0,transparent 71%),radial-gradient(at bottom left,#000 0,transparent 71%),radial-gradient(at top left,#000 0,transparent 71%),radial-gradient(at top right,#000 0,transparent 71%);mask-image:linear-gradient(to right,transparent 0,#000 var(--_ngs-digit-roller-scaled-mask-width),#000 calc(100% - var(--_ngs-digit-roller-scaled-mask-width)),transparent 100%),linear-gradient(to bottom,transparent 0,#000 var(--_ngs-digit-roller-resolved-mask-height),#000 calc(100% - var(--_ngs-digit-roller-resolved-mask-height)),transparent 100%),radial-gradient(at bottom right,#000 0,transparent 71%),radial-gradient(at bottom left,#000 0,transparent 71%),radial-gradient(at top left,#000 0,transparent 71%),radial-gradient(at top right,#000 0,transparent 71%);-webkit-mask-size:100% calc(100% - var(--_ngs-digit-roller-resolved-mask-height) * 2),calc(100% - var(--_ngs-digit-roller-scaled-mask-width) * 2) 100%,var(--_ngs-digit-roller-scaled-mask-width) var(--_ngs-digit-roller-resolved-mask-height),var(--_ngs-digit-roller-scaled-mask-width) var(--_ngs-digit-roller-resolved-mask-height),var(--_ngs-digit-roller-scaled-mask-width) var(--_ngs-digit-roller-resolved-mask-height),var(--_ngs-digit-roller-scaled-mask-width) var(--_ngs-digit-roller-resolved-mask-height);mask-size:100% calc(100% - var(--_ngs-digit-roller-resolved-mask-height) * 2),calc(100% - var(--_ngs-digit-roller-scaled-mask-width) * 2) 100%,var(--_ngs-digit-roller-scaled-mask-width) var(--_ngs-digit-roller-resolved-mask-height),var(--_ngs-digit-roller-scaled-mask-width) var(--_ngs-digit-roller-resolved-mask-height),var(--_ngs-digit-roller-scaled-mask-width) var(--_ngs-digit-roller-resolved-mask-height),var(--_ngs-digit-roller-scaled-mask-width) var(--_ngs-digit-roller-resolved-mask-height);-webkit-mask-position:center,center,top left,top right,bottom right,bottom left;mask-position:center,center,top left,top right,bottom right,bottom left;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat}ngs-digit-roller .ngs-digit-roller__number-inner{display:inline-flex;align-items:baseline;padding:var(--_ngs-digit-roller-half-mask-height) var(--ngs-digit-roller-mask-width);transform-origin:left top;transform:scaleX(calc(1 / var(--_ngs-digit-roller-scale-x))) translate(calc(-1 * var(--_ngs-digit-roller-dx)))}ngs-digit-roller .ngs-digit-roller__section{display:inline-flex;align-items:baseline}ngs-digit-roller .ngs-digit-roller__digit{display:inline-block;position:relative;height:calc(1em + var(--_ngs-digit-roller-resolved-mask-height, .25em));clip-path:inset(0 -.2em);vertical-align:top;--_ngs-digit-roller-c: var(--_ngs-digit-roller-current, 0) + var(--_ngs-digit-roller-d);--_ngs-digit-roller-len: 10}ngs-digit-roller .ngs-digit-roller__digit,ngs-digit-roller .ngs-digit-roller__separator,ngs-digit-roller .ngs-digit-roller__literal,ngs-digit-roller .ngs-digit-roller__ghost{opacity:calc(1 + var(--_ngs-digit-roller-d-opacity, 0))}ngs-digit-roller .ngs-digit-roller__digit-number{display:inline-block;height:1em;line-height:1;text-align:center;min-width:var(--ngs-digit-roller-min-digit-width);padding:var(--_ngs-digit-roller-half-mask-height, .125em) 0;box-sizing:content-box;--_ngs-digit-roller-offset-raw: mod( var(--_ngs-digit-roller-len) + var(--_ngs-digit-roller-n) - mod(var(--_ngs-digit-roller-c), var(--_ngs-digit-roller-len)), var(--_ngs-digit-roller-len) );--_ngs-digit-roller-offset: calc( var(--_ngs-digit-roller-offset-raw) - var(--_ngs-digit-roller-len) * round(down, var(--_ngs-digit-roller-offset-raw) / (var(--_ngs-digit-roller-len) / 2), 1) );--_ngs-digit-roller-y: clamp(-100%, var(--_ngs-digit-roller-offset) * 100%, 100%);transform:translateY(var(--_ngs-digit-roller-y))}ngs-digit-roller .ngs-digit-roller__digit-number[inert]{position:absolute;top:0;left:50%;transform:translate(-50%) translateY(var(--_ngs-digit-roller-y))}ngs-digit-roller .ngs-digit-roller__digit:not(.ngs-digit-roller__digit--spinning) .ngs-digit-roller__digit-number[inert]{display:none}ngs-digit-roller .ngs-digit-roller__separator,ngs-digit-roller .ngs-digit-roller__literal{display:inline-block}ngs-digit-roller .ngs-digit-roller__sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}ngs-digit-roller[data-animated=false] .ngs-digit-roller__digit-number,ngs-digit-roller[data-animated=false] .ngs-digit-roller__digit,ngs-digit-roller[data-animated=false] .ngs-digit-roller__separator,ngs-digit-roller[data-animated=false] .ngs-digit-roller__literal{transition:none!important;animation:none!important}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){:root,:host{--_ngs-digit-roller-d: 0;--_ngs-digit-roller-dx: 0px}*,:before,:after,::backdrop{--_ngs-digit-roller-d-opacity: 0;--_ngs-digit-roller-d-width: 0}}}\n/*! tailwindcss v4.2.2 | MIT License | https://tailwindcss.com */\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
681
+ }
682
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: DigitRoller, decorators: [{
683
+ type: Component,
684
+ args: [{ selector: 'ngs-digit-roller', exportAs: 'ngsDigitRoller', encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, host: {
685
+ class: 'ngs-digit-roller',
686
+ '[attr.data-animated]': 'animated()',
687
+ }, template: "<span class=\"ngs-digit-roller__number\" aria-hidden=\"true\">\n <span class=\"ngs-digit-roller__number-inner\">\n @if (data().pre.length) {\n <span class=\"ngs-digit-roller__section ngs-digit-roller__section--pre\">\n @for (part of data().pre; track part.key) {\n <span class=\"ngs-digit-roller__literal\" [attr.data-key]=\"part.key\">{{ part.value }}</span>\n }\n </span>\n }\n\n <span class=\"ngs-digit-roller__section ngs-digit-roller__section--integer\">\n @for (part of data().integer; track part.key) {\n @if (part.type === 'integer') {\n <span\n class=\"ngs-digit-roller__digit\"\n [attr.data-key]=\"part.key\"\n [style.--_ngs-digit-roller-current]=\"part.numericValue\"\n [style.--_ngs-digit-roller-len]=\"digitLengthForKey(part.key)\"\n >\n @for (digit of digitGlyphsForKey(part.key); track digit.value) {\n <span\n class=\"ngs-digit-roller__digit-number\"\n [style.--_ngs-digit-roller-n]=\"digit.value\"\n [attr.inert]=\"digit.value !== part.numericValue ? '' : null\"\n >\n {{ digit.glyph }}\n </span>\n }\n </span>\n } @else {\n <span class=\"ngs-digit-roller__separator\" [attr.data-key]=\"part.key\">{{ part.value }}</span>\n }\n }\n </span>\n\n @if (data().fraction.length) {\n <span class=\"ngs-digit-roller__section ngs-digit-roller__section--fraction\">\n @for (part of data().fraction; track part.key) {\n @if (part.type === 'fraction') {\n <span\n class=\"ngs-digit-roller__digit\"\n [attr.data-key]=\"part.key\"\n [style.--_ngs-digit-roller-current]=\"part.numericValue\"\n [style.--_ngs-digit-roller-len]=\"digitLengthForKey(part.key)\"\n >\n @for (digit of digitGlyphsForKey(part.key); track digit.value) {\n <span\n class=\"ngs-digit-roller__digit-number\"\n [style.--_ngs-digit-roller-n]=\"digit.value\"\n [attr.inert]=\"digit.value !== part.numericValue ? '' : null\"\n >\n {{ digit.glyph }}\n </span>\n }\n </span>\n } @else {\n <span class=\"ngs-digit-roller__separator\" [attr.data-key]=\"part.key\">{{ part.value }}</span>\n }\n }\n </span>\n }\n\n @if (data().post.length) {\n <span class=\"ngs-digit-roller__section ngs-digit-roller__section--post\">\n @for (part of data().post; track part.key) {\n <span class=\"ngs-digit-roller__literal\" [attr.data-key]=\"part.key\">{{ part.value }}</span>\n }\n </span>\n }\n </span>\n</span>\n\n<span class=\"ngs-digit-roller__sr-only\">{{ formattedPlainText() }}</span>\n", styles: ["@layer properties;@property --_ngs-digit-roller-d{syntax: \"<number>\"; inherits: true; initial-value: 0;}@property --_ngs-digit-roller-d-opacity{syntax: \"<number>\"; inherits: false; initial-value: 0;}@property --_ngs-digit-roller-d-width{syntax: \"<number>\"; inherits: false; initial-value: 0;}@property --_ngs-digit-roller-dx{syntax: \"<length>\"; inherits: true; initial-value: 0px;}ngs-digit-roller{--ngs-digit-roller-mask-height: .25em;--ngs-digit-roller-mask-width: .5em;--ngs-digit-roller-min-digit-width: .6em;display:inline-block;position:relative;direction:ltr;isolation:isolate;line-height:1;white-space:nowrap}ngs-digit-roller .ngs-digit-roller__number{--_ngs-digit-roller-width: 1;--_ngs-digit-roller-scale-x: calc( 1 + var(--_ngs-digit-roller-d-width) / var(--_ngs-digit-roller-width) );--_ngs-digit-roller-half-mask-height: round( nearest, calc(var(--ngs-digit-roller-mask-height) / 2), 1px );--_ngs-digit-roller-resolved-mask-height: calc(var(--_ngs-digit-roller-half-mask-height) * 2);--_ngs-digit-roller-scaled-mask-width: calc( var(--ngs-digit-roller-mask-width) / var(--_ngs-digit-roller-scale-x) );display:inline-block;line-height:1;font-variant-numeric:tabular-nums;font-feature-settings:\"tnum\";position:relative;transform-origin:left top;transform:translate(var(--_ngs-digit-roller-dx)) scaleX(var(--_ngs-digit-roller-scale-x));margin:0 calc(-1 * var(--ngs-digit-roller-mask-width));-webkit-mask-image:linear-gradient(to right,transparent 0,#000 var(--_ngs-digit-roller-scaled-mask-width),#000 calc(100% - var(--_ngs-digit-roller-scaled-mask-width)),transparent 100%),linear-gradient(to bottom,transparent 0,#000 var(--_ngs-digit-roller-resolved-mask-height),#000 calc(100% - var(--_ngs-digit-roller-resolved-mask-height)),transparent 100%),radial-gradient(at bottom right,#000 0,transparent 71%),radial-gradient(at bottom left,#000 0,transparent 71%),radial-gradient(at top left,#000 0,transparent 71%),radial-gradient(at top right,#000 0,transparent 71%);mask-image:linear-gradient(to right,transparent 0,#000 var(--_ngs-digit-roller-scaled-mask-width),#000 calc(100% - var(--_ngs-digit-roller-scaled-mask-width)),transparent 100%),linear-gradient(to bottom,transparent 0,#000 var(--_ngs-digit-roller-resolved-mask-height),#000 calc(100% - var(--_ngs-digit-roller-resolved-mask-height)),transparent 100%),radial-gradient(at bottom right,#000 0,transparent 71%),radial-gradient(at bottom left,#000 0,transparent 71%),radial-gradient(at top left,#000 0,transparent 71%),radial-gradient(at top right,#000 0,transparent 71%);-webkit-mask-size:100% calc(100% - var(--_ngs-digit-roller-resolved-mask-height) * 2),calc(100% - var(--_ngs-digit-roller-scaled-mask-width) * 2) 100%,var(--_ngs-digit-roller-scaled-mask-width) var(--_ngs-digit-roller-resolved-mask-height),var(--_ngs-digit-roller-scaled-mask-width) var(--_ngs-digit-roller-resolved-mask-height),var(--_ngs-digit-roller-scaled-mask-width) var(--_ngs-digit-roller-resolved-mask-height),var(--_ngs-digit-roller-scaled-mask-width) var(--_ngs-digit-roller-resolved-mask-height);mask-size:100% calc(100% - var(--_ngs-digit-roller-resolved-mask-height) * 2),calc(100% - var(--_ngs-digit-roller-scaled-mask-width) * 2) 100%,var(--_ngs-digit-roller-scaled-mask-width) var(--_ngs-digit-roller-resolved-mask-height),var(--_ngs-digit-roller-scaled-mask-width) var(--_ngs-digit-roller-resolved-mask-height),var(--_ngs-digit-roller-scaled-mask-width) var(--_ngs-digit-roller-resolved-mask-height),var(--_ngs-digit-roller-scaled-mask-width) var(--_ngs-digit-roller-resolved-mask-height);-webkit-mask-position:center,center,top left,top right,bottom right,bottom left;mask-position:center,center,top left,top right,bottom right,bottom left;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat}ngs-digit-roller .ngs-digit-roller__number-inner{display:inline-flex;align-items:baseline;padding:var(--_ngs-digit-roller-half-mask-height) var(--ngs-digit-roller-mask-width);transform-origin:left top;transform:scaleX(calc(1 / var(--_ngs-digit-roller-scale-x))) translate(calc(-1 * var(--_ngs-digit-roller-dx)))}ngs-digit-roller .ngs-digit-roller__section{display:inline-flex;align-items:baseline}ngs-digit-roller .ngs-digit-roller__digit{display:inline-block;position:relative;height:calc(1em + var(--_ngs-digit-roller-resolved-mask-height, .25em));clip-path:inset(0 -.2em);vertical-align:top;--_ngs-digit-roller-c: var(--_ngs-digit-roller-current, 0) + var(--_ngs-digit-roller-d);--_ngs-digit-roller-len: 10}ngs-digit-roller .ngs-digit-roller__digit,ngs-digit-roller .ngs-digit-roller__separator,ngs-digit-roller .ngs-digit-roller__literal,ngs-digit-roller .ngs-digit-roller__ghost{opacity:calc(1 + var(--_ngs-digit-roller-d-opacity, 0))}ngs-digit-roller .ngs-digit-roller__digit-number{display:inline-block;height:1em;line-height:1;text-align:center;min-width:var(--ngs-digit-roller-min-digit-width);padding:var(--_ngs-digit-roller-half-mask-height, .125em) 0;box-sizing:content-box;--_ngs-digit-roller-offset-raw: mod( var(--_ngs-digit-roller-len) + var(--_ngs-digit-roller-n) - mod(var(--_ngs-digit-roller-c), var(--_ngs-digit-roller-len)), var(--_ngs-digit-roller-len) );--_ngs-digit-roller-offset: calc( var(--_ngs-digit-roller-offset-raw) - var(--_ngs-digit-roller-len) * round(down, var(--_ngs-digit-roller-offset-raw) / (var(--_ngs-digit-roller-len) / 2), 1) );--_ngs-digit-roller-y: clamp(-100%, var(--_ngs-digit-roller-offset) * 100%, 100%);transform:translateY(var(--_ngs-digit-roller-y))}ngs-digit-roller .ngs-digit-roller__digit-number[inert]{position:absolute;top:0;left:50%;transform:translate(-50%) translateY(var(--_ngs-digit-roller-y))}ngs-digit-roller .ngs-digit-roller__digit:not(.ngs-digit-roller__digit--spinning) .ngs-digit-roller__digit-number[inert]{display:none}ngs-digit-roller .ngs-digit-roller__separator,ngs-digit-roller .ngs-digit-roller__literal{display:inline-block}ngs-digit-roller .ngs-digit-roller__sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}ngs-digit-roller[data-animated=false] .ngs-digit-roller__digit-number,ngs-digit-roller[data-animated=false] .ngs-digit-roller__digit,ngs-digit-roller[data-animated=false] .ngs-digit-roller__separator,ngs-digit-roller[data-animated=false] .ngs-digit-roller__literal{transition:none!important;animation:none!important}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){:root,:host{--_ngs-digit-roller-d: 0;--_ngs-digit-roller-dx: 0px}*,:before,:after,::backdrop{--_ngs-digit-roller-d-opacity: 0;--_ngs-digit-roller-d-width: 0}}}\n/*! tailwindcss v4.2.2 | MIT License | https://tailwindcss.com */\n"] }]
688
+ }], ctorParameters: () => [], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: true }] }], format: [{ type: i0.Input, args: [{ isSignal: true, alias: "format", required: false }] }], locales: [{ type: i0.Input, args: [{ isSignal: true, alias: "locales", required: false }] }], prefix: [{ type: i0.Input, args: [{ isSignal: true, alias: "prefix", required: false }] }], suffix: [{ type: i0.Input, args: [{ isSignal: true, alias: "suffix", required: false }] }], animated: [{ type: i0.Input, args: [{ isSignal: true, alias: "animated", required: false }] }], duration: [{ type: i0.Input, args: [{ isSignal: true, alias: "duration", required: false }] }], opacityDuration: [{ type: i0.Input, args: [{ isSignal: true, alias: "opacityDuration", required: false }] }], transformTiming: [{ type: i0.Input, args: [{ isSignal: true, alias: "transformTiming", required: false }] }], spinTiming: [{ type: i0.Input, args: [{ isSignal: true, alias: "spinTiming", required: false }] }], opacityTiming: [{ type: i0.Input, args: [{ isSignal: true, alias: "opacityTiming", required: false }] }], spinEasing: [{ type: i0.Input, args: [{ isSignal: true, alias: "spinEasing", required: false }] }], flipEasing: [{ type: i0.Input, args: [{ isSignal: true, alias: "flipEasing", required: false }] }], trend: [{ type: i0.Input, args: [{ isSignal: true, alias: "trend", required: false }] }], continuous: [{ type: i0.Input, args: [{ isSignal: true, alias: "continuous", required: false }] }], digits: [{ type: i0.Input, args: [{ isSignal: true, alias: "digits", required: false }] }], respectMotionPreference: [{ type: i0.Input, args: [{ isSignal: true, alias: "respectMotionPreference", required: false }] }], stagger: [{ type: i0.Input, args: [{ isSignal: true, alias: "stagger", required: false }] }], colorOnIncrease: [{ type: i0.Input, args: [{ isSignal: true, alias: "colorOnIncrease", required: false }] }], colorOnDecrease: [{ type: i0.Input, args: [{ isSignal: true, alias: "colorOnDecrease", required: false }] }], animationsStart: [{ type: i0.Output, args: ["animationsStart"] }], animationsFinish: [{ type: i0.Output, args: ["animationsFinish"] }] } });
689
+
690
+ class DigitRollerGroupDirective {
691
+ children = contentChildren(DigitRoller, { ...(ngDevMode ? { debugName: "children" } : /* istanbul ignore next */ {}), descendants: true });
692
+ pendingUpdates = new Map();
693
+ flushQueued = false;
694
+ requestGroupedUpdate(member, applyUpdate) {
695
+ if (!member.canGroupAnimateNow()) {
696
+ return false;
697
+ }
698
+ this.pendingUpdates.set(member, applyUpdate);
699
+ if (!this.flushQueued) {
700
+ this.flushQueued = true;
701
+ queueMicrotask(() => this.flushGroupedUpdates());
702
+ }
703
+ return true;
704
+ }
705
+ flushGroupedUpdates() {
706
+ this.flushQueued = false;
707
+ if (this.pendingUpdates.size === 0) {
708
+ return;
709
+ }
710
+ const members = this.children().filter((child) => child.canGroupAnimateNow());
711
+ for (const member of members) {
712
+ member.prepareGroupedUpdate();
713
+ }
714
+ for (const applyUpdate of this.pendingUpdates.values()) {
715
+ applyUpdate();
716
+ }
717
+ this.pendingUpdates.clear();
718
+ for (const member of members) {
719
+ member.queueGroupedAnimation();
720
+ }
721
+ }
722
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: DigitRollerGroupDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
723
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.2.0", version: "21.2.4", type: DigitRollerGroupDirective, isStandalone: true, selector: "[ngsDigitRollerGroup]", providers: [
724
+ {
725
+ provide: DIGIT_ROLLER_GROUP,
726
+ useExisting: forwardRef(() => DigitRollerGroupDirective),
727
+ },
728
+ ], queries: [{ propertyName: "children", predicate: DigitRoller, descendants: true, isSignal: true }], ngImport: i0 });
729
+ }
730
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: DigitRollerGroupDirective, decorators: [{
731
+ type: Directive,
732
+ args: [{
733
+ selector: '[ngsDigitRollerGroup]',
734
+ providers: [
735
+ {
736
+ provide: DIGIT_ROLLER_GROUP,
737
+ useExisting: forwardRef(() => DigitRollerGroupDirective),
738
+ },
739
+ ],
740
+ }]
741
+ }], propDecorators: { children: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => DigitRoller), { ...{ descendants: true }, isSignal: true }] }] } });
742
+
743
+ /**
744
+ * Generated bundle index. Do not edit.
745
+ */
746
+
747
+ export { DIGIT_ROLLER_EMPTY_FORMATTED, DigitRoller, DigitRollerGroupDirective };
748
+ //# sourceMappingURL=ngstarter-ui-components-digit-roller.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ngstarter-ui-components-digit-roller.mjs","sources":["../../../projects/components/digit-roller/src/digit-roller-capabilities.ts","../../../projects/components/digit-roller/src/digit-roller-formatter.ts","../../../projects/components/digit-roller/src/digit-roller-group.token.ts","../../../projects/components/digit-roller/src/digit-roller.types.ts","../../../projects/components/digit-roller/src/digit-roller/digit-roller.ts","../../../projects/components/digit-roller/src/digit-roller/digit-roller.html","../../../projects/components/digit-roller/src/digit-roller-group.directive.ts","../../../projects/components/digit-roller/ngstarter-ui-components-digit-roller.ts"],"sourcesContent":["export interface DigitRollerCapabilityOptions {\n respectMotionPreference?: boolean;\n}\n\nlet staticCapable: boolean | undefined;\nlet prefersReducedMotion: boolean | undefined;\n\nfunction isStaticallyCapable(): boolean {\n if (staticCapable !== undefined) {\n return staticCapable;\n }\n\n staticCapable =\n typeof window !== 'undefined' &&\n typeof window.CSS !== 'undefined' &&\n typeof window.Element !== 'undefined' &&\n typeof window.Element.prototype.animate === 'function' &&\n typeof window.CSS.registerProperty === 'function' &&\n window.CSS.supports('width', 'calc(mod(2, 10) * 1px)') &&\n supportsLinearEasing();\n\n return staticCapable;\n}\n\nfunction getPrefersReducedMotion(): boolean {\n if (prefersReducedMotion !== undefined) {\n return prefersReducedMotion;\n }\n\n if (typeof window === 'undefined' || !window.matchMedia) {\n return false;\n }\n\n const mediaQuery = window.matchMedia('(prefers-reduced-motion: reduce)');\n prefersReducedMotion = mediaQuery.matches;\n\n if (typeof mediaQuery.addEventListener === 'function') {\n mediaQuery.addEventListener('change', (event) => {\n prefersReducedMotion = event.matches;\n });\n }\n\n return prefersReducedMotion;\n}\n\nexport function resetDigitRollerCapabilityCache(): void {\n staticCapable = undefined;\n prefersReducedMotion = undefined;\n}\n\nexport function canAnimateDigitRoller(options: DigitRollerCapabilityOptions = {}): boolean {\n if (!isStaticallyCapable()) {\n return false;\n }\n\n return options.respectMotionPreference === false || !getPrefersReducedMotion();\n}\n\nfunction supportsLinearEasing(): boolean {\n try {\n document.createElement('div').animate({ opacity: 0 }, { easing: 'linear(0, 1)' });\n return true;\n } catch {\n return false;\n }\n}\n","import {\n DigitRollerFormattedNumber,\n DigitRollerNumberPart,\n} from './digit-roller.types';\n\nconst PRE_TYPES = new Set(['currency', 'literal', 'minusSign', 'plusSign', 'nan', 'infinity']);\nconst POST_TYPES = new Set(['percentSign', 'unit']);\n\nconst formatterCache = new Map<string, Intl.NumberFormat>();\n\nfunction getCachedFormatter(\n locales: string | string[] | undefined,\n options: Intl.NumberFormatOptions,\n): Intl.NumberFormat {\n const key = JSON.stringify(locales) + ':' + JSON.stringify(options);\n let formatter = formatterCache.get(key);\n\n if (!formatter) {\n formatter = new Intl.NumberFormat(locales, options);\n formatterCache.set(key, formatter);\n }\n\n return formatter;\n}\n\nexport interface DigitRollerGlyph {\n value: number;\n glyph: string;\n}\n\nexport function getDigitRollerGlyphs(\n locales?: string | string[],\n options: Intl.NumberFormatOptions = {},\n): DigitRollerGlyph[] {\n const formatter = getCachedFormatter(locales, {\n numberingSystem: options.numberingSystem,\n useGrouping: false,\n maximumFractionDigits: 0,\n });\n\n return Array.from({ length: 10 }, (_, value) => ({\n value,\n glyph: formatter.format(value),\n }));\n}\n\nfunction getDigitValueMap(\n locales?: string | string[],\n options: Intl.NumberFormatOptions = {},\n): Map<string, number> {\n return new Map(getDigitRollerGlyphs(locales, options).map(({ glyph, value }) => [glyph, value]));\n}\n\nexport function formatDigitRollerValue(\n value: number,\n options: Intl.NumberFormatOptions = {},\n locales?: string | string[],\n prefix = '',\n suffix = '',\n): DigitRollerFormattedNumber {\n const formatter = getCachedFormatter(locales, options);\n const digitValues = getDigitValueMap(locales, options);\n const parts = formatter.formatToParts(value);\n\n const pre: DigitRollerNumberPart[] = [];\n const rawInteger: Intl.NumberFormatPart[] = [];\n const fraction: DigitRollerNumberPart[] = [];\n const post: DigitRollerNumberPart[] = [];\n\n let seenInteger = false;\n let seenDecimal = false;\n\n for (const part of parts) {\n if (part.type === 'integer' || part.type === 'group') {\n seenInteger = true;\n rawInteger.push(part);\n } else if (part.type === 'decimal' || part.type === 'fraction') {\n seenDecimal = true;\n fraction.push({ type: part.type, value: part.value, key: '' });\n } else if (!seenInteger && PRE_TYPES.has(part.type)) {\n pre.push({ type: part.type, value: part.value, key: `pre-${pre.length}` });\n } else if (seenInteger && POST_TYPES.has(part.type)) {\n post.push({ type: part.type, value: part.value, key: `post-${post.length}` });\n } else if (seenDecimal || seenInteger) {\n post.push({ type: part.type, value: part.value, key: `post-${post.length}` });\n } else {\n pre.push({ type: part.type, value: part.value, key: `pre-${pre.length}` });\n }\n }\n\n if (prefix) {\n pre.unshift({ type: 'prefix', value: prefix, key: '__prefix' });\n }\n\n if (suffix) {\n post.push({ type: 'suffix', value: suffix, key: '__suffix' });\n }\n\n const splitInteger: Intl.NumberFormatPart[] = [];\n for (const part of rawInteger) {\n if (part.type === 'integer') {\n for (const char of part.value) {\n splitInteger.push({ type: 'integer', value: char });\n }\n } else {\n splitInteger.push(part);\n }\n }\n\n let digitIndex = 0;\n const reversedInteger: DigitRollerNumberPart[] = [];\n for (let i = splitInteger.length - 1; i >= 0; i--) {\n const part = splitInteger[i];\n if (part.type === 'integer') {\n reversedInteger.push({\n type: 'integer',\n value: part.value,\n key: `i${digitIndex}`,\n numericValue: digitValues.get(part.value) ?? Number(part.value),\n });\n digitIndex++;\n } else {\n reversedInteger.push({ type: 'group', value: part.value, key: `g${digitIndex}` });\n }\n }\n\n let fractionDigitIndex = 0;\n const keyedFraction: DigitRollerNumberPart[] = [];\n for (const part of fraction) {\n if (part.type === 'fraction') {\n for (const char of part.value) {\n keyedFraction.push({\n type: 'fraction',\n value: char,\n key: `f${++fractionDigitIndex}`,\n numericValue: digitValues.get(char) ?? Number(char),\n });\n }\n } else {\n keyedFraction.push({ ...part, key: 'decimal' });\n }\n }\n\n return { pre, integer: reversedInteger.reverse(), fraction: keyedFraction, post };\n}\n","import { InjectionToken } from '@angular/core';\n\nexport interface DigitRollerGroupMember {\n canGroupAnimateNow(): boolean;\n prepareGroupedUpdate(): void;\n queueGroupedAnimation(): void;\n}\n\nexport interface DigitRollerGroupCoordinator {\n requestGroupedUpdate(member: DigitRollerGroupMember, applyUpdate: () => void): boolean;\n}\n\nexport const DIGIT_ROLLER_GROUP = new InjectionToken<DigitRollerGroupCoordinator>('DIGIT_ROLLER_GROUP');\n","export interface DigitRollerNumberPart {\n type: string;\n value: string;\n key: string;\n numericValue?: number;\n}\n\nexport interface DigitRollerFormattedNumber {\n pre: DigitRollerNumberPart[];\n integer: DigitRollerNumberPart[];\n fraction: DigitRollerNumberPart[];\n post: DigitRollerNumberPart[];\n}\n\nexport const DIGIT_ROLLER_EMPTY_FORMATTED: DigitRollerFormattedNumber = {\n pre: [],\n integer: [],\n fraction: [],\n post: [],\n};\n\nexport type DigitRollerTrend = number | ((oldValue: number, value: number) => number);\n\nexport type DigitRollerTiming = Omit<KeyframeAnimationOptions, 'composite'>;\n\nexport type DigitRollerEasing = 'default' | 'spring' | 'overshoot' | (string & {});\n\nexport interface DigitRollerDigitConfig {\n max?: number;\n}\n\nexport type DigitRollerDigits = Record<number, DigitRollerDigitConfig>;\n","import { isPlatformBrowser } from '@angular/common';\nimport {\n afterEveryRender,\n ChangeDetectionStrategy,\n Component,\n computed,\n DestroyRef,\n effect,\n ElementRef,\n inject,\n input,\n output,\n PLATFORM_ID,\n signal,\n untracked,\n ViewEncapsulation,\n} from '@angular/core';\nimport { canAnimateDigitRoller } from '../digit-roller-capabilities';\nimport { getDigitRollerGlyphs, formatDigitRollerValue } from '../digit-roller-formatter';\nimport { DIGIT_ROLLER_GROUP } from '../digit-roller-group.token';\nimport {\n DIGIT_ROLLER_EMPTY_FORMATTED,\n DigitRollerDigits,\n DigitRollerEasing,\n DigitRollerFormattedNumber,\n DigitRollerTiming,\n DigitRollerTrend,\n} from '../digit-roller.types';\n\nconst SPIN_EASING =\n 'linear(0,.005,.019,.039,.066,.096,.129,.165,.202,.24,.278,.316,.354,.39,.426,.461,' +\n '.494,.526,.557,.586,.614,.64,.665,.689,.711,.731,.751,.769,.786,.802,.817,.831,.844,' +\n '.856,.867,.877,.887,.896,.904,.912,.919,.925,.931,.937,.942,.947,.951,.955,.959,.962,' +\n '.965,.968,.971,.973,.976,.978,.98,.981,.983,.984,.986,.987,.988,.989,.99,.991,.992,' +\n '.992,.993,.994,.994,.995,.995,.996,.996,.9963,.9967,.9969,.9972,.9975,.9977,.9979,' +\n '.9981,.9982,.9984,.9985,.9987,.9988,.9989,1)';\n\nconst EASING_PRESETS: Record<string, string> = {\n default: SPIN_EASING,\n spring: SPIN_EASING,\n overshoot: 'cubic-bezier(0.34, 1.56, 0.64, 1)',\n};\n\n@Component({\n selector: 'ngs-digit-roller',\n exportAs: 'ngsDigitRoller',\n templateUrl: './digit-roller.html',\n styleUrl: './digit-roller.scss',\n encapsulation: ViewEncapsulation.None,\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n class: 'ngs-digit-roller',\n '[attr.data-animated]': 'animated()',\n },\n})\nexport class DigitRoller {\n value = input.required<number>();\n format = input<Intl.NumberFormatOptions>({});\n locales = input<string | string[] | undefined>(undefined);\n prefix = input('');\n suffix = input('');\n animated = input(true);\n\n duration = input<number | undefined>(undefined);\n opacityDuration = input<number | undefined>(undefined);\n transformTiming = input<DigitRollerTiming | undefined>(undefined);\n spinTiming = input<DigitRollerTiming | undefined>(undefined);\n opacityTiming = input<DigitRollerTiming | undefined>(undefined);\n\n spinEasing = input<DigitRollerEasing | undefined>(undefined);\n flipEasing = input<DigitRollerEasing | undefined>(undefined);\n trend = input<DigitRollerTrend | undefined>(undefined);\n\n continuous = input(false);\n digits = input<DigitRollerDigits>({});\n respectMotionPreference = input(true);\n stagger = input(0);\n colorOnIncrease = input<string | undefined>(undefined);\n colorOnDecrease = input<string | undefined>(undefined);\n\n animationsStart = output<void>();\n animationsFinish = output<void>();\n\n protected data = signal<DigitRollerFormattedNumber>(DIGIT_ROLLER_EMPTY_FORMATTED);\n protected digitGlyphs = computed(() => getDigitRollerGlyphs(this.locales(), this.format()));\n protected formattedPlainText = computed(() =>\n new Intl.NumberFormat(this.locales(), this.format()).format(this.value()),\n );\n protected effectiveSettings = computed(() => {\n const duration = this.duration() ?? 900;\n\n return {\n duration,\n opacityDuration: this.opacityDuration() ?? 450,\n spinEasing: this.resolveEasing(this.spinEasing()),\n flipEasing: this.resolveEasing(this.flipEasing()),\n transformTiming: this.transformTiming(),\n spinTiming: this.spinTiming(),\n opacityTiming: this.opacityTiming(),\n };\n });\n\n private platformId = inject(PLATFORM_ID);\n private elementRef = inject<ElementRef<HTMLElement>>(ElementRef);\n private destroyRef = inject(DestroyRef);\n private group = inject(DIGIT_ROLLER_GROUP, { optional: true });\n\n private prevRects = new Map<string, DOMRect>();\n private prevInnerHTML = new Map<string, string>();\n private prevDigitD = new Map<string, string>();\n private prevDigitCurrent = new Map<string, string>();\n private prevDigitValues = new Map<string, number>();\n private prevDigitOrder: string[] = [];\n private prevNumberLeft = 0;\n private prevNumberWidth = 0;\n private prevNumericValue = 0;\n\n private animCount = 0;\n private pending = false;\n private destroyed = false;\n private hasRenderedValue = false;\n private liveAnimations: Animation[] = [];\n private spinCount = new Map<HTMLElement, number>();\n private animationsFinishAbort?: AbortController;\n private pendingCanAnimate = false;\n private pendingHostFont = '';\n private pendingHostColor = '';\n private pendingKeyedEls: Array<{ el: HTMLElement; key: string; newRect: DOMRect }> = [];\n private pendingNumberRect: DOMRect | null = null;\n private pendingNumberOffsetWidth = 0;\n private isNearViewport = true;\n private viewportObserver?: IntersectionObserver;\n\n constructor() {\n this.destroyRef.onDestroy(() => {\n this.destroyed = true;\n this.animationsFinishAbort?.abort();\n this.viewportObserver?.disconnect();\n\n for (const animation of this.liveAnimations) {\n try {\n animation.cancel();\n } catch {\n /* Animation cancellation can throw AbortError in some browsers. */\n }\n }\n\n this.liveAnimations = [];\n });\n\n effect(() => {\n const value = this.value();\n const format = this.format();\n const locales = this.locales();\n const prefix = this.prefix();\n const suffix = this.suffix();\n\n if (!this.hasRenderedValue) {\n untracked(() => this.data.set(formatDigitRollerValue(value, format, locales, prefix, suffix)));\n this.prevNumericValue = value;\n this.hasRenderedValue = true;\n return;\n }\n\n const canAnimateThisUpdate =\n isPlatformBrowser(this.platformId) && this.animated() && this.canAnimateNow();\n\n if (canAnimateThisUpdate) {\n const handledByGroup = this.group?.requestGroupedUpdate(this, () => {\n untracked(() => this.data.set(formatDigitRollerValue(value, format, locales, prefix, suffix)));\n });\n\n if (handledByGroup) {\n return;\n }\n\n this.snapshot();\n untracked(() => this.data.set(formatDigitRollerValue(value, format, locales, prefix, suffix)));\n this.pending = true;\n } else {\n untracked(() => this.data.set(formatDigitRollerValue(value, format, locales, prefix, suffix)));\n this.prevNumericValue = value;\n }\n });\n\n if (isPlatformBrowser(this.platformId)) {\n if (typeof IntersectionObserver !== 'undefined') {\n this.viewportObserver = new IntersectionObserver(\n (entries) => {\n this.isNearViewport = entries[entries.length - 1].isIntersecting;\n },\n { rootMargin: '240px' },\n );\n this.viewportObserver.observe(this.elementRef.nativeElement);\n }\n\n afterEveryRender({\n earlyRead: () => {\n if (this.pending) {\n this.readAnimationState();\n }\n },\n write: () => {\n if (this.pending) {\n this.pending = false;\n this.fireAnimations();\n }\n },\n });\n }\n }\n\n canGroupAnimateNow(): boolean {\n return isPlatformBrowser(this.platformId) && this.animated() && this.canAnimateNow();\n }\n\n prepareGroupedUpdate(): void {\n this.snapshot();\n }\n\n queueGroupedAnimation(): void {\n this.pending = true;\n }\n\n private snapshot(): void {\n const host = this.elementRef.nativeElement;\n this.prevRects.clear();\n this.prevInnerHTML.clear();\n this.prevDigitD.clear();\n this.prevDigitCurrent.clear();\n this.prevDigitValues.clear();\n this.prevDigitOrder = [];\n\n const number = host.querySelector<HTMLElement>('.ngs-digit-roller__number');\n if (number) {\n const numberRect = number.getBoundingClientRect();\n this.prevNumberLeft = numberRect.left;\n this.prevNumberWidth = numberRect.width;\n }\n\n untracked(() => {\n [...this.data().integer, ...this.data().fraction].forEach((part) => {\n if (part.type === 'integer' || part.type === 'fraction') {\n this.prevDigitValues.set(part.key, this.getPartDigitValue(part));\n this.prevDigitOrder.push(part.key);\n }\n });\n });\n\n host.querySelectorAll<HTMLElement>('[data-key]').forEach((element) => {\n const key = element.getAttribute('data-key')!;\n this.prevRects.set(key, element.getBoundingClientRect());\n this.prevInnerHTML.set(key, element.innerHTML);\n\n if (element.classList.contains('ngs-digit-roller__digit')) {\n const styles = getComputedStyle(element);\n this.prevDigitD.set(key, styles.getPropertyValue('--_ngs-digit-roller-d').trim() || '0');\n this.prevDigitCurrent.set(\n key,\n (element.style.getPropertyValue('--_ngs-digit-roller-current') || '0').trim(),\n );\n }\n });\n }\n\n private readAnimationState(): void {\n if (this.destroyed || !this.canAnimateNow()) {\n this.pendingCanAnimate = false;\n return;\n }\n\n this.pendingCanAnimate = true;\n const host = this.elementRef.nativeElement;\n const hostStyles = getComputedStyle(host);\n\n this.pendingHostFont = hostStyles.font;\n this.pendingHostColor = hostStyles.color;\n this.pendingKeyedEls = [];\n\n host.querySelectorAll<HTMLElement>('[data-key]').forEach((element) => {\n this.pendingKeyedEls.push({\n el: element,\n key: element.getAttribute('data-key')!,\n newRect: element.getBoundingClientRect(),\n });\n });\n\n const number = host.querySelector<HTMLElement>('.ngs-digit-roller__number');\n this.pendingNumberRect = number ? number.getBoundingClientRect() : null;\n this.pendingNumberOffsetWidth = number ? number.offsetWidth : 0;\n }\n\n private fireAnimations(): void {\n if (this.destroyed) {\n return;\n }\n\n const host = this.elementRef.nativeElement;\n const newNumericValue = untracked(() => this.value());\n\n if (!this.pendingCanAnimate) {\n this.prevNumericValue = newNumericValue;\n return;\n }\n\n const settings = this.effectiveSettings();\n const duration = settings.duration;\n const opacityDuration = settings.opacityDuration;\n const trend = this.resolveTrend(this.prevNumericValue, newNumericValue);\n const staggerMs = this.stagger();\n\n const baseTransformTiming = settings.transformTiming ?? {\n duration,\n easing: settings.flipEasing,\n };\n const spinOptions: KeyframeAnimationOptions = {\n ...baseTransformTiming,\n easing: settings.spinEasing,\n ...(settings.spinTiming ?? {}),\n duration: settings.spinTiming?.duration ?? baseTransformTiming.duration,\n fill: 'none',\n composite: 'accumulate',\n };\n const flipOptions: KeyframeAnimationOptions = {\n ...baseTransformTiming,\n duration: baseTransformTiming.duration,\n fill: 'none',\n composite: 'accumulate',\n };\n const fadeOptions: KeyframeAnimationOptions = {\n duration: opacityDuration,\n easing: 'ease-out',\n fill: 'none',\n composite: 'accumulate',\n ...(settings.opacityTiming ?? {}),\n };\n\n const continuousStartPosition =\n this.continuous() && duration > 0 && trend !== 0 ? this.getContinuousStartPosition() : undefined;\n\n const batch: Animation[] = [];\n const newKeys = new Set<string>();\n let elementIndex = 0;\n const number = host.querySelector<HTMLElement>('.ngs-digit-roller__number');\n\n for (const { el, key, newRect } of this.pendingKeyedEls) {\n newKeys.add(key);\n const prevRect = this.prevRects.get(key);\n const staggerDelay = staggerMs > 0 ? elementIndex * staggerMs : 0;\n elementIndex++;\n\n if (el.classList.contains('ngs-digit-roller__digit')) {\n const digit = this.getDigitValue(key);\n const fromDigit = this.prevDigitValues.has(key) ? this.prevDigitValues.get(key)! : 0;\n const rawDelta = this.getTrendDelta(fromDigit, digit, trend, this.getDigitLength(key));\n const digitPosition = this.getDigitPosition(key);\n const isLowerUnchanged =\n this.continuous() &&\n rawDelta === 0 &&\n continuousStartPosition !== undefined &&\n digitPosition !== undefined &&\n continuousStartPosition >= digitPosition;\n const delta = isLowerUnchanged ? this.getDigitLength(key) * trend : rawDelta;\n\n if (delta !== 0 && duration > 0) {\n this.incrementSpin(el);\n const animation = el.animate(\n { '--_ngs-digit-roller-d': [-delta, 0] } as PropertyIndexedKeyframes,\n spinOptions,\n );\n batch.push(animation);\n animation.finished.then(() => this.decrementSpin(el)).catch(() => this.decrementSpin(el));\n }\n\n this.animatePositionOrFade(el, prevRect, newRect, flipOptions, fadeOptions, staggerDelay, batch);\n } else {\n this.animatePositionOrFade(el, prevRect, newRect, flipOptions, fadeOptions, staggerDelay, batch);\n }\n }\n\n let exitIndex = 0;\n this.prevRects.forEach((rect, key) => {\n if (newKeys.has(key)) {\n return;\n }\n\n const ghost = this.buildGhost(key, rect, this.pendingHostFont, this.pendingHostColor);\n host.appendChild(ghost);\n ghost.style.setProperty('--_ngs-digit-roller-d-opacity', '-0.999');\n\n const staggerDelay = staggerMs > 0 ? exitIndex * staggerMs : 0;\n exitIndex++;\n\n const animation = ghost.animate(\n { '--_ngs-digit-roller-d-opacity': [0.999, 0] } as PropertyIndexedKeyframes,\n this.addStaggerDelay(fadeOptions, staggerDelay),\n );\n batch.push(animation);\n animation.finished.then(() => ghost.remove()).catch(() => ghost.remove());\n });\n\n if (number && this.pendingNumberRect) {\n const rect = this.pendingNumberRect;\n const dx = this.prevNumberLeft - rect.left;\n const width = rect.width || this.pendingNumberOffsetWidth;\n const dWidth = this.prevNumberWidth - width;\n\n number.style.setProperty('--_ngs-digit-roller-width', String(width || this.prevNumberWidth || 1));\n\n if (Math.abs(dx) > 0.5 || Math.abs(dWidth) > 0.5) {\n batch.push(\n number.animate(\n {\n '--_ngs-digit-roller-dx': [`${dx}px`, '0px'],\n '--_ngs-digit-roller-d-width': [dWidth, 0],\n } as PropertyIndexedKeyframes,\n flipOptions,\n ),\n );\n }\n }\n\n if (duration > 0) {\n const colorIncrease = this.colorOnIncrease();\n const colorDecrease = this.colorOnDecrease();\n\n if (trend > 0 && colorIncrease) {\n batch.push(\n host.animate([{ color: colorIncrease }, { color: '' }], {\n duration: Math.max(duration, 400),\n easing: 'ease-out',\n fill: 'none',\n }),\n );\n } else if (trend < 0 && colorDecrease) {\n batch.push(\n host.animate([{ color: colorDecrease }, { color: '' }], {\n duration: Math.max(duration, 400),\n easing: 'ease-out',\n fill: 'none',\n }),\n );\n }\n }\n\n this.prevNumericValue = newNumericValue;\n\n if (batch.length === 0) {\n return;\n }\n\n this.liveAnimations.push(...batch);\n this.animCount++;\n\n if (this.animationsFinishAbort) {\n this.animationsFinishAbort.abort();\n } else {\n this.animationsStart.emit();\n }\n\n const finishController = new AbortController();\n this.animationsFinishAbort = finishController;\n\n Promise.allSettled(batch.map((animation) => animation.finished)).then(() => {\n const batchSet = new Set(batch);\n this.liveAnimations = this.liveAnimations.filter((animation) => !batchSet.has(animation));\n this.animCount--;\n\n if (this.animCount === 0 && !this.destroyed && this.animationsFinishAbort) {\n this.animationsFinish.emit();\n this.animationsFinishAbort = undefined;\n }\n });\n }\n\n private animatePositionOrFade(\n element: HTMLElement,\n prevRect: DOMRect | undefined,\n newRect: DOMRect,\n flipOptions: KeyframeAnimationOptions,\n fadeOptions: KeyframeAnimationOptions,\n staggerDelay: number,\n batch: Animation[],\n ): void {\n if (prevRect) {\n const dx = prevRect.left - newRect.left;\n\n if (Math.abs(dx) > 0.5) {\n batch.push(\n element.animate(\n [{ transform: `translateX(${dx}px)` }, { transform: 'translateX(0)' }],\n flipOptions,\n ),\n );\n }\n } else {\n batch.push(\n element.animate(\n { '--_ngs-digit-roller-d-opacity': [-0.9999, 0] } as PropertyIndexedKeyframes,\n this.addStaggerDelay(fadeOptions, staggerDelay),\n ),\n );\n }\n }\n\n private getDigitValue(key: string): number {\n const part = [...this.data().integer, ...this.data().fraction].find((item) => item.key === key);\n return part ? this.getPartDigitValue(part) : 0;\n }\n\n private getPartDigitValue(part: { value: string; numericValue?: number }): number {\n return part.numericValue ?? Number(part.value);\n }\n\n private resolveTrend(oldValue: number, newValue: number): number {\n const configured = this.trend();\n const trend =\n typeof configured === 'function'\n ? configured(oldValue, newValue)\n : (configured ?? Math.sign(newValue - oldValue));\n return Math.sign(trend);\n }\n\n private canAnimateNow(): boolean {\n const host = this.elementRef.nativeElement;\n\n return (\n canAnimateDigitRoller({ respectMotionPreference: this.respectMotionPreference() }) &&\n this.animated() &&\n host.ownerDocument.visibilityState === 'visible' &&\n this.isHostNearViewport(host)\n );\n }\n\n private isHostNearViewport(host: HTMLElement): boolean {\n if (this.viewportObserver) {\n return this.isNearViewport;\n }\n\n const rect = host.getBoundingClientRect();\n if (rect.width <= 0 || rect.height <= 0) {\n return false;\n }\n\n const windowRef = host.ownerDocument.defaultView;\n if (!windowRef) {\n return true;\n }\n\n const margin = 240;\n return (\n rect.bottom >= -margin &&\n rect.right >= -margin &&\n rect.top <= windowRef.innerHeight + margin &&\n rect.left <= windowRef.innerWidth + margin\n );\n }\n\n private resolveEasing(easing: DigitRollerEasing | undefined): string {\n return easing ? (EASING_PRESETS[easing] ?? easing) : SPIN_EASING;\n }\n\n private getContinuousStartPosition(): number | undefined {\n const current = new Map<string, number>();\n const currentOrder: string[] = [];\n\n untracked(() => {\n [...this.data().integer, ...this.data().fraction].forEach((part) => {\n if (part.type === 'integer' || part.type === 'fraction') {\n current.set(part.key, this.getPartDigitValue(part));\n currentOrder.push(part.key);\n }\n });\n });\n\n const firstChangedPrev = this.prevDigitOrder.find(\n (key) => current.get(key) !== this.prevDigitValues.get(key),\n );\n const firstChangedCurrent = currentOrder.find(\n (key) => current.get(key) !== this.prevDigitValues.get(key),\n );\n const start = Math.max(\n this.getDigitPosition(firstChangedPrev) ?? -Infinity,\n this.getDigitPosition(firstChangedCurrent) ?? -Infinity,\n );\n\n return Number.isFinite(start) ? start : undefined;\n }\n\n private getDigitPosition(key?: string): number | undefined {\n if (!key) {\n return undefined;\n }\n\n if (key.startsWith('i')) {\n return Number(key.slice(1));\n }\n\n if (key.startsWith('f')) {\n return -Number(key.slice(1));\n }\n\n return undefined;\n }\n\n private getDigitLength(key: string): number {\n if (!key.startsWith('i')) {\n return 10;\n }\n\n const position = Number(key.slice(1));\n const max = this.digits()[position]?.max;\n return max !== undefined ? max + 1 : 10;\n }\n\n protected digitLengthForKey(key: string): number {\n return this.getDigitLength(key);\n }\n\n protected digitGlyphsForKey(key: string): { value: number; glyph: string }[] {\n return this.digitGlyphs().slice(0, this.getDigitLength(key));\n }\n\n private addStaggerDelay(\n options: KeyframeAnimationOptions,\n staggerDelay: number,\n ): KeyframeAnimationOptions {\n const currentDelay = typeof options.delay === 'number' ? options.delay : 0;\n return { ...options, delay: currentDelay + staggerDelay };\n }\n\n private getTrendDelta(from: number, to: number, trend: number, length = 10): number {\n const diff = to - from;\n const resolvedTrend = trend || Math.sign(diff);\n\n if (resolvedTrend > 0 && to < from) {\n return length - from + to;\n }\n\n if (resolvedTrend < 0 && to > from) {\n return to - length - from;\n }\n\n return diff;\n }\n\n private incrementSpin(element: HTMLElement): void {\n const count = (this.spinCount.get(element) ?? 0) + 1;\n this.spinCount.set(element, count);\n\n if (count === 1) {\n element.classList.add('ngs-digit-roller__digit--spinning');\n }\n }\n\n private decrementSpin(element: HTMLElement): void {\n const count = Math.max(0, (this.spinCount.get(element) ?? 1) - 1);\n\n if (count === 0) {\n this.spinCount.delete(element);\n element.classList.remove('ngs-digit-roller__digit--spinning');\n } else {\n this.spinCount.set(element, count);\n }\n }\n\n private buildGhost(key: string, rect: DOMRect, font: string, color: string): HTMLElement {\n const ghost = document.createElement('span');\n ghost.style.cssText =\n `position:fixed;left:${rect.left}px;top:${rect.top}px;` +\n `width:${rect.width}px;height:${rect.height}px;` +\n `pointer-events:none;overflow:hidden;display:inline-flex;` +\n `align-items:center;font:${font};color:${color}`;\n ghost.className = 'ngs-digit-roller__ghost';\n\n const savedHTML = this.prevInnerHTML.get(key);\n if (savedHTML) {\n ghost.innerHTML = savedHTML;\n\n const savedD = this.prevDigitD.get(key);\n const savedCurrent = this.prevDigitCurrent.get(key);\n\n if (savedD !== undefined) {\n ghost.style.setProperty('--_ngs-digit-roller-d', savedD);\n }\n\n if (savedCurrent !== undefined) {\n ghost.style.setProperty('--_ngs-digit-roller-current', savedCurrent);\n }\n\n ghost.querySelectorAll<HTMLElement>('[inert]').forEach((element) => {\n element.style.display = 'none';\n });\n }\n\n return ghost;\n }\n}\n","<span class=\"ngs-digit-roller__number\" aria-hidden=\"true\">\n <span class=\"ngs-digit-roller__number-inner\">\n @if (data().pre.length) {\n <span class=\"ngs-digit-roller__section ngs-digit-roller__section--pre\">\n @for (part of data().pre; track part.key) {\n <span class=\"ngs-digit-roller__literal\" [attr.data-key]=\"part.key\">{{ part.value }}</span>\n }\n </span>\n }\n\n <span class=\"ngs-digit-roller__section ngs-digit-roller__section--integer\">\n @for (part of data().integer; track part.key) {\n @if (part.type === 'integer') {\n <span\n class=\"ngs-digit-roller__digit\"\n [attr.data-key]=\"part.key\"\n [style.--_ngs-digit-roller-current]=\"part.numericValue\"\n [style.--_ngs-digit-roller-len]=\"digitLengthForKey(part.key)\"\n >\n @for (digit of digitGlyphsForKey(part.key); track digit.value) {\n <span\n class=\"ngs-digit-roller__digit-number\"\n [style.--_ngs-digit-roller-n]=\"digit.value\"\n [attr.inert]=\"digit.value !== part.numericValue ? '' : null\"\n >\n {{ digit.glyph }}\n </span>\n }\n </span>\n } @else {\n <span class=\"ngs-digit-roller__separator\" [attr.data-key]=\"part.key\">{{ part.value }}</span>\n }\n }\n </span>\n\n @if (data().fraction.length) {\n <span class=\"ngs-digit-roller__section ngs-digit-roller__section--fraction\">\n @for (part of data().fraction; track part.key) {\n @if (part.type === 'fraction') {\n <span\n class=\"ngs-digit-roller__digit\"\n [attr.data-key]=\"part.key\"\n [style.--_ngs-digit-roller-current]=\"part.numericValue\"\n [style.--_ngs-digit-roller-len]=\"digitLengthForKey(part.key)\"\n >\n @for (digit of digitGlyphsForKey(part.key); track digit.value) {\n <span\n class=\"ngs-digit-roller__digit-number\"\n [style.--_ngs-digit-roller-n]=\"digit.value\"\n [attr.inert]=\"digit.value !== part.numericValue ? '' : null\"\n >\n {{ digit.glyph }}\n </span>\n }\n </span>\n } @else {\n <span class=\"ngs-digit-roller__separator\" [attr.data-key]=\"part.key\">{{ part.value }}</span>\n }\n }\n </span>\n }\n\n @if (data().post.length) {\n <span class=\"ngs-digit-roller__section ngs-digit-roller__section--post\">\n @for (part of data().post; track part.key) {\n <span class=\"ngs-digit-roller__literal\" [attr.data-key]=\"part.key\">{{ part.value }}</span>\n }\n </span>\n }\n </span>\n</span>\n\n<span class=\"ngs-digit-roller__sr-only\">{{ formattedPlainText() }}</span>\n","import { contentChildren, Directive, forwardRef } from '@angular/core';\nimport { DigitRoller } from './digit-roller/digit-roller';\nimport {\n DIGIT_ROLLER_GROUP,\n DigitRollerGroupCoordinator,\n DigitRollerGroupMember,\n} from './digit-roller-group.token';\n\n@Directive({\n selector: '[ngsDigitRollerGroup]',\n providers: [\n {\n provide: DIGIT_ROLLER_GROUP,\n useExisting: forwardRef(() => DigitRollerGroupDirective),\n },\n ],\n})\nexport class DigitRollerGroupDirective implements DigitRollerGroupCoordinator {\n private children = contentChildren(DigitRoller, { descendants: true });\n private pendingUpdates = new Map<DigitRollerGroupMember, () => void>();\n private flushQueued = false;\n\n requestGroupedUpdate(member: DigitRollerGroupMember, applyUpdate: () => void): boolean {\n if (!member.canGroupAnimateNow()) {\n return false;\n }\n\n this.pendingUpdates.set(member, applyUpdate);\n\n if (!this.flushQueued) {\n this.flushQueued = true;\n queueMicrotask(() => this.flushGroupedUpdates());\n }\n\n return true;\n }\n\n private flushGroupedUpdates(): void {\n this.flushQueued = false;\n\n if (this.pendingUpdates.size === 0) {\n return;\n }\n\n const members = this.children().filter((child) => child.canGroupAnimateNow());\n\n for (const member of members) {\n member.prepareGroupedUpdate();\n }\n\n for (const applyUpdate of this.pendingUpdates.values()) {\n applyUpdate();\n }\n\n this.pendingUpdates.clear();\n\n for (const member of members) {\n member.queueGroupedAnimation();\n }\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@ngstarter-ui/components",
3
3
  "description": "NgStarter - AI-friendly Enterprise Angular UI Components and Admin Panel",
4
- "version": "21.0.11",
4
+ "version": "21.0.12",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "https://github.com/elementarlabsdev/ngstarter.git"
@@ -210,6 +210,10 @@
210
210
  "types": "./types/ngstarter-ui-components-dialog.d.ts",
211
211
  "default": "./fesm2022/ngstarter-ui-components-dialog.mjs"
212
212
  },
213
+ "./digit-roller": {
214
+ "types": "./types/ngstarter-ui-components-digit-roller.d.ts",
215
+ "default": "./fesm2022/ngstarter-ui-components-digit-roller.mjs"
216
+ },
213
217
  "./divider": {
214
218
  "types": "./types/ngstarter-ui-components-divider.d.ts",
215
219
  "default": "./fesm2022/ngstarter-ui-components-divider.mjs"
@@ -0,0 +1,143 @@
1
+ import * as _angular_core from '@angular/core';
2
+
3
+ interface DigitRollerNumberPart {
4
+ type: string;
5
+ value: string;
6
+ key: string;
7
+ numericValue?: number;
8
+ }
9
+ interface DigitRollerFormattedNumber {
10
+ pre: DigitRollerNumberPart[];
11
+ integer: DigitRollerNumberPart[];
12
+ fraction: DigitRollerNumberPart[];
13
+ post: DigitRollerNumberPart[];
14
+ }
15
+ declare const DIGIT_ROLLER_EMPTY_FORMATTED: DigitRollerFormattedNumber;
16
+ type DigitRollerTrend = number | ((oldValue: number, value: number) => number);
17
+ type DigitRollerTiming = Omit<KeyframeAnimationOptions, 'composite'>;
18
+ type DigitRollerEasing = 'default' | 'spring' | 'overshoot' | (string & {});
19
+ interface DigitRollerDigitConfig {
20
+ max?: number;
21
+ }
22
+ type DigitRollerDigits = Record<number, DigitRollerDigitConfig>;
23
+
24
+ interface DigitRollerGlyph {
25
+ value: number;
26
+ glyph: string;
27
+ }
28
+
29
+ declare class DigitRoller {
30
+ value: _angular_core.InputSignal<number>;
31
+ format: _angular_core.InputSignal<Intl.NumberFormatOptions>;
32
+ locales: _angular_core.InputSignal<string | string[] | undefined>;
33
+ prefix: _angular_core.InputSignal<string>;
34
+ suffix: _angular_core.InputSignal<string>;
35
+ animated: _angular_core.InputSignal<boolean>;
36
+ duration: _angular_core.InputSignal<number | undefined>;
37
+ opacityDuration: _angular_core.InputSignal<number | undefined>;
38
+ transformTiming: _angular_core.InputSignal<DigitRollerTiming | undefined>;
39
+ spinTiming: _angular_core.InputSignal<DigitRollerTiming | undefined>;
40
+ opacityTiming: _angular_core.InputSignal<DigitRollerTiming | undefined>;
41
+ spinEasing: _angular_core.InputSignal<DigitRollerEasing | undefined>;
42
+ flipEasing: _angular_core.InputSignal<DigitRollerEasing | undefined>;
43
+ trend: _angular_core.InputSignal<DigitRollerTrend | undefined>;
44
+ continuous: _angular_core.InputSignal<boolean>;
45
+ digits: _angular_core.InputSignal<DigitRollerDigits>;
46
+ respectMotionPreference: _angular_core.InputSignal<boolean>;
47
+ stagger: _angular_core.InputSignal<number>;
48
+ colorOnIncrease: _angular_core.InputSignal<string | undefined>;
49
+ colorOnDecrease: _angular_core.InputSignal<string | undefined>;
50
+ animationsStart: _angular_core.OutputEmitterRef<void>;
51
+ animationsFinish: _angular_core.OutputEmitterRef<void>;
52
+ protected data: _angular_core.WritableSignal<DigitRollerFormattedNumber>;
53
+ protected digitGlyphs: _angular_core.Signal<DigitRollerGlyph[]>;
54
+ protected formattedPlainText: _angular_core.Signal<string>;
55
+ protected effectiveSettings: _angular_core.Signal<{
56
+ duration: number;
57
+ opacityDuration: number;
58
+ spinEasing: string;
59
+ flipEasing: string;
60
+ transformTiming: DigitRollerTiming | undefined;
61
+ spinTiming: DigitRollerTiming | undefined;
62
+ opacityTiming: DigitRollerTiming | undefined;
63
+ }>;
64
+ private platformId;
65
+ private elementRef;
66
+ private destroyRef;
67
+ private group;
68
+ private prevRects;
69
+ private prevInnerHTML;
70
+ private prevDigitD;
71
+ private prevDigitCurrent;
72
+ private prevDigitValues;
73
+ private prevDigitOrder;
74
+ private prevNumberLeft;
75
+ private prevNumberWidth;
76
+ private prevNumericValue;
77
+ private animCount;
78
+ private pending;
79
+ private destroyed;
80
+ private hasRenderedValue;
81
+ private liveAnimations;
82
+ private spinCount;
83
+ private animationsFinishAbort?;
84
+ private pendingCanAnimate;
85
+ private pendingHostFont;
86
+ private pendingHostColor;
87
+ private pendingKeyedEls;
88
+ private pendingNumberRect;
89
+ private pendingNumberOffsetWidth;
90
+ private isNearViewport;
91
+ private viewportObserver?;
92
+ constructor();
93
+ canGroupAnimateNow(): boolean;
94
+ prepareGroupedUpdate(): void;
95
+ queueGroupedAnimation(): void;
96
+ private snapshot;
97
+ private readAnimationState;
98
+ private fireAnimations;
99
+ private animatePositionOrFade;
100
+ private getDigitValue;
101
+ private getPartDigitValue;
102
+ private resolveTrend;
103
+ private canAnimateNow;
104
+ private isHostNearViewport;
105
+ private resolveEasing;
106
+ private getContinuousStartPosition;
107
+ private getDigitPosition;
108
+ private getDigitLength;
109
+ protected digitLengthForKey(key: string): number;
110
+ protected digitGlyphsForKey(key: string): {
111
+ value: number;
112
+ glyph: string;
113
+ }[];
114
+ private addStaggerDelay;
115
+ private getTrendDelta;
116
+ private incrementSpin;
117
+ private decrementSpin;
118
+ private buildGhost;
119
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<DigitRoller, never>;
120
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<DigitRoller, "ngs-digit-roller", ["ngsDigitRoller"], { "value": { "alias": "value"; "required": true; "isSignal": true; }; "format": { "alias": "format"; "required": false; "isSignal": true; }; "locales": { "alias": "locales"; "required": false; "isSignal": true; }; "prefix": { "alias": "prefix"; "required": false; "isSignal": true; }; "suffix": { "alias": "suffix"; "required": false; "isSignal": true; }; "animated": { "alias": "animated"; "required": false; "isSignal": true; }; "duration": { "alias": "duration"; "required": false; "isSignal": true; }; "opacityDuration": { "alias": "opacityDuration"; "required": false; "isSignal": true; }; "transformTiming": { "alias": "transformTiming"; "required": false; "isSignal": true; }; "spinTiming": { "alias": "spinTiming"; "required": false; "isSignal": true; }; "opacityTiming": { "alias": "opacityTiming"; "required": false; "isSignal": true; }; "spinEasing": { "alias": "spinEasing"; "required": false; "isSignal": true; }; "flipEasing": { "alias": "flipEasing"; "required": false; "isSignal": true; }; "trend": { "alias": "trend"; "required": false; "isSignal": true; }; "continuous": { "alias": "continuous"; "required": false; "isSignal": true; }; "digits": { "alias": "digits"; "required": false; "isSignal": true; }; "respectMotionPreference": { "alias": "respectMotionPreference"; "required": false; "isSignal": true; }; "stagger": { "alias": "stagger"; "required": false; "isSignal": true; }; "colorOnIncrease": { "alias": "colorOnIncrease"; "required": false; "isSignal": true; }; "colorOnDecrease": { "alias": "colorOnDecrease"; "required": false; "isSignal": true; }; }, { "animationsStart": "animationsStart"; "animationsFinish": "animationsFinish"; }, never, never, true, never>;
121
+ }
122
+
123
+ interface DigitRollerGroupMember {
124
+ canGroupAnimateNow(): boolean;
125
+ prepareGroupedUpdate(): void;
126
+ queueGroupedAnimation(): void;
127
+ }
128
+ interface DigitRollerGroupCoordinator {
129
+ requestGroupedUpdate(member: DigitRollerGroupMember, applyUpdate: () => void): boolean;
130
+ }
131
+
132
+ declare class DigitRollerGroupDirective implements DigitRollerGroupCoordinator {
133
+ private children;
134
+ private pendingUpdates;
135
+ private flushQueued;
136
+ requestGroupedUpdate(member: DigitRollerGroupMember, applyUpdate: () => void): boolean;
137
+ private flushGroupedUpdates;
138
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<DigitRollerGroupDirective, never>;
139
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<DigitRollerGroupDirective, "[ngsDigitRollerGroup]", never, {}, {}, ["children"], never, true, never>;
140
+ }
141
+
142
+ export { DIGIT_ROLLER_EMPTY_FORMATTED, DigitRoller, DigitRollerGroupDirective };
143
+ export type { DigitRollerDigitConfig, DigitRollerDigits, DigitRollerEasing, DigitRollerFormattedNumber, DigitRollerNumberPart, DigitRollerTiming, DigitRollerTrend };