UNPKG

vue3-countdown

Version:

A simple countdown component for Vue3.x.

84 lines (73 loc) 2.21 kB
/** * Utils */ interface Unit { symbol: string value: number } type ResolvedCountdown = Record<string, string | number> const units: Array<Unit> = [ { symbol: 'D', value: 24 * 60 * 60 * 1000 }, { symbol: 'H', value: 60 * 60 * 1000 }, { symbol: 'm', value: 60 * 1000 }, { symbol: 's', value: 1000 }, { symbol: 'S', value: 100 } ] function replaceAll(source: string, search: string, replace: string | number): string { const escapeStr = '~' + search if (source.indexOf(escapeStr) > -1) { return source .split(escapeStr) .map(part => replaceAll(part, search, replace)) .join(escapeStr) } return source.replace(new RegExp(search, 'g'), String(replace)) } // Decompose time into time units export function resolveCountdown( countdown: number, format = 'HH:mm:ss' ): ResolvedCountdown { const res: ResolvedCountdown = {} if (format.indexOf('~') > -1) { format = format.replace(/~[DHmsS]/g, '') } const thisUnits = units.filter(unit => format.indexOf(unit.symbol) > -1) for (let i = 0, l = thisUnits.length; i < l; i++) { const { symbol, value } = thisUnits[i] // Use ceil method when only unit const unitValue = ( l === 1 ? Math.ceil(countdown / value) : Math.floor(countdown / value) ) res[symbol] = unitValue res[symbol + symbol] = unitValue < 10 ? `0${unitValue}` : unitValue countdown %= value } return res } // Format countdown export function formatCountdown ( countdown: number | ResolvedCountdown, format = 'HH:mm:ss' ): string { // Check whether resolved const time = ( typeof countdown === 'number' ? resolveCountdown(countdown, format) : countdown ) // Sort the keys from long to short to replace long placeholders first // to prevent long placeholders from being replaced by short ones const keys = Object.keys(time).sort((a, b) => b.length - a.length) let rs = format keys.forEach(key => { rs = replaceAll(rs, key, time[key] as string) }) // Remove escape char if (rs.indexOf('~') > -1) { rs = rs.replace(/~([DHmsS])/g, '$1') } return rs }