@gfazioli/mantine-clock
Version:
React Clock components and hooks for Mantine with timezone support, countdown timers, customization options, and real-time updates.
155 lines (152 loc) • 3.69 kB
JavaScript
'use client';
import dayjs from 'dayjs';
import isLeapYear from 'dayjs/plugin/isLeapYear';
import timezonePlugin from 'dayjs/plugin/timezone';
import utc from 'dayjs/plugin/utc';
import weekOfYear from 'dayjs/plugin/weekOfYear';
import { useState, useRef, useEffect, useCallback } from 'react';
import { useMounted } from '@mantine/hooks';
dayjs.extend(utc);
dayjs.extend(timezonePlugin);
dayjs.extend(weekOfYear);
dayjs.extend(isLeapYear);
function useClock({
enabled = true,
timezone = "UTC",
updateFrequency = 1e3,
use24Hours = true,
padSeconds = false,
padMinutes = false,
padHours = false
}) {
const mounted = useMounted();
const [time, setTime] = useState(null);
const [isRunning, setIsRunning] = useState(false);
const intervalRef = useRef(null);
const initialEnabledRef = useRef(enabled);
useEffect(() => {
if (!mounted) {
return;
}
setTime(dayjs().tz(timezone));
if (enabled) {
setIsRunning(true);
} else {
setIsRunning(false);
}
}, [mounted, enabled, timezone]);
useEffect(() => {
if (!mounted || !isRunning) {
if (intervalRef.current) {
clearInterval(intervalRef.current);
intervalRef.current = null;
}
return;
}
const updateClock = () => {
setTime(dayjs().tz(timezone));
};
updateClock();
intervalRef.current = setInterval(updateClock, updateFrequency);
return () => {
if (intervalRef.current) {
clearInterval(intervalRef.current);
intervalRef.current = null;
}
};
}, [mounted, isRunning, timezone, updateFrequency]);
const start = useCallback(() => {
if (!mounted) {
return;
}
setTime(dayjs().tz(timezone));
setIsRunning(true);
}, [mounted, timezone]);
const pause = useCallback(() => {
setIsRunning(false);
}, []);
const resume = useCallback(() => {
if (!mounted) {
return;
}
setTime(dayjs().tz(timezone));
setIsRunning(true);
}, [mounted, timezone]);
const reset = useCallback(() => {
setIsRunning(false);
if (initialEnabledRef.current) {
setTime(dayjs().tz(timezone));
setIsRunning(true);
} else {
setTime(dayjs().tz(timezone));
}
}, [timezone]);
if (!mounted || !time) {
const staticHours = padHours ? "00" : 0;
const staticMinutes = padMinutes ? "00" : 0;
const staticSeconds = padSeconds ? "00" : 0;
return {
year: 2024,
month: 1,
day: 1,
week: 1,
isLeap: false,
hours: staticHours,
minutes: staticMinutes,
seconds: staticSeconds,
milliseconds: 0,
amPm: use24Hours ? void 0 : "AM",
isRunning: false,
start: () => {
},
pause: () => {
},
resume: () => {
},
reset: () => {
}
};
}
const year = time.year();
const month = time.month() + 1;
const day = time.date();
const week = time.week();
const isLeap = time.isLeapYear();
let hours = time.hour();
let minutes = time.minute();
let seconds = time.second();
const milliseconds = time.millisecond();
let amPm;
if (!use24Hours) {
amPm = Number(hours) >= 12 ? "PM" : "AM";
hours = Number(hours) % 12 || 12;
}
if (padHours) {
hours = hours.toString().padStart(2, "0");
}
if (padMinutes) {
minutes = minutes.toString().padStart(2, "0");
}
if (padSeconds) {
seconds = seconds.toString().padStart(2, "0");
}
return {
year,
month,
day,
week,
isLeap,
hours,
minutes,
seconds,
milliseconds,
amPm,
isRunning,
start,
pause,
resume,
reset
};
}
export { useClock };
//# sourceMappingURL=use-clock.mjs.map