@vaadin/overlay 25.2.5 → 25.2.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vaadin/overlay",
3
- "version": "25.2.5",
3
+ "version": "25.2.6",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -34,19 +34,19 @@
34
34
  ],
35
35
  "dependencies": {
36
36
  "@open-wc/dedupe-mixin": "^1.3.0",
37
- "@vaadin/a11y-base": "~25.2.5",
38
- "@vaadin/component-base": "~25.2.5",
39
- "@vaadin/vaadin-themable-mixin": "~25.2.5",
37
+ "@vaadin/a11y-base": "~25.2.6",
38
+ "@vaadin/component-base": "~25.2.6",
39
+ "@vaadin/vaadin-themable-mixin": "~25.2.6",
40
40
  "lit": "^3.0.0"
41
41
  },
42
42
  "devDependencies": {
43
- "@vaadin/aura": "~25.2.5",
44
- "@vaadin/chai-plugins": "~25.2.5",
45
- "@vaadin/test-runner-commands": "~25.2.5",
43
+ "@vaadin/aura": "~25.2.6",
44
+ "@vaadin/chai-plugins": "~25.2.6",
45
+ "@vaadin/test-runner-commands": "~25.2.6",
46
46
  "@vaadin/testing-helpers": "^2.0.0",
47
- "@vaadin/vaadin-lumo-styles": "~25.2.5",
47
+ "@vaadin/vaadin-lumo-styles": "~25.2.6",
48
48
  "sinon": "^22.0.0"
49
49
  },
50
50
  "customElements": "custom-elements.json",
51
- "gitHead": "bfaf51d71619f34c0b00b326e6426f1cd9f7b2f5"
51
+ "gitHead": "c352225ff025e6163c5e290d6028a42003696441"
52
52
  }
@@ -116,6 +116,11 @@ export const PositionMixin = (superClass) =>
116
116
  constructor() {
117
117
  super();
118
118
 
119
+ /**
120
+ * Used for mixin detection because `instanceof` does not work with mixins.
121
+ */
122
+ this._hasOverlayPositionMixin = true;
123
+
119
124
  this.__onScroll = this.__onScroll.bind(this);
120
125
  this._updatePosition = this._updatePosition.bind(this);
121
126
  }
@@ -14,23 +14,27 @@ const attachedInstances = new Set();
14
14
  const getAttachedInstances = () => [...attachedInstances].filter((el) => !el.hasAttribute('closing'));
15
15
 
16
16
  /**
17
- * Returns true if all the instances on top of the overlay are nested overlays.
18
- * @private
17
+ * Returns overlays shown on top of the given overlay.
18
+ * @param {HTMLElement} overlay
19
+ * @return {HTMLElement[]}
20
+ * @protected
19
21
  */
20
- export const hasOnlyNestedOverlays = (overlay) => {
22
+ export const getOverlaysOnTop = (overlay) => {
21
23
  const instances = getAttachedInstances();
22
- const next = instances[instances.indexOf(overlay) + 1];
23
- if (!next) {
24
- return true;
25
- }
26
-
27
- if (!overlay._deepContains(next)) {
28
- return false;
29
- }
30
-
31
- return hasOnlyNestedOverlays(next);
24
+ const index = instances.indexOf(overlay);
25
+ // The overlay is not in the visible stack (closing), so nothing is "on top" of it.
26
+ return index === -1 ? [] : instances.slice(index + 1);
32
27
  };
33
28
 
29
+ /**
30
+ * Returns true if the given overlay is a child of a parent overlay.
31
+ * @param {HTMLElement} parent
32
+ * @param {HTMLElement} overlay
33
+ * @return {boolean}
34
+ * @protected
35
+ */
36
+ export const isNestedOverlay = (parent, overlay) => parent._deepContains(overlay);
37
+
34
38
  /**
35
39
  * Returns true if the overlay is the last one in the opened overlays stack.
36
40
  * @param {HTMLElement} overlay
@@ -69,22 +73,28 @@ export const OverlayStackMixin = (superClass) =>
69
73
  * Brings the overlay as visually the frontmost one.
70
74
  */
71
75
  bringToFront() {
72
- // If the overlay is the last one, or if all other overlays shown above
73
- // are nested overlays (e.g. date-picker inside a dialog), do not call
74
- // `showPopover()` unnecessarily to avoid scroll position being reset.
75
- if (isLastOverlay(this) || hasOnlyNestedOverlays(this)) {
76
+ if (isLastOverlay(this)) {
76
77
  return;
77
78
  }
78
79
 
79
- // Update stacking order of native popover-based overlays
80
- if (this.matches(':popover-open')) {
81
- this.hidePopover();
82
- this.showPopover();
80
+ const overlays = getOverlaysOnTop(this);
81
+ // Nested positioned overlays anchored must stay visually on top.
82
+ const nestedOverlays = overlays.filter((el) => el._hasOverlayPositionMixin && isNestedOverlay(this, el));
83
+
84
+ // If the only overlays on top are nested positioned overlays, this overlay is already
85
+ // effectively frontmost. Skip to avoid resetting scroll position via `showPopover()`.
86
+ if (nestedOverlays.length === overlays.length) {
87
+ return;
83
88
  }
84
89
 
85
- // Update order of attached instances
86
- this._removeAttachedInstance();
87
- this._appendAttachedInstance();
90
+ [this, ...nestedOverlays].forEach((overlay) => {
91
+ if (overlay.matches(':popover-open')) {
92
+ overlay.hidePopover();
93
+ overlay.showPopover();
94
+ }
95
+ overlay._removeAttachedInstance();
96
+ overlay._appendAttachedInstance();
97
+ });
88
98
  }
89
99
 
90
100
  /** @protected */