@vaadin/overlay 25.0.0-alpha14 → 25.0.0-alpha16

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vaadin/overlay",
3
- "version": "25.0.0-alpha14",
3
+ "version": "25.0.0-alpha16",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -33,17 +33,17 @@
33
33
  ],
34
34
  "dependencies": {
35
35
  "@open-wc/dedupe-mixin": "^1.3.0",
36
- "@vaadin/a11y-base": "25.0.0-alpha14",
37
- "@vaadin/component-base": "25.0.0-alpha14",
38
- "@vaadin/vaadin-themable-mixin": "25.0.0-alpha14",
36
+ "@vaadin/a11y-base": "25.0.0-alpha16",
37
+ "@vaadin/component-base": "25.0.0-alpha16",
38
+ "@vaadin/vaadin-themable-mixin": "25.0.0-alpha16",
39
39
  "lit": "^3.0.0"
40
40
  },
41
41
  "devDependencies": {
42
- "@vaadin/chai-plugins": "25.0.0-alpha14",
43
- "@vaadin/test-runner-commands": "25.0.0-alpha14",
42
+ "@vaadin/chai-plugins": "25.0.0-alpha16",
43
+ "@vaadin/test-runner-commands": "25.0.0-alpha16",
44
44
  "@vaadin/testing-helpers": "^2.0.0",
45
- "@vaadin/vaadin-lumo-styles": "25.0.0-alpha14",
45
+ "@vaadin/vaadin-lumo-styles": "25.0.0-alpha16",
46
46
  "sinon": "^18.0.0"
47
47
  },
48
- "gitHead": "8ebeeeca4b5b6564eff954d6582d0d6760464e51"
48
+ "gitHead": "4b316158a4a4f702f032bc9940fc82f0faa840f4"
49
49
  }
@@ -3,7 +3,6 @@
3
3
  * Copyright (c) 2017 - 2025 Vaadin Ltd.
4
4
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
5
  */
6
- import { AriaModalController } from '@vaadin/a11y-base/src/aria-modal-controller.js';
7
6
  import { FocusRestorationController } from '@vaadin/a11y-base/src/focus-restoration-controller.js';
8
7
  import { FocusTrapController } from '@vaadin/a11y-base/src/focus-trap-controller.js';
9
8
  import { getDeepActiveElement, isKeyboardActive } from '@vaadin/a11y-base/src/focus-utils.js';
@@ -48,7 +47,6 @@ export const OverlayFocusMixin = (superClass) =>
48
47
  constructor() {
49
48
  super();
50
49
 
51
- this.__ariaModalController = new AriaModalController(this, () => this._modalRoot);
52
50
  this.__focusTrapController = new FocusTrapController(this);
53
51
  this.__focusRestorationController = new FocusRestorationController();
54
52
  }
@@ -66,18 +64,17 @@ export const OverlayFocusMixin = (superClass) =>
66
64
  ready() {
67
65
  super.ready();
68
66
 
69
- this.addController(this.__ariaModalController);
70
67
  this.addController(this.__focusTrapController);
71
68
  this.addController(this.__focusRestorationController);
72
69
  }
73
70
 
74
71
  /**
75
- * Override to specify another element used as a modality root,
76
- * e.g. the overlay's owner element, rather than overlay itself.
72
+ * Override to specify another element used as a focus trap root,
73
+ * e.g. the overlay's owner element, rather than overlay part.
77
74
  * @protected
78
75
  */
79
- get _modalRoot() {
80
- return this;
76
+ get _focusTrapRoot() {
77
+ return this.$.overlay;
81
78
  }
82
79
 
83
80
  /**
@@ -87,7 +84,6 @@ export const OverlayFocusMixin = (superClass) =>
87
84
  */
88
85
  _resetFocus() {
89
86
  if (this.focusTrap) {
90
- this.__ariaModalController.close();
91
87
  this.__focusTrapController.releaseFocus();
92
88
  }
93
89
 
@@ -115,8 +111,7 @@ export const OverlayFocusMixin = (superClass) =>
115
111
  */
116
112
  _trapFocus() {
117
113
  if (this.focusTrap) {
118
- this.__ariaModalController.showModal();
119
- this.__focusTrapController.trapFocus(this.$.overlay);
114
+ this.__focusTrapController.trapFocus(this._focusTrapRoot);
120
115
  }
121
116
  }
122
117
 
@@ -156,6 +156,11 @@ export const OverlayMixin = (superClass) =>
156
156
  disconnectedCallback() {
157
157
  super.disconnectedCallback();
158
158
 
159
+ if (this.__scheduledOpen) {
160
+ cancelAnimationFrame(this.__scheduledOpen);
161
+ this.__scheduledOpen = null;
162
+ }
163
+
159
164
  /* c8 ignore next 3 */
160
165
  if (this._boundIosResizeListener) {
161
166
  window.removeEventListener('resize', this._boundIosResizeListener);
@@ -183,7 +188,7 @@ export const OverlayMixin = (superClass) =>
183
188
  const event = new CustomEvent('vaadin-overlay-close', {
184
189
  bubbles: true,
185
190
  cancelable: true,
186
- detail: { sourceEvent },
191
+ detail: { overlay: this, sourceEvent },
187
192
  });
188
193
  this.dispatchEvent(event);
189
194
  // To allow listening for the event globally, also dispatch it on the document body
@@ -237,8 +242,25 @@ export const OverlayMixin = (superClass) =>
237
242
  }
238
243
  }
239
244
 
245
+ /**
246
+ * Whether to add global listeners for closing on outside click.
247
+ * By default, listeners are not added for a modeless overlay.
248
+ *
249
+ * @return {boolean}
250
+ * @protected
251
+ */
252
+ _shouldAddGlobalListeners() {
253
+ return !this.modeless;
254
+ }
255
+
240
256
  /** @private */
241
257
  _addGlobalListeners() {
258
+ if (this.__hasGlobalListeners) {
259
+ return;
260
+ }
261
+
262
+ this.__hasGlobalListeners = true;
263
+
242
264
  document.addEventListener('mousedown', this._boundMouseDownListener);
243
265
  document.addEventListener('mouseup', this._boundMouseUpListener);
244
266
  // Firefox leaks click to document on contextmenu even if prevented
@@ -248,6 +270,12 @@ export const OverlayMixin = (superClass) =>
248
270
 
249
271
  /** @private */
250
272
  _removeGlobalListeners() {
273
+ if (!this.__hasGlobalListeners) {
274
+ return;
275
+ }
276
+
277
+ this.__hasGlobalListeners = false;
278
+
251
279
  document.removeEventListener('mousedown', this._boundMouseDownListener);
252
280
  document.removeEventListener('mouseup', this._boundMouseUpListener);
253
281
  document.documentElement.removeEventListener('click', this._boundOutsideClickListener, true);
@@ -281,13 +309,20 @@ export const OverlayMixin = (superClass) =>
281
309
 
282
310
  /** @private */
283
311
  _modelessChanged(modeless) {
312
+ if (this.opened) {
313
+ // Add / remove listeners if modeless is changed while opened
314
+ if (this._shouldAddGlobalListeners()) {
315
+ this._addGlobalListeners();
316
+ } else {
317
+ this._removeGlobalListeners();
318
+ }
319
+ }
320
+
284
321
  if (!modeless) {
285
322
  if (this.opened) {
286
- this._addGlobalListeners();
287
323
  this._enterModalState();
288
324
  }
289
325
  } else {
290
- this._removeGlobalListeners();
291
326
  this._exitModalState();
292
327
  }
293
328
  setOverlayStateAttribute(this, 'modeless', modeless);
@@ -317,7 +352,7 @@ export const OverlayMixin = (superClass) =>
317
352
 
318
353
  // Dispatch the event on the overlay. Not using composed, as propagating the event through shadow roots
319
354
  // could have side effects when nesting overlays
320
- const event = new CustomEvent('vaadin-overlay-open', { bubbles: true });
355
+ const event = new CustomEvent('vaadin-overlay-open', { detail: { overlay: this }, bubbles: true });
321
356
  this.dispatchEvent(event);
322
357
  // To allow listening for the event globally, also dispatch it on the document body
323
358
  document.body.dispatchEvent(event);
@@ -326,7 +361,7 @@ export const OverlayMixin = (superClass) =>
326
361
 
327
362
  document.addEventListener('keydown', this._boundKeydownListener);
328
363
 
329
- if (!this.modeless) {
364
+ if (this._shouldAddGlobalListeners()) {
330
365
  this._addGlobalListeners();
331
366
  }
332
367
  } else if (wasOpened) {
@@ -341,7 +376,7 @@ export const OverlayMixin = (superClass) =>
341
376
 
342
377
  document.removeEventListener('keydown', this._boundKeydownListener);
343
378
 
344
- if (!this.modeless) {
379
+ if (this._shouldAddGlobalListeners()) {
345
380
  this._removeGlobalListeners();
346
381
  }
347
382
  }
@@ -522,7 +557,7 @@ export const OverlayMixin = (superClass) =>
522
557
  }
523
558
 
524
559
  // Only close modeless overlay on Esc press when it contains focus
525
- if (this.modeless && !event.composedPath().includes(this.$.overlay)) {
560
+ if (!this._shouldAddGlobalListeners() && !event.composedPath().includes(this._focusTrapRoot)) {
526
561
  return;
527
562
  }
528
563
 
@@ -17,13 +17,13 @@ export type OverlayOpenedChangedEvent = CustomEvent<{ value: boolean }>;
17
17
  /**
18
18
  * Fired after the overlay is opened.
19
19
  */
20
- export type OverlayOpenEvent = CustomEvent;
20
+ export type OverlayOpenEvent = CustomEvent<{ overlay: HTMLElement }>;
21
21
 
22
22
  /**
23
23
  * Fired when the opened overlay is about to be closed.
24
24
  * Calling `preventDefault()` on the event cancels the closing.
25
25
  */
26
- export type OverlayCloseEvent = CustomEvent;
26
+ export type OverlayCloseEvent = CustomEvent<{ overlay: HTMLElement }>;
27
27
 
28
28
  /**
29
29
  * Fired after the overlay is closed.