@vaadin/dialog 25.2.11 → 25.2.12
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/custom-elements.json +64 -0
- package/package.json +11 -10
- package/src/vaadin-dialog-draggable-mixin.js +11 -2
- package/src/vaadin-dialog-overlay-mixin.d.ts +5 -0
- package/src/vaadin-dialog-overlay-mixin.js +10 -0
- package/src/vaadin-dialog-resizable-mixin.js +13 -3
- package/src/vaadin-dialog-utils.d.ts +16 -0
- package/src/vaadin-dialog-utils.js +34 -1
- package/web-types.json +1 -1
- package/web-types.lit.json +1 -1
package/custom-elements.json
CHANGED
|
@@ -351,6 +351,16 @@
|
|
|
351
351
|
"package": "@vaadin/overlay/src/vaadin-overlay-mixin.js"
|
|
352
352
|
}
|
|
353
353
|
},
|
|
354
|
+
{
|
|
355
|
+
"kind": "method",
|
|
356
|
+
"name": "containsFocus",
|
|
357
|
+
"description": "Returns true if the overlay contains focus, including nested shadow roots.",
|
|
358
|
+
"return": {
|
|
359
|
+
"type": {
|
|
360
|
+
"text": "boolean"
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
},
|
|
354
364
|
{
|
|
355
365
|
"kind": "field",
|
|
356
366
|
"name": "focusTrap",
|
|
@@ -976,6 +986,60 @@
|
|
|
976
986
|
}
|
|
977
987
|
]
|
|
978
988
|
},
|
|
989
|
+
{
|
|
990
|
+
"kind": "javascript-module",
|
|
991
|
+
"path": "src/vaadin-dialog-utils.js",
|
|
992
|
+
"declarations": [
|
|
993
|
+
{
|
|
994
|
+
"kind": "class",
|
|
995
|
+
"description": "Remembers where a pointer gesture started, to tell a click from a drag once it ends.",
|
|
996
|
+
"name": "ClickTracker",
|
|
997
|
+
"members": [
|
|
998
|
+
{
|
|
999
|
+
"kind": "method",
|
|
1000
|
+
"name": "isClick",
|
|
1001
|
+
"parameters": [
|
|
1002
|
+
{
|
|
1003
|
+
"name": "e",
|
|
1004
|
+
"type": {
|
|
1005
|
+
"text": "!MouseEvent | !TouchEvent"
|
|
1006
|
+
}
|
|
1007
|
+
}
|
|
1008
|
+
],
|
|
1009
|
+
"description": "Returns true if the pointer hasn't moved since the gesture started.",
|
|
1010
|
+
"return": {
|
|
1011
|
+
"type": {
|
|
1012
|
+
"text": "boolean"
|
|
1013
|
+
}
|
|
1014
|
+
}
|
|
1015
|
+
},
|
|
1016
|
+
{
|
|
1017
|
+
"kind": "method",
|
|
1018
|
+
"name": "start",
|
|
1019
|
+
"parameters": [
|
|
1020
|
+
{
|
|
1021
|
+
"name": "e",
|
|
1022
|
+
"type": {
|
|
1023
|
+
"text": "!MouseEvent | !TouchEvent"
|
|
1024
|
+
}
|
|
1025
|
+
}
|
|
1026
|
+
],
|
|
1027
|
+
"description": "Stores the position where the gesture started."
|
|
1028
|
+
}
|
|
1029
|
+
]
|
|
1030
|
+
}
|
|
1031
|
+
],
|
|
1032
|
+
"exports": [
|
|
1033
|
+
{
|
|
1034
|
+
"kind": "js",
|
|
1035
|
+
"name": "ClickTracker",
|
|
1036
|
+
"declaration": {
|
|
1037
|
+
"name": "ClickTracker",
|
|
1038
|
+
"module": "src/vaadin-dialog-utils.js"
|
|
1039
|
+
}
|
|
1040
|
+
}
|
|
1041
|
+
]
|
|
1042
|
+
},
|
|
979
1043
|
{
|
|
980
1044
|
"kind": "javascript-module",
|
|
981
1045
|
"path": "src/vaadin-dialog.js",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vaadin/dialog",
|
|
3
|
-
"version": "25.2.
|
|
3
|
+
"version": "25.2.12",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -37,19 +37,20 @@
|
|
|
37
37
|
],
|
|
38
38
|
"dependencies": {
|
|
39
39
|
"@open-wc/dedupe-mixin": "^1.3.0",
|
|
40
|
-
"@vaadin/
|
|
41
|
-
"@vaadin/
|
|
42
|
-
"@vaadin/
|
|
43
|
-
"@vaadin/
|
|
40
|
+
"@vaadin/a11y-base": "~25.2.12",
|
|
41
|
+
"@vaadin/component-base": "~25.2.12",
|
|
42
|
+
"@vaadin/lit-renderer": "~25.2.12",
|
|
43
|
+
"@vaadin/overlay": "~25.2.12",
|
|
44
|
+
"@vaadin/vaadin-themable-mixin": "~25.2.12",
|
|
44
45
|
"lit": "^3.0.0"
|
|
45
46
|
},
|
|
46
47
|
"devDependencies": {
|
|
47
48
|
"@vaadin/a11y-base": "~25.2.11",
|
|
48
|
-
"@vaadin/aura": "~25.2.
|
|
49
|
-
"@vaadin/chai-plugins": "~25.2.
|
|
50
|
-
"@vaadin/test-runner-commands": "~25.2.
|
|
49
|
+
"@vaadin/aura": "~25.2.12",
|
|
50
|
+
"@vaadin/chai-plugins": "~25.2.12",
|
|
51
|
+
"@vaadin/test-runner-commands": "~25.2.12",
|
|
51
52
|
"@vaadin/testing-helpers": "^2.0.0",
|
|
52
|
-
"@vaadin/vaadin-lumo-styles": "~25.2.
|
|
53
|
+
"@vaadin/vaadin-lumo-styles": "~25.2.12",
|
|
53
54
|
"sinon": "^22.0.0"
|
|
54
55
|
},
|
|
55
56
|
"customElements": "custom-elements.json",
|
|
@@ -57,5 +58,5 @@
|
|
|
57
58
|
"web-types.json",
|
|
58
59
|
"web-types.lit.json"
|
|
59
60
|
],
|
|
60
|
-
"gitHead": "
|
|
61
|
+
"gitHead": "7261133c2bc1c781f5b00037d896bac5443a4e00"
|
|
61
62
|
}
|
|
@@ -3,8 +3,9 @@
|
|
|
3
3
|
* Copyright (c) 2017 - 2026 Vaadin Ltd.
|
|
4
4
|
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
5
|
*/
|
|
6
|
+
import { isKeyboardActive } from '@vaadin/a11y-base/src/focus-utils.js';
|
|
6
7
|
import { isTouch } from '@vaadin/component-base/src/browser-utils.js';
|
|
7
|
-
import { eventInWindow, getMouseOrFirstTouchEvent } from './vaadin-dialog-utils.js';
|
|
8
|
+
import { ClickTracker, eventInWindow, getMouseOrFirstTouchEvent } from './vaadin-dialog-utils.js';
|
|
8
9
|
|
|
9
10
|
export const DialogDraggableMixin = (superClass) =>
|
|
10
11
|
class VaadinDialogDraggableMixin extends superClass {
|
|
@@ -44,6 +45,7 @@ export const DialogDraggableMixin = (superClass) =>
|
|
|
44
45
|
super.ready();
|
|
45
46
|
this._originalBounds = {};
|
|
46
47
|
this._originalMouseCoords = {};
|
|
48
|
+
this.__dragTracker = new ClickTracker();
|
|
47
49
|
this._startDrag = this._startDrag.bind(this);
|
|
48
50
|
this._drag = this._drag.bind(this);
|
|
49
51
|
this._stopDrag = this._stopDrag.bind(this);
|
|
@@ -86,6 +88,8 @@ export const DialogDraggableMixin = (superClass) =>
|
|
|
86
88
|
if ((isResizerContainer && !isResizerContainerScrollbar) || isContentPart || isDraggable) {
|
|
87
89
|
// Signal that we're handling this drag event, so parent dialogs won't also drag
|
|
88
90
|
e.preventDefault();
|
|
91
|
+
// `preventDefault()` above cancels the native focus change, restored in `_stopDrag()`
|
|
92
|
+
this.__dragTracker.start(e);
|
|
89
93
|
this._originalBounds = this.$.overlay.getBounds();
|
|
90
94
|
const event = getMouseOrFirstTouchEvent(e);
|
|
91
95
|
this._originalMouseCoords = { top: event.pageY, left: event.pageX };
|
|
@@ -128,7 +132,12 @@ export const DialogDraggableMixin = (superClass) =>
|
|
|
128
132
|
}
|
|
129
133
|
|
|
130
134
|
/** @private */
|
|
131
|
-
_stopDrag() {
|
|
135
|
+
_stopDrag(e) {
|
|
136
|
+
// Focus on click, not on drag, so that moving the dialog doesn't interrupt editing
|
|
137
|
+
if (this.__dragTracker.isClick(e) && !this.$.overlay.containsFocus()) {
|
|
138
|
+
this.focus({ preventScroll: true, focusVisible: isKeyboardActive() });
|
|
139
|
+
}
|
|
140
|
+
|
|
132
141
|
this.dispatchEvent(new CustomEvent('dragged', { detail: { top: this.top, left: this.left } }));
|
|
133
142
|
window.removeEventListener('mouseup', this._stopDrag);
|
|
134
143
|
window.removeEventListener('touchend', this._stopDrag);
|
|
@@ -44,4 +44,9 @@ export declare class DialogOverlayMixinClass {
|
|
|
44
44
|
* Retrieves the coordinates of the overlay.
|
|
45
45
|
*/
|
|
46
46
|
getBounds(): DialogOverlayBounds;
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Returns true if the overlay contains focus, including nested shadow roots.
|
|
50
|
+
*/
|
|
51
|
+
containsFocus(): boolean;
|
|
47
52
|
}
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
* Copyright (c) 2017 - 2026 Vaadin Ltd.
|
|
4
4
|
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
5
|
*/
|
|
6
|
+
import { getDeepActiveElement } from '@vaadin/a11y-base/src/focus-utils.js';
|
|
6
7
|
import { SlotObserver } from '@vaadin/component-base/src/slot-observer.js';
|
|
7
8
|
import { OverlayMixin } from '@vaadin/overlay/src/vaadin-overlay-mixin.js';
|
|
8
9
|
import { setOverlayStateAttribute } from '@vaadin/overlay/src/vaadin-overlay-utils.js';
|
|
@@ -59,6 +60,15 @@ export const DialogOverlayMixin = (superClass) =>
|
|
|
59
60
|
return this.owner;
|
|
60
61
|
}
|
|
61
62
|
|
|
63
|
+
/**
|
|
64
|
+
* Returns true if the overlay contains focus, including nested shadow roots.
|
|
65
|
+
*
|
|
66
|
+
* @return {boolean}
|
|
67
|
+
*/
|
|
68
|
+
containsFocus() {
|
|
69
|
+
return this._deepContains(getDeepActiveElement());
|
|
70
|
+
}
|
|
71
|
+
|
|
62
72
|
/**
|
|
63
73
|
* Override method from OverlayMixin to use slotted div as a renderer root.
|
|
64
74
|
* @protected
|
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
* Copyright (c) 2017 - 2026 Vaadin Ltd.
|
|
4
4
|
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
5
|
*/
|
|
6
|
-
import {
|
|
6
|
+
import { isKeyboardActive } from '@vaadin/a11y-base/src/focus-utils.js';
|
|
7
|
+
import { ClickTracker, eventInWindow, getMouseOrFirstTouchEvent } from './vaadin-dialog-utils.js';
|
|
7
8
|
export const DialogResizableMixin = (superClass) =>
|
|
8
9
|
class VaadinDialogResizableMixin extends superClass {
|
|
9
10
|
static get properties() {
|
|
@@ -24,6 +25,7 @@ export const DialogResizableMixin = (superClass) =>
|
|
|
24
25
|
super.ready();
|
|
25
26
|
this._originalBounds = {};
|
|
26
27
|
this._originalMouseCoords = {};
|
|
28
|
+
this.__resizeTracker = new ClickTracker();
|
|
27
29
|
this._resizeListeners = { start: {}, resize: {}, stop: {} };
|
|
28
30
|
this._addResizeListeners();
|
|
29
31
|
}
|
|
@@ -35,7 +37,7 @@ export const DialogResizableMixin = (superClass) =>
|
|
|
35
37
|
const resizer = document.createElement('div');
|
|
36
38
|
this._resizeListeners.start[direction] = (e) => this._startResize(e, direction);
|
|
37
39
|
this._resizeListeners.resize[direction] = (e) => this._resize(e, direction);
|
|
38
|
-
this._resizeListeners.stop[direction] = () => this._stopResize(direction);
|
|
40
|
+
this._resizeListeners.stop[direction] = (e) => this._stopResize(e, direction);
|
|
39
41
|
if (direction.length === 1) {
|
|
40
42
|
resizer.classList.add('edge');
|
|
41
43
|
}
|
|
@@ -60,6 +62,8 @@ export const DialogResizableMixin = (superClass) =>
|
|
|
60
62
|
|
|
61
63
|
if (e.button === 0 || e.touches) {
|
|
62
64
|
e.preventDefault();
|
|
65
|
+
// `preventDefault()` above cancels the native focus change, restored in `_stopResize()`
|
|
66
|
+
this.__resizeTracker.start(e);
|
|
63
67
|
|
|
64
68
|
this._originalBounds = this.$.overlay.getBounds();
|
|
65
69
|
const event = getMouseOrFirstTouchEvent(e);
|
|
@@ -127,10 +131,16 @@ export const DialogResizableMixin = (superClass) =>
|
|
|
127
131
|
}
|
|
128
132
|
|
|
129
133
|
/**
|
|
134
|
+
* @param {!MouseEvent | !TouchEvent} e
|
|
130
135
|
* @param {!DialogResizableDirection} direction
|
|
131
136
|
* @protected
|
|
132
137
|
*/
|
|
133
|
-
_stopResize(direction) {
|
|
138
|
+
_stopResize(e, direction) {
|
|
139
|
+
// Focus on click, not on resize, so that resizing the dialog doesn't interrupt editing
|
|
140
|
+
if (this.__resizeTracker.isClick(e) && !this.$.overlay.containsFocus()) {
|
|
141
|
+
this.focus({ preventScroll: true, focusVisible: isKeyboardActive() });
|
|
142
|
+
}
|
|
143
|
+
|
|
134
144
|
window.removeEventListener('mousemove', this._resizeListeners.resize[direction]);
|
|
135
145
|
window.removeEventListener('touchmove', this._resizeListeners.resize[direction]);
|
|
136
146
|
window.removeEventListener('mouseup', this._resizeListeners.stop[direction]);
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* Checks if the argument is a touch event and if so, returns a first touch.
|
|
9
|
+
* On `touchend`, `touches` is empty and the released point is in `changedTouches`.
|
|
9
10
|
* Otherwise, if the mouse event was passed, returns it as is.
|
|
10
11
|
*/
|
|
11
12
|
declare function getMouseOrFirstTouchEvent(e: MouseEvent | TouchEvent): MouseEvent | Touch;
|
|
@@ -18,3 +19,18 @@ export { getMouseOrFirstTouchEvent };
|
|
|
18
19
|
declare function eventInWindow(e: MouseEvent | TouchEvent): boolean;
|
|
19
20
|
|
|
20
21
|
export { eventInWindow };
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Remembers where a pointer gesture started, to tell a click from a drag once it ends.
|
|
25
|
+
*/
|
|
26
|
+
export declare class ClickTracker {
|
|
27
|
+
/**
|
|
28
|
+
* Stores the position where the gesture started.
|
|
29
|
+
*/
|
|
30
|
+
start(e: MouseEvent | TouchEvent): void;
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Returns true if the pointer hasn't moved since the gesture started.
|
|
34
|
+
*/
|
|
35
|
+
isClick(e: MouseEvent | TouchEvent): boolean;
|
|
36
|
+
}
|
|
@@ -6,13 +6,14 @@
|
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* Checks if the argument is a touch event and if so, returns a first touch.
|
|
9
|
+
* On `touchend`, `touches` is empty and the released point is in `changedTouches`.
|
|
9
10
|
* Otherwise, if the mouse event was passed, returns it as is.
|
|
10
11
|
* @param {!MouseEvent | !TouchEvent} e
|
|
11
12
|
* @return {!MouseEvent | !Touch}
|
|
12
13
|
* @protected
|
|
13
14
|
*/
|
|
14
15
|
export function getMouseOrFirstTouchEvent(e) {
|
|
15
|
-
return e.touches ? e.touches[0] : e;
|
|
16
|
+
return e.touches ? e.touches[0] || e.changedTouches[0] : e;
|
|
16
17
|
}
|
|
17
18
|
|
|
18
19
|
/**
|
|
@@ -24,3 +25,35 @@ export function getMouseOrFirstTouchEvent(e) {
|
|
|
24
25
|
export function eventInWindow(e) {
|
|
25
26
|
return e.clientX >= 0 && e.clientX <= window.innerWidth && e.clientY >= 0 && e.clientY <= window.innerHeight;
|
|
26
27
|
}
|
|
28
|
+
|
|
29
|
+
// Pointer movement in pixels above which a gesture is a drag, not a click.
|
|
30
|
+
// Same value as `TRACK_DISTANCE` in `@vaadin/component-base/src/gestures.js`.
|
|
31
|
+
const DRAG_DISTANCE = 5;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Remembers where a pointer gesture started, to tell a click from a drag once it ends.
|
|
35
|
+
*/
|
|
36
|
+
export class ClickTracker {
|
|
37
|
+
/** @type {{ x: number, y: number }} */
|
|
38
|
+
#start;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Stores the position where the gesture started.
|
|
42
|
+
* @param {!MouseEvent | !TouchEvent} e
|
|
43
|
+
*/
|
|
44
|
+
start(e) {
|
|
45
|
+
// Viewport coordinates, so scrolling during the gesture doesn't count as movement
|
|
46
|
+
const { clientX, clientY } = getMouseOrFirstTouchEvent(e);
|
|
47
|
+
this.#start = { x: clientX, y: clientY };
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Returns true if the pointer hasn't moved since the gesture started.
|
|
52
|
+
* @param {!MouseEvent | !TouchEvent} e
|
|
53
|
+
* @return {boolean}
|
|
54
|
+
*/
|
|
55
|
+
isClick(e) {
|
|
56
|
+
const { clientX, clientY } = getMouseOrFirstTouchEvent(e);
|
|
57
|
+
return Math.abs(clientX - this.#start.x) < DRAG_DISTANCE && Math.abs(clientY - this.#start.y) < DRAG_DISTANCE;
|
|
58
|
+
}
|
|
59
|
+
}
|
package/web-types.json
CHANGED