@xsolla/xui-context-menu 0.183.0 → 0.185.0
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.d.mts +14 -1
- package/native/index.d.ts +14 -1
- package/native/index.js +32 -10
- package/native/index.js.map +1 -1
- package/native/index.mjs +41 -19
- package/native/index.mjs.map +1 -1
- package/package.json +10 -10
- package/web/index.d.mts +14 -1
- package/web/index.d.ts +14 -1
- package/web/index.js +32 -10
- package/web/index.js.map +1 -1
- package/web/index.mjs +41 -19
- package/web/index.mjs.map +1 -1
package/web/index.mjs
CHANGED
|
@@ -4,8 +4,8 @@ import {
|
|
|
4
4
|
forwardRef,
|
|
5
5
|
isValidElement,
|
|
6
6
|
useCallback as useCallback3,
|
|
7
|
-
useEffect as
|
|
8
|
-
useLayoutEffect as
|
|
7
|
+
useEffect as useEffect3,
|
|
8
|
+
useLayoutEffect as useLayoutEffect4,
|
|
9
9
|
useMemo,
|
|
10
10
|
useRef as useRef2,
|
|
11
11
|
useState as useState4
|
|
@@ -1123,7 +1123,7 @@ var ContextMenuSubmenu = ({
|
|
|
1123
1123
|
ContextMenuSubmenu.displayName = "ContextMenuSubmenu";
|
|
1124
1124
|
|
|
1125
1125
|
// src/hooks/useContextMenuPosition.ts
|
|
1126
|
-
import {
|
|
1126
|
+
import { useLayoutEffect as useLayoutEffect3, useState as useState3 } from "react";
|
|
1127
1127
|
var splitPlacement = (placement) => {
|
|
1128
1128
|
const [vertical, horizontal] = placement.split("-");
|
|
1129
1129
|
return { vertical, horizontal };
|
|
@@ -1132,12 +1132,13 @@ var joinPlacement = (vertical, horizontal) => `${vertical}-${horizontal}`;
|
|
|
1132
1132
|
var useContextMenuPosition = ({
|
|
1133
1133
|
triggerRef,
|
|
1134
1134
|
panelRef,
|
|
1135
|
+
containerRef,
|
|
1135
1136
|
isOpen,
|
|
1136
1137
|
placement = "bottom-start",
|
|
1137
1138
|
offset = 4
|
|
1138
1139
|
}) => {
|
|
1139
1140
|
const [resolved, setResolved] = useState3();
|
|
1140
|
-
|
|
1141
|
+
useLayoutEffect3(() => {
|
|
1141
1142
|
if (!isOpen) {
|
|
1142
1143
|
setResolved(void 0);
|
|
1143
1144
|
return;
|
|
@@ -1145,6 +1146,7 @@ var useContextMenuPosition = ({
|
|
|
1145
1146
|
const compute = () => {
|
|
1146
1147
|
const trigger = triggerRef.current;
|
|
1147
1148
|
const panel = panelRef.current;
|
|
1149
|
+
const container = containerRef.current;
|
|
1148
1150
|
if (!trigger || !panel) return;
|
|
1149
1151
|
const triggerRect = trigger.getBoundingClientRect();
|
|
1150
1152
|
const panelRect = panel.getBoundingClientRect();
|
|
@@ -1184,6 +1186,15 @@ var useContextMenuPosition = ({
|
|
|
1184
1186
|
}
|
|
1185
1187
|
}
|
|
1186
1188
|
}
|
|
1189
|
+
if (container) {
|
|
1190
|
+
const containerRect = container.getBoundingClientRect();
|
|
1191
|
+
const cOffsetW = container.offsetWidth;
|
|
1192
|
+
const cOffsetH = container.offsetHeight;
|
|
1193
|
+
const scaleX = cOffsetW > 0 ? containerRect.width / cOffsetW : 1;
|
|
1194
|
+
const scaleY = cOffsetH > 0 ? containerRect.height / cOffsetH : 1;
|
|
1195
|
+
left = (left - containerRect.left) / (scaleX || 1);
|
|
1196
|
+
top = (top - containerRect.top) / (scaleY || 1);
|
|
1197
|
+
}
|
|
1187
1198
|
const next = {
|
|
1188
1199
|
top,
|
|
1189
1200
|
left,
|
|
@@ -1193,14 +1204,13 @@ var useContextMenuPosition = ({
|
|
|
1193
1204
|
(prev) => prev && prev.top === next.top && prev.left === next.left && prev.placement === next.placement ? prev : next
|
|
1194
1205
|
);
|
|
1195
1206
|
};
|
|
1196
|
-
|
|
1207
|
+
compute();
|
|
1197
1208
|
const onResize = () => compute();
|
|
1198
1209
|
window.addEventListener("resize", onResize);
|
|
1199
1210
|
return () => {
|
|
1200
|
-
window.cancelAnimationFrame(rafId);
|
|
1201
1211
|
window.removeEventListener("resize", onResize);
|
|
1202
1212
|
};
|
|
1203
|
-
}, [isOpen, placement, offset, triggerRef, panelRef]);
|
|
1213
|
+
}, [isOpen, placement, offset, triggerRef, panelRef, containerRef]);
|
|
1204
1214
|
return resolved;
|
|
1205
1215
|
};
|
|
1206
1216
|
|
|
@@ -1332,6 +1342,7 @@ var SEARCH_DEBOUNCE_MS = 200;
|
|
|
1332
1342
|
var ARROW_SIZE = 10;
|
|
1333
1343
|
var ARROW_HALF = ARROW_SIZE / 2;
|
|
1334
1344
|
var ARROW_EDGE_OFFSET = 12;
|
|
1345
|
+
var ARROW_TIP_PROTRUSION = ARROW_HALF * Math.SQRT2;
|
|
1335
1346
|
var PANEL_SHADOW = "0 4px 12px rgba(0,0,0,0.15)";
|
|
1336
1347
|
var textFromNode = (node) => {
|
|
1337
1348
|
if (node === null || node === void 0 || typeof node === "boolean")
|
|
@@ -1381,7 +1392,9 @@ var ContextMenuRoot = forwardRef(
|
|
|
1381
1392
|
isOpen: propIsOpen,
|
|
1382
1393
|
onOpenChange,
|
|
1383
1394
|
trigger,
|
|
1395
|
+
triggerFullWidth = false,
|
|
1384
1396
|
placement = "bottom-start",
|
|
1397
|
+
offset = 4,
|
|
1385
1398
|
position,
|
|
1386
1399
|
width,
|
|
1387
1400
|
maxHeight = 300,
|
|
@@ -1415,11 +1428,14 @@ var ContextMenuRoot = forwardRef(
|
|
|
1415
1428
|
const sizeStyles = xuiTheme.sizing.contextMenu(size);
|
|
1416
1429
|
const borderRadius = xuiTheme.shape?.contextMenu?.[size]?.borderRadius ?? 8;
|
|
1417
1430
|
const shouldCloseOnSelect = closeOnSelect ?? (type === "checkbox" ? false : true);
|
|
1431
|
+
const positionOffset = withArrow ? offset + ARROW_TIP_PROTRUSION : offset;
|
|
1418
1432
|
const positioned = useContextMenuPosition({
|
|
1419
1433
|
triggerRef,
|
|
1420
1434
|
panelRef,
|
|
1435
|
+
containerRef,
|
|
1421
1436
|
isOpen: isOpen && !!trigger && !position,
|
|
1422
|
-
placement
|
|
1437
|
+
placement,
|
|
1438
|
+
offset: positionOffset
|
|
1423
1439
|
});
|
|
1424
1440
|
const resolvedPlacement = positioned?.placement ?? placement;
|
|
1425
1441
|
const getArrowStyle = (arrowPlacement) => {
|
|
@@ -1494,7 +1510,7 @@ var ContextMenuRoot = forwardRef(
|
|
|
1494
1510
|
onClose: closeMenu,
|
|
1495
1511
|
triggerRef
|
|
1496
1512
|
});
|
|
1497
|
-
|
|
1513
|
+
useEffect3(() => {
|
|
1498
1514
|
if (!isOpen) {
|
|
1499
1515
|
cellsRef.current = [];
|
|
1500
1516
|
setCellsVersion((version) => version + 1);
|
|
@@ -1503,14 +1519,14 @@ var ContextMenuRoot = forwardRef(
|
|
|
1503
1519
|
setActiveSubmenuId(null);
|
|
1504
1520
|
}
|
|
1505
1521
|
}, [isOpen]);
|
|
1506
|
-
|
|
1522
|
+
useEffect3(() => {
|
|
1507
1523
|
const timer = setTimeout(
|
|
1508
1524
|
() => setDebouncedQuery(query),
|
|
1509
1525
|
SEARCH_DEBOUNCE_MS
|
|
1510
1526
|
);
|
|
1511
1527
|
return () => clearTimeout(timer);
|
|
1512
1528
|
}, [query]);
|
|
1513
|
-
|
|
1529
|
+
useEffect3(() => {
|
|
1514
1530
|
if (!isOpen || !trigger) return;
|
|
1515
1531
|
const onMouseDown = (event) => {
|
|
1516
1532
|
const target = event.target;
|
|
@@ -1525,7 +1541,7 @@ var ContextMenuRoot = forwardRef(
|
|
|
1525
1541
|
window.removeEventListener("scroll", onScroll);
|
|
1526
1542
|
};
|
|
1527
1543
|
}, [isOpen, trigger, closeMenu]);
|
|
1528
|
-
|
|
1544
|
+
useLayoutEffect4(() => {
|
|
1529
1545
|
if (!isOpen || !panelRef.current) return;
|
|
1530
1546
|
const searchbox = panelRef.current.querySelector('[role="searchbox"]');
|
|
1531
1547
|
const firstOption = panelRef.current.querySelector(
|
|
@@ -1533,13 +1549,13 @@ var ContextMenuRoot = forwardRef(
|
|
|
1533
1549
|
);
|
|
1534
1550
|
(searchbox ?? firstOption)?.focus();
|
|
1535
1551
|
}, [isOpen]);
|
|
1536
|
-
|
|
1552
|
+
useLayoutEffect4(() => {
|
|
1537
1553
|
if (!isOpen || !panelRef.current) return;
|
|
1538
1554
|
const activeElement = document.activeElement;
|
|
1539
1555
|
if (activeElement && panelRef.current.contains(activeElement)) return;
|
|
1540
1556
|
panelRef.current.focus();
|
|
1541
1557
|
}, [isOpen, cellsVersion]);
|
|
1542
|
-
|
|
1558
|
+
useEffect3(() => {
|
|
1543
1559
|
if (isOpen) return;
|
|
1544
1560
|
triggerRef.current?.focus();
|
|
1545
1561
|
}, [isOpen]);
|
|
@@ -1675,7 +1691,10 @@ var ContextMenuRoot = forwardRef(
|
|
|
1675
1691
|
onClick: (event) => {
|
|
1676
1692
|
if (!event.defaultPrevented) toggleMenu();
|
|
1677
1693
|
},
|
|
1678
|
-
style: {
|
|
1694
|
+
style: {
|
|
1695
|
+
display: "inline-flex",
|
|
1696
|
+
width: triggerFullWidth ? "100%" : "auto"
|
|
1697
|
+
},
|
|
1679
1698
|
children: cloneElement(trigger, {
|
|
1680
1699
|
"aria-haspopup": "menu",
|
|
1681
1700
|
"aria-expanded": isOpen ? "true" : "false"
|
|
@@ -1697,10 +1716,13 @@ var ContextMenuRoot = forwardRef(
|
|
|
1697
1716
|
position: "fixed",
|
|
1698
1717
|
left: position.x,
|
|
1699
1718
|
top: position.y
|
|
1700
|
-
} : trigger ? {
|
|
1701
|
-
position: "
|
|
1702
|
-
left: positioned
|
|
1703
|
-
top: positioned
|
|
1719
|
+
} : trigger ? positioned ? {
|
|
1720
|
+
position: "absolute",
|
|
1721
|
+
left: positioned.left,
|
|
1722
|
+
top: positioned.top
|
|
1723
|
+
} : {
|
|
1724
|
+
position: "absolute",
|
|
1725
|
+
visibility: "hidden"
|
|
1704
1726
|
} : void 0;
|
|
1705
1727
|
return /* @__PURE__ */ jsx4(ContextMenuContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsxs3(
|
|
1706
1728
|
"div",
|