Change dragging mechanims to fix weird dragging behavior in modal dialogs.

This commit is contained in:
2026-06-26 12:05:33 +02:00
parent 084e081607
commit 742cb6f377
2 changed files with 34 additions and 27 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "@tp/tp-dialog", "name": "@tp/tp-dialog",
"version": "1.5.2", "version": "1.5.3",
"description": "", "description": "",
"main": "tp-dialog.js", "main": "tp-dialog.js",
"scripts": { "scripts": {
+33 -26
View File
@@ -52,8 +52,6 @@ class TpDialog extends EventHelpers(LitElement) {
border: var(--tp-dialog-border); border: var(--tp-dialog-border);
padding: var(--tp-dialog-padding); padding: var(--tp-dialog-padding);
pointer-events: all; pointer-events: all;
left: var(--tp-dialog-offset-x, 0px);
top: var(--tp-dialog-offset-y, 0px);
display: flex; display: flex;
flex-direction: column; flex-direction: column;
} }
@@ -287,24 +285,46 @@ class TpDialog extends EventHelpers(LitElement) {
_resetPosition() { _resetPosition() {
this._offsetX = 0; this._offsetX = 0;
this._offsetY = 0; this._offsetY = 0;
this.style.removeProperty('--tp-dialog-offset-x');
this.style.removeProperty('--tp-dialog-offset-y');
this.removeAttribute('constrained'); this.removeAttribute('constrained');
const dialogEl = this.dialog; const dialogEl = this.dialog;
if (dialogEl) { if (dialogEl) {
dialogEl.style.removeProperty('position');
dialogEl.style.removeProperty('inset');
dialogEl.style.removeProperty('left');
dialogEl.style.removeProperty('top');
dialogEl.style.removeProperty('right');
dialogEl.style.removeProperty('bottom');
dialogEl.style.removeProperty('margin');
dialogEl.style.removeProperty('width'); dialogEl.style.removeProperty('width');
dialogEl.style.removeProperty('height'); dialogEl.style.removeProperty('height');
} }
} }
_pinDialogPosition() {
const dialogEl = this.dialog;
const rect = dialogEl.getBoundingClientRect();
dialogEl.style.position = 'fixed';
dialogEl.style.inset = 'auto';
dialogEl.style.left = `${rect.left}px`;
dialogEl.style.top = `${rect.top}px`;
dialogEl.style.right = 'auto';
dialogEl.style.bottom = 'auto';
dialogEl.style.margin = '0';
return rect;
}
_onDragStart(e) { _onDragStart(e) {
if (this.unmovable) return; if (this.unmovable) return;
if (e.button !== 0) return; // Only drag with left/main pointer button if (e.button !== 0) return; // Only drag with left/main pointer button
const rect = this._pinDialogPosition();
this._startX = e.clientX; this._startX = e.clientX;
this._startY = e.clientY; this._startY = e.clientY;
this._startOffsetX = this._offsetX || 0; this._startLeft = rect.left;
this._startOffsetY = this._offsetY || 0; this._startTop = rect.top;
const dragHandle = this.shadowRoot.querySelector('.drag-handle'); const dragHandle = this.shadowRoot.querySelector('.drag-handle');
if (dragHandle && typeof dragHandle.setPointerCapture === 'function') { if (dragHandle && typeof dragHandle.setPointerCapture === 'function') {
@@ -322,11 +342,9 @@ class TpDialog extends EventHelpers(LitElement) {
_onDragMove(e) { _onDragMove(e) {
const dx = e.clientX - this._startX; const dx = e.clientX - this._startX;
const dy = e.clientY - this._startY; const dy = e.clientY - this._startY;
this._offsetX = this._startOffsetX + dx;
this._offsetY = this._startOffsetY + dy;
this.style.setProperty('--tp-dialog-offset-x', `${this._offsetX}px`); this.dialog.style.left = `${this._startLeft + dx}px`;
this.style.setProperty('--tp-dialog-offset-y', `${this._offsetY}px`); this.dialog.style.top = `${this._startTop + dy}px`;
} }
_onDragEnd(e) { _onDragEnd(e) {
@@ -352,13 +370,13 @@ class TpDialog extends EventHelpers(LitElement) {
// Once the user starts resizing, content must scroll inside the fixed box. // Once the user starts resizing, content must scroll inside the fixed box.
this.setAttribute('constrained', ''); this.setAttribute('constrained', '');
const rect = this.dialog.getBoundingClientRect(); const rect = this._pinDialogPosition();
this._startWidth = rect.width; this._startWidth = rect.width;
this._startHeight = rect.height; this._startHeight = rect.height;
this._startX = e.clientX; this._startX = e.clientX;
this._startY = e.clientY; this._startY = e.clientY;
this._startOffsetX = this._offsetX || 0; this._startLeft = rect.left;
this._startOffsetY = this._offsetY || 0; this._startTop = rect.top;
const resizeHandle = this.shadowRoot.querySelector('.resize-handle'); const resizeHandle = this.shadowRoot.querySelector('.resize-handle');
if (resizeHandle && typeof resizeHandle.setPointerCapture === 'function') { if (resizeHandle && typeof resizeHandle.setPointerCapture === 'function') {
@@ -380,21 +398,10 @@ class TpDialog extends EventHelpers(LitElement) {
const newWidth = Math.max(150, this._startWidth + dw); const newWidth = Math.max(150, this._startWidth + dw);
const newHeight = Math.max(100, this._startHeight + dh); const newHeight = Math.max(100, this._startHeight + dh);
const dw_actual = newWidth - this._startWidth;
const dh_actual = newHeight - this._startHeight;
this._offsetX = this._startOffsetX + dw_actual / 2;
this._offsetY = this._startOffsetY + dh_actual / 2;
const originalTop = (window.innerHeight - newHeight) / 2;
if (originalTop + this._offsetY < 0) {
this._offsetY = -originalTop;
}
this.dialog.style.width = `${newWidth}px`; this.dialog.style.width = `${newWidth}px`;
this.dialog.style.height = `${newHeight}px`; this.dialog.style.height = `${newHeight}px`;
this.style.setProperty('--tp-dialog-offset-x', `${this._offsetX}px`); this.dialog.style.left = `${this._startLeft}px`;
this.style.setProperty('--tp-dialog-offset-y', `${this._offsetY}px`); this.dialog.style.top = `${this._startTop}px`;
} }
_onResizeEnd(e) { _onResizeEnd(e) {