Skip to content

Instantly share code, notes, and snippets.

@SebastianHGonzalez
Last active December 12, 2019 19:33
Show Gist options
  • Save SebastianHGonzalez/b632740551557700b055cd54e2001bf1 to your computer and use it in GitHub Desktop.
Save SebastianHGonzalez/b632740551557700b055cd54e2001bf1 to your computer and use it in GitHub Desktop.
import {
createElement, useState, useEffect, useCallback,
} from 'react';
import {
oneOfType, instanceOf, number, elementType,
} from 'prop-types';
function formatUnit (n) {
return Math.floor(n).toString().padStart(2, '0');
}
function getSeconds (timeleft) {
return formatUnit((timeleft / 1000) % 60);
}
function getMinutes (timeleft) {
return formatUnit((timeleft / (60 * 1000)) % 60);
}
function getHours (timeleft) {
return formatUnit((timeleft / (60 * 60 * 1000)));
}
function getTimeLeft (target) {
return target - new Date();
}
function Display ({ timeleft }) {
const hours = getHours(timeleft);
const minutes = getMinutes(timeleft);
const seconds = getSeconds(timeleft);
return `${hours}:${minutes}:${seconds}`;
}
Display.propTypes = {
timeleft: number,
};
Display.defaultProps = {
timeleft: 0,
};
export default function Countdown ({ date, tickRate, component }) {
const [timeleft, setTimeLeft] = useState(getTimeLeft(date));
const tick = useCallback(() => {
setTimeLeft(getTimeLeft(date));
}, [date]);
useEffect(() => {
const interval = setInterval(tick, tickRate);
return () => clearInterval(interval);
}, [tick]);
return createElement(component, { timeleft });
}
Countdown.propTypes = {
date: oneOfType([instanceOf(Date), number]).isRequired,
tickRate: number,
component: elementType,
};
Countdown.defaultProps = {
tickRate: 1000,
component: Display,
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment