File size: 2,121 Bytes
bc20498 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
import { isElement, last, noop, sleep } from '../../helpers/index.js';
import { useInteractOutside } from '../index.js';
const visibleModals = [];
export function useModal(node, config) {
let unsubInteractOutside = noop;
function removeNodeFromVisibleModals() {
const index = visibleModals.indexOf(node);
if (index >= 0) {
visibleModals.splice(index, 1);
}
}
function update(config) {
unsubInteractOutside();
const { open, onClose, shouldCloseOnInteractOutside, closeOnInteractOutside } = config;
sleep(100).then(() => {
if (open) {
visibleModals.push(node);
}
else {
removeNodeFromVisibleModals();
}
});
function isLastModal() {
return last(visibleModals) === node;
}
function closeModal() {
// we only want to call onClose if this is the topmost modal
if (isLastModal() && onClose) {
onClose();
removeNodeFromVisibleModals();
}
}
function onInteractOutsideStart(e) {
const target = e.target;
if (!isElement(target))
return;
if (target && isLastModal()) {
e.preventDefault();
e.stopPropagation();
e.stopImmediatePropagation();
}
}
function onInteractOutside(e) {
if (shouldCloseOnInteractOutside?.(e) && isLastModal()) {
e.preventDefault();
e.stopPropagation();
e.stopImmediatePropagation();
closeModal();
}
}
unsubInteractOutside = useInteractOutside(node, {
onInteractOutsideStart,
onInteractOutside: closeOnInteractOutside ? onInteractOutside : undefined,
enabled: open,
}).destroy;
}
update(config);
return {
update,
destroy() {
removeNodeFromVisibleModals();
unsubInteractOutside();
},
};
}
|