Switch pane resize handle to pointer events
internal/notesium/web/app/pane.js drove the sidebar/pane resize via mousedown + window-level mousemove/mouseup, which doesn't fire on touch (browsers only emulate mouse for taps, not drags). Replaced with pointer events: - @pointerdown on the handle (covers mouse, touch, pen). - setPointerCapture so we keep receiving pointermove/pointerup events when the pointer drifts off the handle. This eliminates the need for document-level listeners and avoids stuck-drag states when the user releases outside the window. - pointermove + pointerup + pointercancel listeners on the captured target only — when the capture ends they're removed regardless of whether the user is still on top of the handle. - Filter on event.pointerId so a second simultaneous touch (e.g., a multi-finger gesture) cannot hijack the in-progress resize. - event.button !== 0 guard rejects right-click / middle-click. - touch-action: none on the handle so the browser doesn't try to interpret a horizontal drag as a page scroll. CodeMirror's internal mousedown handlers in note.js / preview.js are left alone — those are link-click guards, not drags, and CodeMirror's own pointer support handles touch internally. Closes #20. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -4,9 +4,10 @@ var t = `
|
||||
<slot></slot>
|
||||
</div>
|
||||
<div v-show="resizing" v-text="paneWidth + 'px'" class="absolute bottom-0 right-0 p-4 text-gray-400 text-xs"></div>
|
||||
<div @dblclick="setDefaultWidth()" @mousedown="startResize"
|
||||
<div @dblclick="setDefaultWidth()" @pointerdown="startResize"
|
||||
:class="direction == 'right' ? 'left-full pl-1.5 mr-1.5' : 'right-full pr-1.5 ml-1.5'"
|
||||
class="z-50 absolute group inset-y-0 cursor-ew-resize flex items-center">
|
||||
class="z-50 absolute group inset-y-0 cursor-ew-resize flex items-center"
|
||||
style="touch-action: none;">
|
||||
<div class="h-8 w-1 rounded-full group-hover:bg-gray-300"></div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -26,29 +27,49 @@ export default {
|
||||
startResizeClientX: null,
|
||||
startResizePaneWidth: null,
|
||||
resizing: false,
|
||||
activePointerId: null,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
startResize(event) {
|
||||
// Only respond to primary button / single touch / pen.
|
||||
// event.button is 0 for primary mouse and is also 0 for
|
||||
// touch / pen via PointerEvent.
|
||||
if (event.button !== undefined && event.button !== 0) return;
|
||||
this.startResizeClientX = event.clientX;
|
||||
this.startResizePaneWidth = this.paneWidth;
|
||||
this.maxWidth = this.$el.parentElement.offsetWidth - 50;
|
||||
this.resizing = true;
|
||||
this.activePointerId = event.pointerId;
|
||||
event.preventDefault();
|
||||
document.addEventListener('mousemove', this.doResize);
|
||||
document.addEventListener('mouseup', this.stopResize);
|
||||
// Capture the pointer so we keep getting move/up events even
|
||||
// when the pointer leaves the handle. This replaces the
|
||||
// window-level mousemove/mouseup listeners and handles touch
|
||||
// and pen identically.
|
||||
try { event.target.setPointerCapture(event.pointerId); } catch (_) {}
|
||||
event.target.addEventListener('pointermove', this.doResize);
|
||||
event.target.addEventListener('pointerup', this.stopResize);
|
||||
event.target.addEventListener('pointercancel', this.stopResize);
|
||||
},
|
||||
doResize(event) {
|
||||
if (event.pointerId !== this.activePointerId) return;
|
||||
let draggedDistance = event.clientX - this.startResizeClientX;
|
||||
if (this.direction === 'left') draggedDistance = -draggedDistance;
|
||||
const newWidth = this.startResizePaneWidth + draggedDistance;
|
||||
if (newWidth <= this.maxWidth && newWidth >= this.minWidth ) this.paneWidth = newWidth;
|
||||
},
|
||||
stopResize() {
|
||||
stopResize(event) {
|
||||
if (event && event.pointerId !== this.activePointerId) return;
|
||||
this.resizing = false;
|
||||
this.savePreferredWidth();
|
||||
document.removeEventListener('mousemove', this.doResize);
|
||||
document.removeEventListener('mouseup', this.stopResize);
|
||||
const target = event && event.target;
|
||||
if (target) {
|
||||
try { target.releasePointerCapture(this.activePointerId); } catch (_) {}
|
||||
target.removeEventListener('pointermove', this.doResize);
|
||||
target.removeEventListener('pointerup', this.stopResize);
|
||||
target.removeEventListener('pointercancel', this.stopResize);
|
||||
}
|
||||
this.activePointerId = null;
|
||||
},
|
||||
setDefaultWidth() {
|
||||
this.paneWidth = this.defaultWidth;
|
||||
|
||||
Reference in New Issue
Block a user