UNPKG

react-multi-timezone-viewer

Version:
271 lines (269 loc) 10.9 kB
"use strict"; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/index.tsx var index_exports = {}; __export(index_exports, { MultiTimezoneViewer: () => multi_timezone_viewer_default }); module.exports = __toCommonJS(index_exports); // src/multi-timezone-viewer.tsx var import_react = require("react"); var import_luxon = require("luxon"); var import_tzdb = require("@vvo/tzdb"); var import_jsx_runtime = require("react/jsx-runtime"); var STORAGE_KEY = "multi_tz_zones"; var allTimezones = import_tzdb.timeZonesNames.map((tz) => { const now = import_luxon.DateTime.now().setZone(tz); const offset = now.offset / 60; const sign = offset >= 0 ? "+" : "-"; const offsetHours = Math.floor(Math.abs(offset)); const offsetMinutes = Math.abs(now.offset % 60); return { label: `${tz} (UTC${sign}${offsetHours.toString().padStart(2, "0")}:${offsetMinutes.toString().padStart(2, "0")})`, value: tz, offset }; }).sort((a, b) => a.offset - b.offset).map(({ label, value }) => ({ label, value })); var getUserTimezones = () => { const stored = localStorage.getItem(STORAGE_KEY); return stored ? JSON.parse(stored) : [Intl.DateTimeFormat().resolvedOptions().timeZone]; }; var setUserTimezones = (zones) => { localStorage.setItem(STORAGE_KEY, JSON.stringify(zones)); }; var MultiTimezoneViewer = ({ datetime, dateTimeZone, useCrossSiteStorage = false, customStyles = {} }) => { const baseTime = import_luxon.DateTime.fromFormat(datetime, "yyyy-MM-dd HH:mm:ss", { zone: dateTimeZone }); const [timezones, setTimezones] = (0, import_react.useState)([]); const [showTooltip, setShowTooltip] = (0, import_react.useState)(false); const [tooltipPos, setTooltipPos] = (0, import_react.useState)({ top: 0, left: 0 }); const [showDialog, setShowDialog] = (0, import_react.useState)(false); const iframeRef = (0, import_react.useRef)(null); const [hoveringText, setHoveringText] = (0, import_react.useState)(false); const [hoveringTooltip, setHoveringTooltip] = (0, import_react.useState)(false); (0, import_react.useEffect)(() => { if (!hoveringText && !hoveringTooltip) { const timeout = setTimeout(() => { setShowTooltip(false); }, 100); return () => clearTimeout(timeout); } }, [hoveringText, hoveringTooltip]); (0, import_react.useEffect)(() => { if (useCrossSiteStorage) { window.addEventListener("message", (e) => { if (e.data?.type === "RETURN_TIMEZONES") { setTimezones(e.data.zones); } }); const iframe = document.createElement("iframe"); iframe.src = "https://www.explisoft.com/npm/react-multi-timezone-viewer/script.html"; iframe.style.display = "none"; document.body.appendChild(iframe); iframeRef.current = iframe; iframe.onload = () => { iframe.contentWindow?.postMessage("GET_TIMEZONES", "*"); }; } else { setTimezones(getUserTimezones()); } }, [useCrossSiteStorage]); const handleSave = (zones) => { setTimezones(zones); if (useCrossSiteStorage && iframeRef.current) { iframeRef.current.contentWindow?.postMessage({ type: "SET_TIMEZONES", zones }, "*"); } else { setUserTimezones(zones); } }; const handleMouseEnter = (e) => { const spacing = 10; const tooltipWidth = 260; const tooltipHeight = 200; let left = e.clientX; let top = e.clientY; if (left + tooltipWidth > window.innerWidth) { left = window.innerWidth - tooltipWidth - spacing; } if (top + tooltipHeight > window.innerHeight) { top = window.innerHeight - tooltipHeight - spacing; } setTooltipPos({ top: top + window.scrollY + spacing, left: left + window.scrollX + spacing }); setShowTooltip(true); }; return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [ /* @__PURE__ */ (0, import_jsx_runtime.jsx)( "span", { onMouseEnter: (e) => { setHoveringText(true); handleMouseEnter(e); }, onMouseLeave: () => setHoveringText(false), style: { display: "inline", cursor: "pointer", textDecoration: "none", ...customStyles.container }, children: baseTime.toFormat("ff") } ), showTooltip && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)( "div", { onMouseEnter: () => setHoveringTooltip(true), onMouseLeave: () => setHoveringTooltip(false), style: { position: "absolute", top: tooltipPos.top, left: tooltipPos.left, background: "#fff", border: "1px solid #ccc", padding: "10px", borderRadius: "4px", zIndex: 1e3, boxShadow: "0 4px 8px rgba(0,0,0,0.1)", maxWidth: "400px", maxHeight: "300px", overflowY: "auto", textAlign: "left", ...customStyles.tooltip }, children: [ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)( "div", { style: { display: "flex", justifyContent: "space-between", marginBottom: "8px", fontWeight: "bold", ...customStyles.tooltipHeader }, children: [ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: "\u{1F552} Timezones" }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)( "span", { style: { cursor: "pointer" }, onClick: () => { setShowDialog(true); setShowTooltip(false); }, children: "\u2699\uFE0F" } ) ] } ), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("table", { style: { width: "100%", borderCollapse: "collapse" }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("tbody", { children: timezones.map((tz) => { const time = baseTime.setZone(tz).toFormat("ff"); return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("tr", { children: [ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { style: { padding: "4px 8px", verticalAlign: "top", textAlign: "left" }, children: tz }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { style: { padding: "4px 8px", verticalAlign: "top", textAlign: "left" }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("strong", { children: time }) }) ] }, tz); }) }) }), useCrossSiteStorage && iframeRef.current && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { marginTop: "10px", fontSize: "11px", color: "#888", textAlign: "right" }, children: [ "Powered by ", /* @__PURE__ */ (0, import_jsx_runtime.jsx)("a", { href: "https://www.explisoft.com", target: "_blank", rel: "noopener noreferrer", children: "explisoft.com" }) ] }) ] } ), showDialog && /* @__PURE__ */ (0, import_jsx_runtime.jsx)( "div", { style: { position: "fixed", top: 0, left: 0, right: 0, bottom: 0, background: "rgba(0,0,0,0.3)", zIndex: 100, ...customStyles.dialogOverlay }, onClick: () => setShowDialog(false), children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)( "div", { onClick: (e) => e.stopPropagation(), style: { background: "#fff", padding: "20px", borderRadius: "8px", width: "400px", maxHeight: "80vh", overflowY: "auto", margin: "5% auto", textAlign: "left", position: "relative", ...customStyles.dialogBox }, children: [ /* @__PURE__ */ (0, import_jsx_runtime.jsx)( "span", { onClick: () => setShowDialog(false), style: { position: "absolute", top: 10, right: 15, cursor: "pointer" }, children: "\u274C" } ), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", { children: "Select Timezones" }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { margin: "10px 0" }, children: allTimezones.map((tz) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)( "label", { style: { display: "block", marginBottom: "5px", fontSize: "14px", cursor: "pointer", ...customStyles.checkboxLabel }, children: [ /* @__PURE__ */ (0, import_jsx_runtime.jsx)( "input", { type: "checkbox", checked: timezones.includes(tz.value), onChange: (e) => { const newZones = e.target.checked ? [...timezones, tz.value] : timezones.filter((z) => z !== tz.value); handleSave(newZones); } } ), " ", tz.label ] }, tz.value )) }), useCrossSiteStorage && iframeRef.current && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { marginTop: "10px", fontSize: "11px", color: "#888", textAlign: "right" }, children: [ "Powered by ", /* @__PURE__ */ (0, import_jsx_runtime.jsx)("a", { href: "https://www.explisoft.com", target: "_blank", rel: "noopener noreferrer", children: "explisoft.com" }) ] }) ] } ) } ) ] }); }; var multi_timezone_viewer_default = MultiTimezoneViewer; // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { MultiTimezoneViewer }); //# sourceMappingURL=index.js.map