UNPKG

react-native-animated-number

Version:

React Native component that animates a number by smoothly changing it between renders

76 lines (69 loc) 2.73 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var React = require('react'); var reactNative = require('react-native'); function _interopNamespace(e) { if (e && e.__esModule) return e; var n = Object.create(null); if (e) { Object.keys(e).forEach(function (k) { if (k !== 'default') { var d = Object.getOwnPropertyDescriptor(e, k); Object.defineProperty(n, k, d.get ? d : { enumerable: true, get: function () { return e[k]; } }); } }); } n['default'] = e; return Object.freeze(n); } var React__namespace = /*#__PURE__*/_interopNamespace(React); function formatFn(value) { return value.toString(); } function AnimatedNumber({ formatter = formatFn, steps = 15, time = 17, value, ...restProps }) { const viewValue = React__namespace.useRef(value); const textInputRef = React__namespace.useRef(null); const timerRef = React__namespace.useRef(); const maybeClearInterval = () => { if (undefined !== timerRef.current) { clearInterval(timerRef.current); timerRef.current = undefined; } }; React__namespace.useEffect(() => { return () => maybeClearInterval(); }, []); // Start updating current value whenever `value` changes React__namespace.useEffect(() => { if (viewValue.current === value) return; const minimumStep = value - viewValue.current > 0 ? 1 : -1; const stepSize = Math.floor((value - viewValue.current) / steps); const valuePerStep = minimumStep > 0 ? Math.max(stepSize, minimumStep) : Math.min(stepSize, minimumStep); // Clamping is required to correct for rounding errors const clampValue = 1 === minimumStep ? Math.min.bind(undefined, value) : Math.max.bind(undefined, value); timerRef.current = setInterval(() => { viewValue.current = Math.floor(clampValue(viewValue.current + valuePerStep)); textInputRef.current?.setNativeProps({ text: formatter(viewValue.current), }); if ((minimumStep === 1 && viewValue.current >= value) || (minimumStep === -1 && viewValue.current <= value)) { maybeClearInterval(); } }, time); return () => maybeClearInterval(); }, [value]); return (React__namespace.createElement(reactNative.TextInput, Object.assign({}, restProps, { ref: textInputRef, editable: false, value: formatter(viewValue.current) }))); } exports.default = AnimatedNumber; //# sourceMappingURL=index.js.map