UNPKG

@smitch/fluid

Version:

A lightweight, Tailwind-powered React/Next.js UI component library.

99 lines 5.56 kB
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; import { useState, useEffect } from "react"; import { twMerge } from "tailwind-merge"; var layouts = { column: "flex-col items-center", "column-reverse": "flex-col-reverse items-center", row: "flex-row items-center gap-2", "row-reverse": "flex-row-reverse items-center gap-2", }; var labelsizes = { sm: "text-sm", md: "text-base", lg: "text-lg", xl: "text-xl", }; var Clock = function (_a) { var _b; var _c = _a.timezone, timezone = _c === void 0 ? "UTC" : _c, _d = _a.size, size = _d === void 0 ? 120 : _d, _e = _a.showSeconds, showSeconds = _e === void 0 ? false : _e, _f = _a.ticks, ticks = _f === void 0 ? false : _f, theme = _a.theme, _g = _a.layout, layout = _g === void 0 ? "column" : _g, _h = _a.showLabel, showLabel = _h === void 0 ? true : _h, _j = _a.clockFaceStroke, clockFaceStroke = _j === void 0 ? 4 : _j, _k = _a.labelSize, labelSize = _k === void 0 ? "md" : _k, _l = _a.className, className = _l === void 0 ? "" : _l; var _m = useState(new Date()), time = _m[0], setTime = _m[1]; var _o = useState(""), city = _o[0], setCity = _o[1]; useEffect(function () { if (!timezone) setCity(""); else { var parts = timezone.split("/"); if (parts.length > 1) { setCity(parts[1].replace(/_/g, " ")); } else { setCity(timezone); } } }, [timezone]); useEffect(function () { var timer = setInterval(function () { setTime(new Date()); }, 1000); return function () { return clearInterval(timer); }; }, []); var layoutClass = layouts[layout] || "flex-col"; var labelClass = labelsizes[labelSize] || "text-base"; var hours = time.getHours(); var minutes = time.getMinutes(); var seconds = time.getSeconds(); var label = ""; if (timezone) { var parts = new Intl.DateTimeFormat("en-US", { hour: "2-digit", minute: "2-digit", second: "2-digit", hour12: false, timeZone: timezone, timeZoneName: "short", }) .formatToParts(time) .reduce(function (acc, part) { if (part.type === "hour") acc.hour = parseInt(part.value, 10); if (part.type === "minute") acc.minute = parseInt(part.value, 10); if (part.type === "second") acc.second = parseInt(part.value, 10); if (part.type === "timeZoneName") acc.label = part.value; return acc; }, {}); hours = parts.hour; minutes = parts.minute; seconds = parts.second; label = parts.label; } else { label = ((_b = Intl.DateTimeFormat(undefined, { timeZoneName: "short" }) .formatToParts(time) .find(function (part) { return part.type === "timeZoneName"; })) === null || _b === void 0 ? void 0 : _b.value) || ""; } var hourAngle = ((hours % 12) + minutes / 60) * 30; var minuteAngle = (minutes + seconds / 60) * 6; var secondAngle = seconds * 6; var ariaTime = time.toLocaleTimeString("en-US", { hour: "2-digit", minute: "2-digit", second: showSeconds ? "2-digit" : undefined, hour12: false, timeZone: timezone, }); return (_jsxs("div", { "data-testid": "clock", "aria-label": "Analog clock showing ".concat(ariaTime, " in ").concat(city || label), className: twMerge("clock flex group ".concat(layoutClass, " space-y-4"), className), children: [_jsxs("svg", { width: size, height: size, viewBox: "0 0 120 120", "aria-hidden": "true", className: "clock_face", children: [_jsx("circle", { cx: 60, cy: 60, r: 55, fill: theme === "dark" ? "#222" : "#fff", stroke: theme === "dark" ? "#fff" : "#222", strokeWidth: clockFaceStroke }), ticks && Array.from({ length: 12 }).map(function (_, i) { var angle = i * 30 * (Math.PI / 180); var x1 = 60 + 48 * Math.sin(angle); var y1 = 60 - 48 * Math.cos(angle); var x2 = 60 + 54 * Math.sin(angle); var y2 = 60 - 54 * Math.cos(angle); return (_jsx("line", { x1: x1, y1: y1, x2: x2, y2: y2, stroke: theme === "dark" ? "#fff" : "#222", strokeWidth: 3, strokeLinecap: "round" }, i)); }), showSeconds && (_jsx("line", { x1: 60, y1: 60, x2: 60 + 45 * Math.sin((Math.PI / 180) * secondAngle), y2: 60 - 45 * Math.cos((Math.PI / 180) * secondAngle), stroke: theme === "dark" ? "#fff" : "#222", strokeWidth: 2, strokeLinecap: "round", opacity: 0.5 })), _jsx("line", { x1: 60, y1: 60, x2: 60 + 40 * Math.sin((Math.PI / 180) * minuteAngle), y2: 60 - 40 * Math.cos((Math.PI / 180) * minuteAngle), stroke: theme === "dark" ? "#fff" : "#222", strokeWidth: 3, strokeLinecap: "round" }), _jsx("line", { x1: 60, y1: 60, x2: 60 + 25 * Math.sin((Math.PI / 180) * hourAngle), y2: 60 - 25 * Math.cos((Math.PI / 180) * hourAngle), stroke: theme === "dark" ? "#fff" : "#222", strokeWidth: 5, strokeLinecap: "round" }), _jsx("circle", { cx: 60, cy: 60, r: 4, fill: theme === "dark" ? "#fff" : "#222" })] }), showLabel && _jsx("div", { className: "clock_label ".concat(labelClass), children: city || label || timezone })] })); }; export default Clock; //# sourceMappingURL=Clock.js.map