@vaadin/overlay 25.1.8 → 25.1.10

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.1.8",
3
+ "version": "25.1.10",
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.1.8",
38
- "@vaadin/component-base": "~25.1.8",
39
- "@vaadin/vaadin-themable-mixin": "~25.1.8",
37
+ "@vaadin/a11y-base": "~25.1.10",
38
+ "@vaadin/component-base": "~25.1.10",
39
+ "@vaadin/vaadin-themable-mixin": "~25.1.10",
40
40
  "lit": "^3.0.0"
41
41
  },
42
42
  "devDependencies": {
43
- "@vaadin/aura": "~25.1.8",
44
- "@vaadin/chai-plugins": "~25.1.8",
45
- "@vaadin/test-runner-commands": "~25.1.8",
43
+ "@vaadin/aura": "~25.1.10",
44
+ "@vaadin/chai-plugins": "~25.1.10",
45
+ "@vaadin/test-runner-commands": "~25.1.10",
46
46
  "@vaadin/testing-helpers": "^2.0.0",
47
- "@vaadin/vaadin-lumo-styles": "~25.1.8",
47
+ "@vaadin/vaadin-lumo-styles": "~25.1.10",
48
48
  "sinon": "^21.0.2"
49
49
  },
50
50
  "customElements": "custom-elements.json",
51
- "gitHead": "284962838c38ec84495ea097b97d6d03cad2069b"
51
+ "gitHead": "941297a1015ae11bb75d90c0b3c52302e741a528"
52
52
  }
@@ -119,6 +119,11 @@ export const PositionMixin = (superClass) =>
119
119
  constructor() {
120
120
  super();
121
121
 
122
+ /**
123
+ * Used for mixin detection because `instanceof` does not work with mixins.
124
+ */
125
+ this._hasOverlayPositionMixin = true;
126
+
122
127
  this.__onScroll = this.__onScroll.bind(this);
123
128
  this._updatePosition = this._updatePosition.bind(this);
124
129
  }
@@ -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
@@ -72,22 +76,28 @@ export const OverlayStackMixin = (superClass) =>
72
76
  * Brings the overlay as visually the frontmost one.
73
77
  */
74
78
  bringToFront() {
75
- // If the overlay is the last one, or if all other overlays shown above
76
- // are nested overlays (e.g. date-picker inside a dialog), do not call
77
- // `showPopover()` unnecessarily to avoid scroll position being reset.
78
- if (isLastOverlay(this) || hasOnlyNestedOverlays(this)) {
79
+ if (isLastOverlay(this)) {
79
80
  return;
80
81
  }
81
82
 
82
- // Update stacking order of native popover-based overlays
83
- if (this.matches(':popover-open')) {
84
- this.hidePopover();
85
- this.showPopover();
83
+ const overlays = getOverlaysOnTop(this);
84
+ // Nested positioned overlays anchored must stay visually on top.
85
+ const nestedOverlays = overlays.filter((el) => el._hasOverlayPositionMixin && isNestedOverlay(this, el));
86
+
87
+ // If the only overlays on top are nested positioned overlays, this overlay is already
88
+ // effectively frontmost. Skip to avoid resetting scroll position via `showPopover()`.
89
+ if (nestedOverlays.length === overlays.length) {
90
+ return;
86
91
  }
87
92
 
88
- // Update order of attached instances
89
- this._removeAttachedInstance();
90
- this._appendAttachedInstance();
93
+ [this, ...nestedOverlays].forEach((overlay) => {
94
+ if (overlay.matches(':popover-open')) {
95
+ overlay.hidePopover();
96
+ overlay.showPopover();
97
+ }
98
+ overlay._removeAttachedInstance();
99
+ overlay._appendAttachedInstance();
100
+ });
91
101
  }
92
102
 
93
103
  /** @protected */