@vuu-ui/vuu-popups 0.7.6-debug → 0.7.6

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/cjs/index.js CHANGED
@@ -1,1318 +1,2 @@
1
- "use strict";
2
- var __create = Object.create;
3
- var __defProp = Object.defineProperty;
4
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
- var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
- var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __export = (target, all) => {
9
- for (var name in all)
10
- __defProp(target, name, { get: all[name], enumerable: true });
11
- };
12
- var __copyProps = (to, from, except, desc) => {
13
- if (from && typeof from === "object" || typeof from === "function") {
14
- for (let key of __getOwnPropNames(from))
15
- if (!__hasOwnProp.call(to, key) && key !== except)
16
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
- }
18
- return to;
19
- };
20
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
- // If the importer is in node compatibility mode or this is not an ESM
22
- // file that has been converted to a CommonJS file using a Babel-
23
- // compatible transform (i.e. "__esModule" has not been set), then set
24
- // "default" to the CommonJS "module.exports" for node compatibility.
25
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
- mod
27
- ));
28
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
-
30
- // src/index.ts
31
- var src_exports = {};
32
- __export(src_exports, {
33
- ContextMenu: () => ContextMenu,
34
- ContextMenuContext: () => ContextMenuContext,
35
- ContextMenuProvider: () => ContextMenuProvider,
36
- Dialog: () => Dialog,
37
- DialogService: () => DialogService,
38
- MenuItem: () => MenuItem,
39
- MenuItemGroup: () => MenuItemGroup,
40
- Popup: () => Popup,
41
- PopupService: () => PopupService,
42
- Portal: () => Portal,
43
- Separator: () => Separator,
44
- createContainer: () => createContainer,
45
- installTheme: () => installTheme,
46
- isGroupMenuItemDescriptor: () => isGroupMenuItemDescriptor,
47
- renderPortal: () => renderPortal,
48
- useContextMenu: () => useContextMenu
49
- });
50
- module.exports = __toCommonJS(src_exports);
51
-
52
- // src/dialog/Dialog.tsx
53
- var import_salt_lab = require("@heswell/salt-lab");
54
- var import_core2 = require("@salt-ds/core");
55
- var import_classnames = __toESM(require("classnames"));
56
- var import_react2 = require("react");
57
-
58
- // src/portal/Portal.tsx
59
- var import_react = require("react");
60
- var ReactDOM2 = __toESM(require("react-dom"));
61
-
62
- // src/portal/render-portal.tsx
63
- var ReactDOM = __toESM(require("react-dom"));
64
- var import_core = require("@salt-ds/core");
65
- var import_jsx_runtime = require("react/jsx-runtime");
66
- var containerId = 1;
67
- var getPortalContainer = (x = 0, y = 0, win = window) => {
68
- const el = win.document.createElement("div");
69
- el.className = "vuuPopup " + containerId++;
70
- el.style.cssText = `left:${x}px; top:${y}px;`;
71
- win.document.body.appendChild(el);
72
- return el;
73
- };
74
- var createDOMContainer = (x, y) => getPortalContainer(x, y);
75
- var renderPortal = (component, container, x, y, onRender) => {
76
- container.style.cssText = `left:${x}px; top:${y}px;position: absolute;`;
77
- ReactDOM.render(
78
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_core.SaltProvider, { applyClassesTo: "child", children: component }),
79
- container,
80
- onRender
81
- );
82
- };
83
- var createContainer = createDOMContainer;
84
-
85
- // src/portal/Portal.tsx
86
- var Portal = function Portal2({
87
- children,
88
- x = 0,
89
- y = 0,
90
- onRender
91
- }) {
92
- const renderContainer = (0, import_react.useMemo)(() => {
93
- return createContainer();
94
- }, []);
95
- (0, import_react.useLayoutEffect)(() => {
96
- renderPortal(children, renderContainer, x, y, onRender);
97
- }, [children, onRender, renderContainer, x, y]);
98
- (0, import_react.useLayoutEffect)(() => {
99
- return () => {
100
- var _a;
101
- if (renderContainer) {
102
- ReactDOM2.unmountComponentAtNode(renderContainer);
103
- if (renderContainer.classList.contains("vuuPopup")) {
104
- (_a = renderContainer.parentElement) == null ? void 0 : _a.removeChild(renderContainer);
105
- }
106
- }
107
- };
108
- }, [renderContainer]);
109
- return null;
110
- };
111
-
112
- // src/portal/portal-utils.ts
113
- var installTheme = (themeId) => {
114
- const installedThemes = getComputedStyle(document.body).getPropertyValue(
115
- "--installed-themes"
116
- );
117
- document.body.style.setProperty(
118
- "--installed-themes",
119
- `${installedThemes} ${themeId}`
120
- );
121
- };
122
-
123
- // src/dialog/Dialog.tsx
124
- var import_jsx_runtime2 = require("react/jsx-runtime");
125
- var classBase = "vuuDialog";
126
- var Dialog = ({
127
- children,
128
- className,
129
- isOpen = false,
130
- onClose,
131
- title,
132
- ...props
133
- }) => {
134
- const root = (0, import_react2.useRef)(null);
135
- const [posX] = (0, import_react2.useState)(0);
136
- const [posY] = (0, import_react2.useState)(0);
137
- const close = (0, import_react2.useCallback)(() => {
138
- onClose == null ? void 0 : onClose();
139
- }, [onClose]);
140
- const handleRender = (0, import_react2.useCallback)(() => {
141
- }, []);
142
- if (!isOpen) {
143
- return null;
144
- }
145
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Portal, { onRender: handleRender, x: posX, y: posY, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_salt_lab.Scrim, { className: `${classBase}-scrim`, open: isOpen, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { ...props, className: (0, import_classnames.default)(classBase, className), ref: root, children: [
146
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_salt_lab.Toolbar, { className: `${classBase}-header`, children: [
147
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_core2.Text, { children: title }),
148
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
149
- import_salt_lab.ToolbarButton,
150
- {
151
- onClick: close,
152
- "data-align-end": true,
153
- "data-icon": "close"
154
- },
155
- "close"
156
- )
157
- ] }),
158
- children
159
- ] }) }) });
160
- };
161
-
162
- // src/menu/ContextMenu.tsx
163
- var import_core4 = require("@salt-ds/core");
164
- var import_react8 = require("react");
165
-
166
- // src/menu/MenuList.tsx
167
- var import_react5 = __toESM(require("react"));
168
- var import_classnames2 = __toESM(require("classnames"));
169
- var import_core3 = require("@salt-ds/core");
170
-
171
- // src/menu/use-keyboard-navigation.ts
172
- var import_react3 = require("react");
173
-
174
- // src/menu/utils.ts
175
- var isRoot = (el) => el.closest(`[data-root='true']`) !== null;
176
- var hasPopup = (el, idx) => {
177
- var _a;
178
- return el.ariaHasPopup === "true" && ((_a = el.dataset) == null ? void 0 : _a.idx) === `${idx}` || el.querySelector(`:scope > [data-idx='${idx}'][aria-haspopup='true']`) !== null;
179
- };
180
-
181
- // src/menu/key-code.ts
182
- function union(set1, ...sets) {
183
- const result = new Set(set1);
184
- for (const set of sets) {
185
- for (const element of set) {
186
- result.add(element);
187
- }
188
- }
189
- return result;
190
- }
191
- var Enter = "Enter";
192
- var Delete = "Delete";
193
- var actionKeys = /* @__PURE__ */ new Set([Enter, Delete]);
194
- var focusKeys = /* @__PURE__ */ new Set(["Tab"]);
195
- var arrowLeftRightKeys = /* @__PURE__ */ new Set(["ArrowRight", "ArrowLeft"]);
196
- var verticalNavigationKeys = /* @__PURE__ */ new Set(["Home", "End", "ArrowDown", "ArrowUp"]);
197
- var horizontalNavigationKeys = /* @__PURE__ */ new Set([
198
- "Home",
199
- "End",
200
- "ArrowRight",
201
- "ArrowLeft"
202
- ]);
203
- var functionKeys = /* @__PURE__ */ new Set([
204
- "F1",
205
- "F2",
206
- "F3",
207
- "F4",
208
- "F5",
209
- "F6",
210
- "F7",
211
- "F8",
212
- "F9",
213
- "F10",
214
- "F11",
215
- "F12"
216
- ]);
217
- var specialKeys = union(
218
- actionKeys,
219
- horizontalNavigationKeys,
220
- verticalNavigationKeys,
221
- arrowLeftRightKeys,
222
- functionKeys,
223
- focusKeys
224
- );
225
- var isNavigationKey = ({ key }, orientation = "vertical") => {
226
- const navigationKeys = orientation === "vertical" ? verticalNavigationKeys : horizontalNavigationKeys;
227
- return navigationKeys.has(key);
228
- };
229
-
230
- // src/menu/use-keyboard-navigation.ts
231
- var useKeyboardNavigation = ({
232
- autoHighlightFirstItem = false,
233
- count,
234
- highlightedIndex: highlightedIndexProp,
235
- onActivate,
236
- onHighlight,
237
- // onKeyDown,
238
- onCloseMenu,
239
- onOpenMenu
240
- }) => {
241
- const highlightedIndexRef = (0, import_react3.useRef)(
242
- (highlightedIndexProp != null ? highlightedIndexProp : autoHighlightFirstItem) ? 0 : -1
243
- );
244
- const [, forceRender] = (0, import_react3.useState)(null);
245
- const controlledHighlighting = highlightedIndexProp !== void 0;
246
- const setHighlightedIdx = (0, import_react3.useCallback)(
247
- (idx) => {
248
- highlightedIndexRef.current = idx;
249
- onHighlight == null ? void 0 : onHighlight(idx);
250
- forceRender({});
251
- },
252
- [onHighlight]
253
- );
254
- const setHighlightedIndex = (0, import_react3.useCallback)(
255
- (idx) => {
256
- if (idx !== highlightedIndexRef.current) {
257
- if (!controlledHighlighting) {
258
- setHighlightedIdx(idx);
259
- }
260
- }
261
- },
262
- [controlledHighlighting, setHighlightedIdx]
263
- );
264
- const keyBoardNavigation = (0, import_react3.useRef)(true);
265
- const ignoreFocus = (0, import_react3.useRef)(false);
266
- const setIgnoreFocus = (value) => ignoreFocus.current = value;
267
- const highlightedIndex = controlledHighlighting ? highlightedIndexProp : highlightedIndexRef.current;
268
- const navigateChildldItems = (0, import_react3.useCallback)(
269
- (e) => {
270
- const nextIdx = nextItemIdx(count, e.key, highlightedIndexRef.current);
271
- if (nextIdx !== highlightedIndexRef.current) {
272
- setHighlightedIndex(nextIdx);
273
- }
274
- },
275
- [count, setHighlightedIndex]
276
- );
277
- const handleKeyDown = (0, import_react3.useCallback)(
278
- (e) => {
279
- if (isNavigationKey(e)) {
280
- e.preventDefault();
281
- e.stopPropagation();
282
- keyBoardNavigation.current = true;
283
- navigateChildldItems(e);
284
- } else if ((e.key === "ArrowRight" || e.key === "Enter") && hasPopup(e.target, highlightedIndex)) {
285
- onOpenMenu(highlightedIndex);
286
- } else if (e.key === "ArrowLeft" && !isRoot(e.target)) {
287
- onCloseMenu(highlightedIndex);
288
- } else if (e.key === "Enter") {
289
- onActivate && onActivate(highlightedIndex);
290
- }
291
- },
292
- [
293
- highlightedIndex,
294
- navigateChildldItems,
295
- onActivate,
296
- onCloseMenu,
297
- onOpenMenu
298
- ]
299
- );
300
- const listProps = (0, import_react3.useMemo)(
301
- () => ({
302
- onFocus: () => {
303
- if (highlightedIndex === -1) {
304
- setHighlightedIdx(0);
305
- }
306
- },
307
- onKeyDown: handleKeyDown,
308
- onMouseDownCapture: () => {
309
- keyBoardNavigation.current = false;
310
- setIgnoreFocus(true);
311
- },
312
- // onMouseEnter would seem less expensive but it misses some cases
313
- onMouseMove: () => {
314
- if (keyBoardNavigation.current) {
315
- keyBoardNavigation.current = false;
316
- }
317
- },
318
- onMouseLeave: () => {
319
- keyBoardNavigation.current = true;
320
- setIgnoreFocus(false);
321
- setHighlightedIndex(-1);
322
- }
323
- }),
324
- [
325
- highlightedIndex,
326
- setHighlightedIndex,
327
- navigateChildldItems,
328
- onActivate,
329
- onCloseMenu,
330
- onOpenMenu,
331
- setHighlightedIdx
332
- ]
333
- );
334
- return {
335
- focusVisible: keyBoardNavigation.current ? highlightedIndex : -1,
336
- controlledHighlighting,
337
- highlightedIndex,
338
- setHighlightedIndex,
339
- // keyBoardNavigation,
340
- listProps,
341
- setIgnoreFocus
342
- };
343
- };
344
- function nextItemIdx(count, key, idx) {
345
- if (key === "ArrowUp") {
346
- if (idx > 0) {
347
- return idx - 1;
348
- } else {
349
- return idx;
350
- }
351
- } else {
352
- if (idx === null) {
353
- return 0;
354
- } else if (idx === count - 1) {
355
- return idx;
356
- } else {
357
- return idx + 1;
358
- }
359
- }
360
- }
361
-
362
- // src/menu/use-items-with-ids.ts
363
- var import_react4 = __toESM(require("react"));
364
- var isMenuItemGroup = (child) => child.type === MenuItemGroup || !!child.props["data-group"];
365
- var useItemsWithIds = (childrenProp) => {
366
- const normalizeChildren = (0, import_react4.useCallback)(() => {
367
- const collectChildren = (children, path = "root", menus2 = {}, actions2 = {}) => {
368
- const list = menus2[path] = [];
369
- let idx = 0;
370
- let hasSeparator = false;
371
- import_react4.default.Children.forEach(children, (child) => {
372
- if (child.type === Separator) {
373
- hasSeparator = true;
374
- } else {
375
- const group = isMenuItemGroup(child);
376
- const childPath = path === "root" ? `${idx}` : `${path}.${idx}`;
377
- const {
378
- props: { action, options }
379
- } = child;
380
- const { childWithId, grandChildren } = assignId(
381
- child,
382
- childPath,
383
- group,
384
- hasSeparator
385
- );
386
- list.push(childWithId);
387
- if (grandChildren) {
388
- collectChildren(grandChildren, childPath, menus2, actions2);
389
- } else {
390
- actions2[childPath] = { action, options };
391
- }
392
- idx += 1;
393
- hasSeparator = false;
394
- }
395
- });
396
- return [menus2, actions2];
397
- };
398
- const assignId = (child, path, group, hasSeparator = false) => {
399
- const {
400
- props: { children }
401
- } = child;
402
- return {
403
- childWithId: import_react4.default.cloneElement(child, {
404
- hasSeparator,
405
- id: `${path}`,
406
- key: path,
407
- children: group ? void 0 : children
408
- }),
409
- grandChildren: group ? children : void 0
410
- };
411
- };
412
- return collectChildren(childrenProp);
413
- }, [childrenProp]);
414
- const [menus, actions] = (0, import_react4.useMemo)(
415
- () => normalizeChildren(),
416
- [normalizeChildren]
417
- );
418
- return [menus, actions];
419
- };
420
-
421
- // src/menu/MenuList.tsx
422
- var import_jsx_runtime3 = require("react/jsx-runtime");
423
- var classBase2 = "vuuMenuList";
424
- var Separator = () => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("li", { className: "vuuMenuItem-divider" });
425
- var MenuItemGroup = () => null;
426
- var MenuItem = ({ children, idx, ...props }) => {
427
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { ...props, children });
428
- };
429
- var hasIcon = (child) => child.props["data-icon"];
430
- var MenuList = ({
431
- activatedByKeyboard,
432
- childMenuShowing = -1,
433
- children,
434
- className,
435
- highlightedIdx: highlightedIdxProp,
436
- id: idProp,
437
- isRoot: isRoot2,
438
- listItemProps,
439
- menuId,
440
- onHighlightMenuItem,
441
- onActivate,
442
- onCloseMenu,
443
- onOpenMenu,
444
- ...props
445
- }) => {
446
- const id = (0, import_core3.useIdMemo)(idProp);
447
- const root = (0, import_react5.useRef)(null);
448
- const mapIdxToId = (0, import_react5.useMemo)(() => /* @__PURE__ */ new Map(), []);
449
- const handleOpenMenu = (idx) => {
450
- var _a;
451
- const el = (_a = root.current) == null ? void 0 : _a.querySelector(`:scope > [data-idx='${idx}']`);
452
- (el == null ? void 0 : el.id) && (onOpenMenu == null ? void 0 : onOpenMenu(el.id));
453
- };
454
- const handleActivate = (idx) => {
455
- var _a;
456
- const el = (_a = root.current) == null ? void 0 : _a.querySelector(`:scope > [data-idx='${idx}']`);
457
- (el == null ? void 0 : el.id) && (onActivate == null ? void 0 : onActivate(el.id));
458
- };
459
- const { focusVisible, highlightedIndex, listProps } = useKeyboardNavigation({
460
- count: import_react5.default.Children.count(children),
461
- highlightedIndex: highlightedIdxProp,
462
- onActivate: handleActivate,
463
- onHighlight: onHighlightMenuItem,
464
- onOpenMenu: handleOpenMenu,
465
- onCloseMenu
466
- });
467
- const appliedFocusVisible = childMenuShowing == -1 ? focusVisible : -1;
468
- (0, import_react5.useLayoutEffect)(() => {
469
- var _a;
470
- if (childMenuShowing === -1 && activatedByKeyboard) {
471
- (_a = root.current) == null ? void 0 : _a.focus();
472
- }
473
- }, [activatedByKeyboard, childMenuShowing]);
474
- const getActiveDescendant = () => highlightedIndex === void 0 || highlightedIndex === -1 ? void 0 : mapIdxToId.get(highlightedIndex);
475
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
476
- "div",
477
- {
478
- ...props,
479
- ...listProps,
480
- "aria-activedescendant": getActiveDescendant(),
481
- className: (0, import_classnames2.default)(classBase2, className, {
482
- [`${classBase2}-childMenuShowing`]: childMenuShowing !== -1
483
- }),
484
- "data-root": isRoot2 || void 0,
485
- id: `${id}-${menuId}`,
486
- ref: root,
487
- role: "menu",
488
- tabIndex: 0,
489
- children: renderContent()
490
- }
491
- );
492
- function renderContent() {
493
- const propsCommonToAllListItems = {
494
- ...listItemProps,
495
- role: "menuitem"
496
- };
497
- const maybeIcon = (childElement, withIcon, iconName) => withIcon ? [
498
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
499
- "span",
500
- {
501
- className: "vuuIconContainer",
502
- "data-icon": iconName
503
- },
504
- "icon"
505
- )
506
- ].concat(childElement) : childElement;
507
- function addClonedChild(list, child, idx, withIcon) {
508
- var _a;
509
- const {
510
- children: children2,
511
- className: className2,
512
- "data-icon": iconName,
513
- id: itemId,
514
- hasSeparator,
515
- label,
516
- ...props2
517
- } = child.props;
518
- const hasSubMenu = isMenuItemGroup(child);
519
- const subMenuShowing = hasSubMenu && childMenuShowing === idx;
520
- const ariaControls = subMenuShowing ? `${id}-${itemId}` : void 0;
521
- list.push(
522
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
523
- MenuItem,
524
- {
525
- ...props2,
526
- ...propsCommonToAllListItems,
527
- ...getMenuItemProps(
528
- `${id}-${menuId}`,
529
- itemId,
530
- idx,
531
- (_a = child.key) != null ? _a : itemId,
532
- highlightedIndex,
533
- appliedFocusVisible,
534
- className2,
535
- hasSeparator
536
- ),
537
- "aria-controls": ariaControls,
538
- "aria-haspopup": hasSubMenu || void 0,
539
- "aria-expanded": subMenuShowing || void 0,
540
- children: hasSubMenu ? maybeIcon(label, withIcon, iconName) : maybeIcon(children2, withIcon, iconName)
541
- }
542
- )
543
- );
544
- }
545
- const listItems = [];
546
- if (children.length > 0) {
547
- const withIcon = children.some(hasIcon);
548
- children.forEach((child, idx) => {
549
- addClonedChild(listItems, child, idx, withIcon);
550
- });
551
- }
552
- return listItems;
553
- }
554
- };
555
- var getMenuItemProps = (baseId, itemId, idx, key, highlightedIdx, focusVisible, className, hasSeparator) => ({
556
- id: `${baseId}-${itemId}`,
557
- key: key != null ? key : idx,
558
- "data-idx": idx,
559
- "data-highlighted": idx === highlightedIdx || void 0,
560
- className: (0, import_classnames2.default)("vuuMenuItem", className, {
561
- "vuuMenuItem-separator": hasSeparator,
562
- focusVisible: focusVisible === idx
563
- })
564
- });
565
- MenuList.displayName = "MenuList";
566
- var MenuList_default = MenuList;
567
-
568
- // src/menu/use-cascade.ts
569
- var import_react6 = require("react");
570
-
571
- // src/menu/list-dom-utils.ts
572
- function listItemIndex(listItemEl) {
573
- if (listItemEl) {
574
- const idx = listItemEl.dataset.idx;
575
- if (idx) {
576
- return parseInt(idx, 10);
577
- } else if (listItemEl.ariaPosInSet) {
578
- return parseInt(listItemEl.ariaPosInSet, 10) - 1;
579
- }
580
- }
581
- }
582
- var closestListItem = (el) => el == null ? void 0 : el.closest("[data-idx],[aria-posinset]");
583
-
584
- // src/menu/use-cascade.ts
585
- var nudge = (menus, distance, pos) => {
586
- return menus.map(
587
- (m, i) => i === menus.length - 1 ? {
588
- ...m,
589
- [pos]: m[pos] - distance
590
- } : m
591
- );
592
- };
593
- var nudgeLeft = (menus, distance) => nudge(menus, distance, "left");
594
- var nudgeUp = (menus, distance) => nudge(menus, distance, "top");
595
- var flipSides = (id, menus) => {
596
- const [parentMenu, menu] = menus.slice(-2);
597
- const el = document.getElementById(`${id}-${menu.id}`);
598
- if (el === null) {
599
- throw Error(`useCascade.flipSides element with id ${menu.id} not found`);
600
- }
601
- const { width } = el.getBoundingClientRect();
602
- return menus.map(
603
- (m) => m === menu ? {
604
- ...m,
605
- left: parentMenu.left - (width - 2)
606
- } : m
607
- );
608
- };
609
- var getPosition = (el, openMenus) => {
610
- const [{ left, top: menuTop }] = openMenus.slice(-1);
611
- const { offsetWidth: width, offsetTop: top } = el;
612
- return { left: left + width, top: top + menuTop };
613
- };
614
- var getItemId = (id) => {
615
- const pos = id.lastIndexOf("-");
616
- return pos === -1 ? id : id.slice(pos + 1);
617
- };
618
- var getMenuId = (id) => {
619
- const itemId = getItemId(id);
620
- const pos = itemId.lastIndexOf(".");
621
- return pos > -1 ? itemId.slice(0, pos) : "root";
622
- };
623
- var getMenuDepth = (id) => {
624
- let count = 0, pos = id.indexOf(".", 0);
625
- while (pos !== -1) {
626
- count += 1;
627
- pos = id.indexOf(".", pos + 1);
628
- }
629
- return count;
630
- };
631
- var identifyItem = (el) => ({
632
- menuId: getMenuId(el.id),
633
- itemId: getItemId(el.id),
634
- isGroup: el.ariaHasPopup === "true",
635
- isOpen: el.ariaExpanded === "true",
636
- level: getMenuDepth(el.id)
637
- });
638
- var useCascade = ({
639
- id,
640
- onActivate,
641
- onMouseEnterItem,
642
- position: { x: posX, y: posY }
643
- }) => {
644
- const [, forceRefresh] = (0, import_react6.useState)({});
645
- const openMenus = (0, import_react6.useRef)([
646
- { id: "root", left: posX, top: posY }
647
- ]);
648
- const setOpenMenus = (0, import_react6.useCallback)((menus) => {
649
- openMenus.current = menus;
650
- forceRefresh({});
651
- }, []);
652
- const menuOpenPendingTimeout = (0, import_react6.useRef)();
653
- const menuClosePendingTimeout = (0, import_react6.useRef)();
654
- const menuState = (0, import_react6.useRef)({ root: "no-popup" });
655
- const prevLevel = (0, import_react6.useRef)(0);
656
- const openMenu = (0, import_react6.useCallback)(
657
- (menuId = "root", itemId = null, listItemEl = null) => {
658
- if (menuId === "root" && itemId === null) {
659
- setOpenMenus([{ id: "root", left: posX, top: posY }]);
660
- } else {
661
- menuState.current[menuId] = "popup-open";
662
- const doc = listItemEl ? listItemEl.ownerDocument : document;
663
- const el = doc.getElementById(`${id}-${menuId}-${itemId}`);
664
- const { left, top } = getPosition(el, openMenus.current);
665
- setOpenMenus(openMenus.current.concat({ id: itemId, left, top }));
666
- }
667
- },
668
- [id, posX, posY, setOpenMenus]
669
- );
670
- const closeMenu = (0, import_react6.useCallback)(
671
- (menuId) => {
672
- if (menuId === "root") {
673
- setOpenMenus([]);
674
- } else {
675
- setOpenMenus(openMenus.current.slice(0, -1));
676
- }
677
- },
678
- [setOpenMenus]
679
- );
680
- const closeMenus = (0, import_react6.useCallback)(
681
- (menuId, itemId) => {
682
- const menus = openMenus.current.slice();
683
- let { id: lastMenuId } = menus[menus.length - 1];
684
- while (menus.length > 1 && !itemId.startsWith(lastMenuId)) {
685
- const parentMenuId = getMenuId(lastMenuId);
686
- menus.pop();
687
- menuState.current[lastMenuId] = "no-popup";
688
- menuState.current[parentMenuId] = "no-popup";
689
- ({ id: lastMenuId } = menus[menus.length - 1]);
690
- }
691
- if (menus.length < openMenus.current.length) {
692
- setOpenMenus(menus);
693
- }
694
- },
695
- [setOpenMenus]
696
- );
697
- const scheduleOpen = (0, import_react6.useCallback)(
698
- (menuId, itemId, listItemEl) => {
699
- if (menuOpenPendingTimeout.current) {
700
- clearTimeout(menuOpenPendingTimeout.current);
701
- }
702
- menuOpenPendingTimeout.current = window.setTimeout(() => {
703
- console.log(`scheduleOpen timed out opening ${itemId}`);
704
- closeMenus(menuId, itemId);
705
- menuState.current[menuId] = "popup-open";
706
- menuState.current[itemId] = "no-popup";
707
- openMenu(menuId, itemId, listItemEl);
708
- }, 400);
709
- },
710
- [closeMenus, openMenu]
711
- );
712
- const scheduleClose = (0, import_react6.useCallback)(
713
- (openMenuId, menuId, itemId) => {
714
- console.log(
715
- `scheduleClose openMenuId ${openMenuId} menuId ${menuId} itemId ${itemId}`
716
- );
717
- menuState.current[openMenuId] = "pending-close";
718
- menuClosePendingTimeout.current = window.setTimeout(() => {
719
- closeMenus(menuId, itemId);
720
- }, 400);
721
- },
722
- [closeMenus]
723
- );
724
- const handleRender = (0, import_react6.useCallback)(() => {
725
- const { current: menus } = openMenus;
726
- const [menu] = menus.slice(-1);
727
- const el = document.getElementById(`${id}-${menu.id}`);
728
- if (el) {
729
- const { right, bottom } = el.getBoundingClientRect();
730
- const { clientHeight, clientWidth } = document.body;
731
- if (right > clientWidth) {
732
- const newMenus = menus.length > 1 ? flipSides(id, menus) : nudgeLeft(menus, right - clientWidth);
733
- setOpenMenus(newMenus);
734
- } else if (bottom > clientHeight) {
735
- const newMenus = nudgeUp(menus, bottom - clientHeight);
736
- setOpenMenus(newMenus);
737
- }
738
- }
739
- }, [id, setOpenMenus]);
740
- const listItemProps = (0, import_react6.useMemo)(
741
- () => ({
742
- onMouseEnter: (evt) => {
743
- const listItemEl = closestListItem(evt.target);
744
- const { menuId, itemId, isGroup, isOpen, level } = identifyItem(listItemEl);
745
- const sameLevel = prevLevel.current === level;
746
- const {
747
- current: { [menuId]: state }
748
- } = menuState;
749
- prevLevel.current = level;
750
- if (state === "no-popup" && isGroup) {
751
- menuState.current[menuId] = "popup-pending";
752
- scheduleOpen(menuId, itemId, listItemEl);
753
- } else if (state === "popup-pending" && !isGroup) {
754
- menuState.current[menuId] = "no-popup";
755
- clearTimeout(menuOpenPendingTimeout.current);
756
- menuOpenPendingTimeout.current = void 0;
757
- } else if (state === "popup-pending" && isGroup) {
758
- clearTimeout(menuOpenPendingTimeout.current);
759
- scheduleOpen(menuId, itemId, listItemEl);
760
- } else if (state === "popup-open") {
761
- const [{ id: parentMenuId }, { id: openMenuId }] = openMenus.current.slice(-2);
762
- if (parentMenuId === menuId && menuState.current[openMenuId] !== "pending-close" && sameLevel) {
763
- scheduleClose(openMenuId, menuId, itemId);
764
- if (isGroup && !isOpen) {
765
- scheduleOpen(menuId, itemId, listItemEl);
766
- }
767
- } else if (parentMenuId === menuId && isGroup && itemId !== openMenuId && menuState.current[openMenuId] === "pending-close") {
768
- scheduleOpen(menuId, itemId, listItemEl);
769
- } else if (isGroup) {
770
- closeMenus(menuId, itemId);
771
- scheduleOpen(menuId, itemId, listItemEl);
772
- } else if (!(menuState.current[openMenuId] === "pending-close" && sameLevel)) {
773
- closeMenus(menuId, itemId);
774
- }
775
- }
776
- if (state === "pending-close") {
777
- if (menuOpenPendingTimeout.current) {
778
- clearTimeout(menuOpenPendingTimeout.current);
779
- menuOpenPendingTimeout.current = void 0;
780
- }
781
- clearTimeout(menuClosePendingTimeout.current);
782
- menuClosePendingTimeout.current = void 0;
783
- menuState.current[menuId] = "popup-open";
784
- }
785
- onMouseEnterItem(evt, itemId);
786
- },
787
- onClick: (evt) => {
788
- const targetElement = evt.target;
789
- const listItemEl = closestListItem(targetElement);
790
- const idx = listItemIndex(listItemEl);
791
- console.log(
792
- `list item click [${idx}] hasPopup ${listItemEl.ariaHasPopup}`
793
- );
794
- if (listItemEl.ariaHasPopup === "true") {
795
- if (listItemEl.ariaExpanded !== "true") {
796
- openMenu(idx);
797
- } else {
798
- }
799
- } else {
800
- onActivate(getItemId(listItemEl.id));
801
- }
802
- }
803
- }),
804
- [
805
- closeMenus,
806
- onActivate,
807
- onMouseEnterItem,
808
- openMenu,
809
- scheduleClose,
810
- scheduleOpen
811
- ]
812
- );
813
- return {
814
- closeMenu,
815
- handleRender,
816
- listItemProps,
817
- openMenu,
818
- openMenus: openMenus.current
819
- };
820
- };
821
-
822
- // src/menu/use-click-away.ts
823
- var import_react7 = require("react");
824
- var useClickAway = ({
825
- containerClassName,
826
- isOpen,
827
- onClose
828
- }) => {
829
- (0, import_react7.useEffect)(() => {
830
- let clickHandler;
831
- if (isOpen) {
832
- clickHandler = (evt) => {
833
- const target = evt.target;
834
- const container = target.closest(`.${containerClassName}`);
835
- if (container === null) {
836
- onClose == null ? void 0 : onClose("root");
837
- }
838
- };
839
- document.body.addEventListener("click", clickHandler, true);
840
- }
841
- return () => {
842
- if (clickHandler) {
843
- document.body.removeEventListener("click", clickHandler, true);
844
- }
845
- };
846
- }, [containerClassName, isOpen, onClose]);
847
- };
848
-
849
- // src/menu/ContextMenu.tsx
850
- var import_jsx_runtime4 = require("react/jsx-runtime");
851
- var import_react9 = require("react");
852
- var noop = () => void 0;
853
- var ContextMenu = ({
854
- activatedByKeyboard,
855
- children: childrenProp,
856
- className,
857
- id: idProp,
858
- onClose = () => void 0,
859
- position = { x: 0, y: 0 },
860
- style,
861
- ...menuListProps
862
- }) => {
863
- const id = (0, import_core4.useIdMemo)(idProp);
864
- const closeMenuRef = (0, import_react8.useRef)(noop);
865
- const [menus, actions] = useItemsWithIds(childrenProp);
866
- const navigatingWithKeyboard = (0, import_react8.useRef)(activatedByKeyboard);
867
- const handleMouseEnterItem = (0, import_react8.useCallback)(() => {
868
- navigatingWithKeyboard.current = false;
869
- }, []);
870
- const handleActivate = (0, import_react8.useCallback)(
871
- (menuId) => {
872
- const { action, options } = actions[menuId];
873
- closeMenuRef.current("root");
874
- onClose(action, options);
875
- },
876
- [actions, onClose]
877
- );
878
- const { closeMenu, listItemProps, openMenu, openMenus, handleRender } = useCascade({
879
- id,
880
- onActivate: handleActivate,
881
- onMouseEnterItem: handleMouseEnterItem,
882
- position
883
- });
884
- closeMenuRef.current = closeMenu;
885
- console.log({ openMenus });
886
- const handleClose = (0, import_react8.useCallback)(() => {
887
- closeMenu();
888
- onClose();
889
- }, [closeMenu, onClose]);
890
- useClickAway({
891
- containerClassName: "vuuMenuList",
892
- onClose: handleClose,
893
- isOpen: openMenus.length > 0
894
- });
895
- const handleOpenMenu = (id2) => {
896
- const itemId = getItemId(id2);
897
- const menuId = getMenuId(itemId);
898
- navigatingWithKeyboard.current = true;
899
- openMenu(menuId, itemId);
900
- };
901
- const handleCloseMenu = () => {
902
- navigatingWithKeyboard.current = true;
903
- closeMenu();
904
- };
905
- const handleHighlightMenuItem = () => {
906
- };
907
- const lastMenu = openMenus.length - 1;
908
- const getChildMenuIndex = (i) => {
909
- if (i >= lastMenu) {
910
- return -1;
911
- } else {
912
- const { id: menuId } = openMenus[i + 1];
913
- const pos = menuId.lastIndexOf(".");
914
- const idx = pos === -1 ? parseInt(menuId, 10) : parseInt(menuId.slice(-pos), 10);
915
- return idx;
916
- }
917
- };
918
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_jsx_runtime4.Fragment, { children: openMenus.map(({ id: menuId, left, top }, i) => {
919
- const childMenuIndex = getChildMenuIndex(i);
920
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Portal, { x: left, y: top, onRender: handleRender, children: /* @__PURE__ */ (0, import_react9.createElement)(
921
- MenuList_default,
922
- {
923
- ...menuListProps,
924
- activatedByKeyboard: navigatingWithKeyboard.current,
925
- childMenuShowing: childMenuIndex,
926
- className,
927
- id,
928
- menuId,
929
- isRoot: i === 0,
930
- key: i,
931
- listItemProps,
932
- onActivate: handleActivate,
933
- onHighlightMenuItem: handleHighlightMenuItem,
934
- onCloseMenu: handleCloseMenu,
935
- onOpenMenu: handleOpenMenu,
936
- style
937
- },
938
- menus[menuId]
939
- ) }, i);
940
- }) });
941
- };
942
- ContextMenu.displayName = "ContextMenu";
943
-
944
- // src/menu/context-menu-provider.tsx
945
- var import_react10 = require("react");
946
- var import_jsx_runtime5 = require("react/jsx-runtime");
947
- var ContextMenuContext = (0, import_react10.createContext)(
948
- null
949
- );
950
- var isGroupMenuItemDescriptor = (menuItem) => menuItem !== void 0 && "children" in menuItem;
951
- var Provider = ({
952
- children,
953
- context,
954
- menuActionHandler,
955
- menuBuilder
956
- }) => {
957
- const menuBuilders = (0, import_react10.useMemo)(() => {
958
- if ((context == null ? void 0 : context.menuBuilders) && menuBuilder) {
959
- return context.menuBuilders.concat(menuBuilder);
960
- } else if (menuBuilder) {
961
- return [menuBuilder];
962
- } else {
963
- return (context == null ? void 0 : context.menuBuilders) || [];
964
- }
965
- }, [context, menuBuilder]);
966
- const handleMenuAction = (0, import_react10.useCallback)(
967
- (type, options) => {
968
- var _a;
969
- if (menuActionHandler == null ? void 0 : menuActionHandler(type, options)) {
970
- return true;
971
- }
972
- if ((_a = context == null ? void 0 : context.menuActionHandler) == null ? void 0 : _a.call(context, type, options)) {
973
- return true;
974
- }
975
- },
976
- [context, menuActionHandler]
977
- );
978
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
979
- ContextMenuContext.Provider,
980
- {
981
- value: {
982
- menuActionHandler: handleMenuAction,
983
- menuBuilders
984
- },
985
- children
986
- }
987
- );
988
- };
989
- var ContextMenuProvider = ({
990
- children,
991
- label,
992
- menuActionHandler,
993
- menuBuilder
994
- }) => {
995
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ContextMenuContext.Consumer, { children: (parentContext) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
996
- Provider,
997
- {
998
- context: parentContext,
999
- label,
1000
- menuActionHandler,
1001
- menuBuilder,
1002
- children
1003
- }
1004
- ) });
1005
- };
1006
-
1007
- // src/menu/useContextMenu.tsx
1008
- var import_react12 = require("react");
1009
-
1010
- // src/popup/popup-service.ts
1011
- var import_classnames3 = __toESM(require("classnames"));
1012
- var import_react11 = __toESM(require("react"));
1013
- var import_react_dom = __toESM(require("react-dom"));
1014
- var _dialogOpen = false;
1015
- var _popups = [];
1016
- function specialKeyHandler(e) {
1017
- if (e.key === "Esc") {
1018
- if (_popups.length) {
1019
- closeAllPopups();
1020
- } else if (_dialogOpen) {
1021
- const dialogRoot = document.body.querySelector(".vuuDialog");
1022
- if (dialogRoot) {
1023
- import_react_dom.default.unmountComponentAtNode(dialogRoot);
1024
- }
1025
- }
1026
- }
1027
- }
1028
- function outsideClickHandler(e) {
1029
- if (_popups.length) {
1030
- const popupContainers = document.body.querySelectorAll(".vuuPopup");
1031
- for (let i = 0; i < popupContainers.length; i++) {
1032
- if (popupContainers[i].contains(e.target)) {
1033
- return;
1034
- }
1035
- }
1036
- closeAllPopups();
1037
- }
1038
- }
1039
- function closeAllPopups() {
1040
- if (_popups.length) {
1041
- const popupContainers = document.body.querySelectorAll(".vuuPopup");
1042
- for (let i = 0; i < popupContainers.length; i++) {
1043
- import_react_dom.default.unmountComponentAtNode(popupContainers[i]);
1044
- }
1045
- popupClosed("*");
1046
- }
1047
- }
1048
- function dialogOpened() {
1049
- if (_dialogOpen === false) {
1050
- _dialogOpen = true;
1051
- window.addEventListener("keydown", specialKeyHandler, true);
1052
- }
1053
- }
1054
- function dialogClosed() {
1055
- if (_dialogOpen) {
1056
- _dialogOpen = false;
1057
- window.removeEventListener("keydown", specialKeyHandler, true);
1058
- }
1059
- }
1060
- function popupOpened(name) {
1061
- if (_popups.indexOf(name) === -1) {
1062
- _popups.push(name);
1063
- if (_dialogOpen === false) {
1064
- window.addEventListener("keydown", specialKeyHandler, true);
1065
- window.addEventListener("click", outsideClickHandler, true);
1066
- }
1067
- }
1068
- }
1069
- function popupClosed(name) {
1070
- if (_popups.length) {
1071
- if (name === "*") {
1072
- _popups.length = 0;
1073
- } else {
1074
- const pos = _popups.indexOf(name);
1075
- if (pos !== -1) {
1076
- _popups.splice(pos, 1);
1077
- }
1078
- }
1079
- if (_popups.length === 0 && _dialogOpen === false) {
1080
- window.removeEventListener("keydown", specialKeyHandler, true);
1081
- window.removeEventListener("click", outsideClickHandler, true);
1082
- }
1083
- }
1084
- }
1085
- var PopupComponent = ({
1086
- children,
1087
- position,
1088
- style
1089
- }) => {
1090
- const className = (0, import_classnames3.default)("hwPopup", "hwPopupContainer", position);
1091
- return (0, import_react11.createElement)("div", { className, style }, children);
1092
- };
1093
- var incrementingKey = 1;
1094
- var PopupService = class {
1095
- static showPopup({
1096
- name = "anon",
1097
- group = "all",
1098
- position = "",
1099
- left = 0,
1100
- right = "auto",
1101
- top = 0,
1102
- width = "auto",
1103
- component
1104
- }) {
1105
- if (!component) {
1106
- throw Error(`PopupService showPopup, no component supplied`);
1107
- }
1108
- popupOpened(name);
1109
- let el = document.body.querySelector(".vuuPopup." + group);
1110
- if (el === null) {
1111
- el = document.createElement("div");
1112
- el.className = "vuuPopup " + group;
1113
- document.body.appendChild(el);
1114
- }
1115
- const style = { width };
1116
- renderPortal(
1117
- (0, import_react11.createElement)(
1118
- PopupComponent,
1119
- { key: incrementingKey++, position, style },
1120
- component
1121
- ),
1122
- el,
1123
- left,
1124
- top,
1125
- () => {
1126
- PopupService.keepWithinThePage(el, right);
1127
- }
1128
- );
1129
- }
1130
- static hidePopup(name = "anon", group = "all") {
1131
- if (_popups.indexOf(name) !== -1) {
1132
- popupClosed(name);
1133
- const popupRoot = document.body.querySelector(`.vuuPopup.${group}`);
1134
- if (popupRoot) {
1135
- import_react_dom.default.unmountComponentAtNode(popupRoot);
1136
- }
1137
- }
1138
- }
1139
- static keepWithinThePage(el, right = "auto") {
1140
- const target = el.querySelector(".vuuPopupContainer > *");
1141
- if (target) {
1142
- const {
1143
- top,
1144
- left,
1145
- width,
1146
- height,
1147
- right: currentRight
1148
- } = target.getBoundingClientRect();
1149
- const w = window.innerWidth;
1150
- const h = window.innerHeight;
1151
- const overflowH = h - (top + height);
1152
- if (overflowH < 0) {
1153
- target.style.top = Math.round(top) + overflowH + "px";
1154
- }
1155
- const overflowW = w - (left + width);
1156
- if (overflowW < 0) {
1157
- target.style.left = Math.round(left) + overflowW + "px";
1158
- }
1159
- if (typeof right === "number" && right !== currentRight) {
1160
- const adjustment = right - currentRight;
1161
- target.style.left = left + adjustment + "px";
1162
- }
1163
- }
1164
- }
1165
- };
1166
- var DialogService = class {
1167
- static showDialog(dialog) {
1168
- const containerEl = ".vuuDialog";
1169
- const onClose = dialog.props.onClose;
1170
- dialogOpened();
1171
- import_react_dom.default.render(
1172
- import_react11.default.cloneElement(dialog, {
1173
- container: containerEl,
1174
- onClose: () => {
1175
- DialogService.closeDialog();
1176
- if (onClose) {
1177
- onClose();
1178
- }
1179
- }
1180
- }),
1181
- document.body.querySelector(containerEl)
1182
- );
1183
- }
1184
- static closeDialog() {
1185
- dialogClosed();
1186
- const dialogRoot = document.body.querySelector(".vuuDialog");
1187
- if (dialogRoot) {
1188
- import_react_dom.default.unmountComponentAtNode(dialogRoot);
1189
- }
1190
- }
1191
- };
1192
- var Popup = (props) => {
1193
- const pendingTask = (0, import_react11.useRef)();
1194
- const ref = (0, import_react11.useRef)(null);
1195
- const show = (props2, boundingClientRect) => {
1196
- const { name, group, depth, width } = props2;
1197
- let left;
1198
- let top;
1199
- if (pendingTask.current) {
1200
- window.clearTimeout(pendingTask.current);
1201
- pendingTask.current = void 0;
1202
- }
1203
- if (props2.close === true) {
1204
- PopupService.hidePopup(name, group);
1205
- } else {
1206
- const { position, children: component } = props2;
1207
- const {
1208
- left: targetLeft,
1209
- top: targetTop,
1210
- width: clientWidth,
1211
- bottom: targetBottom
1212
- } = boundingClientRect;
1213
- if (position === "below") {
1214
- left = targetLeft;
1215
- top = targetBottom;
1216
- } else if (position === "above") {
1217
- left = targetLeft;
1218
- top = targetTop;
1219
- }
1220
- pendingTask.current = window.setTimeout(() => {
1221
- PopupService.showPopup({
1222
- name,
1223
- group,
1224
- depth,
1225
- position,
1226
- left,
1227
- top,
1228
- width: width || clientWidth,
1229
- component
1230
- });
1231
- }, 10);
1232
- }
1233
- };
1234
- (0, import_react11.useEffect)(() => {
1235
- if (ref.current) {
1236
- const el = ref.current.parentElement;
1237
- const boundingClientRect = el == null ? void 0 : el.getBoundingClientRect();
1238
- if (boundingClientRect) {
1239
- show(props, boundingClientRect);
1240
- }
1241
- }
1242
- return () => {
1243
- PopupService.hidePopup(props.name, props.group);
1244
- };
1245
- }, [props]);
1246
- return import_react11.default.createElement("div", { className: "popup-proxy", ref });
1247
- };
1248
-
1249
- // src/menu/useContextMenu.tsx
1250
- var import_jsx_runtime6 = require("react/jsx-runtime");
1251
- var useContextMenu = (menuBuilder) => {
1252
- const ctx = (0, import_react12.useContext)(ContextMenuContext);
1253
- const buildMenuOptions = (0, import_react12.useCallback)(
1254
- (menuBuilders, location, options) => {
1255
- let results = [];
1256
- for (const menuBuilder2 of menuBuilders) {
1257
- results = results.concat(menuBuilder2(location, options));
1258
- }
1259
- return results;
1260
- },
1261
- []
1262
- );
1263
- const handleShowContextMenu = (0, import_react12.useCallback)(
1264
- (e, location, options) => {
1265
- var _a;
1266
- e.stopPropagation();
1267
- e.preventDefault();
1268
- const menuBuilders = (_a = ctx == null ? void 0 : ctx.menuBuilders) != null ? _a : menuBuilder ? [menuBuilder] : void 0;
1269
- if (Array.isArray(menuBuilders) && menuBuilders.length > 0) {
1270
- const menuItemDescriptors = buildMenuOptions(
1271
- menuBuilders,
1272
- location,
1273
- options
1274
- );
1275
- console.log({
1276
- menuItemDescriptors
1277
- });
1278
- if (menuItemDescriptors.length && (ctx == null ? void 0 : ctx.menuActionHandler)) {
1279
- console.log(`showContextMenu ${location}`, {
1280
- options
1281
- });
1282
- showContextMenu(e, menuItemDescriptors, ctx.menuActionHandler);
1283
- }
1284
- } else {
1285
- console.warn(
1286
- "useContextMenu, no menuBuilders configured. These should be supplied via the ContextMenuProvider(s)"
1287
- );
1288
- }
1289
- },
1290
- [buildMenuOptions, ctx == null ? void 0 : ctx.menuActionHandler, ctx == null ? void 0 : ctx.menuBuilders, menuBuilder]
1291
- );
1292
- return handleShowContextMenu;
1293
- };
1294
- var showContextMenu = (e, menuDescriptors, handleContextMenuAction) => {
1295
- const { clientX: left, clientY: top } = e;
1296
- const menuItems = (menuDescriptors2) => {
1297
- const fromDescriptor = (menuItem, i) => isGroupMenuItemDescriptor(menuItem) ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(MenuItemGroup, { label: menuItem.label, children: menuItem.children.map(fromDescriptor) }, i) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1298
- MenuItem,
1299
- {
1300
- action: menuItem.action,
1301
- "data-icon": menuItem.icon,
1302
- options: menuItem.options,
1303
- children: menuItem.label
1304
- },
1305
- i
1306
- );
1307
- return menuDescriptors2.map(fromDescriptor);
1308
- };
1309
- const handleClose = (menuId, options) => {
1310
- if (menuId) {
1311
- handleContextMenuAction(menuId, options);
1312
- PopupService.hidePopup();
1313
- }
1314
- };
1315
- const component = /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ContextMenu, { onClose: handleClose, position: { x: left, y: top }, children: menuItems(menuDescriptors) });
1316
- PopupService.showPopup({ left: 0, top: 0, component });
1317
- };
1
+ "use strict";var rt=Object.create;var oe=Object.defineProperty;var st=Object.getOwnPropertyDescriptor;var it=Object.getOwnPropertyNames;var ut=Object.getPrototypeOf,ct=Object.prototype.hasOwnProperty;var lt=(t,e)=>{for(var n in e)oe(t,n,{get:e[n],enumerable:!0})},Ie=(t,e,n,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of it(e))!ct.call(t,r)&&r!==n&&oe(t,r,{get:()=>e[r],enumerable:!(o=st(e,r))||o.enumerable});return t};var K=(t,e,n)=>(n=t!=null?rt(ut(t)):{},Ie(e||!t||!t.__esModule?oe(n,"default",{value:t,enumerable:!0}):n,t)),at=t=>Ie(oe({},"__esModule",{value:!0}),t);var qt={};lt(qt,{ContextMenu:()=>ie,ContextMenuContext:()=>ee,ContextMenuProvider:()=>St,Dialog:()=>gt,DialogService:()=>te,MenuItem:()=>re,MenuItemGroup:()=>Z,Popup:()=>Ft,PopupService:()=>D,Portal:()=>Y,Separator:()=>ge,createContainer:()=>de,installTheme:()=>ft,isGroupMenuItemDescriptor:()=>xe,renderPortal:()=>Q,useContextMenu:()=>Gt});module.exports=at(qt);var V=require("@heswell/salt-lab"),Re=require("@salt-ds/core"),He=K(require("classnames")),B=require("react");var X=require("react"),Le=K(require("react-dom"));var we=K(require("react-dom")),Pe=require("@salt-ds/core"),Ee=require("react/jsx-runtime"),pt=1,dt=(t=0,e=0,n=window)=>{let o=n.document.createElement("div");return o.className="vuuPopup "+pt++,o.style.cssText=`left:${t}px; top:${e}px;`,n.document.body.appendChild(o),o},mt=(t,e)=>dt(t,e),Q=(t,e,n,o,r)=>{e.style.cssText=`left:${n}px; top:${o}px;position: absolute;`,we.render((0,Ee.jsx)(Pe.SaltProvider,{applyClassesTo:"child",children:t}),e,r)},de=mt;var Y=function({children:e,x:n=0,y:o=0,onRender:r}){let c=(0,X.useMemo)(()=>de(),[]);return(0,X.useLayoutEffect)(()=>{Q(e,c,n,o,r)},[e,r,c,n,o]),(0,X.useLayoutEffect)(()=>()=>{var u;c&&(Le.unmountComponentAtNode(c),c.classList.contains("vuuPopup")&&((u=c.parentElement)==null||u.removeChild(c)))},[c]),null};var ft=t=>{let e=getComputedStyle(document.body).getPropertyValue("--installed-themes");document.body.style.setProperty("--installed-themes",`${e} ${t}`)};var N=require("react/jsx-runtime"),me="vuuDialog",gt=({children:t,className:e,isOpen:n=!1,onClose:o,title:r,...c})=>{let u=(0,B.useRef)(null),[i]=(0,B.useState)(0),[l]=(0,B.useState)(0),d=(0,B.useCallback)(()=>{o==null||o()},[o]),a=(0,B.useCallback)(()=>{},[]);return n?(0,N.jsx)(Y,{onRender:a,x:i,y:l,children:(0,N.jsx)(V.Scrim,{className:`${me}-scrim`,open:n,children:(0,N.jsxs)("div",{...c,className:(0,He.default)(me,e),ref:u,children:[(0,N.jsxs)(V.Toolbar,{className:`${me}-header`,children:[(0,N.jsx)(Re.Text,{children:r}),(0,N.jsx)(V.ToolbarButton,{onClick:d,"data-align-end":!0,"data-icon":"close"},"close")]}),t]})})}):null};var ze=require("@salt-ds/core"),G=require("react");var O=K(require("react")),Me=K(require("classnames")),Be=require("@salt-ds/core");var H=require("react");var Te=t=>t.closest("[data-root='true']")!==null,ke=(t,e)=>{var n;return t.ariaHasPopup==="true"&&((n=t.dataset)==null?void 0:n.idx)===`${e}`||t.querySelector(`:scope > [data-idx='${e}'][aria-haspopup='true']`)!==null};function Mt(t,...e){let n=new Set(t);for(let o of e)for(let r of o)n.add(r);return n}var ht="Enter";var xt="Delete",bt=new Set([ht,xt]),vt=new Set(["Tab"]),yt=new Set(["ArrowRight","ArrowLeft"]),De=new Set(["Home","End","ArrowDown","ArrowUp"]),Ae=new Set(["Home","End","ArrowRight","ArrowLeft"]),Ct=new Set(["F1","F2","F3","F4","F5","F6","F7","F8","F9","F10","F11","F12"]),an=Mt(bt,Ae,De,yt,Ct,vt);var Se=({key:t},e="vertical")=>(e==="vertical"?De:Ae).has(t);var $e=({autoHighlightFirstItem:t=!1,count:e,highlightedIndex:n,onActivate:o,onHighlight:r,onCloseMenu:c,onOpenMenu:u})=>{let i=(0,H.useRef)((n!=null?n:t)?0:-1),[,l]=(0,H.useState)(null),d=n!==void 0,a=(0,H.useCallback)(s=>{i.current=s,r==null||r(s),l({})},[r]),h=(0,H.useCallback)(s=>{s!==i.current&&(d||a(s))},[d,a]),f=(0,H.useRef)(!0),w=(0,H.useRef)(!1),v=s=>w.current=s,g=d?n:i.current,E=(0,H.useCallback)(s=>{let m=It(e,s.key,i.current);m!==i.current&&h(m)},[e,h]),T=(0,H.useCallback)(s=>{Se(s)?(s.preventDefault(),s.stopPropagation(),f.current=!0,E(s)):(s.key==="ArrowRight"||s.key==="Enter")&&ke(s.target,g)?u(g):s.key==="ArrowLeft"&&!Te(s.target)?c(g):s.key==="Enter"&&o&&o(g)},[g,E,o,c,u]),R=(0,H.useMemo)(()=>({onFocus:()=>{g===-1&&a(0)},onKeyDown:T,onMouseDownCapture:()=>{f.current=!1,v(!0)},onMouseMove:()=>{f.current&&(f.current=!1)},onMouseLeave:()=>{f.current=!0,v(!1),h(-1)}}),[g,h,E,o,c,u,a]);return{focusVisible:f.current?g:-1,controlledHighlighting:d,highlightedIndex:g,setHighlightedIndex:h,listProps:R,setIgnoreFocus:v}};function It(t,e,n){return e==="ArrowUp"?n>0?n-1:n:n===null?0:n===t-1?n:n+1}var F=K(require("react"));var fe=t=>t.type===Z||!!t.props["data-group"],Ke=t=>{let e=(0,F.useCallback)(()=>{let r=(u,i="root",l={},d={})=>{let a=l[i]=[],h=0,f=!1;return F.default.Children.forEach(u,w=>{if(w.type===ge)f=!0;else{let v=fe(w),g=i==="root"?`${h}`:`${i}.${h}`,{props:{action:E,options:T}}=w,{childWithId:R,grandChildren:s}=c(w,g,v,f);a.push(R),s?r(s,g,l,d):d[g]={action:E,options:T},h+=1,f=!1}}),[l,d]},c=(u,i,l,d=!1)=>{let{props:{children:a}}=u;return{childWithId:F.default.cloneElement(u,{hasSeparator:d,id:`${i}`,key:i,children:l?void 0:a}),grandChildren:l?a:void 0}};return r(t)},[t]),[n,o]=(0,F.useMemo)(()=>e(),[e]);return[n,o]};var U=require("react/jsx-runtime"),Ne="vuuMenuList",ge=()=>(0,U.jsx)("li",{className:"vuuMenuItem-divider"}),Z=()=>null,re=({children:t,idx:e,...n})=>(0,U.jsx)("div",{...n,children:t}),wt=t=>t.props["data-icon"],Oe=({activatedByKeyboard:t,childMenuShowing:e=-1,children:n,className:o,highlightedIdx:r,id:c,isRoot:u,listItemProps:i,menuId:l,onHighlightMenuItem:d,onActivate:a,onCloseMenu:h,onOpenMenu:f,...w})=>{let v=(0,Be.useIdMemo)(c),g=(0,O.useRef)(null),E=(0,O.useMemo)(()=>new Map,[]),T=y=>{var b;let M=(b=g.current)==null?void 0:b.querySelector(`:scope > [data-idx='${y}']`);M!=null&&M.id&&(f==null||f(M.id))},R=y=>{var b;let M=(b=g.current)==null?void 0:b.querySelector(`:scope > [data-idx='${y}']`);M!=null&&M.id&&(a==null||a(M.id))},{focusVisible:s,highlightedIndex:m,listProps:p}=$e({count:O.default.Children.count(n),highlightedIndex:r,onActivate:R,onHighlight:d,onOpenMenu:T,onCloseMenu:h}),x=e==-1?s:-1;return(0,O.useLayoutEffect)(()=>{var y;e===-1&&t&&((y=g.current)==null||y.focus())},[t,e]),(0,U.jsx)("div",{...w,...p,"aria-activedescendant":(()=>m===void 0||m===-1?void 0:E.get(m))(),className:(0,Me.default)(Ne,o,{[`${Ne}-childMenuShowing`]:e!==-1}),"data-root":u||void 0,id:`${v}-${l}`,ref:g,role:"menu",tabIndex:0,children:S()});function S(){let y={...i,role:"menuitem"},M=(C,$,q)=>$?[(0,U.jsx)("span",{className:"vuuIconContainer","data-icon":q},"icon")].concat(C):C;function b(C,$,q,be){var Ce;let{children:_e,className:je,"data-icon":ve,id:ae,hasSeparator:et,label:tt,...nt}=$.props,pe=fe($),ye=pe&&e===q,ot=ye?`${v}-${ae}`:void 0;C.push((0,U.jsx)(re,{...nt,...y,...Pt(`${v}-${l}`,ae,q,(Ce=$.key)!=null?Ce:ae,m,x,je,et),"aria-controls":ot,"aria-haspopup":pe||void 0,"aria-expanded":ye||void 0,children:M(pe?tt:_e,be,ve)}))}let L=[];if(n.length>0){let C=n.some(wt);n.forEach(($,q)=>{b(L,$,q,C)})}return L}},Pt=(t,e,n,o,r,c,u,i)=>({id:`${t}-${e}`,key:o!=null?o:n,"data-idx":n,"data-highlighted":n===r||void 0,className:(0,Me.default)("vuuMenuItem",u,{"vuuMenuItem-separator":i,focusVisible:c===n})});Oe.displayName="MenuList";var Fe=Oe;var I=require("react");function Ge(t){if(t){let e=t.dataset.idx;if(e)return parseInt(e,10);if(t.ariaPosInSet)return parseInt(t.ariaPosInSet,10)-1}}var he=t=>t==null?void 0:t.closest("[data-idx],[aria-posinset]");var We=(t,e,n)=>t.map((o,r)=>r===t.length-1?{...o,[n]:o[n]-e}:o),Et=(t,e)=>We(t,e,"left"),Lt=(t,e)=>We(t,e,"top"),Rt=(t,e)=>{let[n,o]=e.slice(-2),r=document.getElementById(`${t}-${o.id}`);if(r===null)throw Error(`useCascade.flipSides element with id ${o.id} not found`);let{width:c}=r.getBoundingClientRect();return e.map(u=>u===o?{...u,left:n.left-(c-2)}:u)},Ht=(t,e)=>{let[{left:n,top:o}]=e.slice(-1),{offsetWidth:r,offsetTop:c}=t;return{left:n+r,top:c+o}},_=t=>{let e=t.lastIndexOf("-");return e===-1?t:t.slice(e+1)},se=t=>{let e=_(t),n=e.lastIndexOf(".");return n>-1?e.slice(0,n):"root"},Tt=t=>{let e=0,n=t.indexOf(".",0);for(;n!==-1;)e+=1,n=t.indexOf(".",n+1);return e},kt=t=>({menuId:se(t.id),itemId:_(t.id),isGroup:t.ariaHasPopup==="true",isOpen:t.ariaExpanded==="true",level:Tt(t.id)}),qe=({id:t,onActivate:e,onMouseEnterItem:n,position:{x:o,y:r}})=>{let[,c]=(0,I.useState)({}),u=(0,I.useRef)([{id:"root",left:o,top:r}]),i=(0,I.useCallback)(s=>{u.current=s,c({})},[]),l=(0,I.useRef)(),d=(0,I.useRef)(),a=(0,I.useRef)({root:"no-popup"}),h=(0,I.useRef)(0),f=(0,I.useCallback)((s="root",m=null,p=null)=>{if(s==="root"&&m===null)i([{id:"root",left:o,top:r}]);else{a.current[s]="popup-open";let P=(p?p.ownerDocument:document).getElementById(`${t}-${s}-${m}`),{left:S,top:y}=Ht(P,u.current);i(u.current.concat({id:m,left:S,top:y}))}},[t,o,r,i]),w=(0,I.useCallback)(s=>{i(s==="root"?[]:u.current.slice(0,-1))},[i]),v=(0,I.useCallback)((s,m)=>{let p=u.current.slice(),{id:x}=p[p.length-1];for(;p.length>1&&!m.startsWith(x);){let P=se(x);p.pop(),a.current[x]="no-popup",a.current[P]="no-popup",{id:x}=p[p.length-1]}p.length<u.current.length&&i(p)},[i]),g=(0,I.useCallback)((s,m,p)=>{l.current&&clearTimeout(l.current),l.current=window.setTimeout(()=>{console.log(`scheduleOpen timed out opening ${m}`),v(s,m),a.current[s]="popup-open",a.current[m]="no-popup",f(s,m,p)},400)},[v,f]),E=(0,I.useCallback)((s,m,p)=>{console.log(`scheduleClose openMenuId ${s} menuId ${m} itemId ${p}`),a.current[s]="pending-close",d.current=window.setTimeout(()=>{v(m,p)},400)},[v]),T=(0,I.useCallback)(()=>{let{current:s}=u,[m]=s.slice(-1),p=document.getElementById(`${t}-${m.id}`);if(p){let{right:x,bottom:P}=p.getBoundingClientRect(),{clientHeight:S,clientWidth:y}=document.body;if(x>y){let M=s.length>1?Rt(t,s):Et(s,x-y);i(M)}else if(P>S){let M=Lt(s,P-S);i(M)}}},[t,i]),R=(0,I.useMemo)(()=>({onMouseEnter:s=>{let m=he(s.target),{menuId:p,itemId:x,isGroup:P,isOpen:S,level:y}=kt(m),M=h.current===y,{current:{[p]:b}}=a;if(h.current=y,b==="no-popup"&&P)a.current[p]="popup-pending",g(p,x,m);else if(b==="popup-pending"&&!P)a.current[p]="no-popup",clearTimeout(l.current),l.current=void 0;else if(b==="popup-pending"&&P)clearTimeout(l.current),g(p,x,m);else if(b==="popup-open"){let[{id:L},{id:C}]=u.current.slice(-2);L===p&&a.current[C]!=="pending-close"&&M?(E(C,p,x),P&&!S&&g(p,x,m)):L===p&&P&&x!==C&&a.current[C]==="pending-close"?g(p,x,m):P?(v(p,x),g(p,x,m)):a.current[C]==="pending-close"&&M||v(p,x)}b==="pending-close"&&(l.current&&(clearTimeout(l.current),l.current=void 0),clearTimeout(d.current),d.current=void 0,a.current[p]="popup-open"),n(s,x)},onClick:s=>{let m=s.target,p=he(m),x=Ge(p);console.log(`list item click [${x}] hasPopup ${p.ariaHasPopup}`),p.ariaHasPopup==="true"?p.ariaExpanded!=="true"&&f(x):e(_(p.id))}}),[v,e,n,f,E,g]);return{closeMenu:w,handleRender:T,listItemProps:R,openMenu:f,openMenus:u.current}};var Ve=require("react"),Ue=({containerClassName:t,isOpen:e,onClose:n})=>{(0,Ve.useEffect)(()=>{let o;return e&&(o=r=>{r.target.closest(`.${t}`)===null&&(n==null||n("root"))},document.body.addEventListener("click",o,!0)),()=>{o&&document.body.removeEventListener("click",o,!0)}},[t,e,n])};var j=require("react/jsx-runtime"),Je=require("react"),Dt=()=>{},ie=({activatedByKeyboard:t,children:e,className:n,id:o,onClose:r=()=>{},position:c={x:0,y:0},style:u,...i})=>{let l=(0,ze.useIdMemo)(o),d=(0,G.useRef)(Dt),[a,h]=Ke(e),f=(0,G.useRef)(t),w=(0,G.useCallback)(()=>{f.current=!1},[]),v=(0,G.useCallback)(M=>{let{action:b,options:L}=h[M];d.current("root"),r(b,L)},[h,r]),{closeMenu:g,listItemProps:E,openMenu:T,openMenus:R,handleRender:s}=qe({id:l,onActivate:v,onMouseEnterItem:w,position:c});d.current=g,console.log({openMenus:R});let m=(0,G.useCallback)(()=>{g(),r()},[g,r]);Ue({containerClassName:"vuuMenuList",onClose:m,isOpen:R.length>0});let p=M=>{let b=_(M),L=se(b);f.current=!0,T(L,b)},x=()=>{f.current=!0,g()},P=()=>{},S=R.length-1,y=M=>{if(M>=S)return-1;{let{id:b}=R[M+1],L=b.lastIndexOf(".");return parseInt(L===-1?b:b.slice(-L),10)}};return(0,j.jsx)(j.Fragment,{children:R.map(({id:M,left:b,top:L},C)=>{let $=y(C);return(0,j.jsx)(Y,{x:b,y:L,onRender:s,children:(0,Je.createElement)(Fe,{...i,activatedByKeyboard:f.current,childMenuShowing:$,className:n,id:l,menuId:M,isRoot:C===0,key:C,listItemProps:E,onActivate:v,onHighlightMenuItem:P,onCloseMenu:x,onOpenMenu:p,style:u},a[M])},C)})})};ie.displayName="ContextMenu";var z=require("react"),ue=require("react/jsx-runtime"),ee=(0,z.createContext)(null),xe=t=>t!==void 0&&"children"in t,At=({children:t,context:e,menuActionHandler:n,menuBuilder:o})=>{let r=(0,z.useMemo)(()=>e!=null&&e.menuBuilders&&o?e.menuBuilders.concat(o):o?[o]:(e==null?void 0:e.menuBuilders)||[],[e,o]),c=(0,z.useCallback)((u,i)=>{var l;if(n!=null&&n(u,i)||(l=e==null?void 0:e.menuActionHandler)!=null&&l.call(e,u,i))return!0},[e,n]);return(0,ue.jsx)(ee.Provider,{value:{menuActionHandler:c,menuBuilders:r},children:t})},St=({children:t,label:e,menuActionHandler:n,menuBuilder:o})=>(0,ue.jsx)(ee.Consumer,{children:r=>(0,ue.jsx)(At,{context:r,label:e,menuActionHandler:n,menuBuilder:o,children:t})});var ne=require("react");var Qe=K(require("classnames")),A=K(require("react")),J=K(require("react-dom"));var W=!1,k=[];function ce(t){if(t.key==="Esc"){if(k.length)Ye();else if(W){let e=document.body.querySelector(".vuuDialog");e&&J.default.unmountComponentAtNode(e)}}}function Xe(t){if(k.length){let e=document.body.querySelectorAll(".vuuPopup");for(let n=0;n<e.length;n++)if(e[n].contains(t.target))return;Ye()}}function Ye(){if(k.length){let t=document.body.querySelectorAll(".vuuPopup");for(let e=0;e<t.length;e++)J.default.unmountComponentAtNode(t[e]);Ze("*")}}function $t(){W===!1&&(W=!0,window.addEventListener("keydown",ce,!0))}function Kt(){W&&(W=!1,window.removeEventListener("keydown",ce,!0))}function Nt(t){k.indexOf(t)===-1&&(k.push(t),W===!1&&(window.addEventListener("keydown",ce,!0),window.addEventListener("click",Xe,!0)))}function Ze(t){if(k.length){if(t==="*")k.length=0;else{let e=k.indexOf(t);e!==-1&&k.splice(e,1)}k.length===0&&W===!1&&(window.removeEventListener("keydown",ce,!0),window.removeEventListener("click",Xe,!0))}}var Bt=({children:t,position:e,style:n})=>{let o=(0,Qe.default)("hwPopup","hwPopupContainer",e);return(0,A.createElement)("div",{className:o,style:n},t)},Ot=1,D=class{static showPopup({name:e="anon",group:n="all",position:o="",left:r=0,right:c="auto",top:u=0,width:i="auto",component:l}){if(!l)throw Error("PopupService showPopup, no component supplied");Nt(e);let d=document.body.querySelector(".vuuPopup."+n);d===null&&(d=document.createElement("div"),d.className="vuuPopup "+n,document.body.appendChild(d));let a={width:i};Q((0,A.createElement)(Bt,{key:Ot++,position:o,style:a},l),d,r,u,()=>{D.keepWithinThePage(d,c)})}static hidePopup(e="anon",n="all"){if(k.indexOf(e)!==-1){Ze(e);let o=document.body.querySelector(`.vuuPopup.${n}`);o&&J.default.unmountComponentAtNode(o)}}static keepWithinThePage(e,n="auto"){let o=e.querySelector(".vuuPopupContainer > *");if(o){let{top:r,left:c,width:u,height:i,right:l}=o.getBoundingClientRect(),d=window.innerWidth,h=window.innerHeight-(r+i);h<0&&(o.style.top=Math.round(r)+h+"px");let f=d-(c+u);if(f<0&&(o.style.left=Math.round(c)+f+"px"),typeof n=="number"&&n!==l){let w=n-l;o.style.left=c+w+"px"}}}},te=class{static showDialog(e){let n=".vuuDialog",o=e.props.onClose;$t(),J.default.render(A.default.cloneElement(e,{container:n,onClose:()=>{te.closeDialog(),o&&o()}}),document.body.querySelector(n))}static closeDialog(){Kt();let e=document.body.querySelector(".vuuDialog");e&&J.default.unmountComponentAtNode(e)}},Ft=t=>{let e=(0,A.useRef)(),n=(0,A.useRef)(null),o=(r,c)=>{let{name:u,group:i,depth:l,width:d}=r,a,h;if(e.current&&(window.clearTimeout(e.current),e.current=void 0),r.close===!0)D.hidePopup(u,i);else{let{position:f,children:w}=r,{left:v,top:g,width:E,bottom:T}=c;f==="below"?(a=v,h=T):f==="above"&&(a=v,h=g),e.current=window.setTimeout(()=>{D.showPopup({name:u,group:i,depth:l,position:f,left:a,top:h,width:d||E,component:w})},10)}};return(0,A.useEffect)(()=>{if(n.current){let r=n.current.parentElement,c=r==null?void 0:r.getBoundingClientRect();c&&o(t,c)}return()=>{D.hidePopup(t.name,t.group)}},[t]),A.default.createElement("div",{className:"popup-proxy",ref:n})};var le=require("react/jsx-runtime"),Gt=t=>{let e=(0,ne.useContext)(ee),n=(0,ne.useCallback)((r,c,u)=>{let i=[];for(let l of r)i=i.concat(l(c,u));return i},[]);return(0,ne.useCallback)((r,c,u)=>{var l;r.stopPropagation(),r.preventDefault();let i=(l=e==null?void 0:e.menuBuilders)!=null?l:t?[t]:void 0;if(Array.isArray(i)&&i.length>0){let d=n(i,c,u);console.log({menuItemDescriptors:d}),d.length&&(e!=null&&e.menuActionHandler)&&(console.log(`showContextMenu ${c}`,{options:u}),Wt(r,d,e.menuActionHandler))}else console.warn("useContextMenu, no menuBuilders configured. These should be supplied via the ContextMenuProvider(s)")},[n,e==null?void 0:e.menuActionHandler,e==null?void 0:e.menuBuilders,t])},Wt=(t,e,n)=>{let{clientX:o,clientY:r}=t,i=(0,le.jsx)(ie,{onClose:(l,d)=>{l&&(n(l,d),D.hidePopup())},position:{x:o,y:r},children:(l=>{let d=(a,h)=>xe(a)?(0,le.jsx)(Z,{label:a.label,children:a.children.map(d)},h):(0,le.jsx)(re,{action:a.action,"data-icon":a.icon,options:a.options,children:a.label},h);return l.map(d)})(e)});D.showPopup({left:0,top:0,component:i})};
1318
2
  //# sourceMappingURL=index.js.map