Skip to content

Commit 713207e

Browse files
committed
Safely determine decimals for formatting
1 parent 466a009 commit 713207e

File tree

1 file changed

+21
-8
lines changed

1 file changed

+21
-8
lines changed

apps/webapp/app/components/primitives/AnimatedNumber.tsx

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,19 @@ function getDecimalPlaces(value: number): number {
1919
return 4;
2020
}
2121

22+
/**
23+
* Sanitizes a decimal places value to ensure it's valid for toLocaleString.
24+
* - Coerces to a finite number (handles NaN, Infinity, -Infinity)
25+
* - Rounds to an integer
26+
* - Clamps to the valid 0-20 range for toLocaleString options
27+
*/
28+
function sanitizeDecimals(decimals: number): number {
29+
if (!Number.isFinite(decimals)) {
30+
return 0;
31+
}
32+
return Math.min(20, Math.max(0, Math.round(decimals)));
33+
}
34+
2235
export function AnimatedNumber({
2336
value,
2437
duration = 0.5,
@@ -31,19 +44,19 @@ export function AnimatedNumber({
3144
}) {
3245
const motionValue = useMotionValue(value);
3346

34-
// Determine decimal places - use provided value or auto-detect
35-
const decimals = useMemo(
36-
() => (decimalPlaces !== undefined ? decimalPlaces : getDecimalPlaces(value)),
37-
[decimalPlaces, value]
38-
);
47+
// Determine decimal places - use provided value or auto-detect, then sanitize
48+
const safeDecimals = useMemo(() => {
49+
const rawDecimals = decimalPlaces !== undefined ? decimalPlaces : getDecimalPlaces(value);
50+
return sanitizeDecimals(rawDecimals);
51+
}, [decimalPlaces, value]);
3952

4053
const display = useTransform(motionValue, (current) => {
41-
if (decimals === 0) {
54+
if (safeDecimals === 0) {
4255
return Math.round(current).toLocaleString();
4356
}
4457
return current.toLocaleString(undefined, {
45-
minimumFractionDigits: decimals,
46-
maximumFractionDigits: decimals,
58+
minimumFractionDigits: safeDecimals,
59+
maximumFractionDigits: safeDecimals,
4760
});
4861
});
4962

0 commit comments

Comments
 (0)