@greypan/web-ui 10.0.0 → 10.1.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.
Files changed (41) hide show
  1. package/README.CN.md +29 -0
  2. package/README.md +31 -0
  3. package/dist/components/autocomplete/index.js.map +1 -1
  4. package/dist/components/avatar/index.js +5 -5
  5. package/dist/components/avatar/index.js.map +1 -1
  6. package/dist/components/back-top/index.js.map +1 -1
  7. package/dist/components/badge/index.js +5 -5
  8. package/dist/components/button/index.js +5 -5
  9. package/dist/components/button/index.js.map +1 -1
  10. package/dist/components/checkbox/index.js.map +1 -1
  11. package/dist/components/context-menu/index.js +65 -65
  12. package/dist/components/dialog/index.js.map +1 -1
  13. package/dist/components/drawer/index.js.map +1 -1
  14. package/dist/components/dropdown-item/index.js.map +1 -1
  15. package/dist/components/editable-text/index.js +4 -4
  16. package/dist/components/empty/index.js.map +1 -1
  17. package/dist/components/image-preview/index.js.map +1 -1
  18. package/dist/components/input/index.js +5 -5
  19. package/dist/components/input/index.js.map +1 -1
  20. package/dist/components/input-number/index.js.map +1 -1
  21. package/dist/components/layout/index.js.map +1 -1
  22. package/dist/components/option/index.js.map +1 -1
  23. package/dist/components/select/index.js.map +1 -1
  24. package/dist/components/switch/index.js.map +1 -1
  25. package/dist/components/textarea/index.js +8 -8
  26. package/dist/components/textarea/index.js.map +1 -1
  27. package/dist/components/toast/toast.js.map +1 -1
  28. package/dist/scrollbars/index.js.map +1 -1
  29. package/dist/shared/overlay/overlay.js +33 -33
  30. package/dist/vite/index.d.ts +28 -0
  31. package/dist/vite/index.js +16 -0
  32. package/dist/vite/index.js.map +1 -0
  33. package/package.json +5 -1
  34. package/dist/node_modules/.pnpm/@floating-ui_core@1.8.0/node_modules/@floating-ui/core/dist/floating-ui.core.js +0 -246
  35. package/dist/node_modules/.pnpm/@floating-ui_core@1.8.0/node_modules/@floating-ui/core/dist/floating-ui.core.js.map +0 -1
  36. package/dist/node_modules/.pnpm/@floating-ui_dom@1.8.0/node_modules/@floating-ui/dom/dist/floating-ui.dom.js +0 -324
  37. package/dist/node_modules/.pnpm/@floating-ui_dom@1.8.0/node_modules/@floating-ui/dom/dist/floating-ui.dom.js.map +0 -1
  38. package/dist/node_modules/.pnpm/@floating-ui_utils@0.2.12/node_modules/@floating-ui/utils/dist/floating-ui.utils.dom.js +0 -100
  39. package/dist/node_modules/.pnpm/@floating-ui_utils@0.2.12/node_modules/@floating-ui/utils/dist/floating-ui.utils.dom.js.map +0 -1
  40. package/dist/node_modules/.pnpm/@floating-ui_utils@0.2.12/node_modules/@floating-ui/utils/dist/floating-ui.utils.js +0 -102
  41. package/dist/node_modules/.pnpm/@floating-ui_utils@0.2.12/node_modules/@floating-ui/utils/dist/floating-ui.utils.js.map +0 -1
@@ -1,24 +1,24 @@
1
1
  import e from "../../_virtual/_@oxc-project_runtime@0.149.0/helpers/esm/decorate.js";
2
2
  import { normalizeNumber as t } from "../../shared/normalize/index.js";
3
3
  import { dispatchOpenChangeEvent as n } from "../../shared/open-state/index.js";
4
- import { computePosition as r, flip as i, shift as a } from "../../node_modules/.pnpm/@floating-ui_dom@1.8.0/node_modules/@floating-ui/dom/dist/floating-ui.dom.js";
5
- import { defineOverlayPositioningGeneration as o } from "../../shared/overlay/positioning-generation.js";
6
- import { hideOverlayPresence as s, showOverlayPresence as c } from "../../shared/overlay/presence.js";
7
- import { defineOpenOverlay as l } from "../../shared/overlay/open-overlay.js";
8
- import { findNearestTheme as u } from "../../shared/overlay/theme-overlay-scope.js";
9
- import { defineScrollLockLease as d } from "../../shared/scroll-lock/scroll-lock.js";
10
- import { UserChangeController as f } from "../../shared/events/user-change.js";
11
- import { captureFrameworkAnchors as p, findFocusedMenuItem as m, focusMenuItem as h, getMenuChildren as g, getMenuItemFromEvent as _, hideNestedMenuChildren as v, moveMenuChildren as y, orderManagedMenuItems as b, reconcileManagedMenuItems as x, restoreFrameworkAnchors as S, returnManagedMenuItemsToSlot as C } from "../../shared/menu-portal/menu-tree.js";
12
- import { createClosingSubmenuStack as w, createMenuHoverBinder as T, createMenuOutsideClickGuard as E, getEnabledMenuLevelItems as D, getFocusedMenuItemFromPanels as O, handleMenuKeyboard as k } from "../../shared/menu-behavior/index.js";
13
- import { createMenuPortalOverlay as A } from "../../shared/menu-portal/menu-portal.js";
14
- import j from "./scrim.js";
15
- import M from "./style.js";
16
- import { LitElement as N, html as P, unsafeCSS as F } from "lit";
17
- import { customElement as I, property as L, state as R } from "lit/decorators.js";
4
+ import { defineOverlayPositioningGeneration as r } from "../../shared/overlay/positioning-generation.js";
5
+ import { hideOverlayPresence as i, showOverlayPresence as a } from "../../shared/overlay/presence.js";
6
+ import { defineOpenOverlay as o } from "../../shared/overlay/open-overlay.js";
7
+ import { findNearestTheme as s } from "../../shared/overlay/theme-overlay-scope.js";
8
+ import { defineScrollLockLease as c } from "../../shared/scroll-lock/scroll-lock.js";
9
+ import { UserChangeController as l } from "../../shared/events/user-change.js";
10
+ import { captureFrameworkAnchors as u, findFocusedMenuItem as d, focusMenuItem as f, getMenuChildren as p, getMenuItemFromEvent as m, hideNestedMenuChildren as h, moveMenuChildren as g, orderManagedMenuItems as _, reconcileManagedMenuItems as v, restoreFrameworkAnchors as y, returnManagedMenuItemsToSlot as b } from "../../shared/menu-portal/menu-tree.js";
11
+ import { createClosingSubmenuStack as x, createMenuHoverBinder as S, createMenuOutsideClickGuard as C, getEnabledMenuLevelItems as w, getFocusedMenuItemFromPanels as T, handleMenuKeyboard as E } from "../../shared/menu-behavior/index.js";
12
+ import { createMenuPortalOverlay as D } from "../../shared/menu-portal/menu-portal.js";
13
+ import O from "./scrim.js";
14
+ import k from "./style.js";
15
+ import { LitElement as A, html as j, unsafeCSS as M } from "lit";
16
+ import { customElement as N, property as P, state as F } from "lit/decorators.js";
17
+ import { computePosition as I, flip as L, shift as R } from "@floating-ui/dom";
18
18
  //#region src/components/context-menu/index.ts
19
- var z = "wui-context-menu-item", B = 500, V = 5e3, H = 10, U = 1e3, W = "data-wui-menu-scrim", G = 5, K = 8, q = class extends N {
19
+ var z = "wui-context-menu-item", B = 500, V = 5e3, H = 10, U = 1e3, W = "data-wui-menu-scrim", G = 5, K = 8, q = class extends A {
20
20
  constructor(...e) {
21
- super(...e), this.disabled = !1, this.noScrollLock = !1, this.longPress = !1, this._longPressDelay = B, this._isOpen = !1, this._x = 0, this._y = 0, this._activeSubmenus = [], this._activeSubmenuItems = [], this._longPressOpenedAt = null, this._submenuPositionEpochs = /* @__PURE__ */ new WeakMap(), this._centerOnPressPoint = !1, this._closeSource = "default", this._menuHandle = null, this._submenuHandles = /* @__PURE__ */ new Map(), this._outsideClickGuard = E(this, (e) => this._menuHandle?.contains(e) ?? !1), this._closingSubmenus = w({
21
+ super(...e), this.disabled = !1, this.noScrollLock = !1, this.longPress = !1, this._longPressDelay = B, this._isOpen = !1, this._x = 0, this._y = 0, this._activeSubmenus = [], this._activeSubmenuItems = [], this._longPressOpenedAt = null, this._submenuPositionEpochs = /* @__PURE__ */ new WeakMap(), this._centerOnPressPoint = !1, this._closeSource = "default", this._menuHandle = null, this._submenuHandles = /* @__PURE__ */ new Map(), this._outsideClickGuard = C(this, (e) => this._menuHandle?.contains(e) ?? !1), this._closingSubmenus = x({
22
22
  getPanel: (e) => e.panel,
23
23
  restoreItems: (e, t) => this._restoreSubmenuItems(e, t),
24
24
  dispose: (e) => {
@@ -33,13 +33,13 @@ var z = "wui-context-menu-item", B = 500, V = 5e3, H = 10, U = 1e3, W = "data-wu
33
33
  closeFrom: (e) => {
34
34
  this._closeSubmenusFrom(e), this._hoverBinder.bind();
35
35
  }
36
- }, this._hoverBinder = T(this._hoverDelegate, "web-ui-dropdown-item"), this._keyboardDelegate = {
37
- getFocusedItem: (e) => O(e, [this._menu?.content, ...this._activeSubmenus.map((e) => e.content)], "web-ui-dropdown-item"),
36
+ }, this._hoverBinder = S(this._hoverDelegate, "web-ui-dropdown-item"), this._keyboardDelegate = {
37
+ getFocusedItem: (e) => T(e, [this._menu?.content, ...this._activeSubmenus.map((e) => e.content)], "web-ui-dropdown-item"),
38
38
  getLevelOf: (e) => {
39
39
  let t = this._getItemLevel(e);
40
40
  return t === -1 ? void 0 : t;
41
41
  },
42
- getEnabledItems: (e) => D(this._getLevelContainer(e)?.content),
42
+ getEnabledItems: (e) => w(this._getLevelContainer(e)?.content),
43
43
  isSubmenuItem: (e) => e.hasAttribute("submenu"),
44
44
  openSubmenuInstant: (e) => this._openSubmenu(e, !0),
45
45
  closeToParent: (e) => {
@@ -47,10 +47,10 @@ var z = "wui-context-menu-item", B = 500, V = 5e3, H = 10, U = 1e3, W = "data-wu
47
47
  return this._closeSubmenusFrom(e - 1), this._hoverBinder.bind(), t;
48
48
  },
49
49
  closeDeepestOrAll: () => this._closeLastSubmenuOrMenu()
50
- }, this._overlay = l().make({
50
+ }, this._overlay = o().make({
51
51
  requestClose: () => this._keyboardDelegate.closeDeepestOrAll(),
52
52
  isConnected: () => this.isConnected
53
- }), this._menuItemAnchors = /* @__PURE__ */ new Map(), this._scrollLock = d().make(), this._userOpenChange = new f(), this._shouldOpenInstantly = !0, this._suppressInitialFocusVisible = !0, this._refreshScheduled = !1, this._menuPositionGeneration = o().make(), this._contentObserver = new MutationObserver(() => {
53
+ }), this._menuItemAnchors = /* @__PURE__ */ new Map(), this._scrollLock = c().make(), this._userOpenChange = new l(), this._shouldOpenInstantly = !0, this._suppressInitialFocusVisible = !0, this._refreshScheduled = !1, this._menuPositionGeneration = r().make(), this._contentObserver = new MutationObserver(() => {
54
54
  this._isOpen && this._scheduleRefresh();
55
55
  }), this._closeFromUser = (e = "default") => {
56
56
  this._isOpen && (this._userOpenChange.mark(), this._closeSource = e, this.close());
@@ -96,7 +96,7 @@ var z = "wui-context-menu-item", B = 500, V = 5e3, H = 10, U = 1e3, W = "data-wu
96
96
  return;
97
97
  }
98
98
  }, this._onMenuClick = (e) => {
99
- let t = _(e);
99
+ let t = m(e);
100
100
  if (t && !t.hasAttribute("disabled")) {
101
101
  if (t.hasAttribute("submenu")) {
102
102
  this._openSubmenu(t);
@@ -109,11 +109,11 @@ var z = "wui-context-menu-item", B = 500, V = 5e3, H = 10, U = 1e3, W = "data-wu
109
109
  }, this._onTouchMove = (e) => {
110
110
  this._preventBackgroundScroll(e);
111
111
  }, this._onDocumentKeydown = (e) => {
112
- this._isOpen && k(this._keyboardDelegate, e);
112
+ this._isOpen && E(this._keyboardDelegate, e);
113
113
  };
114
114
  }
115
115
  static {
116
- this.styles = F(M);
116
+ this.styles = M(k);
117
117
  }
118
118
  get longPressDelay() {
119
119
  return this._longPressDelay;
@@ -146,7 +146,7 @@ var z = "wui-context-menu-item", B = 500, V = 5e3, H = 10, U = 1e3, W = "data-wu
146
146
  if (this._isOpen) {
147
147
  if (this._syncScrollLock(), !this._menu) {
148
148
  let e = this._openScrim();
149
- this._menu = A("context-menu", this, e), this._menu.panel.setAttribute("role", "menu"), this._menu.panel.setAttribute("aria-label", "上下文菜单"), this._menu.panel.addEventListener("click", this._onMenuClick);
149
+ this._menu = D("context-menu", this, e), this._menu.panel.setAttribute("role", "menu"), this._menu.panel.setAttribute("aria-label", "上下文菜单"), this._menu.panel.addEventListener("click", this._onMenuClick);
150
150
  }
151
151
  if (!this._menuHandle) {
152
152
  this._menuHandle = this._overlay.claim(this._menu.panel);
@@ -157,7 +157,7 @@ var z = "wui-context-menu-item", B = 500, V = 5e3, H = 10, U = 1e3, W = "data-wu
157
157
  childList: !0,
158
158
  subtree: !0
159
159
  }), requestAnimationFrame(() => {
160
- this._isOpen && this._menu && (this._refreshMenu(), c(this._menu.panel, { isInstant: this._shouldOpenInstantly }), this._shouldOpenInstantly = !0, requestAnimationFrame(() => {
160
+ this._isOpen && this._menu && (this._refreshMenu(), a(this._menu.panel, { isInstant: this._shouldOpenInstantly }), this._shouldOpenInstantly = !0, requestAnimationFrame(() => {
161
161
  this._isOpen && this._menu && this._focusFirstItem();
162
162
  }));
163
163
  });
@@ -188,20 +188,20 @@ var z = "wui-context-menu-item", B = 500, V = 5e3, H = 10, U = 1e3, W = "data-wu
188
188
  if (!e) return;
189
189
  let t = this._safeAreaBottom();
190
190
  e.style.visibility = "hidden", e.style.display = "";
191
- let n = this._menuPositionGeneration.next(), o = {
191
+ let n = this._menuPositionGeneration.next(), r = {
192
192
  top: K,
193
193
  bottom: K + t,
194
194
  left: K,
195
195
  right: K
196
- }, s = this._centerOnPressPoint ? ["bottom", "top"] : ["bottom-start", "top-start"];
197
- r({ getBoundingClientRect: () => new DOMRect(this._x, this._y, 0, 0) }, e, {
196
+ }, i = this._centerOnPressPoint ? ["bottom", "top"] : ["bottom-start", "top-start"];
197
+ I({ getBoundingClientRect: () => new DOMRect(this._x, this._y, 0, 0) }, e, {
198
198
  strategy: "fixed",
199
- placement: s[0],
200
- middleware: [i({
201
- fallbackPlacements: [...s],
202
- padding: o
203
- }), a({
204
- padding: o,
199
+ placement: i[0],
200
+ middleware: [L({
201
+ fallbackPlacements: [...i],
202
+ padding: r
203
+ }), R({
204
+ padding: r,
205
205
  crossAxis: !0
206
206
  })]
207
207
  }).then(({ x: t, y: r, placement: i, middlewareData: a }) => {
@@ -219,7 +219,7 @@ var z = "wui-context-menu-item", B = 500, V = 5e3, H = 10, U = 1e3, W = "data-wu
219
219
  }
220
220
  _focusFirstItem(e = 0) {
221
221
  let t = this._menu?.content.querySelectorAll("web-ui-dropdown-item:not([disabled])")?.[0];
222
- t && (h(t, { suppressFocusVisible: this._suppressInitialFocusVisible }), !(e + 1 >= G) && (m([this._menu?.panel]) || requestAnimationFrame(() => {
222
+ t && (f(t, { suppressFocusVisible: this._suppressInitialFocusVisible }), !(e + 1 >= G) && (d([this._menu?.panel]) || requestAnimationFrame(() => {
223
223
  this._isOpen && this._menu && this._focusFirstItem(e + 1);
224
224
  })));
225
225
  }
@@ -227,22 +227,22 @@ var z = "wui-context-menu-item", B = 500, V = 5e3, H = 10, U = 1e3, W = "data-wu
227
227
  let e = this._menu;
228
228
  if (!e) return;
229
229
  let t = e.content;
230
- x(this, t, this._menuItemAnchors, z), this._hideMenuItems(), v(t, "context-menu-hidden");
231
- let n = p(t, z);
232
- b(this, t, this._menuItemAnchors, z), S(t, n);
230
+ v(this, t, this._menuItemAnchors, z), this._hideMenuItems(), h(t, "context-menu-hidden");
231
+ let n = u(t, z);
232
+ _(this, t, this._menuItemAnchors, z), y(t, n);
233
233
  }
234
234
  _returnItemsToSlot() {
235
235
  let e = this._menu;
236
- e && (this._closeSubmenusFrom(0, !0), this._closingSubmenus.restoreAll(), C(this, e.content, this._menuItemAnchors));
236
+ e && (this._closeSubmenusFrom(0, !0), this._closingSubmenus.restoreAll(), b(this, e.content, this._menuItemAnchors));
237
237
  }
238
238
  _openScrim() {
239
239
  let e = document.createElement("dialog");
240
240
  e.className = "wui-context-menu-scrim";
241
241
  let t = document.createElement("style");
242
- return t.textContent = j, e.append(t), e.setAttribute(W, ""), e.addEventListener("click", this._onScrimClick), e.addEventListener("cancel", this._onScrimCancel), this._scrimParent().append(e), e.showModal(), this._scrim = e, e;
242
+ return t.textContent = O, e.append(t), e.setAttribute(W, ""), e.addEventListener("click", this._onScrimClick), e.addEventListener("cancel", this._onScrimCancel), this._scrimParent().append(e), e.showModal(), this._scrim = e, e;
243
243
  }
244
244
  _scrimParent() {
245
- return u(this)?.getOverlayRoot() ?? document.body;
245
+ return s(this)?.getOverlayRoot() ?? document.body;
246
246
  }
247
247
  _closeScrim() {
248
248
  let e = this._scrim;
@@ -254,10 +254,10 @@ var z = "wui-context-menu-item", B = 500, V = 5e3, H = 10, U = 1e3, W = "data-wu
254
254
  }
255
255
  async _closeMenuAfterPresence() {
256
256
  let e = this._menu;
257
- (!e || await s(e.panel)) && !this._isOpen && this.isConnected && this._menu === e && (this._closeScrim(), this._returnItemsToSlot(), e?.panel.remove(), this._menu = void 0);
257
+ (!e || await i(e.panel)) && !this._isOpen && this.isConnected && this._menu === e && (this._closeScrim(), this._returnItemsToSlot(), e?.panel.remove(), this._menu = void 0);
258
258
  }
259
259
  _hideMenuItems() {
260
- g(this).forEach((e) => e.setAttribute("slot", "context-menu-hidden")), v(this, "context-menu-hidden");
260
+ p(this).forEach((e) => e.setAttribute("slot", "context-menu-hidden")), h(this, "context-menu-hidden");
261
261
  }
262
262
  _openSubmenu(e, t = !1) {
263
263
  if (!this._isOpen || !e.hasAttribute("submenu") || e.hasAttribute("disabled")) return;
@@ -266,12 +266,12 @@ var z = "wui-context-menu-item", B = 500, V = 5e3, H = 10, U = 1e3, W = "data-wu
266
266
  this._closeSubmenusFrom(n);
267
267
  let r = this._closingSubmenus.take(e);
268
268
  if (r) {
269
- this._activeSubmenus[n] = r, this._activeSubmenuItems[n] = e, this._menuHandle && this._submenuHandles.set(r.panel, this._menuHandle.adopt(r.panel)), e.setAttribute("active", ""), this._positionSubmenu(e, r), c(r.panel, { isInstant: t }), this._hoverBinder.bind();
269
+ this._activeSubmenus[n] = r, this._activeSubmenuItems[n] = e, this._menuHandle && this._submenuHandles.set(r.panel, this._menuHandle.adopt(r.panel)), e.setAttribute("active", ""), this._positionSubmenu(e, r), a(r.panel, { isInstant: t }), this._hoverBinder.bind();
270
270
  return;
271
271
  }
272
- if (g(e).length === 0) return;
273
- let i = A("context-submenu", this, this._scrim);
274
- i.panel.dataset.level = String(n), i.panel.setAttribute("role", "menu"), i.panel.setAttribute("aria-label", "子菜单"), i.panel.style.visibility = "hidden", i.panel.addEventListener("click", this._onMenuClick), y(e, i.content), this._activeSubmenus[n] = i, this._activeSubmenuItems[n] = e, this._menuHandle && this._submenuHandles.set(i.panel, this._menuHandle.adopt(i.panel)), e.setAttribute("active", ""), this._positionSubmenu(e, i), c(i.panel, { isInstant: t }), this._hoverBinder.bind();
272
+ if (p(e).length === 0) return;
273
+ let i = D("context-submenu", this, this._scrim);
274
+ i.panel.dataset.level = String(n), i.panel.setAttribute("role", "menu"), i.panel.setAttribute("aria-label", "子菜单"), i.panel.style.visibility = "hidden", i.panel.addEventListener("click", this._onMenuClick), g(e, i.content), this._activeSubmenus[n] = i, this._activeSubmenuItems[n] = e, this._menuHandle && this._submenuHandles.set(i.panel, this._menuHandle.adopt(i.panel)), e.setAttribute("active", ""), this._positionSubmenu(e, i), a(i.panel, { isInstant: t }), this._hoverBinder.bind();
275
275
  }
276
276
  _closeSubmenusFrom(e, t = !1) {
277
277
  for (let n = this._activeSubmenus.length - 1; n >= e; n--) {
@@ -281,7 +281,7 @@ var z = "wui-context-menu-item", B = 500, V = 5e3, H = 10, U = 1e3, W = "data-wu
281
281
  this._activeSubmenus.length = e, this._activeSubmenuItems.length = e;
282
282
  }
283
283
  _restoreSubmenuItems(e, t) {
284
- t && (y(e.content, t), v(t, "context-menu-hidden"));
284
+ t && (g(e.content, t), h(t, "context-menu-hidden"));
285
285
  }
286
286
  _getItemLevel(e) {
287
287
  if (this._menu?.panel.contains(e)) return 0;
@@ -290,23 +290,23 @@ var z = "wui-context-menu-item", B = 500, V = 5e3, H = 10, U = 1e3, W = "data-wu
290
290
  }
291
291
  _positionSubmenu(e, t) {
292
292
  if (t.panel.parentElement instanceof HTMLDialogElement && t.panel.parentElement.open) {
293
- let n = e.getBoundingClientRect().right + t.panel.getBoundingClientRect().width + 8 <= window.innerWidth, i = (this._submenuPositionEpochs.get(t.panel) ?? 0) + 1;
294
- this._submenuPositionEpochs.set(t.panel, i), r(e, t.panel, {
293
+ let n = e.getBoundingClientRect().right + t.panel.getBoundingClientRect().width + 8 <= window.innerWidth, r = (this._submenuPositionEpochs.get(t.panel) ?? 0) + 1;
294
+ this._submenuPositionEpochs.set(t.panel, r), I(e, t.panel, {
295
295
  strategy: "fixed",
296
296
  placement: n ? "right-start" : "left-start",
297
- middleware: [a({
297
+ middleware: [R({
298
298
  padding: 8,
299
299
  crossAxis: !0
300
300
  })]
301
- }).then(({ x: e, y: n, middlewareData: r }) => {
302
- if (!this._activeSubmenus.includes(t) || i !== this._submenuPositionEpochs.get(t.panel)) return;
303
- let a = r.shift?.x ?? 0, o = r.shift?.y ?? 0, s = a < 0 ? "right" : "left", c = o < 0 ? "bottom" : "top";
301
+ }).then(({ x: e, y: n, middlewareData: i }) => {
302
+ if (!this._activeSubmenus.includes(t) || r !== this._submenuPositionEpochs.get(t.panel)) return;
303
+ let a = i.shift?.x ?? 0, o = i.shift?.y ?? 0, s = a < 0 ? "right" : "left", c = o < 0 ? "bottom" : "top";
304
304
  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 = "";
305
305
  });
306
306
  return;
307
307
  }
308
- let n = e.getBoundingClientRect(), i = t.panel.getBoundingClientRect(), o = n.right + i.width + 8 <= window.innerWidth, s = o ? n.right : Math.max(8, n.left - i.width), c = Math.min(Math.max(8, n.top), window.innerHeight - i.height - 8);
309
- 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 = "";
308
+ let n = e.getBoundingClientRect(), r = t.panel.getBoundingClientRect(), i = n.right + r.width + 8 <= window.innerWidth, a = i ? n.right : Math.max(8, n.left - r.width), o = Math.min(Math.max(8, n.top), window.innerHeight - r.height - 8);
309
+ t.panel.style.left = `${a}px`, t.panel.style.top = `${o}px`, t.panel.style.setProperty("--wui-internal-overlay-transform-origin", i ? "top left" : "top right"), t.panel.style.visibility = "";
310
310
  }
311
311
  _dispatchChange(e) {
312
312
  n(this, e);
@@ -323,12 +323,12 @@ var z = "wui-context-menu-item", B = 500, V = 5e3, H = 10, U = 1e3, W = "data-wu
323
323
  }
324
324
  _getLevelItems(e) {
325
325
  let t = this._getLevelContainer(e);
326
- return t ? g(t.content) : [];
326
+ return t ? p(t.content) : [];
327
327
  }
328
328
  _closeLastSubmenuOrMenu() {
329
329
  if (this._activeSubmenus.length > 0) {
330
330
  let e = this._activeSubmenus.length - 1, t = this._activeSubmenuItems[e];
331
- this._closeSubmenusFrom(e), h(t), this._hoverBinder.bind();
331
+ this._closeSubmenusFrom(e), f(t), this._hoverBinder.bind();
332
332
  } else this._closeFromUser();
333
333
  }
334
334
  _preventBackgroundScroll(e) {
@@ -344,7 +344,7 @@ var z = "wui-context-menu-item", B = 500, V = 5e3, H = 10, U = 1e3, W = "data-wu
344
344
  return this._menuHandle?.containsEvent(e) ?? !1;
345
345
  }
346
346
  render() {
347
- return P`
347
+ return j`
348
348
  <div class="context-menu-anchor">
349
349
  <slot @slotchange=${this._onSlotChange}></slot>
350
350
  </div>
@@ -354,21 +354,21 @@ var z = "wui-context-menu-item", B = 500, V = 5e3, H = 10, U = 1e3, W = "data-wu
354
354
  this._hideMenuItems(), this._isOpen && this._scheduleRefresh();
355
355
  }
356
356
  };
357
- e([L({
357
+ e([P({
358
358
  type: Boolean,
359
359
  reflect: !0
360
- })], q.prototype, "disabled", void 0), e([L({
360
+ })], q.prototype, "disabled", void 0), e([P({
361
361
  type: Boolean,
362
362
  reflect: !0,
363
363
  attribute: "no-scroll-lock"
364
- })], q.prototype, "noScrollLock", void 0), e([L({
364
+ })], q.prototype, "noScrollLock", void 0), e([P({
365
365
  type: Boolean,
366
366
  reflect: !0,
367
367
  attribute: "long-press"
368
- })], q.prototype, "longPress", void 0), e([L({
368
+ })], q.prototype, "longPress", void 0), e([P({
369
369
  type: Number,
370
370
  attribute: "long-press-delay"
371
- })], q.prototype, "longPressDelay", null), e([R()], q.prototype, "_isOpen", void 0), e([R()], q.prototype, "_x", void 0), e([R()], q.prototype, "_y", void 0), q = e([I("web-ui-context-menu")], q);
371
+ })], q.prototype, "longPressDelay", null), e([F()], q.prototype, "_isOpen", void 0), e([F()], q.prototype, "_x", void 0), e([F()], q.prototype, "_y", void 0), q = e([N("web-ui-context-menu")], q);
372
372
  //#endregion
373
373
  export { q as WebUiContextMenu };
374
374
 
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../src/components/dialog/index.ts"],"sourcesContent":["import { html, LitElement, nothing, type PropertyValues, unsafeCSS } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\n\nimport '@/components/icon'\nimport '@/components/button'\nimport glass from '@/assets/glass.css?inline'\nimport modalSurface from '@/assets/modal-surface.css?inline'\nimport { oouiClose } from '@/icons'\nimport { UserChangeController } from '@/shared/events/user-change'\nimport { dispatchOpenChangeEvent } from '@/shared/open-state'\nimport { defineNativeDialogPresence } from '@/shared/overlay/native-dialog-presence'\nimport { defineOpenOverlay, type OpenOverlayHandle } from '@/shared/overlay/open-overlay'\nimport { defineScrollLockLease } from '@/shared/scroll-lock/scroll-lock'\n\nimport style from './style.css?inline'\n\n@customElement('web-ui-dialog')\nexport class WebUiDialog extends LitElement {\n static override styles = [unsafeCSS(glass), unsafeCSS(modalSurface), unsafeCSS(style)]\n\n @property({ type: Boolean, reflect: true }) open = false\n @property({ type: Boolean, reflect: true }) closable = false\n @property({ type: Boolean, reflect: true, attribute: 'no-scroll-lock' }) noScrollLock = false\n @property({ type: Boolean, reflect: true, attribute: 'no-backdrop-close' }) noBackdropClose = false\n @property({ type: Boolean, reflect: true, attribute: 'no-escape-close' }) noEscapeClose = false\n\n /**\n * Controlled 模式下,Escape 和遮罩点击只派发 `open-change` 请求,\n * 不会自行修改 `open`。Consumer 回写 `open` 后才执行关闭动画。\n * 程序化 API(showModal/close/直接赋值 open)不受此模式影响,始终直通。\n */\n @property({ type: Boolean, reflect: true }) controlled = false\n\n /**\n * `header` 槽为空时的标题文案。槽优先:一旦有元素分配到 `header`,槽内容整条接管,\n * 属性被忽略。默认空串且槽也为空时不渲染 chrome 带。`headless` 模式不渲染 chrome 带,\n * `heading` 一并失效。\n */\n @property({ type: String }) heading = ''\n\n /**\n * Headless 模式:只保留 overlay 基础设施(backdrop、动画、scroll lock、`<dialog>` 语义),\n * 移除内置 UI(chrome 带、正文区、footer),默认槽的内容渲染进卡片内的滚动层\n * `.wui-dialog-content`,视觉交给 Consumer。形态与 `<web-ui-drawer>` 的 `headless` 一致。\n *\n * 该模式没有可自动关联的内置标题,内部原生 dialog 的 accessible name 必须由 Consumer\n * 用 `dialog-label`(或自绘标题 + 自己的 `aria-labelledby`)提供。\n */\n @property({ type: Boolean, reflect: true }) headless = false\n\n /**\n * 内部原生 dialog 的 accessible name。`headless` 模式必须由 Consumer 提供,\n * 因为该模式不会渲染可自动关联的内置 chrome 带。\n */\n @property({ type: String, attribute: 'dialog-label' }) dialogLabel = ''\n\n @state() private _hasHeader = false\n private readonly _userOpenChange = new UserChangeController()\n\n /*\n * 开启态浮层(issue #120 Block 1)。dialog 的 Escape 原本只走原生 cancel 事件:仲裁者\n * 会在 keydown 上 preventDefault 压掉原生关闭请求并 stopPropagation,因此这里必须\n * 自己表达关闭语义(controlled 只派发请求)。\n */\n private readonly _overlay = defineOpenOverlay().make({\n requestClose: () => this._closeFromUser(),\n isConnected: () => this.isConnected\n })\n /** 当前开启会话的句柄;未开启时为 null。查询与惰性同步走它。 */\n private _handle: OpenOverlayHandle | null = null\n private readonly _scrollLock = defineScrollLockLease().make()\n private readonly _presence = defineNativeDialogPresence().make({\n getDialog: () => this.dialog,\n isConnected: () => this.isConnected,\n isOpen: () => this.open\n })\n\n private get dialog() {\n return this.shadowRoot?.querySelector('dialog') ?? null\n }\n\n protected override updated(props: PropertyValues) {\n super.updated(props)\n if (!this.isConnected) return\n\n if (props.has('open')) {\n if (this._userOpenChange.consume()) this.emitOpenChange()\n this._presence.sync(this.open)\n if (this.open) {\n // presence.sync 内的 showModal() 把 dialog 提升进 top layer。双击手势本身\n // 留下的活选区会被浏览器拿去和提升后的新布局重新解析,结果选区落到刚挂载的\n // dialog 正文上。脆弱的是「手势来源的活选区」,不是 dblclick 的判定窗口:把\n // 打开推迟 250ms(早过双击判定)仍然复现。选区由浏览器在 showModal() 调用\n // 内部生成:脚本没有任何 Selection API 调用,在 dblclick 上 preventDefault\n // 也拦不住。\n //\n // 实测(Chromium)showModal() 不会动打开前已经存在的选区,所以这一次清理\n // 同时也覆盖「先选中页面文本、再打开」的情况——modal 打开后被选中的内容挡在\n // 遮罩后面本来也已不可用。这里只清文档选区,不动 user-select,浮层内正文\n // 仍可正常拖选。\n window.getSelection()?.removeAllRanges()\n }\n // 原生 dialog 登记为开启态浮层:挂在它上面的 portal 面板成为本层后代,\n // Escape 仲裁据此判出最内层(issue #120 Block 1)。\n const dialog = this.dialog\n if (dialog) {\n if (this.open) {\n // 同一面板重新 claim = 新的一次开启:旧会话(含其子层)整体作废。\n this._handle?.release()\n this._handle = this._overlay.claim(dialog, { ancestryFrom: this })\n } else {\n this._handle?.release()\n this._handle = null\n }\n }\n }\n if (props.has('open') || props.has('noScrollLock')) this._syncScrollLock()\n this._syncOverlayInert()\n }\n\n override connectedCallback() {\n super.connectedCallback()\n // 重挂载对账:断连时 presence、滚动锁与登记都已被撤销,而 `open` 未变化时\n // `updated()` 不会补跑任何 sync 分支。首次连接时 shadow 尚未渲染、`this.dialog`\n // 为 null,三种情况都直接跳过;打开态的首次进入仍由 updated() 的\n // `props.has('open')` 分支处理。\n this._presence.reconcile()\n this._syncScrollLock()\n this._reclaimIfOpen()\n }\n\n override disconnectedCallback() {\n super.disconnectedCallback()\n this._presence.dispose()\n this._scrollLock.release()\n // 断连即撤销登记:层不留在全局注册表里,重连后由 _reclaimIfOpen 显式重新声明。\n this._handle?.release()\n this._handle = null\n }\n\n /*\n * 「重挂载恢复」的调用方一半:模块刻意不观察 DOM 连接状态,所以断连撤销登记之后,\n * 重连时仍有开启态就必须由组件重新声明。\n */\n private _reclaimIfOpen() {\n if (!this.open || this._handle) return\n const dialog = this.dialog\n if (!dialog) return\n this._handle = this._overlay.claim(dialog, { ancestryFrom: this })\n this._syncOverlayInert()\n }\n\n /*\n * `no-escape-close` 时 dialog 仍是候选(Escape 被吞掉、原生 cancel 被压掉),只是\n * 不走关闭入口。与旧的「跳过候选」语义不同:旧语义放任事件落到下层浮层,把外层\n * 一起关掉。该属性可在开启期间改写,所以每次渲染后读它,而不是在 claim 时固定。\n */\n private _syncOverlayInert() {\n this._handle?.setInert(this.noEscapeClose)\n }\n\n showModal() {\n if (this.open) return\n this.open = true\n }\n\n close() {\n this.open = false\n }\n\n /*\n * 仲裁者在 capture 阶段 preventDefault 了 Escape 的 keydown,UA 因此不再派发原生\n * cancel,但本 handler 仍有两个仲裁者不负责的职责,**不可删**:\n * ① 任何到达 dialog 的 cancel 都要 preventDefault,把 top layer 保留到视觉退场结束\n * (否则原生关闭会跳过退出动画);\n * ② 忽略子控件(例如 file input)冒泡上来的 cancel。\n * 实测(overlay-open-owner-260918,2026-09-18)摘掉 `@cancel` 后 dialog.browser.spec.ts\n * 的「no-escape-close 存在时 Escape/cancel 不关闭对话框」与 remount-reconcile 的\n * 「打开态被移出文档再接回」两例立刻转红,断言正是 `dispatchEvent(cancel) === false`。\n */\n private handleCancel(e: Event) {\n if (e.target !== e.currentTarget) return\n\n e.preventDefault()\n if (this.noEscapeClose) return\n this._closeFromUser()\n }\n\n private handleBackdropClick(e: MouseEvent) {\n if (e.target !== (e.currentTarget as HTMLDialogElement)) return\n if (this.noBackdropClose) return\n this._closeFromUser()\n }\n\n /** 用户发起的关闭入口(Escape、遮罩点击、关闭按钮)共用一条路径。 */\n private readonly _closeFromUser = () => {\n if (this.controlled) {\n this.emitOpenChange(false)\n return\n }\n this._userOpenChange.mark()\n this.close()\n }\n\n // controlled 下派发关闭请求:detail 固定 false(用户只能请求关闭,打开永远由 Consumer 写)。\n private emitOpenChange(open = this.open) {\n dispatchOpenChangeEvent(this, open)\n }\n\n private _onTransitionEnd = (event: TransitionEvent) => {\n this._presence.handleTransitionEnd(event)\n }\n\n private _onNativeClose = () => {\n // 关闭态下的 close 事件只可能是我们自己 finishClosing 排队的异步事件(或冗余的\n // 外部关闭):交给 presence 消费 self-close 标志,避免标志泄漏到下一次真实关闭。\n if (!this.open) {\n this._presence.handleNativeClose()\n return\n }\n\n // 我们自己 dialog.close() 排队的 close 事件是异步任务:正常时序在本关闭会话内\n // 到达,快速「关闭→重开」时它在重新打开之后才到达(过期事件)。两种情况都已\n // 完成清理,由 presence 消费并返回 true,不能当成外部关闭把刚重开的 dialog 关掉。\n if (this._presence.handleNativeClose()) return\n\n // controlled 下原生关闭(如表单 method=\"dialog\")视为未经 Consumer 批准的状态丢失:\n // 恢复受控状态并派发关闭请求,由 Consumer 决定是否关闭。\n if (this.controlled) {\n this._presence.sync(true)\n this.emitOpenChange(false)\n return\n }\n\n this._userOpenChange.mark()\n this.open = false\n }\n\n private _syncScrollLock(isOpen = this.open) {\n this._scrollLock.sync(isOpen && !this.noScrollLock)\n }\n\n /**\n * 只在「有/无」翻转时写 state:slotchange 在每次分配变化时都会触发,逐次赋值会让\n * Lit 无谓重渲染。`heading` 与槽共同决定 chrome 带的存在,见 `_showHeader`。\n */\n private _onHeaderSlotChange(e: Event) {\n if (!(e.target instanceof HTMLSlotElement)) return\n const has = e.target.assignedElements().length > 0\n if (has !== this._hasHeader) this._hasHeader = has\n }\n\n private get _showHeader(): boolean {\n return this._hasHeader || this.heading !== ''\n }\n\n /**\n * 默认模式与 `headless` 模式共用同一枚关闭按钮:都绝对定位到卡片右上角,偏移由\n * `--wui-dialog-close-top` / `--wui-dialog-close-right` 控制(见 style.css)。\n * 它在两种模式下都是卡片的直接子元素,定位参照是卡片本身(.wui-dialog-body)。\n */\n private _renderCloseButton() {\n return html`\n <web-ui-button\n class=\"wui-dialog-close\"\n @click=${this._closeFromUser}\n aria-label=\"关闭\"\n variant=\"secondary\"\n icon\n size=\"26\"\n >\n <web-ui-icon size=\"14\" .icon=${oouiClose}></web-ui-icon>\n </web-ui-button>\n `\n }\n\n override render() {\n const showHeader = this._showHeader\n /*\n * accessible name:显式 `dialog-label` 优先;否则(非 headless 且带可见时)把原生 dialog\n * 的 `aria-labelledby` 指向 chrome 带——与 drawer 同形。headless 模式没有可自动关联的\n * 内置标题,名字留给 Consumer。\n */\n const dialogLabel = this.dialogLabel.trim()\n const dialogLabelledBy = !dialogLabel && !this.headless && showHeader ? 'wui-dialog-heading' : nothing\n\n return html`\n <dialog\n aria-label=${dialogLabel || nothing}\n aria-labelledby=${dialogLabelledBy}\n @cancel=${this.handleCancel}\n @close=${this._onNativeClose}\n @click=${this.handleBackdropClick}\n @transitionend=${this._onTransitionEnd}\n >\n <div class=\"wui-dialog-body wui-glass\">\n ${\n this.headless\n ? html`\n <div class=\"wui-dialog-content\">\n <slot></slot>\n </div>\n ${this.closable ? this._renderCloseButton() : nothing}\n `\n : html`\n <div class=\"header\" id=\"wui-dialog-heading\" ?hidden=${!showHeader}>\n <slot name=\"header\" @slotchange=${this._onHeaderSlotChange}>\n ${this.heading ? html`<span class=\"wui-dialog-heading\">${this.heading}</span>` : nothing}\n </slot>\n </div>\n <div class=\"desc\"><slot></slot></div>\n <div class=\"wui-dialog-footer\"><slot name=\"footer\"></slot></div>\n ${this.closable ? this._renderCloseButton() : nothing}\n `\n }\n </div>\n </dialog>\n `\n }\n\n declare readonly $events: {\n 'open-change': CustomEvent<{ open: boolean }>\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'web-ui-dialog': WebUiDialog\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../src/components/dialog/index.ts"],"sourcesContent":["import '@/components/button'\nimport '@/components/icon'\n\nimport { html, LitElement, nothing, type PropertyValues, unsafeCSS } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\n\nimport glass from '@/assets/glass.css?inline'\nimport modalSurface from '@/assets/modal-surface.css?inline'\nimport { oouiClose } from '@/icons'\nimport { UserChangeController } from '@/shared/events/user-change'\nimport { dispatchOpenChangeEvent } from '@/shared/open-state'\nimport { defineNativeDialogPresence } from '@/shared/overlay/native-dialog-presence'\nimport { defineOpenOverlay, type OpenOverlayHandle } from '@/shared/overlay/open-overlay'\nimport { defineScrollLockLease } from '@/shared/scroll-lock/scroll-lock'\n\nimport style from './style.css?inline'\n\n@customElement('web-ui-dialog')\nexport class WebUiDialog extends LitElement {\n static override styles = [unsafeCSS(glass), unsafeCSS(modalSurface), unsafeCSS(style)]\n\n @property({ type: Boolean, reflect: true }) open = false\n @property({ type: Boolean, reflect: true }) closable = false\n @property({ type: Boolean, reflect: true, attribute: 'no-scroll-lock' }) noScrollLock = false\n @property({ type: Boolean, reflect: true, attribute: 'no-backdrop-close' }) noBackdropClose = false\n @property({ type: Boolean, reflect: true, attribute: 'no-escape-close' }) noEscapeClose = false\n\n /**\n * Controlled 模式下,Escape 和遮罩点击只派发 `open-change` 请求,\n * 不会自行修改 `open`。Consumer 回写 `open` 后才执行关闭动画。\n * 程序化 API(showModal/close/直接赋值 open)不受此模式影响,始终直通。\n */\n @property({ type: Boolean, reflect: true }) controlled = false\n\n /**\n * `header` 槽为空时的标题文案。槽优先:一旦有元素分配到 `header`,槽内容整条接管,\n * 属性被忽略。默认空串且槽也为空时不渲染 chrome 带。`headless` 模式不渲染 chrome 带,\n * `heading` 一并失效。\n */\n @property({ type: String }) heading = ''\n\n /**\n * Headless 模式:只保留 overlay 基础设施(backdrop、动画、scroll lock、`<dialog>` 语义),\n * 移除内置 UI(chrome 带、正文区、footer),默认槽的内容渲染进卡片内的滚动层\n * `.wui-dialog-content`,视觉交给 Consumer。形态与 `<web-ui-drawer>` 的 `headless` 一致。\n *\n * 该模式没有可自动关联的内置标题,内部原生 dialog 的 accessible name 必须由 Consumer\n * 用 `dialog-label`(或自绘标题 + 自己的 `aria-labelledby`)提供。\n */\n @property({ type: Boolean, reflect: true }) headless = false\n\n /**\n * 内部原生 dialog 的 accessible name。`headless` 模式必须由 Consumer 提供,\n * 因为该模式不会渲染可自动关联的内置 chrome 带。\n */\n @property({ type: String, attribute: 'dialog-label' }) dialogLabel = ''\n\n @state() private _hasHeader = false\n private readonly _userOpenChange = new UserChangeController()\n\n /*\n * 开启态浮层(issue #120 Block 1)。dialog 的 Escape 原本只走原生 cancel 事件:仲裁者\n * 会在 keydown 上 preventDefault 压掉原生关闭请求并 stopPropagation,因此这里必须\n * 自己表达关闭语义(controlled 只派发请求)。\n */\n private readonly _overlay = defineOpenOverlay().make({\n requestClose: () => this._closeFromUser(),\n isConnected: () => this.isConnected\n })\n /** 当前开启会话的句柄;未开启时为 null。查询与惰性同步走它。 */\n private _handle: OpenOverlayHandle | null = null\n private readonly _scrollLock = defineScrollLockLease().make()\n private readonly _presence = defineNativeDialogPresence().make({\n getDialog: () => this.dialog,\n isConnected: () => this.isConnected,\n isOpen: () => this.open\n })\n\n private get dialog() {\n return this.shadowRoot?.querySelector('dialog') ?? null\n }\n\n protected override updated(props: PropertyValues) {\n super.updated(props)\n if (!this.isConnected) return\n\n if (props.has('open')) {\n if (this._userOpenChange.consume()) this.emitOpenChange()\n this._presence.sync(this.open)\n if (this.open) {\n // presence.sync 内的 showModal() 把 dialog 提升进 top layer。双击手势本身\n // 留下的活选区会被浏览器拿去和提升后的新布局重新解析,结果选区落到刚挂载的\n // dialog 正文上。脆弱的是「手势来源的活选区」,不是 dblclick 的判定窗口:把\n // 打开推迟 250ms(早过双击判定)仍然复现。选区由浏览器在 showModal() 调用\n // 内部生成:脚本没有任何 Selection API 调用,在 dblclick 上 preventDefault\n // 也拦不住。\n //\n // 实测(Chromium)showModal() 不会动打开前已经存在的选区,所以这一次清理\n // 同时也覆盖「先选中页面文本、再打开」的情况——modal 打开后被选中的内容挡在\n // 遮罩后面本来也已不可用。这里只清文档选区,不动 user-select,浮层内正文\n // 仍可正常拖选。\n window.getSelection()?.removeAllRanges()\n }\n // 原生 dialog 登记为开启态浮层:挂在它上面的 portal 面板成为本层后代,\n // Escape 仲裁据此判出最内层(issue #120 Block 1)。\n const dialog = this.dialog\n if (dialog) {\n if (this.open) {\n // 同一面板重新 claim = 新的一次开启:旧会话(含其子层)整体作废。\n this._handle?.release()\n this._handle = this._overlay.claim(dialog, { ancestryFrom: this })\n } else {\n this._handle?.release()\n this._handle = null\n }\n }\n }\n if (props.has('open') || props.has('noScrollLock')) this._syncScrollLock()\n this._syncOverlayInert()\n }\n\n override connectedCallback() {\n super.connectedCallback()\n // 重挂载对账:断连时 presence、滚动锁与登记都已被撤销,而 `open` 未变化时\n // `updated()` 不会补跑任何 sync 分支。首次连接时 shadow 尚未渲染、`this.dialog`\n // 为 null,三种情况都直接跳过;打开态的首次进入仍由 updated() 的\n // `props.has('open')` 分支处理。\n this._presence.reconcile()\n this._syncScrollLock()\n this._reclaimIfOpen()\n }\n\n override disconnectedCallback() {\n super.disconnectedCallback()\n this._presence.dispose()\n this._scrollLock.release()\n // 断连即撤销登记:层不留在全局注册表里,重连后由 _reclaimIfOpen 显式重新声明。\n this._handle?.release()\n this._handle = null\n }\n\n /*\n * 「重挂载恢复」的调用方一半:模块刻意不观察 DOM 连接状态,所以断连撤销登记之后,\n * 重连时仍有开启态就必须由组件重新声明。\n */\n private _reclaimIfOpen() {\n if (!this.open || this._handle) return\n const dialog = this.dialog\n if (!dialog) return\n this._handle = this._overlay.claim(dialog, { ancestryFrom: this })\n this._syncOverlayInert()\n }\n\n /*\n * `no-escape-close` 时 dialog 仍是候选(Escape 被吞掉、原生 cancel 被压掉),只是\n * 不走关闭入口。与旧的「跳过候选」语义不同:旧语义放任事件落到下层浮层,把外层\n * 一起关掉。该属性可在开启期间改写,所以每次渲染后读它,而不是在 claim 时固定。\n */\n private _syncOverlayInert() {\n this._handle?.setInert(this.noEscapeClose)\n }\n\n showModal() {\n if (this.open) return\n this.open = true\n }\n\n close() {\n this.open = false\n }\n\n /*\n * 仲裁者在 capture 阶段 preventDefault 了 Escape 的 keydown,UA 因此不再派发原生\n * cancel,但本 handler 仍有两个仲裁者不负责的职责,**不可删**:\n * ① 任何到达 dialog 的 cancel 都要 preventDefault,把 top layer 保留到视觉退场结束\n * (否则原生关闭会跳过退出动画);\n * ② 忽略子控件(例如 file input)冒泡上来的 cancel。\n * 实测(overlay-open-owner-260918,2026-09-18)摘掉 `@cancel` 后 dialog.browser.spec.ts\n * 的「no-escape-close 存在时 Escape/cancel 不关闭对话框」与 remount-reconcile 的\n * 「打开态被移出文档再接回」两例立刻转红,断言正是 `dispatchEvent(cancel) === false`。\n */\n private handleCancel(e: Event) {\n if (e.target !== e.currentTarget) return\n\n e.preventDefault()\n if (this.noEscapeClose) return\n this._closeFromUser()\n }\n\n private handleBackdropClick(e: MouseEvent) {\n if (e.target !== (e.currentTarget as HTMLDialogElement)) return\n if (this.noBackdropClose) return\n this._closeFromUser()\n }\n\n /** 用户发起的关闭入口(Escape、遮罩点击、关闭按钮)共用一条路径。 */\n private readonly _closeFromUser = () => {\n if (this.controlled) {\n this.emitOpenChange(false)\n return\n }\n this._userOpenChange.mark()\n this.close()\n }\n\n // controlled 下派发关闭请求:detail 固定 false(用户只能请求关闭,打开永远由 Consumer 写)。\n private emitOpenChange(open = this.open) {\n dispatchOpenChangeEvent(this, open)\n }\n\n private _onTransitionEnd = (event: TransitionEvent) => {\n this._presence.handleTransitionEnd(event)\n }\n\n private _onNativeClose = () => {\n // 关闭态下的 close 事件只可能是我们自己 finishClosing 排队的异步事件(或冗余的\n // 外部关闭):交给 presence 消费 self-close 标志,避免标志泄漏到下一次真实关闭。\n if (!this.open) {\n this._presence.handleNativeClose()\n return\n }\n\n // 我们自己 dialog.close() 排队的 close 事件是异步任务:正常时序在本关闭会话内\n // 到达,快速「关闭→重开」时它在重新打开之后才到达(过期事件)。两种情况都已\n // 完成清理,由 presence 消费并返回 true,不能当成外部关闭把刚重开的 dialog 关掉。\n if (this._presence.handleNativeClose()) return\n\n // controlled 下原生关闭(如表单 method=\"dialog\")视为未经 Consumer 批准的状态丢失:\n // 恢复受控状态并派发关闭请求,由 Consumer 决定是否关闭。\n if (this.controlled) {\n this._presence.sync(true)\n this.emitOpenChange(false)\n return\n }\n\n this._userOpenChange.mark()\n this.open = false\n }\n\n private _syncScrollLock(isOpen = this.open) {\n this._scrollLock.sync(isOpen && !this.noScrollLock)\n }\n\n /**\n * 只在「有/无」翻转时写 state:slotchange 在每次分配变化时都会触发,逐次赋值会让\n * Lit 无谓重渲染。`heading` 与槽共同决定 chrome 带的存在,见 `_showHeader`。\n */\n private _onHeaderSlotChange(e: Event) {\n if (!(e.target instanceof HTMLSlotElement)) return\n const has = e.target.assignedElements().length > 0\n if (has !== this._hasHeader) this._hasHeader = has\n }\n\n private get _showHeader(): boolean {\n return this._hasHeader || this.heading !== ''\n }\n\n /**\n * 默认模式与 `headless` 模式共用同一枚关闭按钮:都绝对定位到卡片右上角,偏移由\n * `--wui-dialog-close-top` / `--wui-dialog-close-right` 控制(见 style.css)。\n * 它在两种模式下都是卡片的直接子元素,定位参照是卡片本身(.wui-dialog-body)。\n */\n private _renderCloseButton() {\n return html`\n <web-ui-button\n class=\"wui-dialog-close\"\n @click=${this._closeFromUser}\n aria-label=\"关闭\"\n variant=\"secondary\"\n icon\n size=\"26\"\n >\n <web-ui-icon size=\"14\" .icon=${oouiClose}></web-ui-icon>\n </web-ui-button>\n `\n }\n\n override render() {\n const showHeader = this._showHeader\n /*\n * accessible name:显式 `dialog-label` 优先;否则(非 headless 且带可见时)把原生 dialog\n * 的 `aria-labelledby` 指向 chrome 带——与 drawer 同形。headless 模式没有可自动关联的\n * 内置标题,名字留给 Consumer。\n */\n const dialogLabel = this.dialogLabel.trim()\n const dialogLabelledBy = !dialogLabel && !this.headless && showHeader ? 'wui-dialog-heading' : nothing\n\n return html`\n <dialog\n aria-label=${dialogLabel || nothing}\n aria-labelledby=${dialogLabelledBy}\n @cancel=${this.handleCancel}\n @close=${this._onNativeClose}\n @click=${this.handleBackdropClick}\n @transitionend=${this._onTransitionEnd}\n >\n <div class=\"wui-dialog-body wui-glass\">\n ${\n this.headless\n ? html`\n <div class=\"wui-dialog-content\">\n <slot></slot>\n </div>\n ${this.closable ? this._renderCloseButton() : nothing}\n `\n : html`\n <div class=\"header\" id=\"wui-dialog-heading\" ?hidden=${!showHeader}>\n <slot name=\"header\" @slotchange=${this._onHeaderSlotChange}>\n ${this.heading ? html`<span class=\"wui-dialog-heading\">${this.heading}</span>` : nothing}\n </slot>\n </div>\n <div class=\"desc\"><slot></slot></div>\n <div class=\"wui-dialog-footer\"><slot name=\"footer\"></slot></div>\n ${this.closable ? this._renderCloseButton() : nothing}\n `\n }\n </div>\n </dialog>\n `\n }\n\n declare readonly $events: {\n 'open-change': CustomEvent<{ open: boolean }>\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'web-ui-dialog': WebUiDialog\n }\n}\n"],"mappings":"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"}