@greypan/web-ui 6.0.0 → 6.2.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.CN.md +285 -93
- package/README.md +266 -87
- package/dist/assets/glass.js +1 -1
- package/dist/assets/glass.js.map +1 -1
- package/dist/assets/menu-portal.js +1 -1
- package/dist/assets/menu-portal.js.map +1 -1
- package/dist/assets/overlay-motion.js +1 -1
- package/dist/assets/overlay-motion.js.map +1 -1
- package/dist/components/autocomplete/index.d.ts +367 -4
- package/dist/components/autocomplete/index.js +87 -80
- package/dist/components/autocomplete/index.js.map +1 -1
- package/dist/components/autocomplete/style.js +1 -1
- package/dist/components/autocomplete/style.js.map +1 -1
- package/dist/components/avatar/style.js +1 -1
- package/dist/components/avatar/style.js.map +1 -1
- package/dist/components/back-top/style.js +1 -1
- package/dist/components/back-top/style.js.map +1 -1
- package/dist/components/badge/style.js +1 -1
- package/dist/components/badge/style.js.map +1 -1
- package/dist/components/button/index.js +36 -32
- package/dist/components/button/index.js.map +1 -1
- package/dist/components/button/style.js +1 -1
- package/dist/components/button/style.js.map +1 -1
- package/dist/components/button-group/style.js +1 -1
- package/dist/components/button-group/style.js.map +1 -1
- package/dist/components/checkbox/index.d.ts +366 -5
- package/dist/components/checkbox/index.js +19 -31
- package/dist/components/checkbox/index.js.map +1 -1
- package/dist/components/checkbox/style.js +1 -1
- package/dist/components/checkbox/style.js.map +1 -1
- package/dist/components/checkbox-group/index.d.ts +366 -4
- package/dist/components/checkbox-group/index.js +16 -25
- package/dist/components/checkbox-group/index.js.map +1 -1
- package/dist/components/collapse/index.d.ts +29 -1
- package/dist/components/collapse/index.js +105 -46
- package/dist/components/collapse/index.js.map +1 -1
- package/dist/components/collapse/style.js +1 -1
- package/dist/components/collapse/style.js.map +1 -1
- package/dist/components/context-menu/index.d.ts +7 -14
- package/dist/components/context-menu/index.js +113 -164
- package/dist/components/context-menu/index.js.map +1 -1
- package/dist/components/dialog/index.js +26 -25
- package/dist/components/dialog/index.js.map +1 -1
- package/dist/components/dialog/style.js +1 -1
- package/dist/components/dialog/style.js.map +1 -1
- package/dist/components/drawer/index.js +71 -64
- package/dist/components/drawer/index.js.map +1 -1
- package/dist/components/drawer/style.js +1 -1
- package/dist/components/drawer/style.js.map +1 -1
- package/dist/components/dropdown/index.d.ts +6 -14
- package/dist/components/dropdown/index.js +100 -156
- package/dist/components/dropdown/index.js.map +1 -1
- package/dist/components/dropdown-header/style.js +1 -1
- package/dist/components/dropdown-header/style.js.map +1 -1
- package/dist/components/dropdown-item/style.js +1 -1
- package/dist/components/dropdown-item/style.js.map +1 -1
- package/dist/components/empty/style.js +1 -1
- package/dist/components/empty/style.js.map +1 -1
- package/dist/components/image-preview/index.d.ts +58 -0
- package/dist/components/image-preview/index.js +481 -0
- package/dist/components/image-preview/index.js.map +1 -0
- package/dist/components/image-preview/style.js +6 -0
- package/dist/components/image-preview/style.js.map +1 -0
- package/dist/components/index.d.ts +1 -0
- package/dist/components/index.js +20 -19
- package/dist/components/input/index.d.ts +366 -5
- package/dist/components/input/index.js +35 -47
- package/dist/components/input/index.js.map +1 -1
- package/dist/components/input/style.js +1 -1
- package/dist/components/input/style.js.map +1 -1
- package/dist/components/input-number/index.d.ts +366 -5
- package/dist/components/input-number/index.js +31 -44
- package/dist/components/input-number/index.js.map +1 -1
- package/dist/components/input-number/style.js +1 -1
- package/dist/components/input-number/style.js.map +1 -1
- package/dist/components/layout/index.d.ts +1 -1
- package/dist/components/layout/index.js +5 -3
- package/dist/components/layout/index.js.map +1 -1
- package/dist/components/layout/style.js +1 -1
- package/dist/components/layout/style.js.map +1 -1
- package/dist/components/option/style.js +1 -1
- package/dist/components/option/style.js.map +1 -1
- package/dist/components/popover/index.d.ts +1 -0
- package/dist/components/popover/index.js +55 -60
- package/dist/components/popover/index.js.map +1 -1
- package/dist/components/popover/style.js +1 -1
- package/dist/components/popover/style.js.map +1 -1
- package/dist/components/radio/index.d.ts +366 -5
- package/dist/components/radio/index.js +21 -31
- package/dist/components/radio/index.js.map +1 -1
- package/dist/components/radio/style.js +1 -1
- package/dist/components/radio/style.js.map +1 -1
- package/dist/components/radio-group/index.d.ts +366 -4
- package/dist/components/radio-group/index.js +16 -25
- package/dist/components/radio-group/index.js.map +1 -1
- package/dist/components/segmented/index.d.ts +366 -4
- package/dist/components/segmented/index.js +28 -35
- package/dist/components/segmented/index.js.map +1 -1
- package/dist/components/segmented/style.js +1 -1
- package/dist/components/segmented/style.js.map +1 -1
- package/dist/components/segmented-trigger/index.js +17 -15
- package/dist/components/segmented-trigger/index.js.map +1 -1
- package/dist/components/segmented-trigger/style.js +1 -1
- package/dist/components/segmented-trigger/style.js.map +1 -1
- package/dist/components/select/index.d.ts +368 -5
- package/dist/components/select/index.js +71 -68
- package/dist/components/select/index.js.map +1 -1
- package/dist/components/select/style.js +1 -1
- package/dist/components/select/style.js.map +1 -1
- package/dist/components/slider/index.d.ts +366 -5
- package/dist/components/slider/index.js +40 -50
- package/dist/components/slider/index.js.map +1 -1
- package/dist/components/slider/style.js +1 -1
- package/dist/components/slider/style.js.map +1 -1
- package/dist/components/spinner/style.js +1 -1
- package/dist/components/spinner/style.js.map +1 -1
- package/dist/components/svg-draw-lines/index.js +1 -1
- package/dist/components/svg-draw-lines/index.js.map +1 -1
- package/dist/components/switch/index.d.ts +366 -5
- package/dist/components/switch/index.js +28 -38
- package/dist/components/switch/index.js.map +1 -1
- package/dist/components/switch/style.js +1 -1
- package/dist/components/switch/style.js.map +1 -1
- package/dist/components/textarea/index.d.ts +366 -5
- package/dist/components/textarea/index.js +43 -57
- package/dist/components/textarea/index.js.map +1 -1
- package/dist/components/textarea/style.js +1 -1
- package/dist/components/textarea/style.js.map +1 -1
- package/dist/components/theme/index.js +1 -1
- package/dist/components/theme/index.js.map +1 -1
- package/dist/components/theme/style.js +1 -1
- package/dist/components/theme/style.js.map +1 -1
- package/dist/components/toast/manager.js +2 -2
- package/dist/components/toast/manager.js.map +1 -1
- package/dist/components/toast/style.js +1 -1
- package/dist/components/toast/style.js.map +1 -1
- package/dist/components/tooltip/index.d.ts +1 -0
- package/dist/components/tooltip/index.js +43 -58
- package/dist/components/tooltip/index.js.map +1 -1
- package/dist/components/tooltip/style.js +1 -1
- package/dist/components/tooltip/style.js.map +1 -1
- package/dist/icons/generated/radix-icons-reset.d.ts +6 -0
- package/dist/icons/generated/radix-icons-reset.js +10 -0
- package/dist/icons/generated/radix-icons-reset.js.map +1 -0
- package/dist/icons/index.d.ts +1 -0
- package/dist/icons/index.js +2 -1
- package/dist/shared/focus/pointer-focus.js +37 -0
- package/dist/shared/focus/pointer-focus.js.map +1 -0
- package/dist/shared/form-association/index.js +31 -4
- package/dist/shared/form-association/index.js.map +1 -1
- package/dist/shared/gesture/drag-gesture.js +53 -30
- package/dist/shared/gesture/drag-gesture.js.map +1 -1
- package/dist/shared/gesture/pinch-gesture.js +84 -0
- package/dist/shared/gesture/pinch-gesture.js.map +1 -0
- package/dist/shared/group-management/index.js.map +1 -1
- package/dist/shared/menu-behavior/index.js +112 -0
- package/dist/shared/menu-behavior/index.js.map +1 -0
- package/dist/shared/menu-portal/menu-portal.js.map +1 -1
- package/dist/shared/open-state/index.js +12 -0
- package/dist/shared/open-state/index.js.map +1 -0
- package/dist/shared/option-portal/combobox-shell.js +43 -0
- package/dist/shared/option-portal/combobox-shell.js.map +1 -0
- package/dist/shared/option-portal/index.js +22 -21
- package/dist/shared/option-portal/index.js.map +1 -1
- package/dist/shared/overlay/anchored-panel.js +33 -30
- package/dist/shared/overlay/anchored-panel.js.map +1 -1
- package/dist/shared/overlay/composition.js +57 -0
- package/dist/shared/overlay/composition.js.map +1 -0
- package/dist/shared/overlay/lifecycle.js +41 -0
- package/dist/shared/overlay/lifecycle.js.map +1 -0
- package/dist/shared/overlay/native-dialog-presence.js +15 -15
- package/dist/shared/overlay/native-dialog-presence.js.map +1 -1
- package/dist/shared/{theme → overlay}/overlay-root.js +1 -1
- package/dist/shared/overlay/overlay-root.js.map +1 -0
- package/dist/shared/overlay/overlay.js +43 -41
- package/dist/shared/overlay/overlay.js.map +1 -1
- package/dist/shared/overlay/placement-props.js +19 -0
- package/dist/shared/overlay/placement-props.js.map +1 -0
- package/dist/shared/overlay/portal.js +6 -4
- package/dist/shared/overlay/portal.js.map +1 -1
- package/dist/shared/overlay/positioning-generation.js +20 -0
- package/dist/shared/overlay/positioning-generation.js.map +1 -0
- package/dist/shared/{theme/theme-scope.js → overlay/theme-overlay-scope.js} +2 -2
- package/dist/shared/overlay/theme-overlay-scope.js.map +1 -0
- package/package.json +6 -10
- package/dist/shared/theme/overlay-root.js.map +0 -1
- package/dist/shared/theme/theme-scope.js.map +0 -1
|
@@ -1,27 +1,60 @@
|
|
|
1
1
|
import e from "../../_virtual/_@oxc-project_runtime@0.146.0/helpers/esm/decorate.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
2
|
+
import { dispatchOpenChangeEvent as t } from "../../shared/open-state/index.js";
|
|
3
|
+
import { overlayComposition as n } from "../../shared/overlay/composition.js";
|
|
4
|
+
import { computePosition as r, shift as i } from "../../node_modules/.pnpm/@floating-ui_dom@1.8.0/node_modules/@floating-ui/dom/dist/floating-ui.dom.js";
|
|
5
|
+
import { defineOverlayPositioningGeneration as a } from "../../shared/overlay/positioning-generation.js";
|
|
6
|
+
import { hideOverlayPresence as o, showOverlayPresence as s } from "../../shared/overlay/presence.js";
|
|
7
|
+
import { defineScrollLockLease as c } from "../../shared/scroll-lock/scroll-lock.js";
|
|
8
|
+
import { UserChangeController as l } from "../../shared/events/user-change.js";
|
|
6
9
|
import "../dropdown-divider/index.js";
|
|
7
10
|
import "../dropdown-header/index.js";
|
|
8
11
|
import "../dropdown-item/index.js";
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import
|
|
12
|
-
import
|
|
13
|
-
import {
|
|
12
|
+
import { captureFrameworkAnchors as u, focusMenuItem as d, getMenuChildren as f, getMenuItemFromEvent as p, hideNestedMenuChildren as m, moveMenuChildren as h, orderManagedMenuItems as g, reconcileManagedMenuItems as _, restoreFrameworkAnchors as v, returnManagedMenuItemsToSlot as y } from "../../shared/menu-portal/menu-tree.js";
|
|
13
|
+
import { createClosingSubmenuStack as b, createMenuHoverBinder as x, createMenuOutsideClickGuard as S, getEnabledMenuLevelItems as C, getFocusedMenuItemFromPanels as w, handleMenuKeyboard as T } from "../../shared/menu-behavior/index.js";
|
|
14
|
+
import { createMenuPortalOverlay as E } from "../../shared/menu-portal/menu-portal.js";
|
|
15
|
+
import D from "./style.js";
|
|
16
|
+
import { LitElement as O, html as k, unsafeCSS as A } from "lit";
|
|
17
|
+
import { customElement as j, property as M, state as N } from "lit/decorators.js";
|
|
14
18
|
//#region src/components/context-menu/index.ts
|
|
15
|
-
var
|
|
19
|
+
var P = "wui-context-menu-item", F = class extends O {
|
|
16
20
|
constructor(...e) {
|
|
17
|
-
super(...e), this.disabled = !1, this.noScrollLock = !1, this._isOpen = !1, this._x = 0, this._y = 0, this._activeSubmenus = [], this._activeSubmenuItems = [], this._submenuPositionEpochs = /* @__PURE__ */ new WeakMap(), this.
|
|
21
|
+
super(...e), this.disabled = !1, this.noScrollLock = !1, this._isOpen = !1, this._x = 0, this._y = 0, this._activeSubmenus = [], this._activeSubmenuItems = [], this._submenuPositionEpochs = /* @__PURE__ */ new WeakMap(), this._outsideClickGuard = S(this, (e) => [this._menu?.panel, ...this._activeSubmenus.map((e) => e.panel)].filter((e) => e instanceof HTMLElement).some((t) => n.contains(t, e))), this._closingSubmenus = b({
|
|
22
|
+
getPanel: (e) => e.panel,
|
|
23
|
+
restoreItems: (e, t) => this._restoreSubmenuItems(e, t),
|
|
24
|
+
dispose: (e) => {
|
|
25
|
+
n.unregisterPanel(e.panel), e.panel.remove();
|
|
26
|
+
}
|
|
27
|
+
}), this._hoverDelegate = {
|
|
28
|
+
getOpenDepth: () => this._activeSubmenus.length,
|
|
29
|
+
getLevelItems: (e) => this._getLevelItems(e),
|
|
30
|
+
getActiveItem: (e) => this._activeSubmenuItems[e],
|
|
31
|
+
isSubmenuItem: (e) => e.hasAttribute("submenu"),
|
|
32
|
+
openSubmenu: (e) => this._openSubmenu(e),
|
|
33
|
+
closeFrom: (e) => {
|
|
34
|
+
this._closeSubmenusFrom(e), this._hoverBinder.bind();
|
|
35
|
+
}
|
|
36
|
+
}, this._hoverBinder = x(this._hoverDelegate, "web-ui-dropdown-item"), this._keyboardDelegate = {
|
|
37
|
+
getFocusedItem: (e) => w(e, [this._menu?.content, ...this._activeSubmenus.map((e) => e.content)], "web-ui-dropdown-item"),
|
|
38
|
+
getLevelOf: (e) => {
|
|
39
|
+
let t = this._getItemLevel(e);
|
|
40
|
+
return t === -1 ? void 0 : t;
|
|
41
|
+
},
|
|
42
|
+
getEnabledItems: (e) => C(this._getLevelContainer(e)?.content),
|
|
43
|
+
isSubmenuItem: (e) => e.hasAttribute("submenu"),
|
|
44
|
+
openSubmenuInstant: (e) => this._openSubmenu(e, !0),
|
|
45
|
+
closeToParent: (e) => {
|
|
46
|
+
let t = this._activeSubmenuItems[e - 1];
|
|
47
|
+
return this._closeSubmenusFrom(e - 1), this._hoverBinder.bind(), t;
|
|
48
|
+
},
|
|
49
|
+
closeDeepestOrAll: () => this._closeLastSubmenuOrMenu()
|
|
50
|
+
}, this._menuItemAnchors = /* @__PURE__ */ new Map(), this._scrollLock = c().make(), this._userOpenChange = new l(), this._shouldOpenInstantly = !0, this._refreshScheduled = !1, this._menuPositionGeneration = a().make(), this._contentObserver = new MutationObserver(() => {
|
|
18
51
|
this._isOpen && this._scheduleRefresh();
|
|
19
52
|
}), this._closeFromUser = () => {
|
|
20
53
|
this._isOpen && (this._userOpenChange.mark(), this.close());
|
|
21
54
|
}, this._onContextMenu = (e) => {
|
|
22
55
|
this.disabled || (e.preventDefault(), this._restoreFocusTarget = e.target instanceof HTMLElement ? e.target : void 0, this._openAt(e.clientX, e.clientY, !1) && this._userOpenChange.mark());
|
|
23
56
|
}, this._onContextMenuOutside = (e) => {
|
|
24
|
-
this._isOpen && !this.
|
|
57
|
+
this._isOpen && !this._outsideClickGuard.isInside(e) && this._closeFromUser();
|
|
25
58
|
}, this._onKeydown = (e) => {
|
|
26
59
|
if (!this.disabled && (e.key === "ContextMenu" || e.shiftKey && e.key === "F10")) {
|
|
27
60
|
e.preventDefault();
|
|
@@ -33,7 +66,7 @@ var D = "wui-context-menu-item", O = class extends x {
|
|
|
33
66
|
return;
|
|
34
67
|
}
|
|
35
68
|
}, this._onClickOutside = (e) => {
|
|
36
|
-
!this._isOpen || this.
|
|
69
|
+
!this._isOpen || this._outsideClickGuard.isArmed() || this._outsideClickGuard.isInside(e) || this._closeFromUser();
|
|
37
70
|
}, this._onMenuClick = (e) => {
|
|
38
71
|
let t = p(e);
|
|
39
72
|
if (!(!t || t.hasAttribute("disabled"))) {
|
|
@@ -48,50 +81,11 @@ var D = "wui-context-menu-item", O = class extends x {
|
|
|
48
81
|
}, this._onTouchMove = (e) => {
|
|
49
82
|
this._preventBackgroundScroll(e);
|
|
50
83
|
}, this._onDocumentKeydown = (e) => {
|
|
51
|
-
|
|
52
|
-
if (e.key === "Escape") {
|
|
53
|
-
this._closeLastSubmenuOrMenu(), e.preventDefault();
|
|
54
|
-
return;
|
|
55
|
-
}
|
|
56
|
-
let t = this._getFocusedLevel();
|
|
57
|
-
if (t === void 0) return;
|
|
58
|
-
let n = this._getEnabledLevelItems(t), r = this._getFocusedItem(), i = r ? n.indexOf(r) : -1;
|
|
59
|
-
switch (e.key) {
|
|
60
|
-
case "ArrowDown":
|
|
61
|
-
this._focusMenuItem(n[(i + 1 + n.length) % n.length]);
|
|
62
|
-
break;
|
|
63
|
-
case "ArrowUp":
|
|
64
|
-
this._focusMenuItem(n[(i - 1 + n.length) % n.length]);
|
|
65
|
-
break;
|
|
66
|
-
case "Home":
|
|
67
|
-
this._focusMenuItem(n[0]);
|
|
68
|
-
break;
|
|
69
|
-
case "End":
|
|
70
|
-
this._focusMenuItem(n.at(-1));
|
|
71
|
-
break;
|
|
72
|
-
case "ArrowRight":
|
|
73
|
-
r?.hasAttribute("submenu") && (this._openSubmenu(r, !0), requestAnimationFrame(() => this._focusMenuItem(this._getEnabledLevelItems(t + 1)[0])));
|
|
74
|
-
break;
|
|
75
|
-
case "ArrowLeft":
|
|
76
|
-
if (t > 0) {
|
|
77
|
-
let e = this._activeSubmenuItems[t - 1];
|
|
78
|
-
this._closeSubmenusFrom(t - 1), this._focusMenuItem(e), this._bindLevelHovers();
|
|
79
|
-
}
|
|
80
|
-
break;
|
|
81
|
-
case "Enter":
|
|
82
|
-
case " ":
|
|
83
|
-
r?.click();
|
|
84
|
-
break;
|
|
85
|
-
case "Escape":
|
|
86
|
-
this._closeLastSubmenuOrMenu();
|
|
87
|
-
break;
|
|
88
|
-
default: return;
|
|
89
|
-
}
|
|
90
|
-
e.preventDefault();
|
|
84
|
+
this._isOpen && T(this._keyboardDelegate, e);
|
|
91
85
|
};
|
|
92
86
|
}
|
|
93
87
|
static {
|
|
94
|
-
this.styles =
|
|
88
|
+
this.styles = A(D);
|
|
95
89
|
}
|
|
96
90
|
get isOpen() {
|
|
97
91
|
return this._isOpen;
|
|
@@ -106,28 +100,28 @@ var D = "wui-context-menu-item", O = class extends x {
|
|
|
106
100
|
}), document.addEventListener("keydown", this._onDocumentKeydown);
|
|
107
101
|
}
|
|
108
102
|
disconnectedCallback() {
|
|
109
|
-
super.disconnectedCallback(), this.removeEventListener("contextmenu", this._onContextMenu), this.removeEventListener("keydown", this._onKeydown), this.removeEventListener("click", this._onMenuClick), document.removeEventListener("click", this._onClickOutside), document.removeEventListener("contextmenu", this._onContextMenuOutside), document.removeEventListener("wheel", this._onWheel, !0), document.removeEventListener("touchmove", this._onTouchMove, !0), document.removeEventListener("keydown", this._onDocumentKeydown), this._contentObserver.disconnect(),
|
|
103
|
+
super.disconnectedCallback(), this.removeEventListener("contextmenu", this._onContextMenu), this.removeEventListener("keydown", this._onKeydown), this.removeEventListener("click", this._onMenuClick), document.removeEventListener("click", this._onClickOutside), document.removeEventListener("contextmenu", this._onContextMenuOutside), document.removeEventListener("wheel", this._onWheel, !0), document.removeEventListener("touchmove", this._onTouchMove, !0), document.removeEventListener("keydown", this._onDocumentKeydown), this._contentObserver.disconnect(), this._menuPositionGeneration.invalidate(), this._outsideClickGuard.dispose(), this._hoverBinder.dispose(), this._scrollLock.release(), this._menu && n.unregisterPanel(this._menu.panel), this._returnItemsToSlot(), this._menu?.panel.remove(), this._menu = void 0, this._closeSubmenusFrom(0, !0), this._closingSubmenus.restoreAll(), this._isOpen = !1, this._restoreFocusTarget = void 0;
|
|
110
104
|
}
|
|
111
105
|
updated(e) {
|
|
112
106
|
if (!this.isConnected) {
|
|
113
107
|
this._syncScrollLock(!1);
|
|
114
108
|
return;
|
|
115
109
|
}
|
|
116
|
-
e.has("_isOpen") && (this._isOpen ? (this._syncScrollLock(), this._menu || (this._menu =
|
|
110
|
+
e.has("_isOpen") && (this._isOpen ? (this._syncScrollLock(), this._menu || (this._menu = E("context-menu", this), this._menu.panel.setAttribute("role", "menu"), this._menu.panel.setAttribute("aria-label", "上下文菜单"), this._menu.panel.addEventListener("click", this._onMenuClick), n.registerPanel(this._menu.panel)), this._contentObserver.observe(this._menu.content, {
|
|
117
111
|
childList: !0,
|
|
118
112
|
subtree: !0
|
|
119
113
|
}), requestAnimationFrame(() => {
|
|
120
|
-
!this._isOpen || !this._menu || (this._refreshMenu(),
|
|
121
|
-
})) : (this._syncScrollLock(!1), this._contentObserver.disconnect(), this._refreshScheduled = !1, this._closeMenuAfterPresence()), this._userOpenChange.consume() && this._dispatchChange(this._isOpen)), e.has("noScrollLock") && this._syncScrollLock();
|
|
114
|
+
!this._isOpen || !this._menu || (this._refreshMenu(), s(this._menu.panel, { isInstant: this._shouldOpenInstantly }), this._shouldOpenInstantly = !0, this._focusFirstItem());
|
|
115
|
+
})) : (this._syncScrollLock(!1), this._contentObserver.disconnect(), this._menuPositionGeneration.invalidate(), this._refreshScheduled = !1, this._closeMenuAfterPresence()), this._userOpenChange.consume() && this._dispatchChange(this._isOpen)), e.has("noScrollLock") && this._syncScrollLock();
|
|
122
116
|
}
|
|
123
117
|
openAt(e, t) {
|
|
124
118
|
this._openAt(e, t, !0);
|
|
125
119
|
}
|
|
126
120
|
_openAt(e, t, n) {
|
|
127
|
-
return !this.disabled && (this._x = e, this._y = t, this._shouldOpenInstantly = n, this.
|
|
121
|
+
return !this.disabled && (this._x = e, this._y = t, this._shouldOpenInstantly = n, this._outsideClickGuard.arm(), this._isOpen ? (this._closeSubmenusFrom(0, !0), this._closingSubmenus.restoreAll(), this._menuPositionGeneration.invalidate(), this._scheduleRefresh(), !1) : (this._restoreFocusTarget ??= document.activeElement instanceof HTMLElement ? document.activeElement : void 0, this._isOpen = !0, !0));
|
|
128
122
|
}
|
|
129
123
|
close() {
|
|
130
|
-
this._isOpen
|
|
124
|
+
this._isOpen && (this._isOpen = !1, this._menuPositionGeneration.invalidate());
|
|
131
125
|
}
|
|
132
126
|
_scheduleRefresh() {
|
|
133
127
|
this._refreshScheduled || !this._isOpen || (this._refreshScheduled = !0, requestAnimationFrame(() => {
|
|
@@ -135,28 +129,28 @@ var D = "wui-context-menu-item", O = class extends x {
|
|
|
135
129
|
}));
|
|
136
130
|
}
|
|
137
131
|
_refreshMenu() {
|
|
138
|
-
this._menu && (this._setupMenuItems(), this._positionMenu(), this.
|
|
132
|
+
this._menu && (this._setupMenuItems(), this._positionMenu(), this._hoverBinder.bind());
|
|
139
133
|
}
|
|
140
134
|
_positionMenu() {
|
|
141
135
|
let e = this._menu?.panel;
|
|
142
|
-
if (e)
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
}
|
|
147
|
-
t({ getBoundingClientRect: () => new DOMRect(this._x, this._y, 0, 0) }, e, {
|
|
148
|
-
strategy: "fixed",
|
|
149
|
-
placement: "bottom-start",
|
|
150
|
-
middleware: [n({
|
|
151
|
-
padding: 8,
|
|
152
|
-
crossAxis: !0
|
|
153
|
-
})]
|
|
154
|
-
}).then(({ x: t, y: n, middlewareData: r }) => {
|
|
155
|
-
if (!this._isOpen || this._menu?.panel !== e) return;
|
|
156
|
-
let i = r.shift?.x ?? 0, a = r.shift?.y ?? 0;
|
|
157
|
-
this._applyMenuPosition(e, t, n, i < 0 ? "right" : "left", a < 0 ? "bottom" : "top");
|
|
158
|
-
});
|
|
136
|
+
if (!e) return;
|
|
137
|
+
if (e.style.visibility = "hidden", e.style.display = "", !(e.parentElement instanceof HTMLDialogElement && e.parentElement.open)) {
|
|
138
|
+
this._positionMenuInViewport(e);
|
|
139
|
+
return;
|
|
159
140
|
}
|
|
141
|
+
let t = this._menuPositionGeneration.next();
|
|
142
|
+
r({ getBoundingClientRect: () => new DOMRect(this._x, this._y, 0, 0) }, e, {
|
|
143
|
+
strategy: "fixed",
|
|
144
|
+
placement: "bottom-start",
|
|
145
|
+
middleware: [i({
|
|
146
|
+
padding: 8,
|
|
147
|
+
crossAxis: !0
|
|
148
|
+
})]
|
|
149
|
+
}).then(({ x: n, y: r, middlewareData: i }) => {
|
|
150
|
+
if (!this._isOpen || this._menu?.panel !== e || !this._menuPositionGeneration.isCurrent(t)) return;
|
|
151
|
+
let a = i.shift?.x ?? 0, o = i.shift?.y ?? 0;
|
|
152
|
+
this._applyMenuPosition(e, n, r, a < 0 ? "right" : "left", o < 0 ? "bottom" : "top");
|
|
153
|
+
});
|
|
160
154
|
}
|
|
161
155
|
_positionMenuInViewport(e) {
|
|
162
156
|
let { width: t, height: n } = e.getBoundingClientRect(), r = window.innerWidth, i = window.innerHeight, a = this._x, o = this._y;
|
|
@@ -169,118 +163,90 @@ var D = "wui-context-menu-item", O = class extends x {
|
|
|
169
163
|
}
|
|
170
164
|
_focusFirstItem() {
|
|
171
165
|
let e = this._menu?.content.querySelectorAll("web-ui-dropdown-item:not([disabled])")?.[0];
|
|
172
|
-
e &&
|
|
166
|
+
e && d(e);
|
|
173
167
|
}
|
|
174
168
|
_setupMenuItems() {
|
|
175
169
|
let e = this._menu;
|
|
176
170
|
if (!e) return;
|
|
177
171
|
let t = e.content;
|
|
178
|
-
_(this, t, this._menuItemAnchors,
|
|
179
|
-
let n =
|
|
180
|
-
g(this, t, this._menuItemAnchors,
|
|
172
|
+
_(this, t, this._menuItemAnchors, P), this._hideMenuItems(), m(t, "context-menu-hidden");
|
|
173
|
+
let n = u(t, P);
|
|
174
|
+
g(this, t, this._menuItemAnchors, P), v(t, n);
|
|
181
175
|
}
|
|
182
176
|
_returnItemsToSlot() {
|
|
183
177
|
let e = this._menu;
|
|
184
|
-
e && (this._closeSubmenusFrom(0, !0), this.
|
|
178
|
+
e && (this._closeSubmenusFrom(0, !0), this._closingSubmenus.restoreAll(), y(this, e.content, this._menuItemAnchors));
|
|
185
179
|
}
|
|
186
180
|
async _closeMenuAfterPresence() {
|
|
187
181
|
let e = this._menu;
|
|
188
|
-
e && !await
|
|
182
|
+
e && !await o(e.panel) || this._isOpen || !this.isConnected || this._menu !== e || (e && n.unregisterPanel(e.panel), this._returnItemsToSlot(), e?.panel.remove(), this._menu = void 0, this._restoreFocusTarget?.focus(), this._restoreFocusTarget = void 0);
|
|
189
183
|
}
|
|
190
184
|
_hideMenuItems() {
|
|
191
185
|
f(this).forEach((e) => e.setAttribute("slot", "context-menu-hidden")), m(this, "context-menu-hidden");
|
|
192
186
|
}
|
|
193
187
|
_openSubmenu(e, t = !1) {
|
|
194
188
|
if (!this._isOpen || !e.hasAttribute("submenu") || e.hasAttribute("disabled")) return;
|
|
195
|
-
let
|
|
196
|
-
if (
|
|
197
|
-
this._closeSubmenusFrom(
|
|
198
|
-
let
|
|
199
|
-
if (
|
|
200
|
-
this.
|
|
189
|
+
let r = this._getItemLevel(e);
|
|
190
|
+
if (r === -1 || this._activeSubmenuItems[r] === e) return;
|
|
191
|
+
this._closeSubmenusFrom(r);
|
|
192
|
+
let i = this._closingSubmenus.take(e);
|
|
193
|
+
if (i) {
|
|
194
|
+
this._activeSubmenus[r] = i, this._activeSubmenuItems[r] = e, e.setAttribute("active", ""), this._positionSubmenu(e, i), s(i.panel, { isInstant: t }), this._hoverBinder.bind();
|
|
201
195
|
return;
|
|
202
196
|
}
|
|
203
197
|
if (f(e).length === 0) return;
|
|
204
|
-
let a =
|
|
205
|
-
a.panel.dataset.level = String(
|
|
198
|
+
let a = E("context-submenu", this);
|
|
199
|
+
a.panel.dataset.level = String(r), a.panel.setAttribute("role", "menu"), a.panel.setAttribute("aria-label", "子菜单"), a.panel.style.visibility = "hidden", a.panel.addEventListener("click", this._onMenuClick), h(e, a.content), this._activeSubmenus[r] = a, this._activeSubmenuItems[r] = e, n.registerPanel(a.panel, r === 0 ? this._menu?.panel : this._activeSubmenus[r - 1]?.panel), e.setAttribute("active", ""), this._positionSubmenu(e, a), s(a.panel, { isInstant: t }), this._hoverBinder.bind();
|
|
206
200
|
}
|
|
207
201
|
_closeSubmenusFrom(e, t = !1) {
|
|
208
|
-
for (let
|
|
209
|
-
let e = this._activeSubmenus[
|
|
210
|
-
|
|
202
|
+
for (let r = this._activeSubmenus.length - 1; r >= e; r--) {
|
|
203
|
+
let e = this._activeSubmenus[r], i = this._activeSubmenuItems[r];
|
|
204
|
+
i?.removeAttribute("active"), !i || t ? (e && n.unregisterPanel(e.panel), this._restoreSubmenuItems(e, i), e.panel.remove()) : this._closingSubmenus.closeAsync(i, e);
|
|
211
205
|
}
|
|
212
206
|
this._activeSubmenus.length = e, this._activeSubmenuItems.length = e;
|
|
213
207
|
}
|
|
214
|
-
async _closeSubmenuAfterPresence(e, t) {
|
|
215
|
-
await r(e.panel) && this._closingSubmenus.get(t) === e && (this._closingSubmenus.delete(t), this._restoreSubmenuItems(e, t), e.panel.remove());
|
|
216
|
-
}
|
|
217
208
|
_restoreSubmenuItems(e, t) {
|
|
218
209
|
t && (h(e.content, t), m(t, "context-menu-hidden"));
|
|
219
210
|
}
|
|
220
|
-
_restoreClosingSubmenus() {
|
|
221
|
-
this._closingSubmenus.forEach((e, t) => {
|
|
222
|
-
this._restoreSubmenuItems(e, t), e.panel.remove();
|
|
223
|
-
}), this._closingSubmenus.clear();
|
|
224
|
-
}
|
|
225
211
|
_getItemLevel(e) {
|
|
226
212
|
if (this._menu?.panel.contains(e)) return 0;
|
|
227
213
|
let t = this._activeSubmenus.findIndex((t) => t.panel.contains(e));
|
|
228
214
|
return t === -1 ? -1 : t + 1;
|
|
229
215
|
}
|
|
230
|
-
_positionSubmenu(e,
|
|
231
|
-
if (
|
|
232
|
-
let
|
|
233
|
-
this._submenuPositionEpochs.set(
|
|
216
|
+
_positionSubmenu(e, t) {
|
|
217
|
+
if (t.panel.parentElement instanceof HTMLDialogElement && t.panel.parentElement.open) {
|
|
218
|
+
let n = e.getBoundingClientRect().right + t.panel.getBoundingClientRect().width + 8 <= window.innerWidth, a = (this._submenuPositionEpochs.get(t.panel) ?? 0) + 1;
|
|
219
|
+
this._submenuPositionEpochs.set(t.panel, a), r(e, t.panel, {
|
|
234
220
|
strategy: "fixed",
|
|
235
|
-
placement:
|
|
236
|
-
middleware: [
|
|
221
|
+
placement: n ? "right-start" : "left-start",
|
|
222
|
+
middleware: [i({
|
|
237
223
|
padding: 8,
|
|
238
224
|
crossAxis: !0
|
|
239
225
|
})]
|
|
240
|
-
}).then(({ x: e, y:
|
|
241
|
-
if (!this._activeSubmenus.includes(
|
|
242
|
-
let i =
|
|
243
|
-
|
|
226
|
+
}).then(({ x: e, y: n, middlewareData: r }) => {
|
|
227
|
+
if (!this._activeSubmenus.includes(t) || a !== this._submenuPositionEpochs.get(t.panel)) return;
|
|
228
|
+
let i = r.shift?.x ?? 0, o = r.shift?.y ?? 0, s = i < 0 ? "right" : "left", c = o < 0 ? "bottom" : "top";
|
|
229
|
+
t.panel.style.left = `${e}px`, t.panel.style.top = `${n}px`, t.panel.style.setProperty("--wui-internal-overlay-transform-origin", `${c} ${s}`), t.panel.style.visibility = "";
|
|
244
230
|
});
|
|
245
231
|
return;
|
|
246
232
|
}
|
|
247
|
-
let
|
|
248
|
-
|
|
233
|
+
let n = e.getBoundingClientRect(), a = t.panel.getBoundingClientRect(), o = n.right + a.width + 8 <= window.innerWidth, s = o ? n.right : Math.max(8, n.left - a.width), c = Math.min(Math.max(8, n.top), window.innerHeight - a.height - 8);
|
|
234
|
+
t.panel.style.left = `${s}px`, t.panel.style.top = `${c}px`, t.panel.style.setProperty("--wui-internal-overlay-transform-origin", o ? "top left" : "top right"), t.panel.style.visibility = "";
|
|
249
235
|
}
|
|
250
236
|
_dispatchChange(e) {
|
|
251
|
-
this
|
|
252
|
-
detail: { open: e },
|
|
253
|
-
bubbles: !0,
|
|
254
|
-
composed: !0
|
|
255
|
-
}));
|
|
237
|
+
t(this, e);
|
|
256
238
|
}
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
return !1;
|
|
239
|
+
_getLevelContainer(e) {
|
|
240
|
+
return e === 0 ? this._menu : this._activeSubmenus[e - 1];
|
|
260
241
|
}
|
|
261
242
|
_getLevelItems(e) {
|
|
262
|
-
let t =
|
|
263
|
-
return t ? f(t) : [];
|
|
264
|
-
}
|
|
265
|
-
_bindLevelHovers() {
|
|
266
|
-
this._hoverCleanupFns.forEach((e) => e()), this._hoverCleanupFns.length = 0;
|
|
267
|
-
for (let e = 0; e <= this._activeSubmenus.length; e++) this._getLevelItems(e).forEach((t) => {
|
|
268
|
-
if (!t.matches("web-ui-dropdown-item") || t.hasAttribute("disabled")) return;
|
|
269
|
-
let n = (n) => {
|
|
270
|
-
n.pointerType !== "touch" && (clearTimeout(this._submenuTimer), t.hasAttribute("submenu") ? this._activeSubmenuItems[e] !== t && (this._submenuTimer = setTimeout(() => this._openSubmenu(t), 200)) : this._activeSubmenus.length > e && (this._closeSubmenusFrom(e), this._bindLevelHovers()));
|
|
271
|
-
};
|
|
272
|
-
t.addEventListener("pointerenter", n, { passive: !0 }), this._hoverCleanupFns.push(() => t.removeEventListener("pointerenter", n));
|
|
273
|
-
});
|
|
274
|
-
}
|
|
275
|
-
_ignoreCurrentOutsideClick() {
|
|
276
|
-
this._ignoreOutsideClick = !0, clearTimeout(this._ignoreOutsideClickTimer), this._ignoreOutsideClickTimer = setTimeout(() => {
|
|
277
|
-
this._ignoreOutsideClick = !1;
|
|
278
|
-
});
|
|
243
|
+
let t = this._getLevelContainer(e);
|
|
244
|
+
return t ? f(t.content) : [];
|
|
279
245
|
}
|
|
280
246
|
_closeLastSubmenuOrMenu() {
|
|
281
247
|
if (this._activeSubmenus.length > 0) {
|
|
282
248
|
let e = this._activeSubmenus.length - 1, t = this._activeSubmenuItems[e];
|
|
283
|
-
this._closeSubmenusFrom(e),
|
|
249
|
+
this._closeSubmenusFrom(e), d(t), this._hoverBinder.bind();
|
|
284
250
|
} else this._closeFromUser();
|
|
285
251
|
}
|
|
286
252
|
_preventBackgroundScroll(e) {
|
|
@@ -289,28 +255,11 @@ var D = "wui-context-menu-item", O = class extends x {
|
|
|
289
255
|
_syncScrollLock(e = this._isOpen) {
|
|
290
256
|
this._scrollLock.sync(e && !this.noScrollLock);
|
|
291
257
|
}
|
|
292
|
-
_getEnabledLevelItems(e) {
|
|
293
|
-
let t = e === 0 ? this._menu?.content : this._activeSubmenus[e - 1]?.content;
|
|
294
|
-
return t ? d(t) : [];
|
|
295
|
-
}
|
|
296
|
-
_getFocusedItem() {
|
|
297
|
-
return l([this._menu?.content, ...this._activeSubmenus.map((e) => e.content)]);
|
|
298
|
-
}
|
|
299
|
-
_getFocusedLevel() {
|
|
300
|
-
let e = this._getFocusedItem();
|
|
301
|
-
if (!e) return;
|
|
302
|
-
if (this._menu?.panel.contains(e)) return 0;
|
|
303
|
-
let t = this._activeSubmenus.findIndex((t) => t.panel.contains(e));
|
|
304
|
-
return t < 0 ? void 0 : t + 1;
|
|
305
|
-
}
|
|
306
|
-
_focusMenuItem(e) {
|
|
307
|
-
u(e);
|
|
308
|
-
}
|
|
309
258
|
_isMenuPanelEvent(e) {
|
|
310
|
-
return
|
|
259
|
+
return [this._menu?.panel, ...this._activeSubmenus.map((e) => e.panel)].filter((e) => e instanceof HTMLElement).some((t) => n.containsEvent(t, e));
|
|
311
260
|
}
|
|
312
261
|
render() {
|
|
313
|
-
return
|
|
262
|
+
return k`
|
|
314
263
|
<div class="context-menu-anchor">
|
|
315
264
|
<slot @slotchange=${this._onSlotChange}></slot>
|
|
316
265
|
</div>
|
|
@@ -320,15 +269,15 @@ var D = "wui-context-menu-item", O = class extends x {
|
|
|
320
269
|
this._hideMenuItems(), this._isOpen && this._scheduleRefresh();
|
|
321
270
|
}
|
|
322
271
|
};
|
|
323
|
-
e([
|
|
272
|
+
e([M({
|
|
324
273
|
type: Boolean,
|
|
325
274
|
reflect: !0
|
|
326
|
-
})],
|
|
275
|
+
})], F.prototype, "disabled", void 0), e([M({
|
|
327
276
|
type: Boolean,
|
|
328
277
|
reflect: !0,
|
|
329
278
|
attribute: "no-scroll-lock"
|
|
330
|
-
})],
|
|
279
|
+
})], F.prototype, "noScrollLock", void 0), e([N()], F.prototype, "_isOpen", void 0), e([N()], F.prototype, "_x", void 0), e([N()], F.prototype, "_y", void 0), F = e([j("web-ui-context-menu")], F);
|
|
331
280
|
//#endregion
|
|
332
|
-
export {
|
|
281
|
+
export { F as WebUiContextMenu };
|
|
333
282
|
|
|
334
283
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../../src/components/context-menu/index.ts"],"sourcesContent":["import { computePosition, shift } from '@floating-ui/dom'\nimport { html, LitElement, unsafeCSS } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\n\nimport '@/components/dropdown-divider'\nimport '@/components/dropdown-header'\nimport '@/components/dropdown-item'\nimport { UserChangeController } from '@/shared/events/user-change'\nimport { createMenuPortalOverlay, type MenuPortalOverlay } from '@/shared/menu-portal/menu-portal'\nimport {\n captureFrameworkAnchors,\n findFocusedMenuItem,\n focusMenuItem,\n getEnabledMenuItems,\n getMenuChildren,\n getMenuItemFromEvent,\n hideNestedMenuChildren,\n moveMenuChildren,\n orderManagedMenuItems,\n reconcileManagedMenuItems,\n restoreFrameworkAnchors,\n returnManagedMenuItemsToSlot\n} from '@/shared/menu-portal/menu-tree'\nimport { hideOverlayPresence, showOverlayPresence } from '@/shared/overlay/presence'\nimport { defineScrollLockLease } from '@/shared/scroll-lock/scroll-lock'\n\nimport style from './style.css?inline'\n\nconst MARKER_TEXT = 'wui-context-menu-item'\n\n@customElement('web-ui-context-menu')\nexport class WebUiContextMenu extends LitElement {\n static override styles = unsafeCSS(style)\n\n @property({ type: Boolean, reflect: true }) disabled = false\n @property({ type: Boolean, reflect: true, attribute: 'no-scroll-lock' }) noScrollLock = false\n\n @state() private _isOpen = false\n @state() private _x = 0\n @state() private _y = 0\n\n private _activeSubmenus: MenuPortalOverlay[] = []\n private _activeSubmenuItems: HTMLElement[] = []\n // 子菜单 dialog 定位的唯一写者代数(按 panel 键控):同帧关闭→重开复用同一 panel\n // 时只允许最新一次定位写入;不同层级子菜单各有 panel,互不作废。\n private readonly _submenuPositionEpochs = new WeakMap<HTMLElement, number>()\n private readonly _closingSubmenus = new Map<HTMLElement, MenuPortalOverlay>()\n private _submenuTimer?: ReturnType<typeof setTimeout>\n private _ignoreOutsideClick = false\n private _ignoreOutsideClickTimer?: ReturnType<typeof setTimeout>\n private _hoverCleanupFns: (() => void)[] = []\n private _menu?: MenuPortalOverlay\n private readonly _menuItemAnchors = new Map<HTMLElement, Comment>()\n private readonly _scrollLock = defineScrollLockLease().make()\n private readonly _userOpenChange = new UserChangeController()\n private _restoreFocusTarget?: HTMLElement\n private _shouldOpenInstantly = true\n private _refreshScheduled = false\n // 菜单打开期间宿主可能不经重定位直接改写子内容(网络推送、定时器等),\n // 新节点缺隐藏 slot 会可见叠加到菜单上;观察 portal 内容并在下一帧重新同步。\n private readonly _contentObserver = new MutationObserver(() => {\n if (this._isOpen) this._scheduleRefresh()\n })\n\n get isOpen(): boolean {\n return this._isOpen\n }\n\n override connectedCallback() {\n super.connectedCallback()\n this._hideMenuItems()\n this.addEventListener('contextmenu', this._onContextMenu)\n this.addEventListener('keydown', this._onKeydown)\n this.addEventListener('click', this._onMenuClick)\n document.addEventListener('click', this._onClickOutside)\n document.addEventListener('contextmenu', this._onContextMenuOutside)\n document.addEventListener('wheel', this._onWheel, { capture: true, passive: false })\n document.addEventListener('touchmove', this._onTouchMove, { capture: true, passive: false })\n document.addEventListener('keydown', this._onDocumentKeydown)\n }\n\n override disconnectedCallback() {\n super.disconnectedCallback()\n this.removeEventListener('contextmenu', this._onContextMenu)\n this.removeEventListener('keydown', this._onKeydown)\n this.removeEventListener('click', this._onMenuClick)\n document.removeEventListener('click', this._onClickOutside)\n document.removeEventListener('contextmenu', this._onContextMenuOutside)\n document.removeEventListener('wheel', this._onWheel, true)\n document.removeEventListener('touchmove', this._onTouchMove, true)\n document.removeEventListener('keydown', this._onDocumentKeydown)\n this._contentObserver.disconnect()\n clearTimeout(this._submenuTimer)\n clearTimeout(this._ignoreOutsideClickTimer)\n this._hoverCleanupFns.forEach(cleanup => cleanup())\n this._scrollLock.release()\n this._returnItemsToSlot()\n this._menu?.panel.remove()\n this._menu = undefined\n this._closeSubmenusFrom(0, true)\n this._restoreClosingSubmenus()\n // 脱离文档即视为关闭:否则重连后 _isOpen 仍为 true 而 _menu 已清空,\n // 下次 openAt 会走已打开分支静默失败,菜单无法再打开。\n this._isOpen = false\n this._restoreFocusTarget = undefined\n }\n\n protected override updated(changed: Map<string, unknown>) {\n // Lit 的已排队更新可在卸载后执行,不能让已失效实例重新获取全局滚动锁。\n if (!this.isConnected) {\n this._syncScrollLock(false)\n return\n }\n\n if (changed.has('_isOpen')) {\n if (this._isOpen) {\n this._syncScrollLock()\n if (!this._menu) {\n this._menu = createMenuPortalOverlay('context-menu', this)\n this._menu.panel.setAttribute('role', 'menu')\n this._menu.panel.setAttribute('aria-label', '上下文菜单')\n this._menu.panel.addEventListener('click', this._onMenuClick)\n }\n // 父项始终留在 menu.content 内,观察它即可覆盖各级子菜单在打开期间的内容重建。\n this._contentObserver.observe(this._menu.content, { childList: true, subtree: true })\n requestAnimationFrame(() => {\n if (!this._isOpen || !this._menu) return\n this._refreshMenu()\n showOverlayPresence(this._menu.panel, { isInstant: this._shouldOpenInstantly })\n this._shouldOpenInstantly = true\n this._focusFirstItem()\n })\n } else {\n this._syncScrollLock(false)\n this._contentObserver.disconnect()\n this._refreshScheduled = false\n void this._closeMenuAfterPresence()\n }\n if (this._userOpenChange.consume()) this._dispatchChange(this._isOpen)\n }\n if (changed.has('noScrollLock')) this._syncScrollLock()\n }\n\n /**\n * 在指定视口坐标打开菜单。\n * @param x 水平坐标(px)。\n * @param y 垂直坐标(px)。\n * @returns 无返回值;命令式打开不派发 `open-change` 事件。\n */\n openAt(x: number, y: number) {\n this._openAt(x, y, true)\n }\n\n private _openAt(x: number, y: number, isInstant: boolean): boolean {\n if (this.disabled) return false\n this._x = x\n this._y = y\n this._shouldOpenInstantly = isInstant\n this._ignoreCurrentOutsideClick()\n if (this._isOpen) {\n this._closeSubmenusFrom(0, true)\n this._restoreClosingSubmenus()\n this._scheduleRefresh()\n return false\n }\n this._restoreFocusTarget ??= document.activeElement instanceof HTMLElement ? document.activeElement : undefined\n this._isOpen = true\n return true\n }\n\n /**\n * 关闭菜单。\n * @returns 无返回值;命令式关闭不派发 `open-change` 事件。\n */\n close() {\n if (!this._isOpen) return\n this._isOpen = false\n }\n\n private readonly _closeFromUser = () => {\n if (!this._isOpen) return\n this._userOpenChange.mark()\n this.close()\n }\n\n // 同一帧内多次内容变化只刷新一次,避免观察者与刷新自身 append 形成循环。\n private _scheduleRefresh() {\n if (this._refreshScheduled || !this._isOpen) return\n this._refreshScheduled = true\n requestAnimationFrame(() => {\n this._refreshScheduled = false\n if (!this._isOpen || !this._menu) return\n this._refreshMenu()\n })\n }\n\n // 重新同步 portal 内容并重定位;fresh-open、重定位与观察者触发的刷新共用。\n private _refreshMenu() {\n if (!this._menu) return\n this._setupMenuItems()\n this._positionMenu()\n this._bindLevelHovers()\n }\n\n private _positionMenu() {\n const panel = this._menu?.panel\n if (!panel) return\n\n panel.style.visibility = 'hidden'\n panel.style.display = ''\n\n // 普通 overlay root 不经过 transformed containing block,保留轻量的同步定位。\n // 只有 panel 已进入 open native dialog 时才需要 Floating UI 解析坐标。\n if (!(panel.parentElement instanceof HTMLDialogElement && panel.parentElement.open)) {\n this._positionMenuInViewport(panel)\n return\n }\n\n void computePosition({ getBoundingClientRect: () => new DOMRect(this._x, this._y, 0, 0) }, panel, {\n strategy: 'fixed',\n placement: 'bottom-start',\n // crossAxis 必须显式开启:bottom-start 的 sideAxis 为 y,默认只钳制 x,\n // 视口下缘打开时菜单底部会溢出且无法滚动进入视野。\n middleware: [shift({ padding: 8, crossAxis: true })]\n }).then(({ x, y, middlewareData }) => {\n if (!this._isOpen || this._menu?.panel !== panel) return\n // dialog 相对坐标不能与 viewport 的 _x/_y 比较推导 origin(原点非零时几乎恒判\n // right/bottom);shift 数据是该坐标系内的钳制位移增量,负值即被推向该轴起点侧。\n const shiftX = middlewareData.shift?.x ?? 0\n const shiftY = middlewareData.shift?.y ?? 0\n this._applyMenuPosition(panel, x, y, shiftX < 0 ? 'right' : 'left', shiftY < 0 ? 'bottom' : 'top')\n })\n }\n\n private _positionMenuInViewport(panel: HTMLElement) {\n const { width, height } = panel.getBoundingClientRect()\n const vw = window.innerWidth\n const vh = window.innerHeight\n\n let x = this._x\n let y = this._y\n\n if (x + width > vw) x = vw - width - 8\n if (y + height > vh) y = vh - height - 8\n if (x < 0) x = 8\n if (y < 0) y = 8\n\n this._applyMenuPosition(panel, x, y)\n }\n\n private _applyMenuPosition(\n panel: HTMLElement,\n x: number,\n y: number,\n horizontalOrigin?: 'left' | 'right',\n verticalOrigin?: 'top' | 'bottom'\n ) {\n panel.style.left = `${x}px`\n panel.style.top = `${y}px`\n // 非 dialog 路径保持 viewport 坐标比较;dialog 路径由调用方传入 shift 推导值。\n const horizontal = horizontalOrigin ?? (x < this._x ? 'right' : 'left')\n const vertical = verticalOrigin ?? (y < this._y ? 'bottom' : 'top')\n panel.style.setProperty('--wui-internal-overlay-transform-origin', `${vertical} ${horizontal}`)\n panel.style.visibility = ''\n }\n\n private _focusFirstItem() {\n const items = this._menu?.content.querySelectorAll<HTMLElement>('web-ui-dropdown-item:not([disabled])')\n const firstItem = items?.[0]\n if (firstItem) {\n this._focusMenuItem(firstItem)\n }\n }\n\n private _setupMenuItems() {\n const menu = this._menu\n if (!menu) return\n const content = menu.content\n\n reconcileManagedMenuItems(this, content, this._menuItemAnchors, MARKER_TEXT)\n this._hideMenuItems()\n // 宿主可能在菜单打开期间动态改写 slot 子内容(如切换上下文后重建嵌套子项),\n // 新节点没有隐藏 slot 会落入父项默认 slot 可见渲染并叠到一级菜单上;\n // 因此对已移入 content 的嵌套子项也要重新隐藏。\n hideNestedMenuChildren(content, 'context-menu-hidden')\n\n // 框架 v-if 注释锚点的复位独立于元素重排:无论元素序是否已变都要执行。\n // 若挂在「元素序已变才重排」之下,顺序恰好正确时会跳过复位,锚点漂移无法收敛,\n // 而 Vue 下次翻转正依赖锚点引导新分支项的插入点。\n const anchors = captureFrameworkAnchors(content, MARKER_TEXT)\n orderManagedMenuItems(this, content, this._menuItemAnchors, MARKER_TEXT)\n restoreFrameworkAnchors(content, anchors)\n }\n\n private _returnItemsToSlot() {\n const menu = this._menu\n if (!menu) return\n\n this._closeSubmenusFrom(0, true)\n this._restoreClosingSubmenus()\n\n returnManagedMenuItemsToSlot(this, menu.content, this._menuItemAnchors)\n }\n\n private async _closeMenuAfterPresence() {\n const menu = this._menu\n if (menu && !(await hideOverlayPresence(menu.panel))) return\n if (this._isOpen || !this.isConnected || this._menu !== menu) return\n\n this._returnItemsToSlot()\n menu?.panel.remove()\n this._menu = undefined\n this._restoreFocusTarget?.focus()\n this._restoreFocusTarget = undefined\n }\n\n private _hideMenuItems() {\n getMenuChildren(this).forEach(child => child.setAttribute('slot', 'context-menu-hidden'))\n hideNestedMenuChildren(this, 'context-menu-hidden')\n }\n\n private _openSubmenu(item: HTMLElement, isInstant = false) {\n if (!this._isOpen || !item.hasAttribute('submenu') || item.hasAttribute('disabled')) return\n\n const level = this._getItemLevel(item)\n if (level === -1 || this._activeSubmenuItems[level] === item) return\n\n this._closeSubmenusFrom(level)\n const closingSubmenu = this._closingSubmenus.get(item)\n if (closingSubmenu) {\n this._closingSubmenus.delete(item)\n this._activeSubmenus[level] = closingSubmenu\n this._activeSubmenuItems[level] = item\n item.setAttribute('active', '')\n this._positionSubmenu(item, closingSubmenu)\n showOverlayPresence(closingSubmenu.panel, { isInstant })\n this._bindLevelHovers()\n return\n }\n if (getMenuChildren(item).length === 0) return\n\n const submenu = createMenuPortalOverlay('context-submenu', this)\n submenu.panel.dataset.level = String(level)\n submenu.panel.setAttribute('role', 'menu')\n submenu.panel.setAttribute('aria-label', '子菜单')\n submenu.panel.style.visibility = 'hidden'\n submenu.panel.addEventListener('click', this._onMenuClick)\n moveMenuChildren(item, submenu.content)\n\n this._activeSubmenus[level] = submenu\n this._activeSubmenuItems[level] = item\n item.setAttribute('active', '')\n this._positionSubmenu(item, submenu)\n showOverlayPresence(submenu.panel, { isInstant })\n this._bindLevelHovers()\n }\n\n private _closeSubmenusFrom(level: number, isInstant = false) {\n for (let index = this._activeSubmenus.length - 1; index >= level; index--) {\n const submenu = this._activeSubmenus[index]\n const item = this._activeSubmenuItems[index]\n item?.removeAttribute('active')\n if (!item || isInstant) {\n this._restoreSubmenuItems(submenu, item)\n submenu.panel.remove()\n } else {\n this._closingSubmenus.set(item, submenu)\n void this._closeSubmenuAfterPresence(submenu, item)\n }\n }\n this._activeSubmenus.length = level\n this._activeSubmenuItems.length = level\n }\n\n private async _closeSubmenuAfterPresence(submenu: MenuPortalOverlay, item: HTMLElement) {\n if (!(await hideOverlayPresence(submenu.panel))) return\n if (this._closingSubmenus.get(item) !== submenu) return\n\n this._closingSubmenus.delete(item)\n this._restoreSubmenuItems(submenu, item)\n submenu.panel.remove()\n }\n\n private _restoreSubmenuItems(submenu: MenuPortalOverlay, item?: HTMLElement) {\n if (!item) return\n moveMenuChildren(submenu.content, item)\n // 子菜单打开期间宿主可能重建了嵌套子项,归还时补隐藏,避免可见叠加。\n hideNestedMenuChildren(item, 'context-menu-hidden')\n }\n\n private _restoreClosingSubmenus() {\n this._closingSubmenus.forEach((submenu, item) => {\n this._restoreSubmenuItems(submenu, item)\n submenu.panel.remove()\n })\n this._closingSubmenus.clear()\n }\n\n private _getItemLevel(item: HTMLElement): number {\n const menu = this._menu\n if (menu?.panel.contains(item)) return 0\n const parentLevel = this._activeSubmenus.findIndex(submenu => submenu.panel.contains(item))\n return parentLevel === -1 ? -1 : parentLevel + 1\n }\n\n private _positionSubmenu(item: HTMLElement, submenu: MenuPortalOverlay) {\n // 与主菜单同因:panel 进入 open native dialog 后处于 transformed containing\n // block,viewport 坐标的 left/top 会相对 dialog padding box 解析而整体偏移,\n // 需改走 Floating UI 换算为 dialog 相对坐标;开合方向仍按视口坐标度量预判。\n if (submenu.panel.parentElement instanceof HTMLDialogElement && submenu.panel.parentElement.open) {\n const itemRect = item.getBoundingClientRect()\n const padding = 8\n const canOpenRight = itemRect.right + submenu.panel.getBoundingClientRect().width + padding <= window.innerWidth\n // 同帧关闭→重开会复用同一 panel 产生两个 in-flight 定位 promise,完成序不保证\n // 后者胜出;按 panel 键控的代数 token 只允许最新一次调用写入,迟到旧 promise 丢弃。\n const epoch = (this._submenuPositionEpochs.get(submenu.panel) ?? 0) + 1\n this._submenuPositionEpochs.set(submenu.panel, epoch)\n void computePosition(item, submenu.panel, {\n strategy: 'fixed',\n placement: canOpenRight ? 'right-start' : 'left-start',\n middleware: [shift({ padding, crossAxis: true })]\n }).then(({ x, y, middlewareData }) => {\n if (!this._activeSubmenus.includes(submenu) || epoch !== this._submenuPositionEpochs.get(submenu.panel)) return\n // 与主菜单 dialog 路径一致:origin 由 shift 增量推导,视口预判只决定 placement。\n const shiftX = middlewareData.shift?.x ?? 0\n const shiftY = middlewareData.shift?.y ?? 0\n const horizontalOrigin = shiftX < 0 ? 'right' : 'left'\n const verticalOrigin = shiftY < 0 ? 'bottom' : 'top'\n submenu.panel.style.left = `${x}px`\n submenu.panel.style.top = `${y}px`\n submenu.panel.style.setProperty(\n '--wui-internal-overlay-transform-origin',\n `${verticalOrigin} ${horizontalOrigin}`\n )\n submenu.panel.style.visibility = ''\n })\n return\n }\n\n const itemRect = item.getBoundingClientRect()\n const submenuRect = submenu.panel.getBoundingClientRect()\n const padding = 8\n const canOpenRight = itemRect.right + submenuRect.width + padding <= window.innerWidth\n const left = canOpenRight ? itemRect.right : Math.max(padding, itemRect.left - submenuRect.width)\n const top = Math.min(Math.max(padding, itemRect.top), window.innerHeight - submenuRect.height - padding)\n\n submenu.panel.style.left = `${left}px`\n submenu.panel.style.top = `${top}px`\n submenu.panel.style.setProperty('--wui-internal-overlay-transform-origin', canOpenRight ? 'top left' : 'top right')\n submenu.panel.style.visibility = ''\n }\n\n private _dispatchChange(open: boolean) {\n this.dispatchEvent(\n new CustomEvent('open-change', {\n detail: { open },\n bubbles: true,\n composed: true\n })\n )\n }\n\n private _isInsideShadowRoot(e: MouseEvent): boolean {\n for (const node of e.composedPath()) {\n if (node === this || node === this.shadowRoot) return true\n if (node instanceof Node && node.getRootNode() === this.shadowRoot) return true\n if (\n node instanceof Node &&\n (this._menu?.panel.contains(node) || this._activeSubmenus.some(menu => menu.panel.contains(node)))\n ) {\n return true\n }\n }\n return false\n }\n\n private _onContextMenu = (e: MouseEvent) => {\n if (this.disabled) return\n e.preventDefault()\n this._restoreFocusTarget = e.target instanceof HTMLElement ? e.target : undefined\n if (this._openAt(e.clientX, e.clientY, false)) this._userOpenChange.mark()\n }\n\n private _onContextMenuOutside = (e: MouseEvent) => {\n if (this._isOpen && !this._isInsideShadowRoot(e)) {\n this._closeFromUser()\n }\n }\n\n private _onKeydown = (e: KeyboardEvent) => {\n if (this.disabled) return\n\n // 键盘 ContextMenu 键或 Shift+F10\n if (e.key === 'ContextMenu' || (e.shiftKey && e.key === 'F10')) {\n e.preventDefault()\n const focused = document.activeElement\n if (focused && focused !== document.body) {\n const rect = focused.getBoundingClientRect()\n if (this._openAt(rect.left, rect.bottom, true)) this._userOpenChange.mark()\n } else {\n if (this._openAt(window.innerWidth / 2, window.innerHeight / 2, true)) this._userOpenChange.mark()\n }\n return\n }\n }\n\n private _onClickOutside = (e: MouseEvent) => {\n if (!this._isOpen || this._ignoreOutsideClick) return\n if (this._isInsideShadowRoot(e)) return\n this._closeFromUser()\n }\n\n private _onMenuClick = (e: MouseEvent) => {\n const item = getMenuItemFromEvent(e)\n if (!item || item.hasAttribute('disabled')) return\n if (item.hasAttribute('submenu')) {\n this._openSubmenu(item)\n return\n }\n this._closeFromUser()\n }\n\n private _getLevelItems(level: number): HTMLElement[] {\n const container = level === 0 ? this._menu?.content : this._activeSubmenus[level - 1]?.content\n if (!container) return []\n return getMenuChildren(container)\n }\n\n private _bindLevelHovers() {\n this._hoverCleanupFns.forEach(cleanup => cleanup())\n this._hoverCleanupFns.length = 0\n\n for (let level = 0; level <= this._activeSubmenus.length; level++) {\n this._getLevelItems(level).forEach(item => {\n if (!item.matches('web-ui-dropdown-item') || item.hasAttribute('disabled')) return\n const handler = (event: PointerEvent) => {\n if (event.pointerType === 'touch') return\n clearTimeout(this._submenuTimer)\n if (item.hasAttribute('submenu')) {\n if (this._activeSubmenuItems[level] !== item) {\n this._submenuTimer = setTimeout(() => this._openSubmenu(item), 200)\n }\n } else if (this._activeSubmenus.length > level) {\n this._closeSubmenusFrom(level)\n this._bindLevelHovers()\n }\n }\n item.addEventListener('pointerenter', handler, { passive: true })\n this._hoverCleanupFns.push(() => item.removeEventListener('pointerenter', handler))\n })\n }\n }\n\n private _ignoreCurrentOutsideClick() {\n this._ignoreOutsideClick = true\n clearTimeout(this._ignoreOutsideClickTimer)\n this._ignoreOutsideClickTimer = setTimeout(() => {\n this._ignoreOutsideClick = false\n })\n }\n\n private _onWheel = (e: WheelEvent) => {\n this._preventBackgroundScroll(e)\n }\n\n private _onTouchMove = (e: TouchEvent) => {\n this._preventBackgroundScroll(e)\n }\n\n private _onDocumentKeydown = (e: KeyboardEvent) => {\n if (!this._isOpen) return\n // 鼠标右键打开的菜单焦点不在菜单内,e.target !== this 时也必须能 Escape 关闭;\n // 菜单为模态浮层,按 Escape 即关闭,无需限定焦点位置\n if (e.key === 'Escape') {\n this._closeLastSubmenuOrMenu()\n e.preventDefault()\n return\n }\n const level = this._getFocusedLevel()\n if (level === undefined) return\n const items = this._getEnabledLevelItems(level)\n const focused = this._getFocusedItem()\n const currentIndex = focused ? items.indexOf(focused) : -1\n\n switch (e.key) {\n case 'ArrowDown':\n this._focusMenuItem(items[(currentIndex + 1 + items.length) % items.length])\n break\n case 'ArrowUp':\n this._focusMenuItem(items[(currentIndex - 1 + items.length) % items.length])\n break\n case 'Home':\n this._focusMenuItem(items[0])\n break\n case 'End':\n this._focusMenuItem(items.at(-1))\n break\n case 'ArrowRight':\n if (focused?.hasAttribute('submenu')) {\n this._openSubmenu(focused, true)\n requestAnimationFrame(() => this._focusMenuItem(this._getEnabledLevelItems(level + 1)[0]))\n }\n break\n case 'ArrowLeft':\n if (level > 0) {\n const parent = this._activeSubmenuItems[level - 1]\n this._closeSubmenusFrom(level - 1)\n this._focusMenuItem(parent)\n this._bindLevelHovers()\n }\n break\n case 'Enter':\n case ' ':\n focused?.click()\n break\n case 'Escape':\n this._closeLastSubmenuOrMenu()\n break\n default:\n return\n }\n e.preventDefault()\n }\n\n private _closeLastSubmenuOrMenu() {\n if (this._activeSubmenus.length > 0) {\n const level = this._activeSubmenus.length - 1\n const parent = this._activeSubmenuItems[level]\n this._closeSubmenusFrom(level)\n this._focusMenuItem(parent)\n this._bindLevelHovers()\n } else {\n this._closeFromUser()\n }\n }\n\n private _preventBackgroundScroll(e: Event) {\n if (!this._isOpen || this.noScrollLock || this._isMenuPanelEvent(e)) return\n e.preventDefault()\n }\n\n private _syncScrollLock(isOpen = this._isOpen) {\n this._scrollLock.sync(isOpen && !this.noScrollLock)\n }\n\n private _getEnabledLevelItems(level: number) {\n const container = level === 0 ? this._menu?.content : this._activeSubmenus[level - 1]?.content\n return container ? getEnabledMenuItems(container) : []\n }\n\n private _getFocusedItem(): HTMLElement | undefined {\n return findFocusedMenuItem([this._menu?.content, ...this._activeSubmenus.map(submenu => submenu.content)])\n }\n\n private _getFocusedLevel(): number | undefined {\n const item = this._getFocusedItem()\n if (!item) return undefined\n if (this._menu?.panel.contains(item)) return 0\n const submenuIndex = this._activeSubmenus.findIndex(menu => menu.panel.contains(item))\n return submenuIndex < 0 ? undefined : submenuIndex + 1\n }\n\n private _focusMenuItem(item: HTMLElement | undefined) {\n focusMenuItem(item)\n }\n\n private _isMenuPanelEvent(e: Event): boolean {\n return e\n .composedPath()\n .some(\n node =>\n node instanceof HTMLElement &&\n (node.classList.contains('context-menu') || node.classList.contains('context-submenu'))\n )\n }\n\n override render() {\n return html`\n <div class=\"context-menu-anchor\">\n <slot @slotchange=${this._onSlotChange}></slot>\n </div>\n `\n }\n\n private _onSlotChange() {\n this._hideMenuItems()\n // 打开期间宿主重建顶层项时,新成员要移入 portal 才对用户可见;\n // 关闭状态下无需移动,等下次打开时由 _setupMenuItems 统一处理。\n if (this._isOpen) this._scheduleRefresh()\n }\n\n declare readonly $events: {\n 'open-change': CustomEvent<{ open: boolean }>\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'web-ui-context-menu': WebUiContextMenu\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../src/components/context-menu/index.ts"],"sourcesContent":["import { computePosition, shift } from '@floating-ui/dom'\nimport { html, LitElement, unsafeCSS } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\n\nimport '@/components/dropdown-divider'\nimport '@/components/dropdown-header'\nimport '@/components/dropdown-item'\nimport { UserChangeController } from '@/shared/events/user-change'\nimport {\n createClosingSubmenuStack,\n createMenuHoverBinder,\n createMenuOutsideClickGuard,\n getEnabledMenuLevelItems,\n getFocusedMenuItemFromPanels,\n handleMenuKeyboard,\n type MenuHoverDelegate,\n type MenuKeyboardDelegate\n} from '@/shared/menu-behavior'\nimport { createMenuPortalOverlay, type MenuPortalOverlay } from '@/shared/menu-portal/menu-portal'\nimport {\n captureFrameworkAnchors,\n focusMenuItem,\n getMenuChildren,\n getMenuItemFromEvent,\n hideNestedMenuChildren,\n moveMenuChildren,\n orderManagedMenuItems,\n reconcileManagedMenuItems,\n restoreFrameworkAnchors,\n returnManagedMenuItemsToSlot\n} from '@/shared/menu-portal/menu-tree'\nimport { dispatchOpenChangeEvent } from '@/shared/open-state'\nimport { overlayComposition } from '@/shared/overlay/composition'\nimport { defineOverlayPositioningGeneration } from '@/shared/overlay/positioning-generation'\nimport { hideOverlayPresence, showOverlayPresence } from '@/shared/overlay/presence'\nimport { defineScrollLockLease } from '@/shared/scroll-lock/scroll-lock'\n\nimport style from './style.css?inline'\n\nconst MARKER_TEXT = 'wui-context-menu-item'\n\n@customElement('web-ui-context-menu')\nexport class WebUiContextMenu extends LitElement {\n static override styles = unsafeCSS(style)\n\n @property({ type: Boolean, reflect: true }) disabled = false\n @property({ type: Boolean, reflect: true, attribute: 'no-scroll-lock' }) noScrollLock = false\n\n @state() private _isOpen = false\n @state() private _x = 0\n @state() private _y = 0\n\n private _activeSubmenus: MenuPortalOverlay[] = []\n private _activeSubmenuItems: HTMLElement[] = []\n // 子菜单 dialog 定位的唯一写者代数(按 panel 键控):同帧关闭→重开复用同一 panel\n // 时只允许最新一次定位写入;不同层级子菜单各有 panel,互不作废。\n private readonly _submenuPositionEpochs = new WeakMap<HTMLElement, number>()\n private _menu?: MenuPortalOverlay\n // 行为层(hover / outside-click / 键盘 / submenu 收尾)由 shared/menu-behavior 驱动\n private readonly _outsideClickGuard = createMenuOutsideClickGuard(this, node => {\n const panels = [this._menu?.panel, ...this._activeSubmenus.map(menu => menu.panel)].filter(\n (panel): panel is HTMLElement => panel instanceof HTMLElement\n )\n return panels.some(panel => overlayComposition.contains(panel, node))\n })\n private readonly _closingSubmenus = createClosingSubmenuStack<MenuPortalOverlay>({\n getPanel: container => container.panel,\n restoreItems: (container, parentItem) => this._restoreSubmenuItems(container, parentItem),\n dispose: container => {\n overlayComposition.unregisterPanel(container.panel)\n container.panel.remove()\n }\n })\n private readonly _hoverDelegate: MenuHoverDelegate = {\n getOpenDepth: () => this._activeSubmenus.length,\n getLevelItems: level => this._getLevelItems(level),\n getActiveItem: level => this._activeSubmenuItems[level],\n isSubmenuItem: item => item.hasAttribute('submenu'),\n openSubmenu: item => this._openSubmenu(item),\n closeFrom: level => {\n this._closeSubmenusFrom(level)\n this._hoverBinder.bind()\n }\n }\n private readonly _hoverBinder = createMenuHoverBinder(this._hoverDelegate, 'web-ui-dropdown-item')\n private readonly _keyboardDelegate: MenuKeyboardDelegate = {\n getFocusedItem: event =>\n getFocusedMenuItemFromPanels(\n event,\n [this._menu?.content, ...this._activeSubmenus.map(submenu => submenu.content)],\n 'web-ui-dropdown-item'\n ),\n getLevelOf: item => {\n const level = this._getItemLevel(item)\n return level === -1 ? undefined : level\n },\n getEnabledItems: level => getEnabledMenuLevelItems(this._getLevelContainer(level)?.content),\n isSubmenuItem: item => item.hasAttribute('submenu'),\n openSubmenuInstant: item => this._openSubmenu(item, true),\n closeToParent: level => {\n const parent = this._activeSubmenuItems[level - 1]\n this._closeSubmenusFrom(level - 1)\n this._hoverBinder.bind()\n return parent\n },\n closeDeepestOrAll: () => this._closeLastSubmenuOrMenu()\n }\n private readonly _menuItemAnchors = new Map<HTMLElement, Comment>()\n private readonly _scrollLock = defineScrollLockLease().make()\n private readonly _userOpenChange = new UserChangeController()\n private _restoreFocusTarget?: HTMLElement\n private _shouldOpenInstantly = true\n private _refreshScheduled = false\n // 主菜单 dialog 路径与子菜单一样使用代数令牌;快速 openAt/refresh 或 close 后,\n // 迟到的 positioning promise 只能被丢弃,不能覆盖最新坐标。\n private readonly _menuPositionGeneration = defineOverlayPositioningGeneration().make()\n // 菜单打开期间宿主可能不经重定位直接改写子内容(网络推送、定时器等),\n // 新节点缺隐藏 slot 会可见叠加到菜单上;观察 portal 内容并在下一帧重新同步。\n private readonly _contentObserver = new MutationObserver(() => {\n if (this._isOpen) this._scheduleRefresh()\n })\n\n get isOpen(): boolean {\n return this._isOpen\n }\n\n override connectedCallback() {\n super.connectedCallback()\n this._hideMenuItems()\n this.addEventListener('contextmenu', this._onContextMenu)\n this.addEventListener('keydown', this._onKeydown)\n this.addEventListener('click', this._onMenuClick)\n document.addEventListener('click', this._onClickOutside)\n document.addEventListener('contextmenu', this._onContextMenuOutside)\n document.addEventListener('wheel', this._onWheel, { capture: true, passive: false })\n document.addEventListener('touchmove', this._onTouchMove, { capture: true, passive: false })\n document.addEventListener('keydown', this._onDocumentKeydown)\n }\n\n override disconnectedCallback() {\n super.disconnectedCallback()\n this.removeEventListener('contextmenu', this._onContextMenu)\n this.removeEventListener('keydown', this._onKeydown)\n this.removeEventListener('click', this._onMenuClick)\n document.removeEventListener('click', this._onClickOutside)\n document.removeEventListener('contextmenu', this._onContextMenuOutside)\n document.removeEventListener('wheel', this._onWheel, true)\n document.removeEventListener('touchmove', this._onTouchMove, true)\n document.removeEventListener('keydown', this._onDocumentKeydown)\n this._contentObserver.disconnect()\n this._menuPositionGeneration.invalidate()\n this._outsideClickGuard.dispose()\n this._hoverBinder.dispose()\n this._scrollLock.release()\n if (this._menu) overlayComposition.unregisterPanel(this._menu.panel)\n this._returnItemsToSlot()\n this._menu?.panel.remove()\n this._menu = undefined\n this._closeSubmenusFrom(0, true)\n this._closingSubmenus.restoreAll()\n // 脱离文档即视为关闭:否则重连后 _isOpen 仍为 true 而 _menu 已清空,\n // 下次 openAt 会走已打开分支静默失败,菜单无法再打开。\n this._isOpen = false\n this._restoreFocusTarget = undefined\n }\n\n protected override updated(changed: Map<string, unknown>) {\n // Lit 的已排队更新可在卸载后执行,不能让已失效实例重新获取全局滚动锁。\n if (!this.isConnected) {\n this._syncScrollLock(false)\n return\n }\n\n if (changed.has('_isOpen')) {\n if (this._isOpen) {\n this._syncScrollLock()\n if (!this._menu) {\n this._menu = createMenuPortalOverlay('context-menu', this)\n this._menu.panel.setAttribute('role', 'menu')\n this._menu.panel.setAttribute('aria-label', '上下文菜单')\n this._menu.panel.addEventListener('click', this._onMenuClick)\n overlayComposition.registerPanel(this._menu.panel)\n }\n // 父项始终留在 menu.content 内,观察它即可覆盖各级子菜单在打开期间的内容重建。\n this._contentObserver.observe(this._menu.content, { childList: true, subtree: true })\n requestAnimationFrame(() => {\n if (!this._isOpen || !this._menu) return\n this._refreshMenu()\n showOverlayPresence(this._menu.panel, { isInstant: this._shouldOpenInstantly })\n this._shouldOpenInstantly = true\n this._focusFirstItem()\n })\n } else {\n this._syncScrollLock(false)\n this._contentObserver.disconnect()\n this._menuPositionGeneration.invalidate()\n this._refreshScheduled = false\n void this._closeMenuAfterPresence()\n }\n if (this._userOpenChange.consume()) this._dispatchChange(this._isOpen)\n }\n if (changed.has('noScrollLock')) this._syncScrollLock()\n }\n\n /**\n * 在指定视口坐标打开菜单。\n * @param x 水平坐标(px)。\n * @param y 垂直坐标(px)。\n * @returns 无返回值;命令式打开不派发 `open-change` 事件。\n */\n openAt(x: number, y: number) {\n this._openAt(x, y, true)\n }\n\n private _openAt(x: number, y: number, isInstant: boolean): boolean {\n if (this.disabled) return false\n this._x = x\n this._y = y\n this._shouldOpenInstantly = isInstant\n this._outsideClickGuard.arm()\n if (this._isOpen) {\n this._closeSubmenusFrom(0, true)\n this._closingSubmenus.restoreAll()\n // 先失效尚未完成的旧定位,再调度下一帧新代;避免新请求前的旧 promise 胜出。\n this._menuPositionGeneration.invalidate()\n this._scheduleRefresh()\n return false\n }\n this._restoreFocusTarget ??= document.activeElement instanceof HTMLElement ? document.activeElement : undefined\n this._isOpen = true\n return true\n }\n\n /**\n * 关闭菜单。\n * @returns 无返回值;命令式关闭不派发 `open-change` 事件。\n */\n close() {\n if (!this._isOpen) return\n this._isOpen = false\n this._menuPositionGeneration.invalidate()\n }\n\n private readonly _closeFromUser = () => {\n if (!this._isOpen) return\n this._userOpenChange.mark()\n this.close()\n }\n\n // 同一帧内多次内容变化只刷新一次,避免观察者与刷新自身 append 形成循环。\n private _scheduleRefresh() {\n if (this._refreshScheduled || !this._isOpen) return\n this._refreshScheduled = true\n requestAnimationFrame(() => {\n this._refreshScheduled = false\n if (!this._isOpen || !this._menu) return\n this._refreshMenu()\n })\n }\n\n // 重新同步 portal 内容并重定位;fresh-open、重定位与观察者触发的刷新共用。\n private _refreshMenu() {\n if (!this._menu) return\n this._setupMenuItems()\n this._positionMenu()\n this._hoverBinder.bind()\n }\n\n private _positionMenu() {\n const panel = this._menu?.panel\n if (!panel) return\n\n panel.style.visibility = 'hidden'\n panel.style.display = ''\n\n // 普通 overlay root 不经过 transformed containing block,保留轻量的同步定位。\n // 只有 panel 已进入 open native dialog 时才需要 Floating UI 解析坐标。\n if (!(panel.parentElement instanceof HTMLDialogElement && panel.parentElement.open)) {\n this._positionMenuInViewport(panel)\n return\n }\n\n const generation = this._menuPositionGeneration.next()\n void computePosition({ getBoundingClientRect: () => new DOMRect(this._x, this._y, 0, 0) }, panel, {\n strategy: 'fixed',\n placement: 'bottom-start',\n // crossAxis 必须显式开启:bottom-start 的 sideAxis 为 y,默认只钳制 x,\n // 视口下缘打开时菜单底部会溢出且无法滚动进入视野。\n middleware: [shift({ padding: 8, crossAxis: true })]\n }).then(({ x, y, middlewareData }) => {\n if (!this._isOpen || this._menu?.panel !== panel || !this._menuPositionGeneration.isCurrent(generation)) return\n // dialog 相对坐标不能与 viewport 的 _x/_y 比较推导 origin(原点非零时几乎恒判\n // right/bottom);shift 数据是该坐标系内的钳制位移增量,负值即被推向该轴起点侧。\n const shiftX = middlewareData.shift?.x ?? 0\n const shiftY = middlewareData.shift?.y ?? 0\n this._applyMenuPosition(panel, x, y, shiftX < 0 ? 'right' : 'left', shiftY < 0 ? 'bottom' : 'top')\n })\n }\n\n private _positionMenuInViewport(panel: HTMLElement) {\n const { width, height } = panel.getBoundingClientRect()\n const vw = window.innerWidth\n const vh = window.innerHeight\n\n let x = this._x\n let y = this._y\n\n if (x + width > vw) x = vw - width - 8\n if (y + height > vh) y = vh - height - 8\n if (x < 0) x = 8\n if (y < 0) y = 8\n\n this._applyMenuPosition(panel, x, y)\n }\n\n private _applyMenuPosition(\n panel: HTMLElement,\n x: number,\n y: number,\n horizontalOrigin?: 'left' | 'right',\n verticalOrigin?: 'top' | 'bottom'\n ) {\n panel.style.left = `${x}px`\n panel.style.top = `${y}px`\n // 非 dialog 路径保持 viewport 坐标比较;dialog 路径由调用方传入 shift 推导值。\n const horizontal = horizontalOrigin ?? (x < this._x ? 'right' : 'left')\n const vertical = verticalOrigin ?? (y < this._y ? 'bottom' : 'top')\n panel.style.setProperty('--wui-internal-overlay-transform-origin', `${vertical} ${horizontal}`)\n panel.style.visibility = ''\n }\n\n private _focusFirstItem() {\n const items = this._menu?.content.querySelectorAll<HTMLElement>('web-ui-dropdown-item:not([disabled])')\n const firstItem = items?.[0]\n if (firstItem) {\n focusMenuItem(firstItem)\n }\n }\n\n private _setupMenuItems() {\n const menu = this._menu\n if (!menu) return\n const content = menu.content\n\n reconcileManagedMenuItems(this, content, this._menuItemAnchors, MARKER_TEXT)\n this._hideMenuItems()\n // 宿主可能在菜单打开期间动态改写 slot 子内容(如切换上下文后重建嵌套子项),\n // 新节点没有隐藏 slot 会落入父项默认 slot 可见渲染并叠到一级菜单上;\n // 因此对已移入 content 的嵌套子项也要重新隐藏。\n hideNestedMenuChildren(content, 'context-menu-hidden')\n\n // 框架 v-if 注释锚点的复位独立于元素重排:无论元素序是否已变都要执行。\n // 若挂在「元素序已变才重排」之下,顺序恰好正确时会跳过复位,锚点漂移无法收敛,\n // 而 Vue 下次翻转正依赖锚点引导新分支项的插入点。\n const anchors = captureFrameworkAnchors(content, MARKER_TEXT)\n orderManagedMenuItems(this, content, this._menuItemAnchors, MARKER_TEXT)\n restoreFrameworkAnchors(content, anchors)\n }\n\n private _returnItemsToSlot() {\n const menu = this._menu\n if (!menu) return\n\n this._closeSubmenusFrom(0, true)\n this._closingSubmenus.restoreAll()\n\n returnManagedMenuItemsToSlot(this, menu.content, this._menuItemAnchors)\n }\n\n private async _closeMenuAfterPresence() {\n const menu = this._menu\n if (menu && !(await hideOverlayPresence(menu.panel))) return\n if (this._isOpen || !this.isConnected || this._menu !== menu) return\n\n if (menu) overlayComposition.unregisterPanel(menu.panel)\n this._returnItemsToSlot()\n menu?.panel.remove()\n this._menu = undefined\n this._restoreFocusTarget?.focus()\n this._restoreFocusTarget = undefined\n }\n\n private _hideMenuItems() {\n getMenuChildren(this).forEach(child => child.setAttribute('slot', 'context-menu-hidden'))\n hideNestedMenuChildren(this, 'context-menu-hidden')\n }\n\n private _openSubmenu(item: HTMLElement, isInstant = false) {\n if (!this._isOpen || !item.hasAttribute('submenu') || item.hasAttribute('disabled')) return\n\n const level = this._getItemLevel(item)\n if (level === -1 || this._activeSubmenuItems[level] === item) return\n\n this._closeSubmenusFrom(level)\n const closingSubmenu = this._closingSubmenus.take(item)\n if (closingSubmenu) {\n this._activeSubmenus[level] = closingSubmenu\n this._activeSubmenuItems[level] = item\n item.setAttribute('active', '')\n this._positionSubmenu(item, closingSubmenu)\n showOverlayPresence(closingSubmenu.panel, { isInstant })\n this._hoverBinder.bind()\n return\n }\n if (getMenuChildren(item).length === 0) return\n\n const submenu = createMenuPortalOverlay('context-submenu', this)\n submenu.panel.dataset.level = String(level)\n submenu.panel.setAttribute('role', 'menu')\n submenu.panel.setAttribute('aria-label', '子菜单')\n submenu.panel.style.visibility = 'hidden'\n submenu.panel.addEventListener('click', this._onMenuClick)\n moveMenuChildren(item, submenu.content)\n\n this._activeSubmenus[level] = submenu\n this._activeSubmenuItems[level] = item\n overlayComposition.registerPanel(\n submenu.panel,\n level === 0 ? this._menu?.panel : this._activeSubmenus[level - 1]?.panel\n )\n item.setAttribute('active', '')\n this._positionSubmenu(item, submenu)\n showOverlayPresence(submenu.panel, { isInstant })\n this._hoverBinder.bind()\n }\n\n private _closeSubmenusFrom(level: number, isInstant = false) {\n for (let index = this._activeSubmenus.length - 1; index >= level; index--) {\n const submenu = this._activeSubmenus[index]\n const item = this._activeSubmenuItems[index]\n item?.removeAttribute('active')\n if (!item || isInstant) {\n if (submenu) overlayComposition.unregisterPanel(submenu.panel)\n this._restoreSubmenuItems(submenu, item)\n submenu.panel.remove()\n } else {\n this._closingSubmenus.closeAsync(item, submenu)\n }\n }\n this._activeSubmenus.length = level\n this._activeSubmenuItems.length = level\n }\n\n private _restoreSubmenuItems(submenu: MenuPortalOverlay, item?: HTMLElement) {\n if (!item) return\n moveMenuChildren(submenu.content, item)\n // 子菜单打开期间宿主可能重建了嵌套子项,归还时补隐藏,避免可见叠加。\n hideNestedMenuChildren(item, 'context-menu-hidden')\n }\n\n private _getItemLevel(item: HTMLElement): number {\n const menu = this._menu\n if (menu?.panel.contains(item)) return 0\n const parentLevel = this._activeSubmenus.findIndex(submenu => submenu.panel.contains(item))\n return parentLevel === -1 ? -1 : parentLevel + 1\n }\n\n private _positionSubmenu(item: HTMLElement, submenu: MenuPortalOverlay) {\n // 与主菜单同因:panel 进入 open native dialog 后处于 transformed containing\n // block,viewport 坐标的 left/top 会相对 dialog padding box 解析而整体偏移,\n // 需改走 Floating UI 换算为 dialog 相对坐标;开合方向仍按视口坐标度量预判。\n if (submenu.panel.parentElement instanceof HTMLDialogElement && submenu.panel.parentElement.open) {\n const itemRect = item.getBoundingClientRect()\n const padding = 8\n const canOpenRight = itemRect.right + submenu.panel.getBoundingClientRect().width + padding <= window.innerWidth\n // 同帧关闭→重开会复用同一 panel 产生两个 in-flight 定位 promise,完成序不保证\n // 后者胜出;按 panel 键控的代数 token 只允许最新一次调用写入,迟到旧 promise 丢弃。\n const epoch = (this._submenuPositionEpochs.get(submenu.panel) ?? 0) + 1\n this._submenuPositionEpochs.set(submenu.panel, epoch)\n void computePosition(item, submenu.panel, {\n strategy: 'fixed',\n placement: canOpenRight ? 'right-start' : 'left-start',\n middleware: [shift({ padding, crossAxis: true })]\n }).then(({ x, y, middlewareData }) => {\n if (!this._activeSubmenus.includes(submenu) || epoch !== this._submenuPositionEpochs.get(submenu.panel)) return\n // 与主菜单 dialog 路径一致:origin 由 shift 增量推导,视口预判只决定 placement。\n const shiftX = middlewareData.shift?.x ?? 0\n const shiftY = middlewareData.shift?.y ?? 0\n const horizontalOrigin = shiftX < 0 ? 'right' : 'left'\n const verticalOrigin = shiftY < 0 ? 'bottom' : 'top'\n submenu.panel.style.left = `${x}px`\n submenu.panel.style.top = `${y}px`\n submenu.panel.style.setProperty(\n '--wui-internal-overlay-transform-origin',\n `${verticalOrigin} ${horizontalOrigin}`\n )\n submenu.panel.style.visibility = ''\n })\n return\n }\n\n const itemRect = item.getBoundingClientRect()\n const submenuRect = submenu.panel.getBoundingClientRect()\n const padding = 8\n const canOpenRight = itemRect.right + submenuRect.width + padding <= window.innerWidth\n const left = canOpenRight ? itemRect.right : Math.max(padding, itemRect.left - submenuRect.width)\n const top = Math.min(Math.max(padding, itemRect.top), window.innerHeight - submenuRect.height - padding)\n\n submenu.panel.style.left = `${left}px`\n submenu.panel.style.top = `${top}px`\n submenu.panel.style.setProperty('--wui-internal-overlay-transform-origin', canOpenRight ? 'top left' : 'top right')\n submenu.panel.style.visibility = ''\n }\n\n private _dispatchChange(open: boolean) {\n dispatchOpenChangeEvent(this, open)\n }\n\n private _onContextMenu = (e: MouseEvent) => {\n if (this.disabled) return\n e.preventDefault()\n this._restoreFocusTarget = e.target instanceof HTMLElement ? e.target : undefined\n if (this._openAt(e.clientX, e.clientY, false)) this._userOpenChange.mark()\n }\n\n private _onContextMenuOutside = (e: MouseEvent) => {\n if (this._isOpen && !this._outsideClickGuard.isInside(e)) {\n this._closeFromUser()\n }\n }\n\n private _onKeydown = (e: KeyboardEvent) => {\n if (this.disabled) return\n\n // 键盘 ContextMenu 键或 Shift+F10\n if (e.key === 'ContextMenu' || (e.shiftKey && e.key === 'F10')) {\n e.preventDefault()\n const focused = document.activeElement\n if (focused && focused !== document.body) {\n const rect = focused.getBoundingClientRect()\n if (this._openAt(rect.left, rect.bottom, true)) this._userOpenChange.mark()\n } else {\n if (this._openAt(window.innerWidth / 2, window.innerHeight / 2, true)) this._userOpenChange.mark()\n }\n return\n }\n }\n\n private _onClickOutside = (e: MouseEvent) => {\n if (!this._isOpen || this._outsideClickGuard.isArmed()) return\n if (this._outsideClickGuard.isInside(e)) return\n this._closeFromUser()\n }\n\n private _onMenuClick = (e: MouseEvent) => {\n const item = getMenuItemFromEvent(e)\n if (!item || item.hasAttribute('disabled')) return\n if (item.hasAttribute('submenu')) {\n this._openSubmenu(item)\n return\n }\n this._closeFromUser()\n }\n\n private _getLevelContainer(level: number) {\n return level === 0 ? this._menu : this._activeSubmenus[level - 1]\n }\n\n private _getLevelItems(level: number): HTMLElement[] {\n const container = this._getLevelContainer(level)\n if (!container) return []\n return getMenuChildren(container.content)\n }\n\n private _onWheel = (e: WheelEvent) => {\n this._preventBackgroundScroll(e)\n }\n\n private _onTouchMove = (e: TouchEvent) => {\n this._preventBackgroundScroll(e)\n }\n\n private _onDocumentKeydown = (e: KeyboardEvent) => {\n if (!this._isOpen) return\n // 鼠标右键打开的菜单焦点不在菜单内,e.target !== this 时也必须能 Escape 关闭;\n // 菜单为模态浮层,按 Escape 即关闭,无需限定焦点位置\n handleMenuKeyboard(this._keyboardDelegate, e)\n }\n\n private _closeLastSubmenuOrMenu() {\n if (this._activeSubmenus.length > 0) {\n const level = this._activeSubmenus.length - 1\n const parent = this._activeSubmenuItems[level]\n this._closeSubmenusFrom(level)\n focusMenuItem(parent)\n this._hoverBinder.bind()\n } else {\n this._closeFromUser()\n }\n }\n\n private _preventBackgroundScroll(e: Event) {\n if (!this._isOpen || this.noScrollLock || this._isMenuPanelEvent(e)) return\n e.preventDefault()\n }\n\n private _syncScrollLock(isOpen = this._isOpen) {\n this._scrollLock.sync(isOpen && !this.noScrollLock)\n }\n\n private _isMenuPanelEvent(e: Event): boolean {\n const panels = [this._menu?.panel, ...this._activeSubmenus.map(menu => menu.panel)].filter(\n (panel): panel is HTMLElement => panel instanceof HTMLElement\n )\n return panels.some(panel => overlayComposition.containsEvent(panel, e))\n }\n\n override render() {\n return html`\n <div class=\"context-menu-anchor\">\n <slot @slotchange=${this._onSlotChange}></slot>\n </div>\n `\n }\n\n private _onSlotChange() {\n this._hideMenuItems()\n // 打开期间宿主重建顶层项时,新成员要移入 portal 才对用户可见;\n // 关闭状态下无需移动,等下次打开时由 _setupMenuItems 统一处理。\n if (this._isOpen) this._scheduleRefresh()\n }\n\n declare readonly $events: {\n 'open-change': CustomEvent<{ open: boolean }>\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'web-ui-context-menu': WebUiContextMenu\n }\n}\n"],"mappings":"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"}
|