104 lines
4.3 KiB
JavaScript
104 lines
4.3 KiB
JavaScript
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.useZIndex = exports.HigherZIndex = void 0;
|
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
const react_1 = require("react");
|
|
const use_keybinding_1 = require("../helpers/use-keybinding");
|
|
const highest_z_index_1 = require("./highest-z-index");
|
|
const input_dragger_click_lock_1 = require("./input-dragger-click-lock");
|
|
const ZIndexContext = (0, react_1.createContext)({
|
|
currentIndex: 0,
|
|
});
|
|
const margin = {
|
|
margin: 'auto',
|
|
};
|
|
const EscapeHook = ({ onEscape }) => {
|
|
const keybindings = (0, use_keybinding_1.useKeybinding)();
|
|
(0, react_1.useEffect)(() => {
|
|
const escape = keybindings.registerKeybinding({
|
|
event: 'keydown',
|
|
key: 'Escape',
|
|
callback: onEscape,
|
|
commandCtrlKey: false,
|
|
preventDefault: true,
|
|
// To dismiss the Quick Switcher menu if input is focused
|
|
triggerIfInputFieldFocused: true,
|
|
keepRegisteredWhenNotHighestContext: false,
|
|
});
|
|
return () => {
|
|
escape.unregister();
|
|
};
|
|
}, [keybindings, onEscape]);
|
|
return null;
|
|
};
|
|
const HigherZIndex = ({ children, onEscape, onOutsideClick, disabled }) => {
|
|
const context = (0, react_1.useContext)(ZIndexContext);
|
|
const highestContext = (0, react_1.useContext)(highest_z_index_1.HighestZIndexContext);
|
|
const containerRef = (0, react_1.useRef)(null);
|
|
const currentIndex = disabled
|
|
? context.currentIndex
|
|
: context.currentIndex + 1;
|
|
(0, react_1.useEffect)(() => {
|
|
if (disabled) {
|
|
return;
|
|
}
|
|
highestContext.registerZIndex(currentIndex);
|
|
return () => highestContext.unregisterZIndex(currentIndex);
|
|
}, [currentIndex, highestContext, disabled]);
|
|
(0, react_1.useEffect)(() => {
|
|
if (disabled) {
|
|
return;
|
|
}
|
|
let onUp = null;
|
|
const listener = (downEvent) => {
|
|
var _a;
|
|
const outsideClick = !((_a = containerRef.current) === null || _a === void 0 ? void 0 : _a.contains(downEvent.target));
|
|
if (!outsideClick) {
|
|
return;
|
|
}
|
|
onUp = (upEvent) => {
|
|
if (highestContext.highestIndex === currentIndex &&
|
|
!(0, input_dragger_click_lock_1.getClickLock)() &&
|
|
// Don't trigger if that click removed that node
|
|
document.contains(upEvent.target)) {
|
|
upEvent.stopPropagation();
|
|
onOutsideClick(upEvent.target);
|
|
}
|
|
};
|
|
window.addEventListener('pointerup', onUp, { once: true });
|
|
};
|
|
// If a menu is opened, then this component will also still receive the pointerdown event.
|
|
// However we may not interpret it as a outside click, so we need to wait for the next tick
|
|
requestAnimationFrame(() => {
|
|
window.addEventListener('pointerdown', listener);
|
|
});
|
|
return () => {
|
|
if (onUp) {
|
|
// @ts-expect-error
|
|
window.removeEventListener('pointerup', onUp, { once: true });
|
|
}
|
|
onUp = null;
|
|
return window.removeEventListener('pointerdown', listener);
|
|
};
|
|
}, [currentIndex, disabled, highestContext.highestIndex, onOutsideClick]);
|
|
const value = (0, react_1.useMemo)(() => {
|
|
return {
|
|
currentIndex,
|
|
};
|
|
}, [currentIndex]);
|
|
return ((0, jsx_runtime_1.jsxs)(ZIndexContext.Provider, { value: value, children: [disabled ? null : (0, jsx_runtime_1.jsx)(EscapeHook, { onEscape: onEscape }), (0, jsx_runtime_1.jsx)("div", { ref: containerRef, style: margin, children: children })] }));
|
|
};
|
|
exports.HigherZIndex = HigherZIndex;
|
|
const useZIndex = () => {
|
|
const context = (0, react_1.useContext)(ZIndexContext);
|
|
const highestContext = (0, react_1.useContext)(highest_z_index_1.HighestZIndexContext);
|
|
const isHighestContext = highestContext.highestIndex === context.currentIndex;
|
|
return (0, react_1.useMemo)(() => ({
|
|
currentZIndex: context.currentIndex,
|
|
highestZIndex: highestContext.highestIndex,
|
|
isHighestContext,
|
|
tabIndex: isHighestContext ? 0 : -1,
|
|
}), [context.currentIndex, highestContext.highestIndex, isHighestContext]);
|
|
};
|
|
exports.useZIndex = useZIndex;
|