UNPKG

react-animated-numbers

Version:

Library showing animation of number changes in react.js

68 lines (67 loc) 3.67 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const react_1 = __importDefault(require("react")); const react_2 = require("motion/react"); const NUMBERS = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, ]; const AnimatedNumber = ({ className, animateToNumber, fontStyle, transitions, includeComma, locale, }) => { const ref = react_1.default.useRef(null); const isInView = (0, react_2.useInView)(ref, { once: true }); const controls = (0, react_2.useAnimation)(); const animateTonumberString = includeComma ? Math.abs(animateToNumber).toLocaleString(locale || "en-US") : String(Math.abs(animateToNumber)); const animateToNumbersArr = Array.from(animateTonumberString, Number).map((x, idx) => (isNaN(x) ? animateTonumberString[idx] : x)); const [numberHeight, setNumberHeight] = react_1.default.useState(0); const [numberWidth, setNumberWidth] = react_1.default.useState(0); const numberDivRef = react_1.default.useRef(null); react_1.default.useEffect(() => { var _a, _b; const rect = (_b = (_a = numberDivRef.current) === null || _a === void 0 ? void 0 : _a.getClientRects()) === null || _b === void 0 ? void 0 : _b[0]; if (rect) { setNumberHeight(rect.height); setNumberWidth(rect.width); } }, []); react_1.default.useEffect(() => { if (isInView) { controls.start("visible"); } }, [isInView, animateToNumber, controls]); return (react_1.default.createElement("span", { ref: ref }, numberHeight !== 0 && (react_1.default.createElement("div", { style: { display: "flex", flexDirection: "row", overflow: "hidden", }, className: className }, animateToNumbersArr.map((n, index) => { if (typeof n === "string") { return (react_1.default.createElement("div", { key: index, style: Object.assign(Object.assign({}, fontStyle), { fontVariantNumeric: "tabular-nums" }) }, n)); } return (react_1.default.createElement(react_2.motion.div, { key: `${n}_${index}`, style: { height: numberHeight, width: numberWidth, }, initial: "hidden", variants: { hidden: { y: 0 }, visible: { y: -1 * (numberHeight * (typeof animateToNumbersArr[index] === "number" ? animateToNumbersArr[index] : 0)) - numberHeight * 20, }, }, animate: controls, transition: transitions === null || transitions === void 0 ? void 0 : transitions(index) }, NUMBERS.map((number, index) => (react_1.default.createElement("div", { key: index, style: Object.assign(Object.assign({}, fontStyle), { fontVariantNumeric: "tabular-nums" }) }, number))))); }))), react_1.default.createElement("div", { ref: numberDivRef, style: Object.assign({ position: "absolute", top: -9999 }, fontStyle) }, 0))); }; const Enhanced = react_1.default.memo(AnimatedNumber, (prevProps, nextProps) => { return (prevProps.animateToNumber === nextProps.animateToNumber && prevProps.fontStyle === nextProps.fontStyle && prevProps.includeComma === nextProps.includeComma); }); exports.default = Enhanced;