UNPKG

2.77 kBJavaScriptView Raw
1"use client";
2
3import classNames from 'classnames';
4import * as React from 'react';
5function UnitNumber(_ref) {
6 let {
7 prefixCls,
8 value,
9 current,
10 offset = 0
11 } = _ref;
12 let style;
13 if (offset) {
14 style = {
15 position: 'absolute',
16 top: `${offset}00%`,
17 left: 0
18 };
19 }
20 return /*#__PURE__*/React.createElement("span", {
21 style: style,
22 className: classNames(`${prefixCls}-only-unit`, {
23 current
24 })
25 }, value);
26}
27function getOffset(start, end, unit) {
28 let index = start;
29 let offset = 0;
30 while ((index + 10) % 10 !== end) {
31 index += unit;
32 offset += unit;
33 }
34 return offset;
35}
36export default function SingleNumber(props) {
37 const {
38 prefixCls,
39 count: originCount,
40 value: originValue
41 } = props;
42 const value = Number(originValue);
43 const count = Math.abs(originCount);
44 const [prevValue, setPrevValue] = React.useState(value);
45 const [prevCount, setPrevCount] = React.useState(count);
46 // ============================= Events =============================
47 const onTransitionEnd = () => {
48 setPrevValue(value);
49 setPrevCount(count);
50 };
51 // Fallback if transition events are not supported
52 React.useEffect(() => {
53 const timeout = setTimeout(() => {
54 onTransitionEnd();
55 }, 1000);
56 return () => {
57 clearTimeout(timeout);
58 };
59 }, [value]);
60 // ============================= Render =============================
61 // Render unit list
62 let unitNodes;
63 let offsetStyle;
64 if (prevValue === value || Number.isNaN(value) || Number.isNaN(prevValue)) {
65 // Nothing to change
66 unitNodes = [/*#__PURE__*/React.createElement(UnitNumber, Object.assign({}, props, {
67 key: value,
68 current: true
69 }))];
70 offsetStyle = {
71 transition: 'none'
72 };
73 } else {
74 unitNodes = [];
75 // Fill basic number units
76 const end = value + 10;
77 const unitNumberList = [];
78 for (let index = value; index <= end; index += 1) {
79 unitNumberList.push(index);
80 }
81 // Fill with number unit nodes
82 const prevIndex = unitNumberList.findIndex(n => n % 10 === prevValue);
83 unitNodes = unitNumberList.map((n, index) => {
84 const singleUnit = n % 10;
85 return /*#__PURE__*/React.createElement(UnitNumber, Object.assign({}, props, {
86 key: n,
87 value: singleUnit,
88 offset: index - prevIndex,
89 current: index === prevIndex
90 }));
91 });
92 // Calculate container offset value
93 const unit = prevCount < count ? 1 : -1;
94 offsetStyle = {
95 transform: `translateY(${-getOffset(prevValue, value, unit)}00%)`
96 };
97 }
98 return /*#__PURE__*/React.createElement("span", {
99 className: `${prefixCls}-only`,
100 style: offsetStyle,
101 onTransitionEnd: onTransitionEnd
102 }, unitNodes);
103}
\No newline at end of file