From 742cb6f3774259f213d14a9771aa1e5a060ad94a Mon Sep 17 00:00:00 2001 From: pk Date: Fri, 26 Jun 2026 12:05:33 +0200 Subject: [PATCH] Change dragging mechanims to fix weird dragging behavior in modal dialogs. --- package.json | 2 +- tp-dialog.js | 59 +++++++++++++++++++++++++++++----------------------- 2 files changed, 34 insertions(+), 27 deletions(-) diff --git a/package.json b/package.json index c633378..9f91cc8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@tp/tp-dialog", - "version": "1.5.2", + "version": "1.5.3", "description": "", "main": "tp-dialog.js", "scripts": { diff --git a/tp-dialog.js b/tp-dialog.js index 58c0465..4c07054 100644 --- a/tp-dialog.js +++ b/tp-dialog.js @@ -52,8 +52,6 @@ class TpDialog extends EventHelpers(LitElement) { border: var(--tp-dialog-border); padding: var(--tp-dialog-padding); pointer-events: all; - left: var(--tp-dialog-offset-x, 0px); - top: var(--tp-dialog-offset-y, 0px); display: flex; flex-direction: column; } @@ -287,24 +285,46 @@ class TpDialog extends EventHelpers(LitElement) { _resetPosition() { this._offsetX = 0; this._offsetY = 0; - this.style.removeProperty('--tp-dialog-offset-x'); - this.style.removeProperty('--tp-dialog-offset-y'); this.removeAttribute('constrained'); const dialogEl = this.dialog; 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('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) { if (this.unmovable) return; if (e.button !== 0) return; // Only drag with left/main pointer button + const rect = this._pinDialogPosition(); + this._startX = e.clientX; this._startY = e.clientY; - this._startOffsetX = this._offsetX || 0; - this._startOffsetY = this._offsetY || 0; + this._startLeft = rect.left; + this._startTop = rect.top; const dragHandle = this.shadowRoot.querySelector('.drag-handle'); if (dragHandle && typeof dragHandle.setPointerCapture === 'function') { @@ -322,11 +342,9 @@ class TpDialog extends EventHelpers(LitElement) { _onDragMove(e) { const dx = e.clientX - this._startX; 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.style.setProperty('--tp-dialog-offset-y', `${this._offsetY}px`); + this.dialog.style.left = `${this._startLeft + dx}px`; + this.dialog.style.top = `${this._startTop + dy}px`; } _onDragEnd(e) { @@ -352,13 +370,13 @@ class TpDialog extends EventHelpers(LitElement) { // Once the user starts resizing, content must scroll inside the fixed box. this.setAttribute('constrained', ''); - const rect = this.dialog.getBoundingClientRect(); + const rect = this._pinDialogPosition(); this._startWidth = rect.width; this._startHeight = rect.height; this._startX = e.clientX; this._startY = e.clientY; - this._startOffsetX = this._offsetX || 0; - this._startOffsetY = this._offsetY || 0; + this._startLeft = rect.left; + this._startTop = rect.top; const resizeHandle = this.shadowRoot.querySelector('.resize-handle'); if (resizeHandle && typeof resizeHandle.setPointerCapture === 'function') { @@ -380,21 +398,10 @@ class TpDialog extends EventHelpers(LitElement) { const newWidth = Math.max(150, this._startWidth + dw); 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.height = `${newHeight}px`; - this.style.setProperty('--tp-dialog-offset-x', `${this._offsetX}px`); - this.style.setProperty('--tp-dialog-offset-y', `${this._offsetY}px`); + this.dialog.style.left = `${this._startLeft}px`; + this.dialog.style.top = `${this._startTop}px`; } _onResizeEnd(e) {