pl-fe: migrate AnimatedNumber, remove react-motion dependency

Signed-off-by: nicole mikołajczyk <git@mkljczk.pl>
This commit is contained in:
nicole mikołajczyk
2026-01-04 14:39:17 +01:00
parent 240e8a0378
commit cf08ea95ce
3 changed files with 23 additions and 70 deletions

View File

@ -122,7 +122,6 @@
"react-hot-toast": "^2.5.2", "react-hot-toast": "^2.5.2",
"react-inlinesvg": "^4.1.8", "react-inlinesvg": "^4.1.8",
"react-intl": "^7.0.4", "react-intl": "^7.0.4",
"react-motion": "^0.5.2",
"react-redux": "^9.0.4", "react-redux": "^9.0.4",
"react-sparklines": "^1.7.0", "react-sparklines": "^1.7.0",
"react-sticky-box": "^2.0.5", "react-sticky-box": "^2.0.5",
@ -158,7 +157,6 @@
"@types/react": "^18.3.18", "@types/react": "^18.3.18",
"@types/react-color": "^3.0.13", "@types/react-color": "^3.0.13",
"@types/react-dom": "^18.3.5", "@types/react-dom": "^18.3.5",
"@types/react-motion": "^0.0.40",
"@types/react-router-dom": "^5.3.3", "@types/react-router-dom": "^5.3.3",
"@types/react-sparklines": "^1.7.5", "@types/react-sparklines": "^1.7.5",
"@types/react-swipeable-views": "^0.13.6", "@types/react-swipeable-views": "^0.13.6",

View File

@ -1,6 +1,6 @@
import { animated, config, useTransition } from '@react-spring/web';
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState } from 'react';
import { useIntl, type IntlShape } from 'react-intl'; import { useIntl, type IntlShape } from 'react-intl';
import { TransitionMotion, spring } from 'react-motion';
import { useSettings } from 'pl-fe/stores/settings'; import { useSettings } from 'pl-fe/stores/settings';
import { isNumber, roundDown } from 'pl-fe/utils/numbers'; import { isNumber, roundDown } from 'pl-fe/utils/numbers';
@ -52,7 +52,7 @@ const AnimatedNumber: React.FC<IAnimatedNumber> = ({ value, obfuscate, short, ma
const intl = useIntl(); const intl = useIntl();
const { reduceMotion } = useSettings(); const { reduceMotion } = useSettings();
const [direction, setDirection] = useState(1); const [direction, setDirection] = useState(0);
const [displayedValue, setDisplayedValue] = useState<number>(value); const [displayedValue, setDisplayedValue] = useState<number>(value);
const [formattedValue, setFormattedValue] = useState<string>(intl.formatNumber(value, { numberingSystem: 'latn' })); const [formattedValue, setFormattedValue] = useState<string>(intl.formatNumber(value, { numberingSystem: 'latn' }));
@ -68,37 +68,34 @@ const AnimatedNumber: React.FC<IAnimatedNumber> = ({ value, obfuscate, short, ma
: short : short
? shortNumberFormat(value, intl, max) ? shortNumberFormat(value, intl, max)
: intl.formatNumber(value, { numberingSystem: 'latn' })); : intl.formatNumber(value, { numberingSystem: 'latn' }));
}, [value]); }, [value, intl, max, obfuscate, short]);
const willEnter = () => ({ y: -1 * direction }); const transitions = useTransition(formattedValue, {
from: { y: -1 * direction },
const willLeave = () => ({ y: spring(1 * direction, { damping: 35, stiffness: 400 }) }); enter: { y: 0 },
leave: { y: 1 * direction },
config: config.slow,
immediate: reduceMotion || direction === 0,
});
if (reduceMotion) { if (reduceMotion) {
return <>{formattedValue}</>; return <>{formattedValue}</>;
} }
const styles = [{
key: `${formattedValue}`,
data: formattedValue,
style: { y: spring(0, { damping: 35, stiffness: 400 }) },
}];
return ( return (
<TransitionMotion styles={styles} willEnter={willEnter} willLeave={willLeave}> <span className='⁂-animated-number'>
{items => ( {transitions((style, item) => (
<span className='⁂-animated-number'> <animated.span
{items.map(({ key, data, style }) => ( key={item}
<span style={{
key={key} position: item === formattedValue ? 'static' : 'absolute',
style={{ position: (direction * style.y) > 0 ? 'absolute' : 'static', transform: `translateY(${style.y * 100}%)` }} transform: style.y.to(y => `translateY(${y * 100}%)`),
> }}
{data} >
</span> {item}
))} </animated.span>
</span> ))}
)} </span>
</TransitionMotion>
); );
}; };

42
pnpm-lock.yaml generated
View File

@ -367,9 +367,6 @@ importers:
react-intl: react-intl:
specifier: ^7.0.4 specifier: ^7.0.4
version: 7.1.11(react@18.3.1)(typescript@5.7.3) version: 7.1.11(react@18.3.1)(typescript@5.7.3)
react-motion:
specifier: ^0.5.2
version: 0.5.2(react@18.3.1)
react-redux: react-redux:
specifier: ^9.0.4 specifier: ^9.0.4
version: 9.2.0(@types/react@18.3.23)(react@18.3.1)(redux@5.0.1) version: 9.2.0(@types/react@18.3.23)(react@18.3.1)(redux@5.0.1)
@ -470,9 +467,6 @@ importers:
'@types/react-dom': '@types/react-dom':
specifier: ^18.3.5 specifier: ^18.3.5
version: 18.3.7(@types/react@18.3.23) version: 18.3.7(@types/react@18.3.23)
'@types/react-motion':
specifier: ^0.0.40
version: 0.0.40
'@types/react-router-dom': '@types/react-router-dom':
specifier: ^5.3.3 specifier: ^5.3.3
version: 5.3.3 version: 5.3.3
@ -2620,9 +2614,6 @@ packages:
peerDependencies: peerDependencies:
'@types/react': ^18.3.18 '@types/react': ^18.3.18
'@types/react-motion@0.0.40':
resolution: {integrity: sha512-Bp6i9WTvW6QFN2E/XQPm8HPGMx1SVJ7H1DPsvptwWWh1XBymDZ7N7SK4nSZT/4tP4bTGvp1KHSAsswWZKO/WHA==}
'@types/react-router-dom@5.3.3': '@types/react-router-dom@5.3.3':
resolution: {integrity: sha512-kpqnYK4wcdm5UaWI3fLcELopqLrHgLqNsdpHauzlQktfkHL3npOSwtj1Uz9oKBAzs7lFtVkV8j83voAz2D8fhw==} resolution: {integrity: sha512-kpqnYK4wcdm5UaWI3fLcELopqLrHgLqNsdpHauzlQktfkHL3npOSwtj1Uz9oKBAzs7lFtVkV8j83voAz2D8fhw==}
@ -5185,12 +5176,6 @@ packages:
resolution: {integrity: sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==} resolution: {integrity: sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==}
engines: {node: '>= 14.16'} engines: {node: '>= 14.16'}
performance-now@0.2.0:
resolution: {integrity: sha512-YHk5ez1hmMR5LOkb9iJkLKqoBlL7WD5M8ljC75ZfzXriuBIVNuecaXuU7e+hOwyqf24Wxhh7Vxgt7Hnw9288Tg==}
performance-now@2.1.0:
resolution: {integrity: sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==}
picocolors@1.1.1: picocolors@1.1.1:
resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
@ -5508,9 +5493,6 @@ packages:
queue-microtask@1.2.3: queue-microtask@1.2.3:
resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
raf@3.4.1:
resolution: {integrity: sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA==}
randombytes@2.1.0: randombytes@2.1.0:
resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==}
@ -5591,11 +5573,6 @@ packages:
react-is@17.0.2: react-is@17.0.2:
resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==} resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==}
react-motion@0.5.2:
resolution: {integrity: sha512-9q3YAvHoUiWlP3cK0v+w1N5Z23HXMj4IF4YuvjvWegWqNPfLXsOBE/V7UvQGpXxHFKRQQcNcVQE31g9SB/6qgQ==}
peerDependencies:
react: ^0.14.9 || ^15.3.0 || ^16.0.0
react-property@2.0.2: react-property@2.0.2:
resolution: {integrity: sha512-+PbtI3VuDV0l6CleQMsx2gtK0JZbZKbpdu5ynr+lbsuvtmgbNcS3VM0tuY2QjFNOcWxvXeHjDpy42RO+4U2rug==} resolution: {integrity: sha512-+PbtI3VuDV0l6CleQMsx2gtK0JZbZKbpdu5ynr+lbsuvtmgbNcS3VM0tuY2QjFNOcWxvXeHjDpy42RO+4U2rug==}
@ -9208,10 +9185,6 @@ snapshots:
dependencies: dependencies:
'@types/react': 18.3.23 '@types/react': 18.3.23
'@types/react-motion@0.0.40':
dependencies:
'@types/react': 18.3.23
'@types/react-router-dom@5.3.3': '@types/react-router-dom@5.3.3':
dependencies: dependencies:
'@types/history': 4.7.11 '@types/history': 4.7.11
@ -12237,10 +12210,6 @@ snapshots:
pathval@2.0.1: {} pathval@2.0.1: {}
performance-now@0.2.0: {}
performance-now@2.1.0: {}
picocolors@1.1.1: {} picocolors@1.1.1: {}
picomatch@2.3.1: {} picomatch@2.3.1: {}
@ -12517,10 +12486,6 @@ snapshots:
queue-microtask@1.2.3: {} queue-microtask@1.2.3: {}
raf@3.4.1:
dependencies:
performance-now: 2.1.0
randombytes@2.1.0: randombytes@2.1.0:
dependencies: dependencies:
safe-buffer: 5.2.1 safe-buffer: 5.2.1
@ -12615,13 +12580,6 @@ snapshots:
react-is@17.0.2: {} react-is@17.0.2: {}
react-motion@0.5.2(react@18.3.1):
dependencies:
performance-now: 0.2.0
prop-types: 15.8.1
raf: 3.4.1
react: 18.3.1
react-property@2.0.2: {} react-property@2.0.2: {}
react-redux@9.2.0(@types/react@18.3.23)(react@18.3.1)(redux@5.0.1): react-redux@9.2.0(@types/react@18.3.23)(react@18.3.1)(redux@5.0.1):