From c6944b87cab0f24b320dc04dbf552ebf987d9281 Mon Sep 17 00:00:00 2001 From: pk Date: Thu, 1 Jan 2026 21:24:59 +0100 Subject: [PATCH] Switch to pointer events for mobile support --- package.json | 2 +- tp-hsplitter.js | 31 ++++++++++++++++++++++++------- tp-vsplitter.js | 31 ++++++++++++++++++++++++------- 3 files changed, 49 insertions(+), 15 deletions(-) diff --git a/package.json b/package.json index 765e0a8..d811ebf 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@tp/tp-splitter", - "version": "2.0.0", + "version": "2.1.0", "description": "", "main": "tp-splitter.js", "scripts": { diff --git a/tp-hsplitter.js b/tp-hsplitter.js index d6bb79b..ebb5bf6 100644 --- a/tp-hsplitter.js +++ b/tp-hsplitter.js @@ -38,6 +38,7 @@ class TpHSplitter extends LitElement { cursor: row-resize; opacity: 1; z-index: 2; + touch-action: none; } #splitter:hover { @@ -53,7 +54,7 @@ class TpHSplitter extends LitElement { return html`
-
+
`; } @@ -100,8 +101,8 @@ class TpHSplitter extends LitElement { disconnectedCallback() { super.disconnectedCallback(); - document.removeEventListener('mouseup', this._disableDrag) - document.removeEventListener('mousemove', this._resize); + document.removeEventListener('pointerup', this._disableDrag) + document.removeEventListener('pointermove', this._resize); document.body.style['userSelect'] = ''; } @@ -110,8 +111,14 @@ class TpHSplitter extends LitElement { } _enableDrag(e) { - document.addEventListener('mouseup', this._disableDrag) - document.addEventListener('mousemove', this._resize); + e.preventDefault(); + if (this.splitter && e.pointerId != null) { + this.splitter.setPointerCapture(e.pointerId); + this._activePointerId = e.pointerId; + } + + document.addEventListener('pointerup', this._disableDrag) + document.addEventListener('pointermove', this._resize, { passive: false }); document.body.style['userSelect'] = 'none'; this._startY = e.clientY; this._topHeight = this.top.offsetHeight; @@ -119,11 +126,20 @@ class TpHSplitter extends LitElement { } _disableDrag() { - document.removeEventListener('mouseup', this._disableDrag) - document.removeEventListener('mousemove', this._resize); + document.removeEventListener('pointerup', this._disableDrag) + document.removeEventListener('pointermove', this._resize); document.body.style['userSelect'] = ''; this.dragging = false; + if (this.splitter && this._activePointerId != null) { + try { + this.splitter.releasePointerCapture(this._activePointerId); + } catch (_) { + // ignore + } + this._activePointerId = null; + } + let finalTopHeight; if (this.lateResize && this._bufferedDelta) { finalTopHeight = this._topHeight + this._bufferedDelta; @@ -149,6 +165,7 @@ class TpHSplitter extends LitElement { } _resize(e) { + e.preventDefault(); const delta = e.clientY - this._startY; const totalHeight = this.offsetHeight; const minHeight = this.minSideHeight || 0; diff --git a/tp-vsplitter.js b/tp-vsplitter.js index d1231fe..d9b9ab0 100644 --- a/tp-vsplitter.js +++ b/tp-vsplitter.js @@ -33,6 +33,7 @@ class TpVSplitter extends LitElement { background: var(--tp-splitter-line-color, #3b3b3b); cursor: col-resize; opacity: 1; + touch-action: none; } #splitter:hover { @@ -48,7 +49,7 @@ class TpVSplitter extends LitElement { return html`
-
+
`; } @@ -99,8 +100,8 @@ class TpVSplitter extends LitElement { disconnectedCallback() { super.disconnectedCallback(); - document.removeEventListener('mouseup', this._disableDrag) - document.removeEventListener('mousemove', this._resize); + document.removeEventListener('pointerup', this._disableDrag) + document.removeEventListener('pointermove', this._resize); document.body.style['userSelect'] = ''; } @@ -109,8 +110,14 @@ class TpVSplitter extends LitElement { } _enableDrag(e) { - document.addEventListener('mouseup', this._disableDrag) - document.addEventListener('mousemove', this._resize); + e.preventDefault(); + if (this.splitter && e.pointerId != null) { + this.splitter.setPointerCapture(e.pointerId); + this._activePointerId = e.pointerId; + } + + document.addEventListener('pointerup', this._disableDrag) + document.addEventListener('pointermove', this._resize, { passive: false }); document.body.style['userSelect'] = 'none'; this._startX = e.clientX; this._leftWidth = this.left.offsetWidth; @@ -118,11 +125,20 @@ class TpVSplitter extends LitElement { } _disableDrag() { - document.removeEventListener('mouseup', this._disableDrag) - document.removeEventListener('mousemove', this._resize); + document.removeEventListener('pointerup', this._disableDrag) + document.removeEventListener('pointermove', this._resize); document.body.style['userSelect'] = ''; this.dragging = false; + if (this.splitter && this._activePointerId != null) { + try { + this.splitter.releasePointerCapture(this._activePointerId); + } catch (_) { + // ignore + } + this._activePointerId = null; + } + let finalLeftWidth; if (this.lateResize && this._bufferedDelta) { finalLeftWidth = this._leftWidth + this._bufferedDelta; @@ -148,6 +164,7 @@ class TpVSplitter extends LitElement { } _resize(e) { + e.preventDefault(); const delta = e.clientX - this._startX; const totalWidth = this.offsetWidth; const minWidth = this.minSideWidth || 0;