UNPKG

overlay-manager-rc

Version:
199 lines (193 loc) 5.96 kB
var __defProp = Object.defineProperty; var __defProps = Object.defineProperties; var __getOwnPropDescs = Object.getOwnPropertyDescriptors; var __getOwnPropSymbols = Object.getOwnPropertySymbols; var __hasOwnProp = Object.prototype.hasOwnProperty; var __propIsEnum = Object.prototype.propertyIsEnumerable; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __spreadValues = (a, b) => { for (var prop in b || (b = {})) if (__hasOwnProp.call(b, prop)) __defNormalProp(a, prop, b[prop]); if (__getOwnPropSymbols) for (var prop of __getOwnPropSymbols(b)) { if (__propIsEnum.call(b, prop)) __defNormalProp(a, prop, b[prop]); } return a; }; var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b)); var __async = (__this, __arguments, generator) => { return new Promise((resolve, reject) => { var fulfilled = (value) => { try { step(generator.next(value)); } catch (e) { reject(e); } }; var rejected = (value) => { try { step(generator.throw(value)); } catch (e) { reject(e); } }; var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected); step((generator = generator.apply(__this, __arguments)).next()); }); }; // src/use-overlay-manager.tsx import { signal } from "@preact/signals-react"; import { nanoid } from "nanoid"; // src/awaitIfPromise.ts function isPromise(value) { return value instanceof Promise; } function awaitIfPromise(value) { return __async(this, null, function* () { if (isPromise(value)) { const re = yield value; return re; } return value; }); } // src/use-overlay-manager.tsx var overlays = signal([]); var useOverlayManager = () => { const closeOverlay = (id) => { overlays.value = overlays.value.map((overlay) => { if (id === overlay.id) { return __spreadProps(__spreadValues({}, overlay), { open: false, closeTimestamp: Date.now() }); } return overlay; }); }; const openOverlay = (options) => { return new Promise((resolve) => { var _a; const id = (_a = options.id) != null ? _a : nanoid(); const handleExistingOverlay = () => __async(void 0, null, function* () { var _a2; const existingOverlayIndex = overlays.value.findIndex( (o) => o.id === id ); if (existingOverlayIndex > -1) { const existingOverlay = overlays.value[existingOverlayIndex]; const canClose = yield awaitIfPromise( existingOverlay.beforeClose ? existingOverlay.beforeClose() : true ); if (!canClose) { return false; } closeOverlay(id); void ((_a2 = existingOverlay.onClose) == null ? void 0 : _a2.call(existingOverlay, void 0)); } return true; }); const createNewOverlay = () => { var _a2; const newOverlay = __spreadProps(__spreadValues({}, options), { id, open: true, onClose: (result) => { var _a3; closeOverlay(id); void ((_a3 = options.onClose) == null ? void 0 : _a3.call(options, result)); resolve(result); } }); overlays.value = [...overlays.value, newOverlay]; void ((_a2 = options.onOpen) == null ? void 0 : _a2.call(options, id)); }; void handleExistingOverlay().then((shouldContinue) => { if (shouldContinue) { createNewOverlay(); } }); }); }; const closeAllOverlays = () => overlays.value = []; const closeOverlayById = (id) => __async(void 0, null, function* () { var _a; const overlay = overlays.value.find((o) => o.id === id); if (overlay) { const canClose = yield awaitIfPromise( overlay.beforeClose ? overlay.beforeClose() : true ); if (!canClose) { return; } closeOverlay(id); void ((_a = overlay.onClose) == null ? void 0 : _a.call(overlay, void 0)); } }); return { openOverlay, closeAllOverlays, closeOverlayById, overlays }; }; // src/overlay-container.tsx import { useSignals } from "@preact/signals-react/runtime"; import { useEffect } from "react"; import { Fragment, jsx } from "react/jsx-runtime"; var CLEANUP_INTERVAL = 3e4; function OverlayContainer() { useSignals(); const { overlays: activeOverlays, closeAllOverlays } = useOverlayManager(); useEffect(() => { const cleanup = () => { const hasOpenOverlay = activeOverlays.value.some( (overlay) => overlay.open ); if (!hasOpenOverlay) { closeAllOverlays(); } }; const cleanupInterval = setInterval(cleanup, CLEANUP_INTERVAL); return () => { clearInterval(cleanupInterval); }; }, []); return /* @__PURE__ */ jsx(Fragment, { children: activeOverlays.value.map((overlay) => /* @__PURE__ */ jsx( overlay.content, { close: (result) => { var _a; return (_a = overlay.onClose) == null ? void 0 : _a.call(overlay, result); }, data: overlay.data, id: overlay.id, open: overlay.open }, overlay.id )) }); } // src/use-before-close.tsx import { useEffect as useEffect2 } from "react"; var useBeforeClose = (beforeClose, id) => { useEffect2(() => { if (!id) return; overlays.value = overlays.value.map( (o) => o.id === id ? __spreadProps(__spreadValues({}, o), { beforeClose }) : o ); return () => { if (!id) return; overlays.value = overlays.value.map( (o) => o.id === id ? __spreadProps(__spreadValues({}, o), { beforeClose: void 0 }) : o ); }; }, [beforeClose, id]); }; export { OverlayContainer, overlays, useBeforeClose, useOverlayManager };