Skip to content

Commit f361491

Browse files
committed
refactor: extract dialog bounds logic into separate class
1 parent bdcd05b commit f361491

File tree

4 files changed

+87
-26
lines changed

4 files changed

+87
-26
lines changed

packages/dialog/src/vaadin-dialog-draggable-mixin.js

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
55
*/
66
import { isTouch } from '@vaadin/component-base/src/browser-utils.js';
7-
import { eventInWindow, getMouseOrFirstTouchEvent } from './vaadin-dialog-utils.js';
7+
import { DialogManager, eventInWindow, getMouseOrFirstTouchEvent } from './vaadin-dialog-utils.js';
88

99
/**
1010
* @polymerMixin
@@ -47,8 +47,10 @@ export const DialogDraggableMixin = (superClass) =>
4747
/** @protected */
4848
ready() {
4949
super.ready();
50-
this._originalBounds = {};
51-
this._originalMouseCoords = {};
50+
51+
// Get or create an instance of manager
52+
this.__manager = DialogManager.create(this);
53+
5254
this._startDrag = this._startDrag.bind(this);
5355
this._drag = this._drag.bind(this);
5456
this._stopDrag = this._stopDrag.bind(this);
@@ -86,15 +88,12 @@ export const DialogDraggableMixin = (superClass) =>
8688
if (!isDraggable) {
8789
e.preventDefault();
8890
}
89-
this._originalBounds = this.$.overlay.getBounds();
90-
const event = getMouseOrFirstTouchEvent(e);
91-
this._originalMouseCoords = { top: event.pageY, left: event.pageX };
9291
window.addEventListener('mouseup', this._stopDrag);
9392
window.addEventListener('touchend', this._stopDrag);
9493
window.addEventListener('mousemove', this._drag);
9594
window.addEventListener('touchmove', this._drag);
96-
this.$.overlay.setBounds(this._originalBounds);
97-
this.$.overlay.setAttribute('has-bounds-set', '');
95+
96+
this.__manager.handleEvent(e);
9897
}
9998
}
10099
}
@@ -103,10 +102,9 @@ export const DialogDraggableMixin = (superClass) =>
103102
_drag(e) {
104103
const event = getMouseOrFirstTouchEvent(e);
105104
if (eventInWindow(event)) {
106-
const top = this._originalBounds.top + (event.pageY - this._originalMouseCoords.top);
107-
const left = this._originalBounds.left + (event.pageX - this._originalMouseCoords.left);
108-
this.top = top;
109-
this.left = left;
105+
const { top, left } = this.__manager.bounds;
106+
this.top = top + this.__manager.getEventY(event);
107+
this.left = left + this.__manager.getEventX(event);
110108
}
111109
}
112110

packages/dialog/src/vaadin-dialog-resizable-mixin.js

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
* Copyright (c) 2017 - 2025 Vaadin Ltd.
44
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
55
*/
6-
import { eventInWindow, getMouseOrFirstTouchEvent } from './vaadin-dialog-utils.js';
6+
import { DialogManager, eventInWindow, getMouseOrFirstTouchEvent } from './vaadin-dialog-utils.js';
7+
78
/**
89
* @polymerMixin
910
*/
@@ -26,8 +27,10 @@ export const DialogResizableMixin = (superClass) =>
2627
/** @protected */
2728
ready() {
2829
super.ready();
29-
this._originalBounds = {};
30-
this._originalMouseCoords = {};
30+
31+
// Get or create an instance of manager
32+
this.__manager = DialogManager.create(this);
33+
3134
this._resizeListeners = { start: {}, resize: {}, stop: {} };
3235
this._addResizeListeners();
3336
}
@@ -65,15 +68,12 @@ export const DialogResizableMixin = (superClass) =>
6568
if (e.button === 0 || e.touches) {
6669
e.preventDefault();
6770

68-
this._originalBounds = this.$.overlay.getBounds();
69-
const event = getMouseOrFirstTouchEvent(e);
70-
this._originalMouseCoords = { top: event.pageY, left: event.pageX };
7171
window.addEventListener('mousemove', this._resizeListeners.resize[direction]);
7272
window.addEventListener('touchmove', this._resizeListeners.resize[direction]);
7373
window.addEventListener('mouseup', this._resizeListeners.stop[direction]);
7474
window.addEventListener('touchend', this._resizeListeners.stop[direction]);
75-
this.$.overlay.setBounds(this._originalBounds);
76-
this.$.overlay.setAttribute('has-bounds-set', '');
75+
76+
this.__manager.handleEvent(e);
7777
}
7878
}
7979

@@ -86,34 +86,38 @@ export const DialogResizableMixin = (superClass) =>
8686
const event = getMouseOrFirstTouchEvent(e);
8787
if (eventInWindow(event)) {
8888
const minimumSize = 40;
89+
const { height: boundsHeight, width: boundsWidth, top: boundsTop, left: boundsLeft } = this.__manager.bounds;
90+
const eventX = this.__manager.getEventX(event);
91+
const eventY = this.__manager.getEventY(event);
92+
8993
resizer.split('').forEach((direction) => {
9094
switch (direction) {
9195
case 'n': {
92-
const height = this._originalBounds.height - (event.pageY - this._originalMouseCoords.top);
93-
const top = this._originalBounds.top + (event.pageY - this._originalMouseCoords.top);
96+
const height = boundsHeight - eventY;
97+
const top = boundsTop + eventY;
9498
if (height > minimumSize) {
9599
this.top = top;
96100
this.height = height;
97101
}
98102
break;
99103
}
100104
case 'e': {
101-
const width = this._originalBounds.width + (event.pageX - this._originalMouseCoords.left);
105+
const width = boundsWidth + eventX;
102106
if (width > minimumSize) {
103107
this.width = width;
104108
}
105109
break;
106110
}
107111
case 's': {
108-
const height = this._originalBounds.height + (event.pageY - this._originalMouseCoords.top);
112+
const height = boundsHeight + eventY;
109113
if (height > minimumSize) {
110114
this.height = height;
111115
}
112116
break;
113117
}
114118
case 'w': {
115-
const width = this._originalBounds.width - (event.pageX - this._originalMouseCoords.left);
116-
const left = this._originalBounds.left + (event.pageX - this._originalMouseCoords.left);
119+
const width = boundsWidth - eventX;
120+
const left = boundsLeft + eventX;
117121
if (width > minimumSize) {
118122
this.left = left;
119123
this.width = width;

packages/dialog/src/vaadin-dialog-utils.d.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,18 @@ export { getMouseOrFirstTouchEvent };
1818
declare function eventInWindow(e: MouseEvent | TouchEvent): boolean;
1919

2020
export { eventInWindow };
21+
22+
/**
23+
* Internal class handling dialog bounds and coordinates.
24+
*/
25+
export declare class DialogManager {
26+
static create(dialog: HTMLElement): DialogManager;
27+
28+
readonly bounds: { top: number; left: number; width: number; height: number };
29+
30+
handleEvent(event: MouseEvent | Touch): void;
31+
32+
getEventX(event: MouseEvent | Touch): number;
33+
34+
getEventY(event: MouseEvent | Touch): number;
35+
}

packages/dialog/src/vaadin-dialog-utils.js

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,47 @@ export function getMouseOrFirstTouchEvent(e) {
2424
export function eventInWindow(e) {
2525
return e.clientX >= 0 && e.clientX <= window.innerWidth && e.clientY >= 0 && e.clientY <= window.innerHeight;
2626
}
27+
28+
const instancesMap = new WeakMap();
29+
30+
/**
31+
* Internal class handling dialog bounds and coordinates.
32+
*/
33+
export class DialogManager {
34+
static create(dialog) {
35+
if (instancesMap.has(dialog)) {
36+
return instancesMap.get(dialog);
37+
}
38+
39+
const instance = new DialogManager(dialog);
40+
instancesMap.set(dialog, instance);
41+
return instance;
42+
}
43+
44+
constructor(dialog) {
45+
this.host = dialog;
46+
this.overlay = dialog.$.overlay;
47+
this._originalBounds = {};
48+
this._originalMouseCoords = {};
49+
}
50+
51+
handleEvent(e) {
52+
const event = getMouseOrFirstTouchEvent(e);
53+
this._originalBounds = this.overlay.getBounds();
54+
this._originalMouseCoords = { top: event.pageY, left: event.pageX };
55+
this.overlay.setBounds(this._originalBounds);
56+
this.overlay.setAttribute('has-bounds-set', '');
57+
}
58+
59+
get bounds() {
60+
return this._originalBounds;
61+
}
62+
63+
getEventX(event) {
64+
return event.pageX - this._originalMouseCoords.left;
65+
}
66+
67+
getEventY(event) {
68+
return event.pageY - this._originalMouseCoords.top;
69+
}
70+
}

0 commit comments

Comments
 (0)