SingleNumber.js 3.2 KB

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