From fab93ab6874ba898bbacc1bb426d7b7dd8035e45 Mon Sep 17 00:00:00 2001 From: nexiumbiz-debug <265948173+nexiumbiz-debug@users.noreply.github.com> Date: Sun, 14 Jun 2026 04:47:28 -0400 Subject: [PATCH] fix: reset drag direction between drags --- .../src/lib/gridsterDraggable.ts | 8 ++ .../src/lib/tests/gridsterDraggable.spec.ts | 86 +++++++++++++++++++ 2 files changed, 94 insertions(+) create mode 100644 projects/angular-gridster2/src/lib/tests/gridsterDraggable.spec.ts diff --git a/projects/angular-gridster2/src/lib/gridsterDraggable.ts b/projects/angular-gridster2/src/lib/gridsterDraggable.ts index 7103bb6c..ce9a077b 100644 --- a/projects/angular-gridster2/src/lib/gridsterDraggable.ts +++ b/projects/angular-gridster2/src/lib/gridsterDraggable.ts @@ -88,6 +88,8 @@ export class GridsterDraggable { e.stopPropagation(); e.preventDefault(); + this.resetLastMouse(e); + this.zone.runOutsideAngular(() => { this.mousemove = this.gridsterItem.renderer.listen('document', 'mousemove', this.dragMove); this.touchmove = this.gridster.renderer.listen(this.gridster.el, 'touchmove', this.dragMove); @@ -245,6 +247,7 @@ export class GridsterDraggable { this.gridster.dragInProgress = false; this.gridster.updateGrid(); this.path = []; + this.resetLastMouse(); const options = this.gridster.options(); if (options.draggable && options.draggable.stop) { Promise.resolve(options.draggable.stop(this.gridsterItem.item(), this.gridsterItem, e)).then(this.makeDrag, this.cancelDrag); @@ -446,4 +449,9 @@ export class GridsterDraggable { } return directions; } + + private resetLastMouse(e?: MouseEvent): void { + this.lastMouse.clientX = e?.clientX ?? 0; + this.lastMouse.clientY = e?.clientY ?? 0; + } } diff --git a/projects/angular-gridster2/src/lib/tests/gridsterDraggable.spec.ts b/projects/angular-gridster2/src/lib/tests/gridsterDraggable.spec.ts new file mode 100644 index 00000000..db62fd97 --- /dev/null +++ b/projects/angular-gridster2/src/lib/tests/gridsterDraggable.spec.ts @@ -0,0 +1,86 @@ +import { DirTypes } from '../gridsterConfig'; +import { GridsterDraggable } from '../gridsterDraggable'; + +interface DraggableWithPrivate { + getDirections(e: MouseEvent): string[]; +} + +function createDraggable(): GridsterDraggable { + const gridsterEl = document.createElement('div'); + const itemEl = document.createElement('div'); + const removeListener = vi.fn(); + const renderer = { + addClass: vi.fn(), + listen: vi.fn(() => removeListener), + removeClass: vi.fn() + }; + const item = { cols: 1, rows: 1, x: 0, y: 0 }; + const gridster = { + $options: () => ({ + dirType: DirTypes.LTR, + margin: 10, + outerMarginBottom: null, + outerMarginLeft: null, + outerMarginRight: null, + outerMarginTop: null + }), + dragInProgress: false, + el: gridsterEl, + options: () => ({ + draggable: {} + }), + previewStyle: vi.fn(), + renderer, + updateGrid: vi.fn() + }; + const gridsterItem = { + $item: () => item, + el: itemEl, + gridster, + height: 100, + item: () => item, + left: 10, + renderer, + top: 20, + width: 100 + }; + const zone = { + run: (callback: () => void) => callback(), + runOutsideAngular: (callback: () => void) => callback() + }; + const cdRef = { + markForCheck: vi.fn() + }; + + return new GridsterDraggable(gridsterItem as never, gridster as never, zone as never, cdRef as never); +} + +describe('gridster draggable', () => { + it('starts each drag with the current pointer as the direction baseline', () => { + const draggable = createDraggable(); + const draggablePrivate = draggable as unknown as DraggableWithPrivate; + draggable.lastMouse.clientX = 1000; + draggable.lastMouse.clientY = 600; + + draggable.dragStart( + new MouseEvent('mousedown', { + button: 0, + clientX: 1100, + clientY: 700 + }) + ); + + expect(draggable.lastMouse).toEqual({ + clientX: 1100, + clientY: 700 + }); + expect( + draggablePrivate.getDirections( + new MouseEvent('mousemove', { + clientX: 1090, + clientY: 700 + }) + ) + ).toEqual(['LEFT']); + }); +});