@ni7r0g3n/react-context-menu
Version:
React custom context menu
322 lines (307 loc) • 29.8 kB
JavaScript
'use strict';
var React = require('react');
function styleInject(css, ref) {
if ( ref === void 0 ) ref = {};
var insertAt = ref.insertAt;
if (!css || typeof document === 'undefined') { return; }
var head = document.head || document.getElementsByTagName('head')[0];
var style = document.createElement('style');
style.type = 'text/css';
if (insertAt === 'top') {
if (head.firstChild) {
head.insertBefore(style, head.firstChild);
} else {
head.appendChild(style);
}
} else {
head.appendChild(style);
}
if (style.styleSheet) {
style.styleSheet.cssText = css;
} else {
style.appendChild(document.createTextNode(css));
}
}
var css_248z$1 = ":root{\n --radius: 7px;\n}\n\n.ContextMenuWindow-module_container__lO66L {\n display: flex;\n height: fit-content;\n position: absolute;\n overflow: wrap;\n font-size: 1rem;\n border-radius: var(--radius);\n flex-wrap: wrap;\n flex-direction: column;\n cursor: pointer;\n z-index: 9999;\n}\n\n.ContextMenuWindow-module_container__lO66L div:last-child {\n border-bottom-right-radius: inherit;\n border-bottom-left-radius: inherit;\n}\n\n.ContextMenuWindow-module_container__lO66L div:first-child {\n border-top-left-radius: inherit;\n border-top-right-radius: inherit;\n}\n\n.ContextMenuWindow-module_disabledRow__dL8rF {\n background-color: initial;\n filter: grayscale() blur(0.8px);\n cursor: default;\n}\n\n.ContextMenuWindow-module_disabledRow__dL8rF:hover {\n background-color: initial;\n filter: grayscale() blur(1px);\n cursor: default;\n}\n\n.ContextMenuWindow-module_light-transparent__Iuh8- {\n background-color: rgba(240, 240, 240, 0.90);\n color: rgb(50, 50, 50);\n}\n\n.ContextMenuWindow-module_dark-transparent__oztW3 {\n background-color: rgba(50, 50, 50, 0.90);\n color: rgb(240, 240, 240);\n}\n\n.ContextMenuWindow-module_light-solid__86OIH {\n background-color: rgb(240, 240, 240);\n color: rgb(50, 50, 50);\n}\n\n.ContextMenuWindow-module_dark-solid__tvB8x {\n background-color: rgb(50, 50, 50);\n color: rgb(240, 240, 240);\n}\n\n.ContextMenuWindow-module_raised__w-w8P {\n box-shadow: 0 1px 12px 0px rgba(0, 0, 0, 0.5);\n}\n\n.ContextMenuWindow-module_flat__49sOa {\n box-shadow: none;\n}\n\n.ContextMenuWindow-module_zoomIn__AnoPF {\n animation: ContextMenuWindow-module_zoomIn__AnoPF 0.2s ease-in-out forwards;\n}\n\n.ContextMenuWindow-module_transformOrigin-0-0__QI-K8 {\n transform-origin: 0% 0%;\n}\n\n.ContextMenuWindow-module_transformOrigin-0-100__sSopN {\n transform-origin: 0% 100%;\n}\n\n.ContextMenuWindow-module_transformOrigin-100-0__ThU-t {\n transform-origin: 100% 0%;\n}\n\n.ContextMenuWindow-module_transformOrigin-100-100__z8-lk {\n transform-origin: 100% 100%;\n}\n\n.ContextMenuWindow-module_zoomOut__-H2-U {\n animation: ContextMenuWindow-module_zoomOut__-H2-U 0.2s ease-in-out forwards;\n}\n\n.ContextMenuWindow-module_fadeIn__3M3C9 {\n animation: ContextMenuWindow-module_fadeIn__3M3C9 0.2s ease-in-out forwards;\n}\n\n.ContextMenuWindow-module_fadeOut__7v4lb {\n animation: ContextMenuWindow-module_fadeOut__7v4lb 0.2s ease-in-out forwards;\n}\n\n.ContextMenuWindow-module_slideLeftIn__6vsLm {\n animation: ContextMenuWindow-module_slideLeftIn__6vsLm 0.2s ease-in-out forwards;\n}\n\n.ContextMenuWindow-module_slideLeftOut__R9N-- {\n animation: ContextMenuWindow-module_slideLeftOut__R9N-- 0.2s ease-in-out forwards;\n}\n\n.ContextMenuWindow-module_slideRightIn__5z4zu {\n animation: ContextMenuWindow-module_slideRightIn__5z4zu 0.2s ease-in-out forwards;\n}\n\n.ContextMenuWindow-module_slideRightOut__NlEjh {\n animation: ContextMenuWindow-module_slideRightOut__NlEjh 0.2s ease-in-out forwards;\n}\n\n.ContextMenuWindow-module_slideDownIn__eHv52 {\n animation: ContextMenuWindow-module_slideDownIn__eHv52 0.2s ease-in-out forwards;\n}\n\n.ContextMenuWindow-module_slideDownOut__hpRv- {\n animation: ContextMenuWindow-module_slideDownOut__hpRv- 0.2s ease-in-out forwards;\n}\n\n.ContextMenuWindow-module_slideUpIn__9DDlE {\n animation: ContextMenuWindow-module_slideUpIn__9DDlE 0.2s ease-in-out forwards;\n}\n\n.ContextMenuWindow-module_slideUpOut__O3HBm {\n animation: ContextMenuWindow-module_slideUpOut__O3HBm 0.2s ease-in-out forwards;\n}\n\n.ContextMenuWindow-module_menuRow__x2Jkz {\n padding: 0.8rem 1.2rem;\n display: flex;\n align-content: center;\n justify-content: flex-start;\n}\n\n.ContextMenuWindow-module_lightMenuRow__VHjTa:hover {\n background-color: rgb(200, 200, 200, 1);\n color: black;\n}\n\n.ContextMenuWindow-module_darkMenuRow__Hgvuz:hover {\n background-color: rgb(240, 240, 240, 1);\n color: #323232;\n}\n\n/***************/\n/** Animations */\n/***************/\n\n/* Zoom In */\n@-webkit-keyframes ContextMenuWindow-module_zoomIn__AnoPF {\n from {\n -webkit-transform: scale(0);\n transform: scale(0);\n opacity: 0;\n }\n to {\n -webkit-transform: scale(1);\n transform: scale(1);\n opacity: 1;\n }\n}\n@keyframes ContextMenuWindow-module_zoomIn__AnoPF {\n from {\n -webkit-transform: scale(0);\n transform: scale(0);\n opacity: 0;\n }\n to {\n -webkit-transform: scale(1);\n transform: scale(1);\n opacity: 1;\n }\n}\n\n\n\n/* Zoom Out */\n@-webkit-keyframes ContextMenuWindow-module_zoomOut__-H2-U {\n from {\n -webkit-transform: scale(1);\n transform: scale(1);\n opacity: 1;\n }\n to {\n -webkit-transform: scale(0);\n transform: scale(0);\n opacity: 0;\n }\n}\n@keyframes ContextMenuWindow-module_zoomOut__-H2-U {\n from {\n -webkit-transform: scale(1);\n transform: scale(1);\n opacity: 1;\n }\n to {\n -webkit-transform: scale(0);\n transform: scale(0);\n opacity: 0;\n }\n}\n\n\n\n/* Fade In */\n@-webkit-keyframes ContextMenuWindow-module_fadeIn__3M3C9 {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n}\n@keyframes ContextMenuWindow-module_fadeIn__3M3C9 {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n}\n\n\n\n/* Fade Out */\n@-webkit-keyframes ContextMenuWindow-module_fadeOut__7v4lb {\n from {\n opacity: 1;\n }\n to {\n opacity: 0;\n }\n}\n@keyframes ContextMenuWindow-module_fadeOut__7v4lb {\n from {\n opacity: 1;\n }\n to {\n opacity: 0;\n }\n}\n\n\n\n/* Slide In Left */\n@-webkit-keyframes ContextMenuWindow-module_slideLeftIn__6vsLm {\n from {\n -webkit-transform: translateX(-90%);\n transform: translateX(-90%);\n opacity: 0;\n }\n to {\n -webkit-transform: translateX(0);\n transform: translateX(0);\n opacity: 1;\n }\n}\n@keyframes ContextMenuWindow-module_slideLeftIn__6vsLm {\n from {\n -webkit-transform: translateX(-90%);\n transform: translateX(-90%);\n opacity: 0;\n }\n to {\n -webkit-transform: translateX(0);\n transform: translateX(0);\n opacity: 1;\n }\n}\n\n\n/* Slide Out Left */\n@-webkit-keyframes ContextMenuWindow-module_slideLeftOut__R9N-- {\n from {\n -webkit-transform: translateX(0);\n transform: translateX(0);\n opacity: 1;\n }\n to {\n -webkit-transform: translateX(-90%);\n transform: translateX(-90%);\n opacity: 0;\n }\n}\n@keyframes ContextMenuWindow-module_slideLeftOut__R9N-- {\n from {\n -webkit-transform: translateX(0);\n transform: translateX(0);\n opacity: 1;\n }\n to {\n -webkit-transform: translateX(-90%);\n transform: translateX(-90%);\n opacity: 0;\n }\n}\n\n\n\n/* Slide In Right */\n@-webkit-keyframes ContextMenuWindow-module_slideRightIn__5z4zu {\n from {\n -webkit-transform: translateX(90%);\n transform: translateX(90%);\n opacity: 0;\n }\n to {\n -webkit-transform: translateX(0);\n transform: translateX(0);\n opacity: 1;\n }\n}\n@keyframes ContextMenuWindow-module_slideRightIn__5z4zu {\n from {\n -webkit-transform: translateX(90%);\n transform: translateX(90%);\n opacity: 0;\n }\n to {\n -webkit-transform: translateX(0);\n transform: translateX(0);\n opacity: 1;\n }\n}\n\n\n/* Slide Out Right */\n@-webkit-keyframes ContextMenuWindow-module_slideRightOut__NlEjh {\n from {\n -webkit-transform: translateX(0);\n transform: translateX(0);\n opacity: 1;\n }\n to {\n -webkit-transform: translateX(90%);\n transform: translateX(90%);\n opacity: 0;\n }\n}\n@keyframes ContextMenuWindow-module_slideRightOut__NlEjh {\n from {\n -webkit-transform: translateX(0);\n transform: translateX(0);\n opacity: 1;\n }\n to {\n -webkit-transform: translateX(90%);\n transform: translateX(90%);\n opacity: 0;\n }\n}\n\n\n\n\n/* Slide In Up */\n@-webkit-keyframes ContextMenuWindow-module_slideUpIn__9DDlE {\n from {\n -webkit-transform: translateY(-90%);\n transform: translateY(-90%);\n opacity: 0;\n }\n to {\n -webkit-transform: translateY(0);\n transform: translateY(0);\n opacity: 1;\n }\n}\n@keyframes ContextMenuWindow-module_slideUpIn__9DDlE {\n from {\n -webkit-transform: translateY(-90%);\n transform: translateY(-90%);\n opacity: 0;\n }\n to {\n -webkit-transform: translateY(0);\n transform: translateY(0);\n opacity: 1;\n }\n}\n\n\n\n/* Slide Out Up */\n@-webkit-keyframes ContextMenuWindow-module_slideUpOut__O3HBm {\n from {\n -webkit-transform: translateY(0);\n transform: translateY(0);\n opacity: 1;\n }\n to {\n -webkit-transform: translateY(-90%);\n transform: translateY(-90%);\n opacity: 0;\n }\n}\n@keyframes ContextMenuWindow-module_slideUpOut__O3HBm {\n from {\n -webkit-transform: translateY(0);\n transform: translateY(0);\n opacity: 1;\n }\n to {\n -webkit-transform: translateY(-90%);\n transform: translateY(-90%);\n opacity: 0;\n }\n}\n\n\n\n/* Slide In Down */\n@-webkit-keyframes ContextMenuWindow-module_slideDownIn__eHv52 {\n from {\n -webkit-transform: translateY(90%);\n transform: translateY(90%);\n opacity: 0;\n }\n to {\n -webkit-transform: translateY(0);\n transform: translateY(0);\n opacity: 1;\n }\n}\n@keyframes ContextMenuWindow-module_slideDownIn__eHv52 {\n from {\n -webkit-transform: translateY(90%);\n transform: translateY(90%);\n opacity: 0;\n }\n to {\n -webkit-transform: translateY(0);\n transform: translateY(0);\n opacity: 1;\n }\n}\n\n\n\n/* Slide Out Down */\n@-webkit-keyframes ContextMenuWindow-module_slideDownOut__hpRv- {\n from {\n -webkit-transform: translateY(0);\n transform: translateY(0);\n opacity: 1;\n }\n to {\n -webkit-transform: translateY(90%);\n transform: translateY(90%);\n opacity: 0;\n }\n}\n@keyframes ContextMenuWindow-module_slideDownOut__hpRv- {\n from {\n -webkit-transform: translateY(0);\n transform: translateY(0);\n opacity: 1;\n }\n to {\n -webkit-transform: translateY(90%);\n transform: translateY(90%);\n opacity: 0;\n }\n}\n\n\n";
var styles$1 = {"container":"ContextMenuWindow-module_container__lO66L","disabledRow":"ContextMenuWindow-module_disabledRow__dL8rF","light-transparent":"ContextMenuWindow-module_light-transparent__Iuh8-","dark-transparent":"ContextMenuWindow-module_dark-transparent__oztW3","light-solid":"ContextMenuWindow-module_light-solid__86OIH","dark-solid":"ContextMenuWindow-module_dark-solid__tvB8x","raised":"ContextMenuWindow-module_raised__w-w8P","flat":"ContextMenuWindow-module_flat__49sOa","zoomIn":"ContextMenuWindow-module_zoomIn__AnoPF","transformOrigin-0-0":"ContextMenuWindow-module_transformOrigin-0-0__QI-K8","transformOrigin-0-100":"ContextMenuWindow-module_transformOrigin-0-100__sSopN","transformOrigin-100-0":"ContextMenuWindow-module_transformOrigin-100-0__ThU-t","transformOrigin-100-100":"ContextMenuWindow-module_transformOrigin-100-100__z8-lk","zoomOut":"ContextMenuWindow-module_zoomOut__-H2-U","fadeIn":"ContextMenuWindow-module_fadeIn__3M3C9","fadeOut":"ContextMenuWindow-module_fadeOut__7v4lb","slideLeftIn":"ContextMenuWindow-module_slideLeftIn__6vsLm","slideLeftOut":"ContextMenuWindow-module_slideLeftOut__R9N--","slideRightIn":"ContextMenuWindow-module_slideRightIn__5z4zu","slideRightOut":"ContextMenuWindow-module_slideRightOut__NlEjh","slideDownIn":"ContextMenuWindow-module_slideDownIn__eHv52","slideDownOut":"ContextMenuWindow-module_slideDownOut__hpRv-","slideUpIn":"ContextMenuWindow-module_slideUpIn__9DDlE","slideUpOut":"ContextMenuWindow-module_slideUpOut__O3HBm","menuRow":"ContextMenuWindow-module_menuRow__x2Jkz","lightMenuRow":"ContextMenuWindow-module_lightMenuRow__VHjTa","darkMenuRow":"ContextMenuWindow-module_darkMenuRow__Hgvuz"};
styleInject(css_248z$1);
var css_248z = ".Item-module_disabledRow__TGnbc {\n background-color: initial;\n filter: grayscale() blur(0.8px);\n cursor: default;\n}\n\n.Item-module_disabledRow__TGnbc:hover {\n background-color: initial;\n filter: grayscale() blur(1px);\n cursor: default;\n}\n\n.Item-module_light-transparent__PIf2I {\n background-color: rgba(240, 240, 240, 0.90);\n color: rgb(50, 50, 50);\n}\n\n.Item-module_dark-transparent__42-M5 {\n background-color: rgba(50, 50, 50, 0.90);\n color: rgb(240, 240, 240);\n}\n\n.Item-module_light-solid__Vr4xC {\n background-color: rgb(240, 240, 240);\n color: rgb(50, 50, 50);\n}\n\n.Item-module_dark-solid__AVXqe {\n background-color: rgb(50, 50, 50);\n color: rgb(240, 240, 240);\n}\n\n.Item-module_raised__2sIvn {\n box-shadow: 0 1px 12px 0px rgba(0, 0, 0, 0.5);\n}\n\n.Item-module_flat__8vjG9 {\n box-shadow: none;\n}\n\n.Item-module_menuRow__GQmWv {\n padding: 0.8rem 1.2rem;\n display: flex;\n align-content: center;\n justify-content: flex-start;\n}\n\n.Item-module_lightMenuRow__BwD4Y:hover {\n background-color: rgb(200, 200, 200, 1);\n color: black;\n}\n\n.Item-module_darkMenuRow__AuRqL:hover {\n background-color: rgb(240, 240, 240, 1);\n color: #323232;\n}";
var styles = {"disabledRow":"Item-module_disabledRow__TGnbc","light-transparent":"Item-module_light-transparent__PIf2I","dark-transparent":"Item-module_dark-transparent__42-M5","light-solid":"Item-module_light-solid__Vr4xC","dark-solid":"Item-module_dark-solid__AVXqe","raised":"Item-module_raised__2sIvn","flat":"Item-module_flat__8vjG9","menuRow":"Item-module_menuRow__GQmWv","lightMenuRow":"Item-module_lightMenuRow__BwD4Y","darkMenuRow":"Item-module_darkMenuRow__AuRqL"};
styleInject(css_248z);
const langs = {
en: {
"aria-label": "Context menu container. Press enter or space when focusing this element or a children to open it.",
"contextmenu": "Context menu. Use tab or arrow keys to navigate options. Esc to close.",
"contextmenuitem": "Context menu option. Press enter or space to select it."
},
it: {
"aria-label": "Contenitore del menu contestuale. Premi invio o spazio quando questo elemento o un figlio è in focus per aprirlo.",
"contextmenu": "Menu contestuale. Usa tab o le frecce per navigare tra le opzioni. Esc per chiudere.",
"contextmenuitem": "Opzione del menu contestuale. Premi invio o spazio per selezionarla."
},
es: {
"aria-label": "Contenedor del menú contextual. Presione enter o espacio cuando este elemento o un hijo esté enfocado para abrirlo.",
"contextmenu": "Menú contextual. Use tab o las teclas de flecha para navegar por las opciones. Esc para cerrar.",
"contextmenuitem": "Opción del menú contextual. Presione enter o espacio para seleccionarlo."
},
fr: {
"aria-label": "Conteneur de menu contextuel. Appuyez sur Entrée ou Espace lorsque cet élément ou un enfant est en focus pour l'ouvrir.",
"contextmenu": "Menu contextuel. Utilisez Tab ou les touches fléchées pour naviguer dans les options. Esc pour fermer.",
"contextmenuitem": "Option de menu contextuel. Appuyez sur Entrée ou Espace pour le sélectionner."
},
de: {
"aria-label": "Kontextmenü-Container. Drücken Sie die Eingabetaste oder die Leertaste, wenn dieses Element oder ein Kind fokussiert ist, um es zu öffnen.",
"contextmenu": "Kontextmenü. Verwenden Sie Tab oder Pfeiltasten, um die Optionen zu navigieren. Esc zum Schließen.",
"contextmenuitem": "Kontextmenüoption. Drücken Sie die Eingabetaste oder die Leertaste, um sie auszuwählen."
},
pt: {
"aria-label": "Contêiner de menu de contexto. Pressione enter ou espaço quando este elemento ou um filho estiver em foco para abri-lo.",
"contextmenu": "Menu de contexto. Use tab ou as setas para navegar nas opções. Esc para fechar.",
"contextmenuitem": "Opção de menu de contexto. Pressione enter ou espaço para selecioná-lo."
},
};
function useLang() {
const [lang, setLang] = React.useState('en');
React.useEffect(() => {
const browserLang = navigator.language.split('-')[0];
if (langs[browserLang])
setLang(browserLang);
}, []);
return langs[lang];
}
function Item(props) {
var _a;
const [hovering, setHovering] = React.useState(false);
function fireEvent(event) {
if (props[event])
props[event](props.item);
}
const lang = useLang();
const onMouseEnter = React.useCallback(() => {
setHovering(true);
fireEvent('onItemHoverIn');
}, []);
const onMouseLeave = React.useCallback(() => {
fireEvent('onItemHoverOut');
setHovering(false);
}, []);
const onClick = React.useCallback((event) => {
if (props.item.disabled) {
event.preventDefault();
event.stopPropagation();
return;
}
props.item.onClick();
}, []);
const onKeyDown = React.useCallback((event) => {
if (event.key === 'Enter' || event.code === 'Space') {
onClick(event);
}
}, []);
const cleanStyles = React.useCallback(() => {
const styles = props.style;
if (!styles)
return {};
delete styles.normal.borderRadius;
return styles;
}, [props.style]);
const hoveringStyle = React.useCallback(() => {
var _a;
if (hovering)
return Object.assign(Object.assign({}, (_a = props.style) === null || _a === void 0 ? void 0 : _a.hover), props.item.hoverStyle);
return {};
}, [hovering]);
const rowClassName = React.useMemo(() => {
var _a, _b, _c, _d, _e;
const disabled = props.item.disabled ? ((_a = props.item.disabledClassName) !== null && _a !== void 0 ? _a : styles.disabledRow) : '';
const className = (_b = props.className) !== null && _b !== void 0 ? _b : ((_d = styles[`${(_c = props.variant) === null || _c === void 0 ? void 0 : _c.theme}MenuRow`]) !== null && _d !== void 0 ? _d : styles.lightMenuRow);
const itemClassName = (_e = props.item.className) !== null && _e !== void 0 ? _e : '';
return `${styles.menuRow} ${disabled} ${className} ${itemClassName}`;
}, [props.className, props.item.className, props.item.disabled, props.item.disabledClassName, (_a = props.variant) === null || _a === void 0 ? void 0 : _a.theme]);
return (React.createElement("div", { key: props.index, role: 'menuitem', "aria-label": lang.contextmenuitem, "aria-disabled": props.item.disabled, ref: props.itemRef, onMouseEnter: onMouseEnter, onMouseLeave: onMouseLeave, className: rowClassName, onClick: onClick, onKeyDown: onKeyDown, tabIndex: 0, style: Object.assign(Object.assign(Object.assign({}, cleanStyles()), props.item.style), hoveringStyle()) },
React.createElement("div", null, props.item.label)));
}
function useAccessibleFocus(items) {
const [focused, setFocused] = React.useState(-1);
const refs = items.map(() => React.createRef());
function up() {
setFocused((prev) => prev - 1 >= 0 ? prev - 1 : refs.length - 1);
}
function down() {
setFocused((prev) => prev + 1 < refs.length ? prev + 1 : 0);
}
function handleKeyDown(event) {
event.preventDefault();
if (event.key === "Tab") {
down();
}
if (event.key === "ArrowDown") {
down();
}
if (event.key === "ArrowUp") {
up();
}
}
React.useEffect(() => {
window.addEventListener("keydown", handleKeyDown);
return () => {
window.removeEventListener("keydown", handleKeyDown);
};
}, []);
React.useEffect(() => {
var _a;
if (focused >= 0 && focused < refs.length) {
(_a = refs[focused].current) === null || _a === void 0 ? void 0 : _a.focus();
}
}, [focused]);
return refs;
}
function ContextMenuWindow(props) {
var _a, _b, _c;
const [open, setOpen] = React.useState(true);
const itemsRefs = useAccessibleFocus(props.items);
const lang = useLang();
function fireEvent(event, item) {
if (props[event])
props[event](item);
}
const handleClick = React.useCallback(() => {
setOpen(false);
if (props.animated === false)
props.onTransitionEnd();
}, []);
const onKeyUp = React.useCallback((event) => {
event.preventDefault();
if (event.key === 'Escape') {
handleClick();
}
}, []);
React.useEffect(() => {
window.addEventListener("click", handleClick);
window.addEventListener("keyup", onKeyUp);
fireEvent('onAfterOpen');
return () => {
fireEvent('onClose');
window.removeEventListener("click", handleClick);
window.removeEventListener("keyup", onKeyUp);
};
}, []);
const adaptiveWidth = () => `${(props.position.x * 100) / document.documentElement.scrollWidth}vw`;
const adaptiveHeight = () => `${(props.position.y * 100) / document.documentElement.scrollHeight}vh`;
const screenWidth = React.useCallback(() => {
if (props.adaptive === false)
return props.position.x + document.documentElement.scrollLeft;
return adaptiveWidth();
}, [props.adaptive]);
const screenHeight = React.useCallback(() => {
if (props.adaptive === false)
return props.position.y + document.documentElement.scrollTop;
return adaptiveHeight();
}, [props.adaptive]);
const screenSize = { width: screenWidth(), height: screenHeight() };
function getAnimationFromProps(direction) {
var _a, _b;
if (typeof props.animated !== "boolean")
return ((_b = (_a = props.animated) === null || _a === void 0 ? void 0 : _a.animation) !== null && _b !== void 0 ? _b : 'zoom') + direction;
if (props.animated)
return `zoom${direction}`;
}
const originClassName = React.useMemo(() => {
var _a, _b;
return `transformOrigin-${(_a = props.position) === null || _a === void 0 ? void 0 : _a.origin.x}-${(_b = props.position) === null || _b === void 0 ? void 0 : _b.origin.y}`;
}, [(_a = props.position) === null || _a === void 0 ? void 0 : _a.origin.x, (_b = props.position) === null || _b === void 0 ? void 0 : _b.origin.y]);
const composeDefaultVariants = React.useCallback(() => {
var _a, _b, _c, _d, _e, _f;
return `${styles$1[`${((_b = (_a = props.variant) === null || _a === void 0 ? void 0 : _a.theme) !== null && _b !== void 0 ? _b : "light")}-${((_d = (_c = props.variant) === null || _c === void 0 ? void 0 : _c.opacity) !== null && _d !== void 0 ? _d : "transparent")}`]} ${styles$1[(_f = (_e = props.variant) === null || _e === void 0 ? void 0 : _e.elevation) !== null && _f !== void 0 ? _f : "raised"]}`;
}, [props.variant]);
const containerStyle = React.useMemo(() => {
var _a, _b, _c, _d;
if (props.animated === false)
return `${styles$1.container} ${(_b = (_a = props.menuClassName) === null || _a === void 0 ? void 0 : _a.container) !== null && _b !== void 0 ? _b : composeDefaultVariants()}`;
return `${styles$1['container']} ${styles$1[originClassName]} ${styles$1[getAnimationFromProps(open ? "In" : "Out")]} ${(_d = (_c = props.menuClassName) === null || _c === void 0 ? void 0 : _c.container) !== null && _d !== void 0 ? _d : composeDefaultVariants()}`;
}, [open]);
const animationStyle = React.useMemo(() => {
var _a, _b;
if (typeof props.animated !== "boolean")
return { animationDuration: (_b = (_a = props.animated) === null || _a === void 0 ? void 0 : _a.duration) !== null && _b !== void 0 ? _b : '0.2s' };
if (props.animated)
return { animationDuration: '0.2s' };
return {};
}, [open]);
function transitionEnd() {
if (!open) {
fireEvent('onOutAnimationEnd');
props.onTransitionEnd();
return;
}
fireEvent('onInAnimationEnd');
}
return (React.createElement("div", { ref: props.containerRef, className: containerStyle, onAnimationEnd: transitionEnd, role: 'menu', "aria-label": lang.contextmenu, style: Object.assign(Object.assign({ top: screenSize.height, left: screenSize.width }, animationStyle), (_c = props.menuStyle) === null || _c === void 0 ? void 0 : _c.container) }, props.items.map((item, index) => {
var _a, _b;
return (React.createElement(Item, { item: item, key: index, index: index, itemRef: itemsRefs[index], className: (_a = props.menuClassName) === null || _a === void 0 ? void 0 : _a.row, style: (_b = props.menuStyle) === null || _b === void 0 ? void 0 : _b.row, onItemHoverIn: props.onItemHoverIn, onItemHoverOut: props.onItemHoverOut, variant: props.variant }));
})));
}
function ContextMenu(props) {
const [show, setShow] = React.useState(false);
const [mousePosition, setMousePosition] = React.useState({ x: 0, y: 0, origin: { x: 0, y: 0 } });
const [contextMenuSize, setContextMenuSize] = React.useState({ width: 0, height: 0 });
const windowContainerRef = React.useRef(null);
const lang = useLang();
React.useLayoutEffect(() => {
if (windowContainerRef.current && show) {
setContextMenuSize({
width: windowContainerRef.current.offsetWidth,
height: windowContainerRef.current.offsetHeight
});
}
}, [show]);
const onContextMenuKeyDown = React.useCallback((e) => {
if (e.key === 'Enter' || e.code === 'Space') {
e.preventDefault();
e.target.dispatchEvent(new MouseEvent('contextmenu', {
bubbles: true,
cancelable: true,
clientX: e.target.offsetLeft - document.documentElement.scrollLeft,
clientY: e.target.offsetTop - document.documentElement.scrollTop
}));
}
}, []);
const onContextMenu = React.useCallback((e) => {
e.preventDefault();
e.stopPropagation();
openMenu({ x: e.clientX, y: e.clientY });
}, []);
function calculatePosition(position) {
var processedPosition = Object.assign(Object.assign({}, position), { origin: { x: 0, y: 0 } });
if (processedPosition.x + contextMenuSize.width > window.innerWidth) {
processedPosition.x = processedPosition.x - contextMenuSize.width;
processedPosition.origin.x = 100;
}
else {
processedPosition.origin.x = 0;
}
if (processedPosition.y + contextMenuSize.height > window.innerHeight) {
processedPosition.y = processedPosition.y - contextMenuSize.height;
processedPosition.origin.y = 100;
}
else {
processedPosition.origin.y = 0;
}
return Object.assign({}, processedPosition);
}
function openMenu(position) {
if (props.onOpen)
props.onOpen();
setMousePosition(calculatePosition(position));
setShow(true);
}
const onTransitionEnd = React.useCallback(() => {
setShow(false);
}, []);
return (React.createElement("div", { "aria-haspopup": true, tabIndex: 0, "aria-label": lang['aria-label'], onKeyDown: onContextMenuKeyDown, onContextMenu: onContextMenu },
props.children,
show ? React.createElement(ContextMenuWindow, Object.assign({ position: mousePosition, onTransitionEnd: onTransitionEnd, containerRef: windowContainerRef }, props)) : null));
}
exports.ContextMenu = ContextMenu;
exports.ContextMenuWindow = ContextMenuWindow;
//# sourceMappingURL=index.js.map