import React, { useCallback, useState } from 'react'; import ShortNumber from './short_number'; import { TransitionMotion, spring } from 'react-motion'; import { reduceMotion } from '../initial_state'; const obfuscatedCount = (count: number) => { if (count < 0) { return 0; } else if (count <= 1) { return count; } else { return '1+'; } }; type Props = { value: number; obfuscate?: boolean; }; export const AnimatedNumber: React.FC = ({ value, obfuscate }) => { const [previousValue, setPreviousValue] = useState(value); const [direction, setDirection] = useState<1 | -1>(1); if (previousValue !== value) { setPreviousValue(value); setDirection(value > previousValue ? 1 : -1); } const willEnter = useCallback(() => ({ y: -1 * direction }), [direction]); const willLeave = useCallback( () => ({ y: spring(1 * direction, { damping: 35, stiffness: 400 }) }), [direction] ); if (reduceMotion) { return obfuscate ? ( <>{obfuscatedCount(value)} ) : ( ); } const styles = [ { key: `${value}`, data: value, style: { y: spring(0, { damping: 35, stiffness: 400 }) }, }, ]; return ( {(items) => ( {items.map(({ key, data, style }) => ( 0 ? 'absolute' : 'static', transform: `translateY(${style.y * 100}%)`, }} > {obfuscate ? obfuscatedCount(data) : } ))} )} ); };