@nutui/nutui-react
Version:
京东风格的轻量级移动端 React 组件库,支持一套代码生成 H5 和小程序
246 lines (245 loc) • 9.15 kB
JavaScript
import { _ as _object_spread } from "@swc/helpers/_/_object_spread";
import { _ as _object_spread_props } from "@swc/helpers/_/_object_spread_props";
import { _ as _object_without_properties } from "@swc/helpers/_/_object_without_properties";
import { _ as _sliced_to_array } from "@swc/helpers/_/_sliced_to_array";
import React, { useState, useRef, useEffect, useImperativeHandle } from "react";
import { ComponentDefaults } from "../../utils/typings";
import { padZero } from "../../utils/pad-zero";
var defaultProps = _object_spread_props(_object_spread({}, ComponentDefaults), {
type: 'default',
paused: false,
startTime: Date.now(),
endTime: Date.now(),
remainingTime: 0,
millisecond: false,
format: 'HH:mm:ss',
autoStart: true,
time: 0,
destroy: false
});
var InternalCountDown = function(props, ref) {
var _ref = _object_spread({}, defaultProps, props), type = _ref.type, paused = _ref.paused, startTime = _ref.startTime, endTime = _ref.endTime, remainingTime = _ref.remainingTime, millisecond = _ref.millisecond, format = _ref.format, autoStart = _ref.autoStart, time = _ref.time, destroy = _ref.destroy, className = _ref.className, style = _ref.style, onEnd = _ref.onEnd, onPaused = _ref.onPaused, onRestart = _ref.onRestart, onUpdate = _ref.onUpdate, children = _ref.children, rest = _object_without_properties(_ref, [
"type",
"paused",
"startTime",
"endTime",
"remainingTime",
"millisecond",
"format",
"autoStart",
"time",
"destroy",
"className",
"style",
"onEnd",
"onPaused",
"onRestart",
"onUpdate",
"children"
]);
var classPrefix = 'nut-countdown';
var _useState = _sliced_to_array(useState(0), 2), restTimeStamp = _useState[0], setRestTime = _useState[1];
var stateRef = useRef({
pauseTime: 0,
curr: 0,
isPaused: paused,
isIninted: false,
timer: 0,
restTime: 0,
counting: !paused && autoStart,
handleEndTime: Date.now(),
diffTime: 0
});
// 时间戳转换 或 获取当前时间的时间戳
var getTimeStamp = function(timeStr) {
if (!timeStr) return Date.now();
var t = timeStr;
t = Number(t) > 0 ? +t : t.toString().replace(/-/g, '/');
return new Date(t).getTime();
};
// 倒计时 interval
var initTime = function() {
if (remainingTime) {
stateRef.current.handleEndTime = Date.now() + Number(remainingTime);
} else {
stateRef.current.handleEndTime = endTime;
stateRef.current.diffTime = Date.now() - getTimeStamp(startTime) // 时间差
;
}
if (!stateRef.current.counting) stateRef.current.counting = true;
tick();
};
var tick = function() {
stateRef.current.timer = requestAnimationFrame(function() {
if (stateRef.current.counting) {
var currentTime = Date.now() - stateRef.current.diffTime;
var remainTime = Math.max(stateRef.current.handleEndTime - currentTime, 0);
stateRef.current.restTime = remainTime;
setRestTime(remainTime);
if (!remainTime) {
stateRef.current.counting = false;
pause();
onEnd && onEnd();
}
if (remainTime > 0) {
tick();
}
}
});
};
// 将倒计时剩余时间格式化 参数: t 时间戳 type custom 自定义类型
var formatRemainTime = function(t, type) {
var ts = t;
var rest = {
d: 0,
h: 0,
m: 0,
s: 0,
ms: 0
};
var SECOND = 1000;
var MINUTE = 60 * SECOND;
var HOUR = 60 * MINUTE;
var DAY = 24 * HOUR;
if (ts > 0) {
rest.d = ts >= SECOND ? Math.floor(ts / DAY) : 0;
rest.h = Math.floor(ts % DAY / HOUR);
rest.m = Math.floor(ts % HOUR / MINUTE);
rest.s = Math.floor(ts % MINUTE / SECOND);
rest.ms = Math.floor(ts % SECOND);
}
return type === 'custom' ? rest : parseFormat(_object_spread({}, rest));
};
var parseFormat = function(time) {
var d = time.d;
var h = time.h, m = time.m, s = time.s, ms = time.ms;
var formatCache = format;
if (formatCache.includes('DD')) {
formatCache = formatCache.replace('DD', padZero(d));
} else {
h += Number(d) * 24;
}
if (formatCache.includes('HH')) {
formatCache = formatCache.replace('HH', padZero(h));
} else {
m += Number(h) * 60;
}
if (formatCache.includes('mm')) {
formatCache = formatCache.replace('mm', padZero(m));
} else {
s += Number(m) * 60;
}
if (formatCache.includes('ss')) {
formatCache = formatCache.replace('ss', padZero(s));
} else {
ms += Number(s) * 1000;
}
if (formatCache.includes('S')) {
var msC = padZero(ms, 3).toString();
if (formatCache.includes('SSS')) {
formatCache = formatCache.replace('SSS', msC);
} else if (formatCache.includes('SS')) {
formatCache = formatCache.replace('SS', msC.slice(0, 2));
} else if (formatCache.includes('S')) {
formatCache = formatCache.replace('S', msC.slice(0, 1));
}
}
var isTextDom = type === 'text' ? '<span class="nut-countdown-number-text">$1</span>' : '<span class="nut-countdown-number">$1</span>';
formatCache = formatCache.replace(/(\d+)/g, type === 'primary' ? '<span class="nut-countdown-number-primary">$1</span>' : isTextDom);
return formatCache;
};
var pause = function() {
cancelAnimationFrame(stateRef.current.timer);
stateRef.current.counting = false;
onPaused && onPaused(stateRef.current.restTime);
};
useImperativeHandle(ref, function() {
return {
start: function() {
if (!stateRef.current.counting && !autoStart) {
stateRef.current.counting = true;
stateRef.current.handleEndTime = Date.now() + Number(stateRef.current.restTime);
tick();
onRestart && onRestart(stateRef.current.restTime);
}
},
pause: function() {
cancelAnimationFrame(stateRef.current.timer);
stateRef.current.counting = false;
onPaused && onPaused(stateRef.current.restTime);
},
reset: function() {
if (!autoStart) {
pause();
stateRef.current.restTime = time;
setRestTime(time);
}
}
};
});
// 监听值变更
useEffect(function() {
var tranTime = formatRemainTime(stateRef.current.restTime, 'custom');
onUpdate && onUpdate(tranTime);
}, [
restTimeStamp
]);
// 监听暂停
useEffect(function() {
if (stateRef.current.isIninted) {
if (paused) {
if (stateRef.current.counting) {
pause();
}
} else {
if (!stateRef.current.counting) {
stateRef.current.counting = true;
stateRef.current.handleEndTime = Date.now() + Number(stateRef.current.restTime);
tick();
}
onRestart && onRestart(stateRef.current.restTime);
}
}
}, [
paused
]);
// 监听开始结束时间变更
useEffect(function() {
if (stateRef.current.isIninted) {
initTime();
}
}, [
endTime,
startTime,
remainingTime
]);
// 初始化
useEffect(function() {
if (autoStart) {
initTime();
} else {
stateRef.current.restTime = time;
setRestTime(time);
}
if (!stateRef.current.isIninted) {
stateRef.current.isIninted = true;
}
return componentWillUnmount;
}, []);
var componentWillUnmount = function() {
destroy && cancelAnimationFrame(stateRef.current.timer);
};
var renderTime = function() {
return formatRemainTime(stateRef.current.restTime);
}();
return /*#__PURE__*/ React.createElement(React.Fragment, null, children || /*#__PURE__*/ React.createElement("div", _object_spread_props(_object_spread({
className: "".concat(classPrefix, " ").concat(className),
style: _object_spread({}, style)
}, rest), {
dangerouslySetInnerHTML: {
__html: "".concat(renderTime)
}
})));
};
export var CountDown = /*#__PURE__*/ React.forwardRef(InternalCountDown);
CountDown.displayName = 'NutCountDown';