UNPKG

@varlet/ui

Version:

A Vue3 component library based on Material Design 2 and 3, supporting mobile and desktop.

169 lines (168 loc) 4.69 kB
import { defineComponent, onActivated, onDeactivated, onMounted, onUnmounted, ref, watch } from "vue"; import { call, cancelAnimationFrame, requestAnimationFrame, toNumber } from "@varlet/shared"; import { createNamespace } from "../utils/components.mjs"; import { padStart } from "../utils/shared.mjs"; import { props } from "./props.mjs"; const { name, n } = createNamespace("countdown"); const SECOND = 1e3; const MINUTE = 60 * SECOND; const HOUR = 60 * MINUTE; const DAY = 24 * HOUR; import { normalizeProps as _normalizeProps, guardReactiveProps as _guardReactiveProps, renderSlot as _renderSlot, toDisplayString as _toDisplayString, createTextVNode as _createTextVNode, normalizeClass as _normalizeClass, openBlock as _openBlock, createElementBlock as _createElementBlock } from "vue"; function __render__(_ctx, _cache) { return _openBlock(), _createElementBlock( "div", { class: _normalizeClass(_ctx.n()) }, [ _renderSlot(_ctx.$slots, "default", _normalizeProps(_guardReactiveProps(_ctx.timeData)), () => [ _createTextVNode( _toDisplayString(_ctx.showTime), 1 /* TEXT */ ) ]) ], 2 /* CLASS */ ); } const __sfc__ = defineComponent({ name, props, setup(props2) { const showTime = ref(""); const timeData = ref({ days: 0, hours: 0, minutes: 0, seconds: 0, milliseconds: 0 }); let endTime = 0; let isStart = false; let handle = 0; let remainingTime = 0; let cacheIsStart; watch( () => props2.time, () => { reset(); if (props2.autoStart) { start(); } } ); onMounted(() => { countdown(); if (props2.autoStart) { start(); } }); onActivated(() => { if (cacheIsStart == null) { return; } isStart = cacheIsStart; if (isStart === true) { start(true); } }); onDeactivated(() => { cacheIsStart = isStart; pause(); }); onUnmounted(pause); function parseFormat(format, time) { const scannedTimes = Object.values(time); const scannedFormats = ["DD", "HH", "mm", "ss"]; const padValues = [24, 60, 60, 1e3]; scannedFormats.forEach((scannedFormat, index) => { if (!format.includes(scannedFormat)) { scannedTimes[index + 1] += scannedTimes[index] * padValues[index]; } else { format = format.replace(scannedFormat, padStart(`${scannedTimes[index]}`, 2, "0")); } }); if (format.includes("S")) { const ms = padStart(`${scannedTimes[scannedTimes.length - 1]}`, 3, "0"); if (format.includes("SSS")) { format = format.replace("SSS", ms); } else if (format.includes("SS")) { format = format.replace("SS", ms.slice(0, 2)); } else { format = format.replace("S", ms.slice(0, 1)); } } return format; } function displayTime(durationTime) { const days = Math.floor(durationTime / DAY); const hours = Math.floor(durationTime % DAY / HOUR); const minutes = Math.floor(durationTime % HOUR / MINUTE); const seconds = Math.floor(durationTime % MINUTE / SECOND); const milliseconds = Math.floor(durationTime % SECOND); const time = { days, hours, minutes, seconds, milliseconds }; timeData.value = time; call(props2.onChange, timeData.value); showTime.value = parseFormat(props2.format, time); } function countdown() { const { time, onEnd } = props2; const now = performance.now(); if (!endTime) { endTime = now + toNumber(time); } remainingTime = endTime - now; if (remainingTime < 0) { remainingTime = 0; } displayTime(remainingTime); if (remainingTime === 0) { call(onEnd); return; } if (isStart) { handle = requestAnimationFrame(countdown); } } function start(resume = false) { if (isStart && !resume) { return; } isStart = true; endTime = performance.now() + (remainingTime || toNumber(props2.time)); countdown(); } function pause() { isStart = false; cancelAnimationFrame(handle); } function reset() { endTime = 0; isStart = false; cancelAnimationFrame(handle); countdown(); } return { showTime, timeData, n, start, pause, reset }; } }); __sfc__.render = __render__; var stdin_default = __sfc__; export { stdin_default as default };