@chakra-ui/react
Version:
Responsive and accessible React UI components built with React and Emotion
159 lines (153 loc) • 4.02 kB
JavaScript
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;
;
;