@vaadin/overlay 24.4.0-rc2 → 24.5.0-alpha2
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": "24.
|
|
3
|
+
"version": "24.5.0-alpha2",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -36,11 +36,11 @@
|
|
|
36
36
|
"dependencies": {
|
|
37
37
|
"@open-wc/dedupe-mixin": "^1.3.0",
|
|
38
38
|
"@polymer/polymer": "^3.0.0",
|
|
39
|
-
"@vaadin/a11y-base": "24.
|
|
40
|
-
"@vaadin/component-base": "24.
|
|
41
|
-
"@vaadin/vaadin-lumo-styles": "24.
|
|
42
|
-
"@vaadin/vaadin-material-styles": "24.
|
|
43
|
-
"@vaadin/vaadin-themable-mixin": "24.
|
|
39
|
+
"@vaadin/a11y-base": "24.5.0-alpha2",
|
|
40
|
+
"@vaadin/component-base": "24.5.0-alpha2",
|
|
41
|
+
"@vaadin/vaadin-lumo-styles": "24.5.0-alpha2",
|
|
42
|
+
"@vaadin/vaadin-material-styles": "24.5.0-alpha2",
|
|
43
|
+
"@vaadin/vaadin-themable-mixin": "24.5.0-alpha2",
|
|
44
44
|
"lit": "^3.0.0"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
@@ -48,5 +48,5 @@
|
|
|
48
48
|
"@vaadin/testing-helpers": "^0.6.0",
|
|
49
49
|
"sinon": "^13.0.2"
|
|
50
50
|
},
|
|
51
|
-
"gitHead": "
|
|
51
|
+
"gitHead": "403f153bf4351f220cb6172485a0575ddf0d0fba"
|
|
52
52
|
}
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
5
|
*/
|
|
6
6
|
import { getAncestorRootNodes } from '@vaadin/component-base/src/dom-utils.js';
|
|
7
|
+
import { observeMove } from './vaadin-overlay-utils.js';
|
|
7
8
|
|
|
8
9
|
const PROP_NAMES_VERTICAL = {
|
|
9
10
|
start: 'top',
|
|
@@ -153,6 +154,12 @@ export const PositionMixin = (superClass) =>
|
|
|
153
154
|
this.__positionTargetAncestorRootNodes.forEach((node) => {
|
|
154
155
|
node.addEventListener('scroll', this.__onScroll, true);
|
|
155
156
|
});
|
|
157
|
+
|
|
158
|
+
if (this.positionTarget) {
|
|
159
|
+
this.__observePositionTargetMove = observeMove(this.positionTarget, () => {
|
|
160
|
+
this._updatePosition();
|
|
161
|
+
});
|
|
162
|
+
}
|
|
156
163
|
}
|
|
157
164
|
|
|
158
165
|
/** @private */
|
|
@@ -166,6 +173,11 @@ export const PositionMixin = (superClass) =>
|
|
|
166
173
|
});
|
|
167
174
|
this.__positionTargetAncestorRootNodes = null;
|
|
168
175
|
}
|
|
176
|
+
|
|
177
|
+
if (this.__observePositionTargetMove) {
|
|
178
|
+
this.__observePositionTargetMove();
|
|
179
|
+
this.__observePositionTargetMove = null;
|
|
180
|
+
}
|
|
169
181
|
}
|
|
170
182
|
|
|
171
183
|
/** @private */
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright (c) 2024 Vaadin Ltd.
|
|
4
|
+
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Observe moving an element around on a page.
|
|
9
|
+
*
|
|
10
|
+
* Based on the idea from https://samthor.au/2021/observing-dom/ as implemented in Floating UI
|
|
11
|
+
* https://github.com/floating-ui/floating-ui/blob/58ed169/packages/dom/src/autoUpdate.ts#L45
|
|
12
|
+
*/
|
|
13
|
+
export function observeMove(element: HTMLElement, callback: () => void): () => void;
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright (c) 2024 Vaadin Ltd.
|
|
4
|
+
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Observe moving an element around on a page.
|
|
9
|
+
*
|
|
10
|
+
* Based on the idea from https://samthor.au/2021/observing-dom/ as implemented in Floating UI
|
|
11
|
+
* https://github.com/floating-ui/floating-ui/blob/58ed169/packages/dom/src/autoUpdate.ts#L45
|
|
12
|
+
*
|
|
13
|
+
* @param {HTMLElement} element
|
|
14
|
+
* @param {Function} callback
|
|
15
|
+
* @return {Function}
|
|
16
|
+
*/
|
|
17
|
+
export function observeMove(element, callback) {
|
|
18
|
+
let io = null;
|
|
19
|
+
|
|
20
|
+
const root = document.documentElement;
|
|
21
|
+
|
|
22
|
+
function cleanup() {
|
|
23
|
+
io && io.disconnect();
|
|
24
|
+
io = null;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function refresh(skip = false, threshold = 1) {
|
|
28
|
+
cleanup();
|
|
29
|
+
|
|
30
|
+
const { left, top, width, height } = element.getBoundingClientRect();
|
|
31
|
+
|
|
32
|
+
if (!skip) {
|
|
33
|
+
callback();
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if (!width || !height) {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const insetTop = Math.floor(top);
|
|
41
|
+
const insetRight = Math.floor(root.clientWidth - (left + width));
|
|
42
|
+
const insetBottom = Math.floor(root.clientHeight - (top + height));
|
|
43
|
+
const insetLeft = Math.floor(left);
|
|
44
|
+
|
|
45
|
+
const rootMargin = `${-insetTop}px ${-insetRight}px ${-insetBottom}px ${-insetLeft}px`;
|
|
46
|
+
|
|
47
|
+
const options = {
|
|
48
|
+
rootMargin,
|
|
49
|
+
threshold: Math.max(0, Math.min(1, threshold)) || 1,
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
let isFirstUpdate = true;
|
|
53
|
+
|
|
54
|
+
function handleObserve(entries) {
|
|
55
|
+
let ratio = entries[0].intersectionRatio;
|
|
56
|
+
|
|
57
|
+
if (ratio !== threshold) {
|
|
58
|
+
if (!isFirstUpdate) {
|
|
59
|
+
return refresh();
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// It's possible for the watched element to not be at perfect 1.0 visibility when we create
|
|
63
|
+
// the IntersectionObserver. This has a couple of causes:
|
|
64
|
+
// - elements being on partial pixels
|
|
65
|
+
// - elements being hidden offscreen (e.g., <html> has `overflow: hidden`)
|
|
66
|
+
// - delays: if your DOM change occurs due to e.g., page resize, you can see elements
|
|
67
|
+
// behind their actual position
|
|
68
|
+
//
|
|
69
|
+
// In all of these cases, refresh but with this lower ratio of threshold. When the element
|
|
70
|
+
// moves beneath _that_ new value, the user will get notified.
|
|
71
|
+
if (ratio === 0.0) {
|
|
72
|
+
ratio = 0.0000001; // Just needs to be non-zero
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
refresh(false, ratio);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
isFirstUpdate = false;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
io = new IntersectionObserver(handleObserve, options);
|
|
82
|
+
|
|
83
|
+
io.observe(element);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
refresh(true);
|
|
87
|
+
|
|
88
|
+
return cleanup;
|
|
89
|
+
}
|