@vaadin/overlay 25.0.0-alpha15 → 25.0.0-alpha17
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 +9 -9
- package/src/styles/vaadin-overlay-base-styles.js +2 -2
- package/src/vaadin-overlay-focus-mixin.js +0 -27
- package/src/vaadin-overlay-mixin.js +6 -1
- package/src/vaadin-overlay-position-mixin.js +51 -13
- package/src/vaadin-overlay-utils.js +11 -14
- package/src/vaadin-overlay.d.ts +4 -4
- package/src/vaadin-overlay.js +4 -4
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vaadin/overlay",
|
|
3
|
-
"version": "25.0.0-
|
|
3
|
+
"version": "25.0.0-alpha17",
|
|
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-
|
|
37
|
-
"@vaadin/component-base": "25.0.0-
|
|
38
|
-
"@vaadin/vaadin-themable-mixin": "25.0.0-
|
|
36
|
+
"@vaadin/a11y-base": "25.0.0-alpha17",
|
|
37
|
+
"@vaadin/component-base": "25.0.0-alpha17",
|
|
38
|
+
"@vaadin/vaadin-themable-mixin": "25.0.0-alpha17",
|
|
39
39
|
"lit": "^3.0.0"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
|
-
"@vaadin/chai-plugins": "25.0.0-
|
|
43
|
-
"@vaadin/test-runner-commands": "25.0.0-
|
|
42
|
+
"@vaadin/chai-plugins": "25.0.0-alpha17",
|
|
43
|
+
"@vaadin/test-runner-commands": "25.0.0-alpha17",
|
|
44
44
|
"@vaadin/testing-helpers": "^2.0.0",
|
|
45
|
-
"@vaadin/vaadin-lumo-styles": "25.0.0-
|
|
46
|
-
"sinon": "^
|
|
45
|
+
"@vaadin/vaadin-lumo-styles": "25.0.0-alpha17",
|
|
46
|
+
"sinon": "^21.0.0"
|
|
47
47
|
},
|
|
48
|
-
"gitHead": "
|
|
48
|
+
"gitHead": "8264c71309907be99368b09414f0f8d7f591e0b9"
|
|
49
49
|
}
|
|
@@ -16,7 +16,7 @@ export const overlayStyles = css`
|
|
|
16
16
|
|
|
17
17
|
/* Default position constraints. Themes can
|
|
18
18
|
override this to adjust the gap between the overlay and the viewport. */
|
|
19
|
-
inset: 8px;
|
|
19
|
+
inset: var(--vaadin-overlay-viewport-inset, 8px);
|
|
20
20
|
bottom: var(--vaadin-overlay-viewport-bottom);
|
|
21
21
|
|
|
22
22
|
/* Override native [popover] user agent styles */
|
|
@@ -68,7 +68,7 @@ export const overlayStyles = css`
|
|
|
68
68
|
}
|
|
69
69
|
|
|
70
70
|
[part='backdrop'] {
|
|
71
|
-
background: var(--vaadin-overlay-backdrop-background, rgba(0, 0, 0, 0.
|
|
71
|
+
background: var(--vaadin-overlay-backdrop-background, rgba(0, 0, 0, 0.2));
|
|
72
72
|
content: '';
|
|
73
73
|
inset: 0;
|
|
74
74
|
pointer-events: auto;
|
|
@@ -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,20 +64,10 @@ 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
|
-
/**
|
|
75
|
-
* Override to specify another element used as a modality root,
|
|
76
|
-
* e.g. the overlay's owner element, rather than overlay itself.
|
|
77
|
-
* @protected
|
|
78
|
-
*/
|
|
79
|
-
get _modalRoot() {
|
|
80
|
-
return this;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
71
|
/**
|
|
84
72
|
* Override to specify another element used as a focus trap root,
|
|
85
73
|
* e.g. the overlay's owner element, rather than overlay part.
|
|
@@ -89,15 +77,6 @@ export const OverlayFocusMixin = (superClass) =>
|
|
|
89
77
|
return this.$.overlay;
|
|
90
78
|
}
|
|
91
79
|
|
|
92
|
-
/**
|
|
93
|
-
* Override not use a controller for setting `aria-hidden` on
|
|
94
|
-
* elements outside the overlay, e.g. when using `aria-modal`.
|
|
95
|
-
* @protected
|
|
96
|
-
*/
|
|
97
|
-
_useAriaHidden() {
|
|
98
|
-
return true;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
80
|
/**
|
|
102
81
|
* Release focus and restore focus after the overlay is closed.
|
|
103
82
|
*
|
|
@@ -105,9 +84,6 @@ export const OverlayFocusMixin = (superClass) =>
|
|
|
105
84
|
*/
|
|
106
85
|
_resetFocus() {
|
|
107
86
|
if (this.focusTrap) {
|
|
108
|
-
if (this._useAriaHidden) {
|
|
109
|
-
this.__ariaModalController.close();
|
|
110
|
-
}
|
|
111
87
|
this.__focusTrapController.releaseFocus();
|
|
112
88
|
}
|
|
113
89
|
|
|
@@ -135,9 +111,6 @@ export const OverlayFocusMixin = (superClass) =>
|
|
|
135
111
|
*/
|
|
136
112
|
_trapFocus() {
|
|
137
113
|
if (this.focusTrap) {
|
|
138
|
-
if (this._useAriaHidden) {
|
|
139
|
-
this.__ariaModalController.showModal();
|
|
140
|
-
}
|
|
141
114
|
this.__focusTrapController.trapFocus(this._focusTrapRoot);
|
|
142
115
|
}
|
|
143
116
|
}
|
|
@@ -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);
|
|
@@ -552,7 +557,7 @@ export const OverlayMixin = (superClass) =>
|
|
|
552
557
|
}
|
|
553
558
|
|
|
554
559
|
// Only close modeless overlay on Esc press when it contains focus
|
|
555
|
-
if (!this._shouldAddGlobalListeners() && !event.composedPath().includes(this
|
|
560
|
+
if (!this._shouldAddGlobalListeners() && !event.composedPath().includes(this._focusTrapRoot)) {
|
|
556
561
|
return;
|
|
557
562
|
}
|
|
558
563
|
|
|
@@ -116,13 +116,6 @@ export const PositionMixin = (superClass) =>
|
|
|
116
116
|
};
|
|
117
117
|
}
|
|
118
118
|
|
|
119
|
-
static get observers() {
|
|
120
|
-
return [
|
|
121
|
-
'__positionSettingsChanged(horizontalAlign, verticalAlign, noHorizontalOverlap, noVerticalOverlap, requiredVerticalSpace)',
|
|
122
|
-
'__overlayOpenedChanged(opened, positionTarget)',
|
|
123
|
-
];
|
|
124
|
-
}
|
|
125
|
-
|
|
126
119
|
constructor() {
|
|
127
120
|
super();
|
|
128
121
|
|
|
@@ -145,6 +138,36 @@ export const PositionMixin = (superClass) =>
|
|
|
145
138
|
this.__removeUpdatePositionEventListeners();
|
|
146
139
|
}
|
|
147
140
|
|
|
141
|
+
/** @protected */
|
|
142
|
+
updated(props) {
|
|
143
|
+
super.updated(props);
|
|
144
|
+
|
|
145
|
+
if (props.has('positionTarget')) {
|
|
146
|
+
const oldTarget = props.get('positionTarget');
|
|
147
|
+
|
|
148
|
+
// 1. When position target is removed, always reset position settings
|
|
149
|
+
// 2. When position target is set, reset if overlay was opened before
|
|
150
|
+
if ((!this.positionTarget && oldTarget) || (this.positionTarget && !oldTarget && !!this.__margins)) {
|
|
151
|
+
this.__resetPosition();
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
if (props.has('opened') || props.has('positionTarget')) {
|
|
156
|
+
this.__updatePositionSettings(this.opened, this.positionTarget);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
const positionProps = [
|
|
160
|
+
'horizontalAlign',
|
|
161
|
+
'verticalAlign',
|
|
162
|
+
'noHorizontalOverlap',
|
|
163
|
+
'noVerticalOverlap',
|
|
164
|
+
'requiredVerticalSpace',
|
|
165
|
+
];
|
|
166
|
+
if (positionProps.some((prop) => props.has(prop))) {
|
|
167
|
+
this._updatePosition();
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
148
171
|
/** @private */
|
|
149
172
|
__addUpdatePositionEventListeners() {
|
|
150
173
|
window.visualViewport.addEventListener('resize', this._updatePosition);
|
|
@@ -181,7 +204,7 @@ export const PositionMixin = (superClass) =>
|
|
|
181
204
|
}
|
|
182
205
|
|
|
183
206
|
/** @private */
|
|
184
|
-
|
|
207
|
+
__updatePositionSettings(opened, positionTarget) {
|
|
185
208
|
this.__removeUpdatePositionEventListeners();
|
|
186
209
|
|
|
187
210
|
if (positionTarget) {
|
|
@@ -210,20 +233,35 @@ export const PositionMixin = (superClass) =>
|
|
|
210
233
|
}
|
|
211
234
|
}
|
|
212
235
|
|
|
213
|
-
__positionSettingsChanged() {
|
|
214
|
-
this._updatePosition();
|
|
215
|
-
}
|
|
216
|
-
|
|
217
236
|
/** @private */
|
|
218
237
|
__onScroll(e) {
|
|
219
238
|
// If the scroll event occurred inside the overlay, ignore it.
|
|
220
|
-
if (e.target instanceof Node && this.
|
|
239
|
+
if (e.target instanceof Node && this._deepContains(e.target)) {
|
|
221
240
|
return;
|
|
222
241
|
}
|
|
223
242
|
|
|
224
243
|
this._updatePosition();
|
|
225
244
|
}
|
|
226
245
|
|
|
246
|
+
/** @private */
|
|
247
|
+
__resetPosition() {
|
|
248
|
+
this.__margins = null;
|
|
249
|
+
|
|
250
|
+
Object.assign(this.style, {
|
|
251
|
+
justifyContent: '',
|
|
252
|
+
alignItems: '',
|
|
253
|
+
top: '',
|
|
254
|
+
bottom: '',
|
|
255
|
+
left: '',
|
|
256
|
+
right: '',
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
setOverlayStateAttribute(this, 'bottom-aligned', false);
|
|
260
|
+
setOverlayStateAttribute(this, 'top-aligned', false);
|
|
261
|
+
setOverlayStateAttribute(this, 'end-aligned', false);
|
|
262
|
+
setOverlayStateAttribute(this, 'start-aligned', false);
|
|
263
|
+
}
|
|
264
|
+
|
|
227
265
|
_updatePosition() {
|
|
228
266
|
if (!this.positionTarget || !this.opened || !this.__margins) {
|
|
229
267
|
return;
|
|
@@ -16,10 +16,12 @@
|
|
|
16
16
|
*/
|
|
17
17
|
export function observeMove(element, callback) {
|
|
18
18
|
let io = null;
|
|
19
|
+
let timeout;
|
|
19
20
|
|
|
20
21
|
const root = document.documentElement;
|
|
21
22
|
|
|
22
23
|
function cleanup() {
|
|
24
|
+
timeout && clearTimeout(timeout);
|
|
23
25
|
io && io.disconnect();
|
|
24
26
|
io = null;
|
|
25
27
|
}
|
|
@@ -52,27 +54,22 @@ export function observeMove(element, callback) {
|
|
|
52
54
|
let isFirstUpdate = true;
|
|
53
55
|
|
|
54
56
|
function handleObserve(entries) {
|
|
55
|
-
|
|
57
|
+
const ratio = entries[0].intersectionRatio;
|
|
56
58
|
|
|
57
59
|
if (ratio !== threshold) {
|
|
58
60
|
if (!isFirstUpdate) {
|
|
59
61
|
return refresh();
|
|
60
62
|
}
|
|
61
63
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
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
|
|
64
|
+
if (!ratio) {
|
|
65
|
+
// If the reference is clipped, the ratio is 0. Throttle the refresh
|
|
66
|
+
// to prevent an infinite loop of updates.
|
|
67
|
+
timeout = setTimeout(() => {
|
|
68
|
+
refresh(false, 1e-7);
|
|
69
|
+
}, 1000);
|
|
70
|
+
} else {
|
|
71
|
+
refresh(false, ratio);
|
|
73
72
|
}
|
|
74
|
-
|
|
75
|
-
refresh(false, ratio);
|
|
76
73
|
}
|
|
77
74
|
|
|
78
75
|
isFirstUpdate = false;
|
package/src/vaadin-overlay.d.ts
CHANGED
|
@@ -98,10 +98,10 @@ export type OverlayEventMap = HTMLElementEventMap & OverlayCustomEventMap;
|
|
|
98
98
|
*
|
|
99
99
|
* The following state attributes are available for styling:
|
|
100
100
|
*
|
|
101
|
-
* Attribute | Description
|
|
102
|
-
*
|
|
103
|
-
* `opening` | Applied just after the overlay is
|
|
104
|
-
* `closing` | Applied just before the overlay is
|
|
101
|
+
* Attribute | Description
|
|
102
|
+
* ----------|------------
|
|
103
|
+
* `opening` | Applied just after the overlay is opened. You can apply a CSS animation for this state.
|
|
104
|
+
* `closing` | Applied just before the overlay is closed. You can apply a CSS animation for this state.
|
|
105
105
|
*
|
|
106
106
|
* The following custom CSS properties are available for styling:
|
|
107
107
|
*
|
package/src/vaadin-overlay.js
CHANGED
|
@@ -50,10 +50,10 @@ import { OverlayMixin } from './vaadin-overlay-mixin.js';
|
|
|
50
50
|
*
|
|
51
51
|
* The following state attributes are available for styling:
|
|
52
52
|
*
|
|
53
|
-
* Attribute | Description
|
|
54
|
-
*
|
|
55
|
-
* `opening` | Applied just after the overlay is
|
|
56
|
-
* `closing` | Applied just before the overlay is
|
|
53
|
+
* Attribute | Description
|
|
54
|
+
* ----------|------------
|
|
55
|
+
* `opening` | Applied just after the overlay is opened. You can apply a CSS animation for this state.
|
|
56
|
+
* `closing` | Applied just before the overlay is closed. You can apply a CSS animation for this state.
|
|
57
57
|
*
|
|
58
58
|
* The following custom CSS properties are available for styling:
|
|
59
59
|
*
|