@asup/context-menu 1.5.2 → 2.0.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/README.md +114 -65
- package/dist/cjs/main.js +102 -76
- package/dist/cjs/main.js.map +1 -1
- package/dist/context-menu.d.ts +12 -33
- package/dist/context-menu.d.ts.map +1 -1
- package/dist/main.js +104 -78
- package/dist/main.js.map +1 -1
- package/package.json +29 -22
package/README.md
CHANGED
|
@@ -10,84 +10,133 @@
|
|
|
10
10
|
|
|
11
11
|
# @asup/context-menu
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
A small, highly-configurable React + TypeScript context menu component and helpers.
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
Key points:
|
|
16
|
+
|
|
17
|
+
- Works with React 19 (package is built and tested against React 19; React is a peer dependency).
|
|
18
|
+
- TypeScript types included.
|
|
19
|
+
- Lightweight and focused on accessibility and nested sub-menus.
|
|
20
|
+
|
|
21
|
+
## Storybook
|
|
22
|
+
|
|
23
|
+
Run Storybook to see interactive component examples and documentation.
|
|
24
|
+
|
|
25
|
+
```powershell
|
|
26
|
+
# install dependencies
|
|
27
|
+
npm install
|
|
16
28
|
|
|
29
|
+
# run Storybook
|
|
30
|
+
npm run storybook
|
|
31
|
+
|
|
32
|
+
# run tests
|
|
33
|
+
npm run test
|
|
34
|
+
|
|
35
|
+
# build library bundle
|
|
36
|
+
npm run build
|
|
17
37
|
```
|
|
18
|
-
|
|
38
|
+
|
|
39
|
+
## Installation
|
|
40
|
+
|
|
41
|
+
Install from npm:
|
|
42
|
+
|
|
43
|
+
```powershell
|
|
19
44
|
npm install @asup/context-menu
|
|
20
45
|
```
|
|
21
46
|
|
|
47
|
+
Note: React and ReactDOM are peer dependencies — install a compatible React version in your application.
|
|
48
|
+
|
|
22
49
|
## Usage
|
|
23
50
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
51
|
+
### ContextMenuHandler
|
|
52
|
+
|
|
53
|
+
```tsx
|
|
54
|
+
import { ContextMenuHandler, IMenuItem } from "@asup/context-menu";
|
|
27
55
|
|
|
56
|
+
const menuItems: IMenuItem[] = [
|
|
57
|
+
{ label: "Item 1", action: () => console.log("Item 1") },
|
|
58
|
+
{
|
|
59
|
+
label: "Item 2",
|
|
60
|
+
action: () => console.log("Item 2"),
|
|
61
|
+
group: [{ label: "Subitem 2.1", action: () => console.log("Subitem 2.1") }],
|
|
62
|
+
},
|
|
63
|
+
{ label: "Item 3 (disabled)", disabled: true },
|
|
64
|
+
];
|
|
65
|
+
|
|
66
|
+
<ContextMenuHandler menuItems={menuItems}>
|
|
67
|
+
<div>Right click here to open the menu</div>
|
|
68
|
+
</ContextMenuHandler>;
|
|
28
69
|
```
|
|
29
|
-
import { ContextMenuProvider, IMenuItem } from '@asup/context-menu';
|
|
30
|
-
|
|
31
|
-
<ContextMenuHandler
|
|
32
|
-
menuItems={[
|
|
33
|
-
{
|
|
34
|
-
label: 'Item 1',
|
|
35
|
-
action: () => {
|
|
36
|
-
console.log('Item 1 function run');
|
|
37
|
-
},
|
|
38
|
-
},
|
|
39
|
-
{
|
|
40
|
-
label: 'Item 2',
|
|
41
|
-
action: () => console.log('Item 2 function run'),
|
|
42
|
-
group: [
|
|
43
|
-
{ label: 'Subitem 2.1', action: () => console.log('Item 2.1 function run') },
|
|
44
|
-
],
|
|
45
|
-
},
|
|
46
|
-
{
|
|
47
|
-
label: 'Item 3',
|
|
48
|
-
action: () => console.log('Item 3 function run'),
|
|
49
|
-
disabled: true,
|
|
50
|
-
},
|
|
51
|
-
]}
|
|
52
|
-
>
|
|
53
|
-
<Chilren
|
|
54
|
-
where the context menu is applied...
|
|
55
|
-
/>
|
|
56
|
-
</ContextMenuHandler>
|
|
57
70
|
|
|
71
|
+
### AutoHeight
|
|
72
|
+
|
|
73
|
+
Use `AutoHeight` to wrap content that may expand/contract — it will manage layout height for smoother transitions.
|
|
74
|
+
|
|
75
|
+
```tsx
|
|
76
|
+
import { AutoHeight } from "@asup/context-menu";
|
|
77
|
+
|
|
78
|
+
<AutoHeight>
|
|
79
|
+
<div style={{ padding: 12 }}>
|
|
80
|
+
This content can change size; AutoHeight will help the layout adjust smoothly.
|
|
81
|
+
</div>
|
|
82
|
+
</AutoHeight>;
|
|
58
83
|
```
|
|
59
84
|
|
|
85
|
+
### ClickForMenu
|
|
86
|
+
|
|
87
|
+
`ClickForMenu` attaches a click-based menu to any element (useful for toolbar buttons or inline actions).
|
|
88
|
+
|
|
89
|
+
```tsx
|
|
90
|
+
import { ClickForMenu, IMenuItem } from "@asup/context-menu";
|
|
91
|
+
|
|
92
|
+
const clickItems: IMenuItem[] = [
|
|
93
|
+
{ label: "Edit", action: () => console.log("Edit") },
|
|
94
|
+
{ label: "Delete", action: () => console.log("Delete") },
|
|
95
|
+
];
|
|
96
|
+
|
|
97
|
+
<ClickForMenu menuItems={clickItems}>
|
|
98
|
+
<button type="button">Actions</button>
|
|
99
|
+
</ClickForMenu>;
|
|
60
100
|
```
|
|
61
|
-
import { ContextWindowStack, ContextWindow }
|
|
62
|
-
|
|
63
|
-
// Context window stack needs to cover the application, or portion where context windows cannot clash with each other
|
|
64
|
-
<ContextWindowStack>
|
|
65
|
-
...rest of app
|
|
66
|
-
|
|
67
|
-
<ContextWindow
|
|
68
|
-
id='window-1'
|
|
69
|
-
title={'Window 1'}
|
|
70
|
-
visible={visible}
|
|
71
|
-
style={ window styling, applied to the window div}
|
|
72
|
-
onOpen={ called function on opening}
|
|
73
|
-
onClose={ called function on closing (close cross in the window)}
|
|
74
|
-
>
|
|
75
|
-
{window contents}
|
|
76
|
-
</ContextWindow>
|
|
77
|
-
|
|
78
|
-
<ContextWindow
|
|
79
|
-
id='window-2'
|
|
80
|
-
title={'Window 2'}
|
|
81
|
-
visible={visible}
|
|
82
|
-
style={ window styling, applied to the window div}
|
|
83
|
-
onOpen={ called function on opening}
|
|
84
|
-
onClose={ called function on closing (close cross in the window)}
|
|
85
|
-
>
|
|
86
|
-
{window contents}
|
|
87
|
-
</ContextWindow>
|
|
88
|
-
|
|
89
|
-
...end of app
|
|
90
|
-
|
|
91
|
-
</ContextWindowStack>
|
|
92
101
|
|
|
102
|
+
### ContextWindow
|
|
103
|
+
|
|
104
|
+
```tsx
|
|
105
|
+
import { ContextWindow } from "@asup/context-menu";
|
|
106
|
+
|
|
107
|
+
<ContextWindow
|
|
108
|
+
id="window-1"
|
|
109
|
+
title="Window 1"
|
|
110
|
+
visible={true}
|
|
111
|
+
onClose={() => {}}
|
|
112
|
+
>
|
|
113
|
+
Window content
|
|
114
|
+
</ContextWindow>;
|
|
93
115
|
```
|
|
116
|
+
|
|
117
|
+
See the Storybook for interactive examples and more options.
|
|
118
|
+
|
|
119
|
+
## Development
|
|
120
|
+
|
|
121
|
+
Useful scripts (from `package.json`):
|
|
122
|
+
|
|
123
|
+
- `npm run prepare` — run Husky (prepares Git hooks).
|
|
124
|
+
- `npm run storybook` — start Storybook to view component examples.
|
|
125
|
+
- `npm run build-storybook` — build a static Storybook site.
|
|
126
|
+
- `npm run test` — run Jest and collect coverage (`jest --collectCoverage=true`).
|
|
127
|
+
- `npm run test-watch` — run Jest in watch mode with coverage (`jest --watch --collectCoverage=true --maxWorkers=4`).
|
|
128
|
+
- `npm run eslint` — run ESLint over `src` (pattern: `src/**/*.{js,jsx,ts,tsx}`).
|
|
129
|
+
- `npm run build` — build the library bundle with Parcel. This script clears the Parcel cache before building (`parcel build src/main.ts`).
|
|
130
|
+
|
|
131
|
+
## Contributing
|
|
132
|
+
|
|
133
|
+
Contributions and PRs are welcome. Please follow the repository conventions (linting, types, and tests).
|
|
134
|
+
|
|
135
|
+
1. Fork the repo and create a feature branch.
|
|
136
|
+
2. Run `npm install`.
|
|
137
|
+
3. Run and update tests: `npm run test`.
|
|
138
|
+
4. Submit a PR and describe your changes.
|
|
139
|
+
|
|
140
|
+
## License
|
|
141
|
+
|
|
142
|
+
MIT — see the `LICENCE` file for details.
|
package/dist/cjs/main.js
CHANGED
|
@@ -40,7 +40,6 @@ $parcel$export($a68bd8a6c0fd98c2$exports, "ClickForMenu", function () { return $
|
|
|
40
40
|
$parcel$export($a68bd8a6c0fd98c2$exports, "ContextMenu", function () { return $5150b66b01c99189$export$8dc6765e8be191c7; });
|
|
41
41
|
$parcel$export($a68bd8a6c0fd98c2$exports, "ContextMenuHandler", function () { return $3c568ee547c732c3$export$ed4f9641643dc7e4; });
|
|
42
42
|
$parcel$export($a68bd8a6c0fd98c2$exports, "ContextWindow", function () { return $46fb0088a1bbb6d8$export$1af8984c69ba1b24; });
|
|
43
|
-
$parcel$export($a68bd8a6c0fd98c2$exports, "ContextWindowStack", function () { return $16208d559c772441$export$9f37482ccd50dad2; });
|
|
44
43
|
|
|
45
44
|
|
|
46
45
|
|
|
@@ -98,11 +97,16 @@ function $95149596d5a7ed2b$export$77bf000da9303d1(_param) {
|
|
|
98
97
|
setTargetHeight
|
|
99
98
|
]);
|
|
100
99
|
// Trigger height change on children update
|
|
101
|
-
(0, $gTuX4$react.
|
|
102
|
-
|
|
100
|
+
const [, startTransition] = (0, $gTuX4$react.useTransition)();
|
|
101
|
+
(0, $gTuX4$react.useEffect)(()=>{
|
|
102
|
+
// Mark this update as non-urgent to avoid cascading render warnings
|
|
103
|
+
startTransition(()=>{
|
|
104
|
+
setTargetHeight();
|
|
105
|
+
});
|
|
103
106
|
}, [
|
|
104
107
|
setTargetHeight,
|
|
105
|
-
children
|
|
108
|
+
children,
|
|
109
|
+
startTransition
|
|
106
110
|
]);
|
|
107
111
|
return /*#__PURE__*/ (0, $gTuX4$reactjsxruntime.jsx)("div", (0, $gTuX4$swchelperscjs_object_spread_propscjs._)((0, $gTuX4$swchelperscjs_object_spreadcjs._)({}, rest), {
|
|
108
112
|
className: (0, (/*@__PURE__*/$parcel$interopDefault($796f463330153c24$exports))).autoHeightWrapper,
|
|
@@ -247,13 +251,25 @@ const $5150b66b01c99189$var$ESTIMATED_MENU_ITEM_HEIGHT = 34;
|
|
|
247
251
|
const $5150b66b01c99189$var$ESTIMATED_MENU_PADDING = 4;
|
|
248
252
|
const $5150b66b01c99189$var$ESTIMATED_MENU_WIDTH = 200;
|
|
249
253
|
const $5150b66b01c99189$export$8dc6765e8be191c7 = /*#__PURE__*/ (0, $gTuX4$react.forwardRef)(({ visible: visible, entries: entries, xPos: xPos, yPos: yPos, toClose: toClose }, ref)=>{
|
|
250
|
-
//
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
254
|
+
// Measure menu size after mount/render to avoid accessing refs during render
|
|
255
|
+
const [menuHeight, setMenuHeight] = (0, $gTuX4$react.useState)(entries.length * $5150b66b01c99189$var$ESTIMATED_MENU_ITEM_HEIGHT + $5150b66b01c99189$var$ESTIMATED_MENU_PADDING);
|
|
256
|
+
const [menuWidth, setMenuWidth] = (0, $gTuX4$react.useState)($5150b66b01c99189$var$ESTIMATED_MENU_WIDTH);
|
|
257
|
+
(0, $gTuX4$react.useLayoutEffect)(()=>{
|
|
258
|
+
// Only measure when visible; ref access inside effect is allowed
|
|
259
|
+
if (visible && ref && typeof ref !== "function" && ref.current instanceof HTMLDivElement) {
|
|
260
|
+
setMenuHeight(ref.current.offsetHeight);
|
|
261
|
+
setMenuWidth(ref.current.offsetWidth);
|
|
262
|
+
}
|
|
263
|
+
// When not visible, fall back to estimates
|
|
264
|
+
if (!visible) {
|
|
265
|
+
setMenuHeight(entries.length * $5150b66b01c99189$var$ESTIMATED_MENU_ITEM_HEIGHT + $5150b66b01c99189$var$ESTIMATED_MENU_PADDING);
|
|
266
|
+
setMenuWidth($5150b66b01c99189$var$ESTIMATED_MENU_WIDTH);
|
|
267
|
+
}
|
|
268
|
+
}, [
|
|
269
|
+
visible,
|
|
270
|
+
entries,
|
|
271
|
+
ref
|
|
272
|
+
]);
|
|
257
273
|
const adjustedYPos = yPos + menuHeight > window.innerHeight ? Math.max(window.innerHeight - menuHeight - $5150b66b01c99189$var$ESTIMATED_MENU_PADDING, 0) : yPos;
|
|
258
274
|
const adjustedXPos = xPos + menuWidth > window.innerWidth ? Math.max(window.innerWidth - menuWidth - $5150b66b01c99189$var$ESTIMATED_MENU_PADDING, 0) : xPos;
|
|
259
275
|
return /*#__PURE__*/ (0, $gTuX4$reactjsxruntime.jsx)("div", {
|
|
@@ -531,7 +547,6 @@ const $3c568ee547c732c3$export$ed4f9641643dc7e4 = (_param)=>{
|
|
|
531
547
|
"menuItems",
|
|
532
548
|
"showLowMenu"
|
|
533
549
|
]);
|
|
534
|
-
var _divHandlderRef_current;
|
|
535
550
|
// Check for higher content menu
|
|
536
551
|
const higherContext = (0, $gTuX4$react.useContext)($3c568ee547c732c3$export$fc58dc71afe92de2);
|
|
537
552
|
const thisMenuItems = (0, $gTuX4$react.useMemo)(()=>[
|
|
@@ -564,9 +579,34 @@ const $3c568ee547c732c3$export$ed4f9641643dc7e4 = (_param)=>{
|
|
|
564
579
|
const [menuInDom, setMenuInDom] = (0, $gTuX4$react.useState)(false);
|
|
565
580
|
const [mouseOverHandlerDiv, setMouseOverHandlerDiv] = (0, $gTuX4$react.useState)(false);
|
|
566
581
|
const [mouseOverMenu, setMouseOverMenu] = (0, $gTuX4$react.useState)(false);
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
582
|
+
// Holder position - measured in an effect to avoid reading refs during render
|
|
583
|
+
const [divHandlerPos, setDivHandlerPos] = (0, $gTuX4$react.useState)(null);
|
|
584
|
+
(0, $gTuX4$react.useLayoutEffect)(()=>{
|
|
585
|
+
function updatePos() {
|
|
586
|
+
if (divHandlderRef.current) setDivHandlerPos(divHandlderRef.current.getBoundingClientRect());
|
|
587
|
+
}
|
|
588
|
+
// When the handler is hovered or the menu is mounted, ensure we have a fresh position
|
|
589
|
+
if (mouseOverHandlerDiv || menuInDom) updatePos();
|
|
590
|
+
// Attach listeners while the menu/low-menu may be visible so the position stays correct
|
|
591
|
+
if (mouseOverHandlerDiv || menuInDom) {
|
|
592
|
+
window.addEventListener("resize", updatePos);
|
|
593
|
+
// listen on capture to catch scrolls from ancestor elements as well
|
|
594
|
+
window.addEventListener("scroll", updatePos, true);
|
|
595
|
+
let ro = null;
|
|
596
|
+
if (typeof ResizeObserver !== "undefined" && divHandlderRef.current) {
|
|
597
|
+
ro = new ResizeObserver(()=>updatePos());
|
|
598
|
+
ro.observe(divHandlderRef.current);
|
|
599
|
+
}
|
|
600
|
+
return ()=>{
|
|
601
|
+
window.removeEventListener("resize", updatePos);
|
|
602
|
+
window.removeEventListener("scroll", updatePos, true);
|
|
603
|
+
if (ro) ro.disconnect();
|
|
604
|
+
};
|
|
605
|
+
}
|
|
606
|
+
}, [
|
|
607
|
+
mouseOverHandlerDiv,
|
|
608
|
+
menuInDom
|
|
609
|
+
]);
|
|
570
610
|
// Handle click off the menu
|
|
571
611
|
const handleClick = (0, $gTuX4$react.useCallback)((e)=>{
|
|
572
612
|
var _menuRef_current;
|
|
@@ -761,10 +801,12 @@ const $46fb0088a1bbb6d8$export$1af8984c69ba1b24 = (_param)=>{
|
|
|
761
801
|
var _rest_style, _rest_style1, _rest_style2, _rest_style3;
|
|
762
802
|
const divRef = (0, $gTuX4$react.useRef)(null);
|
|
763
803
|
const windowRef = (0, $gTuX4$react.useRef)(null);
|
|
764
|
-
const [windowInDOM, setWindowInDOM] = (0, $gTuX4$react.useState)(false);
|
|
765
|
-
const [windowVisible, setWindowVisible] = (0, $gTuX4$react.useState)(false);
|
|
766
804
|
const [zIndex, setZIndex] = (0, $gTuX4$react.useState)(minZIndex);
|
|
767
805
|
const resizeListenerRef = (0, $gTuX4$react.useRef)(null);
|
|
806
|
+
// Track internal state: whether window is in DOM and whether it's been positioned
|
|
807
|
+
const [windowInDOM, setWindowInDOM] = (0, $gTuX4$react.useState)(false);
|
|
808
|
+
const [windowVisible, setWindowVisible] = (0, $gTuX4$react.useState)(false);
|
|
809
|
+
const [, startTransition] = (0, $gTuX4$react.useTransition)();
|
|
768
810
|
// Position
|
|
769
811
|
const windowPos = (0, $gTuX4$react.useRef)({
|
|
770
812
|
x: 0,
|
|
@@ -826,37 +868,54 @@ const $46fb0088a1bbb6d8$export$1af8984c69ba1b24 = (_param)=>{
|
|
|
826
868
|
}, [
|
|
827
869
|
minZIndex
|
|
828
870
|
]);
|
|
829
|
-
//
|
|
871
|
+
// Sync windowInDOM with visible prop using a layout effect to avoid ESLint warnings
|
|
872
|
+
// This effect derives state from props, which is acceptable when there's no synchronous setState
|
|
830
873
|
(0, $gTuX4$react.useEffect)(()=>{
|
|
831
|
-
//
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
874
|
+
if (visible && !windowInDOM) // Window should be in DOM when visible becomes true
|
|
875
|
+
startTransition(()=>{
|
|
876
|
+
setWindowInDOM(true);
|
|
877
|
+
});
|
|
878
|
+
else if (!visible && windowInDOM) // Window should leave DOM when visible becomes false
|
|
879
|
+
startTransition(()=>{
|
|
880
|
+
setWindowInDOM(false);
|
|
881
|
+
setWindowVisible(false);
|
|
882
|
+
});
|
|
883
|
+
}, [
|
|
884
|
+
visible,
|
|
885
|
+
windowInDOM,
|
|
886
|
+
startTransition
|
|
887
|
+
]);
|
|
888
|
+
// Position and show window after it's added to DOM
|
|
889
|
+
(0, $gTuX4$react.useEffect)(()=>{
|
|
890
|
+
if (windowInDOM && !windowVisible && visible && divRef.current && windowRef.current) {
|
|
891
|
+
// Position the window
|
|
892
|
+
const parentPos = divRef.current.getBoundingClientRect();
|
|
893
|
+
const pos = windowRef.current.getBoundingClientRect();
|
|
894
|
+
const windowHeight = pos.bottom - pos.top;
|
|
895
|
+
windowRef.current.style.left = `${parentPos.left}px`;
|
|
896
|
+
windowRef.current.style.top = `${parentPos.bottom + windowHeight < window.innerHeight ? parentPos.bottom : Math.max(0, parentPos.top - windowHeight)}px`;
|
|
897
|
+
windowRef.current.style.transform = "";
|
|
898
|
+
windowPos.current = {
|
|
899
|
+
x: 0,
|
|
900
|
+
y: 0
|
|
901
|
+
};
|
|
850
902
|
checkPosition();
|
|
851
|
-
|
|
852
|
-
|
|
903
|
+
// Update z-index and make visible - use startTransition
|
|
904
|
+
const maxZ = $46fb0088a1bbb6d8$var$getMaxZIndex(minZIndex);
|
|
905
|
+
onOpen === null || onOpen === void 0 ? void 0 : onOpen();
|
|
906
|
+
startTransition(()=>{
|
|
907
|
+
setZIndex(maxZ + 1);
|
|
908
|
+
setWindowVisible(true);
|
|
909
|
+
});
|
|
910
|
+
}
|
|
853
911
|
}, [
|
|
912
|
+
windowInDOM,
|
|
913
|
+
windowVisible,
|
|
914
|
+
visible,
|
|
854
915
|
checkPosition,
|
|
916
|
+
minZIndex,
|
|
855
917
|
onOpen,
|
|
856
|
-
|
|
857
|
-
visible,
|
|
858
|
-
windowInDOM,
|
|
859
|
-
windowVisible
|
|
918
|
+
startTransition
|
|
860
919
|
]);
|
|
861
920
|
// Cleanup effect to remove event listeners on unmount
|
|
862
921
|
(0, $gTuX4$react.useEffect)(()=>{
|
|
@@ -952,39 +1011,6 @@ $46fb0088a1bbb6d8$export$1af8984c69ba1b24.displayName = "ContextWindow";
|
|
|
952
1011
|
|
|
953
1012
|
|
|
954
1013
|
|
|
955
|
-
const $16208d559c772441$var$SESSION_KEY = "context-menu.ContextWindowStack.rendered";
|
|
956
|
-
const $16208d559c772441$export$9f37482ccd50dad2 = ({ children: children })=>{
|
|
957
|
-
(0, $gTuX4$react.useEffect)(()=>{
|
|
958
|
-
const doWarn = ()=>console.warn("ContextWindowStack is deprecated and no longer required. ContextWindow now manages z-index automatically. Please remove the ContextWindowStack wrapper from your code.");
|
|
959
|
-
try {
|
|
960
|
-
// Prefer sessionStorage so the warning lasts for the browser session.
|
|
961
|
-
if (typeof window !== "undefined" && window.sessionStorage) {
|
|
962
|
-
const already = window.sessionStorage.getItem($16208d559c772441$var$SESSION_KEY);
|
|
963
|
-
if (!already) {
|
|
964
|
-
window.sessionStorage.setItem($16208d559c772441$var$SESSION_KEY, "1");
|
|
965
|
-
doWarn();
|
|
966
|
-
}
|
|
967
|
-
return;
|
|
968
|
-
}
|
|
969
|
-
} catch (e) {
|
|
970
|
-
// sessionStorage may be unavailable (privacy mode). Fall through to global fallback.
|
|
971
|
-
}
|
|
972
|
-
// Fallback: use a global flag for environments where sessionStorage isn't available.
|
|
973
|
-
const g = globalThis;
|
|
974
|
-
if (!g.__ContextWindowStackRendered) {
|
|
975
|
-
g.__ContextWindowStackRendered = true;
|
|
976
|
-
doWarn();
|
|
977
|
-
}
|
|
978
|
-
}, []);
|
|
979
|
-
return /*#__PURE__*/ (0, $gTuX4$reactjsxruntime.jsx)((0, $gTuX4$reactjsxruntime.Fragment), {
|
|
980
|
-
children: children
|
|
981
|
-
});
|
|
982
|
-
};
|
|
983
|
-
$16208d559c772441$export$9f37482ccd50dad2.displayName = "ContextWindowStack";
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
1014
|
$parcel$exportWildcard(module.exports, $a68bd8a6c0fd98c2$exports);
|
|
989
1015
|
|
|
990
1016
|
|