UNPKG

@nutui/nutui-react

Version:

京东风格的轻量级移动端 React 组件库,支持一套代码生成 H5 和小程序

257 lines (256 loc) 9.78 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "CountDown", { enumerable: true, get: function() { return CountDown; } }); var _interop_require_wildcard = require("@swc/helpers/_/_interop_require_wildcard"); var _object_spread = require("@swc/helpers/_/_object_spread"); var _object_spread_props = require("@swc/helpers/_/_object_spread_props"); var _object_without_properties = require("@swc/helpers/_/_object_without_properties"); var _sliced_to_array = require("@swc/helpers/_/_sliced_to_array"); var _react = /*#__PURE__*/ _interop_require_wildcard._(require("react")); var _typings = require("../../utils/typings"); var _padzero = require("../../utils/pad-zero"); var defaultProps = (0, _object_spread_props._)((0, _object_spread._)({}, _typings.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 InternalCountDown(props, ref) { var _ref = (0, _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 = (0, _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 = (0, _sliced_to_array._)((0, _react.useState)(0), 2), restTimeStamp = _useState[0], setRestTime = _useState[1]; var stateRef = (0, _react.useRef)({ pauseTime: 0, curr: 0, isPaused: paused, isIninted: false, timer: 0, restTime: 0, counting: !paused && autoStart, handleEndTime: Date.now(), diffTime: 0 }); // 时间戳转换 或 获取当前时间的时间戳 var getTimeStamp = function getTimeStamp(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 initTime() { 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 tick1() { 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 formatRemainTime(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((0, _object_spread._)({}, rest)); }; var parseFormat = function parseFormat(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', (0, _padzero.padZero)(d)); } else { h += Number(d) * 24; } if (formatCache.includes('HH')) { formatCache = formatCache.replace('HH', (0, _padzero.padZero)(h)); } else { m += Number(h) * 60; } if (formatCache.includes('mm')) { formatCache = formatCache.replace('mm', (0, _padzero.padZero)(m)); } else { s += Number(m) * 60; } if (formatCache.includes('ss')) { formatCache = formatCache.replace('ss', (0, _padzero.padZero)(s)); } else { ms += Number(s) * 1000; } if (formatCache.includes('S')) { var msC = (0, _padzero.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 pause() { cancelAnimationFrame(stateRef.current.timer); stateRef.current.counting = false; onPaused && onPaused(stateRef.current.restTime); }; (0, _react.useImperativeHandle)(ref, function() { return { start: function start() { 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 pause() { cancelAnimationFrame(stateRef.current.timer); stateRef.current.counting = false; onPaused && onPaused(stateRef.current.restTime); }, reset: function reset() { if (!autoStart) { pause(); stateRef.current.restTime = time; setRestTime(time); } } }; }); // 监听值变更 (0, _react.useEffect)(function() { var tranTime = formatRemainTime(stateRef.current.restTime, 'custom'); onUpdate && onUpdate(tranTime); }, [ restTimeStamp ]); // 监听暂停 (0, _react.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 ]); // 监听开始结束时间变更 (0, _react.useEffect)(function() { if (stateRef.current.isIninted) { initTime(); } }, [ endTime, startTime, remainingTime ]); // 初始化 (0, _react.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 componentWillUnmount() { destroy && cancelAnimationFrame(stateRef.current.timer); }; var renderTime = function() { return formatRemainTime(stateRef.current.restTime); }(); return /*#__PURE__*/ _react.default.createElement(_react.default.Fragment, null, children || /*#__PURE__*/ _react.default.createElement("div", (0, _object_spread_props._)((0, _object_spread._)({ className: "".concat(classPrefix, " ").concat(className), style: (0, _object_spread._)({}, style) }, rest), { dangerouslySetInnerHTML: { __html: "".concat(renderTime) } }))); }; var CountDown = /*#__PURE__*/ _react.default.forwardRef(InternalCountDown); CountDown.displayName = 'NutCountDown';