@nutui/nutui-react-taro
Version:
京东风格的轻量级移动端 React 组件库,支持一套代码生成 H5 和小程序
89 lines (88 loc) • 3.98 kB
JavaScript
import React__default, { useRef, useCallback, useState, useEffect, Component } from "react";
import { _ as __rest } from "./tslib.es6-iWu3F_1J.js";
import { createSelectorQuery } from "@tarojs/taro";
import { C as ComponentDefaults } from "./typings-DV9RBfhj.js";
import { m as mergeProps } from "./merge-props-2rRqFlJz.js";
const defaultProps$1 = Object.assign(Object.assign({}, ComponentDefaults), { length: 0, value: "", delay: 300, duration: 1, thousands: false });
const CountUp = (props) => {
const _a = mergeProps(defaultProps$1, props), { length, value, delay, duration, className, thousands, style } = _a;
__rest(_a, ["length", "value", "delay", "duration", "className", "thousands", "style"]);
const classPrefix = "nut-countup";
const countupRef = useRef(null);
const timerRef = useRef(0);
const numbers = Array.from({ length: 10 }, (v, i) => i);
const getShowNumber = useCallback(() => {
const splitArr = value.split(".");
const intNumber = length && splitArr[0].length < length ? (Array(length).join("0") + splitArr[0]).slice(-length) : splitArr[0];
const currNumber = `${thousands ? intNumber.replace(/(\d)(?=(?:\d{3})+$)/g, "$1,") : intNumber}${splitArr[1] ? "." : ""}${splitArr[1] || ""}`;
return currNumber.split("");
}, [length, thousands, value]);
const [numerArr, setNumerArr] = useState([]);
const [transformArr, setTransformArr] = useState([]);
const isLoaded = useRef(false);
const setNumberTransform = useCallback(() => {
if (countupRef.current && numerArr.length) {
createSelectorQuery().selectAll(".nut-countup-listitem").node((numberItems) => {
const transformArrCache = [];
Object.keys(numberItems).forEach((key) => {
const elem = numberItems[Number(key)];
const idx = Number(numerArr[Number(key)]);
if (elem) {
const transform = idx || idx === 0 ? `translate(0, -${(idx === 0 ? 10 : idx) * 5}%)` : "";
transformArrCache.push(transform);
}
});
setTransformArr([...transformArrCache]);
}).exec();
}
}, [numerArr]);
const numberEaseStyle = (idx) => {
return {
transition: `transform ${duration}s ease-in-out`,
transform: transformArr[idx] ? transformArr[idx] : null
};
};
useEffect(() => {
setNumberTransform();
}, [numerArr, setNumberTransform]);
useEffect(() => {
if (!isLoaded.current) {
isLoaded.current = true;
timerRef.current = window.setTimeout(() => {
setNumerArr(getShowNumber());
}, delay);
} else {
setNumerArr(getShowNumber());
}
return () => {
window.clearTimeout(timerRef.current);
};
}, [value, delay, getShowNumber]);
return React__default.createElement(
"div",
{ className: `${classPrefix} ${className}`, ref: countupRef },
React__default.createElement("ul", { className: `${classPrefix}-list` }, numerArr.map((item, idx) => {
return React__default.createElement("li", { className: `${classPrefix}-listitem ${!Number.isNaN(Number(item)) ? `${classPrefix}-listitem-number` : ""}`, key: idx }, !Number.isNaN(Number(item)) ? React__default.createElement("span", { className: `${classPrefix}-number`, style: numberEaseStyle(idx) }, [...numbers, ...numbers].map((number, subidx) => {
return React__default.createElement("span", { key: subidx }, number);
})) : React__default.createElement("span", { className: `${classPrefix}-separator` }, item));
}))
);
};
CountUp.displayName = "NutCountUp";
const defaultProps = {};
class AnimatingNumbers extends Component {
constructor(props) {
super(props);
this.state = {};
}
render() {
return React__default.createElement("div", { className: "nut-animatingnumbers" });
}
}
AnimatingNumbers.defaultProps = defaultProps;
AnimatingNumbers.displayName = "NutAnimatingNumbers";
AnimatingNumbers.CountUp = CountUp;
AnimatingNumbers.CountUp = CountUp;
export {
AnimatingNumbers as default
};