@xsolla/xui-context-menu 0.185.0 → 0.185.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/native/index.js +31 -6
- package/native/index.js.map +1 -1
- package/native/index.mjs +31 -6
- package/native/index.mjs.map +1 -1
- package/package.json +10 -10
- package/web/index.js +31 -6
- package/web/index.js.map +1 -1
- package/web/index.mjs +31 -6
- package/web/index.mjs.map +1 -1
package/web/index.js
CHANGED
|
@@ -456,6 +456,7 @@ var OptionCell = ({
|
|
|
456
456
|
const closeTimerRef = import_react4.default.useRef(
|
|
457
457
|
null
|
|
458
458
|
);
|
|
459
|
+
const ownsSubmenu = Boolean(hasSubmenu && submenu != null);
|
|
459
460
|
const cancelClose = () => {
|
|
460
461
|
if (closeTimerRef.current) {
|
|
461
462
|
clearTimeout(closeTimerRef.current);
|
|
@@ -464,9 +465,22 @@ var OptionCell = ({
|
|
|
464
465
|
};
|
|
465
466
|
const scheduleClose = () => {
|
|
466
467
|
cancelClose();
|
|
467
|
-
closeTimerRef.current = setTimeout(() =>
|
|
468
|
+
closeTimerRef.current = setTimeout(() => {
|
|
469
|
+
setSubmenuOpen(false);
|
|
470
|
+
if (ownsSubmenu && ctx?.activeSubmenuId === id) {
|
|
471
|
+
ctx.setActiveSubmenuId?.(null);
|
|
472
|
+
}
|
|
473
|
+
}, 120);
|
|
468
474
|
};
|
|
469
475
|
(0, import_react4.useEffect)(() => () => cancelClose(), []);
|
|
476
|
+
(0, import_react4.useEffect)(() => {
|
|
477
|
+
if (!ownsSubmenu || !submenuOpen) return;
|
|
478
|
+
const activeId = ctx?.activeSubmenuId;
|
|
479
|
+
if (activeId != null && activeId !== id) {
|
|
480
|
+
cancelClose();
|
|
481
|
+
setSubmenuOpen(false);
|
|
482
|
+
}
|
|
483
|
+
}, [ctx?.activeSubmenuId, ownsSubmenu, submenuOpen, id]);
|
|
470
484
|
(0, import_react4.useEffect)(() => {
|
|
471
485
|
if (!hasSubmenu || !submenuOpen) return;
|
|
472
486
|
const onMouseDown = (e) => {
|
|
@@ -475,13 +489,16 @@ var OptionCell = ({
|
|
|
475
489
|
const inOption = optionRef.current?.contains(target);
|
|
476
490
|
const inSubmenu = submenuWrapperRef.current?.contains(target);
|
|
477
491
|
if (!inOption && !inSubmenu) {
|
|
492
|
+
if (target.closest("[data-xui-context-menu-portal]")) return;
|
|
478
493
|
setSubmenuOpen(false);
|
|
479
494
|
return;
|
|
480
495
|
}
|
|
481
|
-
if (inSubmenu
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
496
|
+
if (inSubmenu) {
|
|
497
|
+
const activated = target.closest(
|
|
498
|
+
'[role="menuitem"],[role="menuitemcheckbox"],[role="menuitemradio"]'
|
|
499
|
+
);
|
|
500
|
+
const isLeafAction = activated?.getAttribute("role") === "menuitem" && activated.getAttribute("aria-haspopup") !== "menu";
|
|
501
|
+
if (isLeafAction) setSubmenuOpen(false);
|
|
485
502
|
}
|
|
486
503
|
};
|
|
487
504
|
document.addEventListener("mousedown", onMouseDown);
|
|
@@ -557,6 +574,7 @@ var OptionCell = ({
|
|
|
557
574
|
if (ctx && index2 >= 0) ctx.setActiveIndex(index2);
|
|
558
575
|
if (!ctx) setIsHovered(true);
|
|
559
576
|
if (hasSubmenu) setSubmenuOpen(true);
|
|
577
|
+
if (ownsSubmenu) ctx?.setActiveSubmenuId?.(id);
|
|
560
578
|
};
|
|
561
579
|
const handleLeave = () => {
|
|
562
580
|
if (!ctx) setIsHovered(false);
|
|
@@ -1368,6 +1386,7 @@ var ARROW_HALF = ARROW_SIZE / 2;
|
|
|
1368
1386
|
var ARROW_EDGE_OFFSET = 12;
|
|
1369
1387
|
var ARROW_TIP_PROTRUSION = ARROW_HALF * Math.SQRT2;
|
|
1370
1388
|
var PANEL_SHADOW = "0 4px 12px rgba(0,0,0,0.15)";
|
|
1389
|
+
var PORTALED_LAYER_SELECTOR = '[data-modal-id],[role="listbox"],[data-xui-context-menu-portal]';
|
|
1371
1390
|
var textFromNode = (node) => {
|
|
1372
1391
|
if (node === null || node === void 0 || typeof node === "boolean")
|
|
1373
1392
|
return "";
|
|
@@ -1554,7 +1573,13 @@ var ContextMenuRoot = (0, import_react8.forwardRef)(
|
|
|
1554
1573
|
if (!isOpen || !trigger) return;
|
|
1555
1574
|
const onMouseDown = (event) => {
|
|
1556
1575
|
const target = event.target;
|
|
1557
|
-
if (!target
|
|
1576
|
+
if (!target) return;
|
|
1577
|
+
if (containerRef.current?.contains(target)) return;
|
|
1578
|
+
const path = typeof event.composedPath === "function" ? event.composedPath() : [];
|
|
1579
|
+
const isInsidePortaledLayer = path.length ? path.some(
|
|
1580
|
+
(node) => node instanceof Element && node.matches(PORTALED_LAYER_SELECTOR)
|
|
1581
|
+
) : target instanceof Element && !!target.closest(PORTALED_LAYER_SELECTOR);
|
|
1582
|
+
if (isInsidePortaledLayer) return;
|
|
1558
1583
|
closeMenu();
|
|
1559
1584
|
};
|
|
1560
1585
|
const onScroll = () => closeMenu();
|