UNPKG

@chakra-ui/react

Version:

Responsive and accessible React UI components built with React and Emotion

159 lines (153 loc) 4.02 kB
"use strict"; 'use strict'; var jsxRuntime = require('react/jsx-runtime'); var React = require('react'); var omit = require('../utils/omit.cjs'); function _interopNamespaceDefault(e) { var n = Object.create(null); if (e) { Object.keys(e).forEach(function (k) { if (k !== 'default') { var d = Object.getOwnPropertyDescriptor(e, k); Object.defineProperty(n, k, d.get ? d : { enumerable: true, get: function () { return e[k]; } }); } }); } n.default = e; return Object.freeze(n); } var React__namespace = /*#__PURE__*/_interopNamespaceDefault(React); const shallowEqual = (a, b) => { if (a.length !== b.length) return false; for (let i = 0; i < a.length; i++) { const aKeys = Object.keys(a[i]); const bKeys = Object.keys(b[i]); if (aKeys.length !== bKeys.length) return false; for (const key of aKeys) { if (!Object.is(a[i][key], b[i][key])) return false; } } return true; }; function createOverlay(Component, options) { const map = /* @__PURE__ */ new Map(); const exitPromises = /* @__PURE__ */ new Map(); const subscribers = /* @__PURE__ */ new Set(); const subscribe = (callback) => { subscribers.add(callback); return () => subscribers.delete(callback); }; const publish = () => { for (const callback of subscribers) { callback(getSnapshot()); } }; let lastSnapshot = []; const getSnapshot = () => { const nextSnapshot = Array.from(map.values()); if (shallowEqual(lastSnapshot, nextSnapshot)) return lastSnapshot; lastSnapshot = nextSnapshot; return lastSnapshot; }; const waitForExit = (id) => { return exitPromises.get(id) || Promise.resolve(); }; const open = (id, props) => { const overlayProps = { ...options?.props, ...props, open: true, onOpenChange: (e) => { if (!e.open) close(id); }, onExitComplete: () => { const overlay = get(id); if (overlay.setExitComplete) { overlay.setExitComplete(); overlay.setExitComplete = void 0; } remove(id); }, setReturnValue: void 0, setExitComplete: void 0 }; map.set(id, overlayProps); const prom = new Promise((resolve) => { map.set(id, { ...overlayProps, setReturnValue: resolve }); }); publish(); return prom; }; const close = (id, value) => { const prevProps = get(id); map.set(id, { ...prevProps, open: false }); if (prevProps.setReturnValue) { prevProps.setReturnValue(value); prevProps.setReturnValue = void 0; } publish(); const exitPromise = new Promise((resolve) => { const overlay = get(id); map.set(id, { ...overlay, setExitComplete: resolve }); }); exitPromises.set(id, exitPromise); return exitPromise; }; const remove = (id) => { map.delete(id); exitPromises.delete(id); publish(); }; const update = (id, props) => { const prevProps = get(id); map.set(id, { ...prevProps, ...omit.omit(props, ["open", "onOpenChange", "onExitComplete"]) }); publish(); }; const get = (id) => { const overlay = map.get(id); if (!overlay) { throw new Error(`[chakra-ui] Overlay with id ${id} not found`); } return overlay; }; const removeAll = () => { map.clear(); exitPromises.clear(); publish(); }; function Viewport() { const overlays = React__namespace.useSyncExternalStore( subscribe, getSnapshot, getSnapshot ); return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: overlays.map((props, index) => ( // @ts-expect-error - TODO: fix this /* @__PURE__ */ jsxRuntime.jsx(Component, { ...props }, index) )) }); } return { Viewport, open, close, update, remove, removeAll, get, getSnapshot, waitForExit }; } exports.createOverlay = createOverlay;