Skip to content

Commit 7f6426e

Browse files
fix: prevent browser drag event in custom handles example
* fix: prevent browser drag event when dragging and resizing custom handles * fix: prevent dragStart event when start drag if is pointerEvent by mouse * fix(grid-item): apply preventDefault on all start drag events starting from a mouse --------- Co-authored-by: llorenspujol <llorenspujol1@gmail.com>
1 parent a1a40a5 commit 7f6426e

File tree

3 files changed

+24
-13
lines changed

3 files changed

+24
-13
lines changed

projects/angular-grid-layout/src/lib/grid-item/grid-item.component.ts

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,17 @@ import {
22
AfterContentInit, ChangeDetectionStrategy, Component, ContentChild, ContentChildren, ElementRef, Inject, Input, NgZone, OnDestroy, OnInit,
33
QueryList, Renderer2, ViewChild
44
} from '@angular/core';
5-
import { BehaviorSubject, iif, merge, NEVER, Observable, Subject, Subscription } from 'rxjs';
6-
import { exhaustMap, filter, map, startWith, switchMap, take, takeUntil } from 'rxjs/operators';
7-
import { ktdPointerDown, ktdPointerUp, ktdPointerClient } from '../utils/pointer.utils';
8-
import { GRID_ITEM_GET_RENDER_DATA_TOKEN, KtdGridItemRenderDataTokenType } from '../grid.definitions';
5+
import { BehaviorSubject, NEVER, Observable, Subject, Subscription, iif, merge } from 'rxjs';
6+
import { exhaustMap, filter, map, startWith, switchMap, take, takeUntil, tap } from 'rxjs/operators';
7+
import { BooleanInput, coerceBooleanProperty } from '../coercion/boolean-property';
8+
import { NumberInput, coerceNumberProperty } from '../coercion/number-property';
99
import { KTD_GRID_DRAG_HANDLE, KtdGridDragHandle } from '../directives/drag-handle';
10+
import { KTD_GRID_ITEM_PLACEHOLDER, KtdGridItemPlaceholder } from '../directives/placeholder';
1011
import { KTD_GRID_RESIZE_HANDLE, KtdGridResizeHandle } from '../directives/resize-handle';
12+
import { GRID_ITEM_GET_RENDER_DATA_TOKEN, KtdGridItemRenderDataTokenType } from '../grid.definitions';
1113
import { KtdGridService } from '../grid.service';
1214
import { ktdOutsideZone } from '../utils/operators';
13-
import { BooleanInput, coerceBooleanProperty } from '../coercion/boolean-property';
14-
import { coerceNumberProperty, NumberInput } from '../coercion/number-property';
15-
import { KTD_GRID_ITEM_PLACEHOLDER, KtdGridItemPlaceholder } from '../directives/placeholder';
15+
import { ktdIsMouseEventOrMousePointerEvent, ktdPointerClient, ktdPointerDown, ktdPointerUp } from '../utils/pointer.utils';
1616

1717
@Component({
1818
standalone: true,
@@ -171,9 +171,9 @@ export class KtdGridItemComponent implements OnInit, OnDestroy, AfterContentInit
171171
// with our own dragging (e.g. `img` tags do it by default). Prevent the default action
172172
// to stop it from happening. Note that preventing on `dragstart` also seems to work, but
173173
// it's flaky and it fails if the user drags it away quickly. Also note that we only want
174-
// to do this for `mousedown` since doing the same for `touchstart` will stop any `click`
175-
// events from firing on touch devices.
176-
if (startEvent.target && (startEvent.target as HTMLElement).draggable && startEvent.type === 'mousedown') {
174+
// to do this for `mousedown` and `pointerdown` since doing the same for `touchstart` will
175+
// stop any `click` events from firing on touch devices.
176+
if (ktdIsMouseEventOrMousePointerEvent(startEvent)) {
177177
startEvent.preventDefault();
178178
}
179179

@@ -216,6 +216,11 @@ export class KtdGridItemComponent implements OnInit, OnDestroy, AfterContentInit
216216
this.renderer.setStyle(this.resizeElem.nativeElement, 'display', 'block');
217217
return ktdPointerDown(this.resizeElem.nativeElement);
218218
}
219+
}),
220+
tap((startEvent) => {
221+
if (ktdIsMouseEventOrMousePointerEvent(startEvent)) {
222+
startEvent.preventDefault();
223+
}
219224
})
220225
);
221226
}

projects/angular-grid-layout/src/lib/utils/pointer.utils.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,11 @@ export function ktdPointerClient(event: MouseEvent | TouchEvent): { clientX: num
5050
};
5151
}
5252

53+
export function ktdIsMouseEventOrMousePointerEvent(event: MouseEvent | TouchEvent | PointerEvent): boolean {
54+
return event.type === 'mousedown'
55+
|| (event.type === 'pointerdown' && (event as PointerEvent).pointerType === 'mouse');
56+
}
57+
5358
/** Returns true if browser supports pointer events */
5459
export function ktdSupportsPointerEvents(): boolean {
5560
return !!window.PointerEvent;
@@ -84,7 +89,7 @@ function ktdMouseOrTouchDown(element, touchNumber = 1): Observable<MouseEvent |
8489
* @param element, html element where to listen the events.
8590
* @param touchNumber number of the touch to track the event, default to the first one.
8691
*/
87-
function ktdMouserOrTouchMove(element: HTMLElement, touchNumber = 1): Observable<MouseEvent | TouchEvent> {
92+
function ktdMouseOrTouchMove(element: HTMLElement, touchNumber = 1): Observable<MouseEvent | TouchEvent> {
8893
return iif(
8994
() => ktdIsMobileOrTablet(),
9095
fromEvent<TouchEvent>(element, 'touchmove', activeEventListenerOptions as AddEventListenerOptions).pipe(
@@ -128,7 +133,7 @@ export function ktdPointerDown(element): Observable<MouseEvent | TouchEvent | Po
128133
return ktdMouseOrTouchDown(element);
129134
}
130135

131-
return fromEvent<PointerEvent>(element, 'pointerdown', passiveEventListenerOptions as AddEventListenerOptions).pipe(
136+
return fromEvent<PointerEvent>(element, 'pointerdown', activeEventListenerOptions as AddEventListenerOptions).pipe(
132137
filter((pointerEvent) => pointerEvent.isPrimary)
133138
)
134139
}
@@ -139,7 +144,7 @@ export function ktdPointerDown(element): Observable<MouseEvent | TouchEvent | Po
139144
*/
140145
export function ktdPointerMove(element): Observable<MouseEvent | TouchEvent | PointerEvent> {
141146
if (!ktdSupportsPointerEvents()) {
142-
return ktdMouserOrTouchMove(element);
147+
return ktdMouseOrTouchMove(element);
143148
}
144149
return fromEvent<PointerEvent>(element, 'pointermove', activeEventListenerOptions as AddEventListenerOptions).pipe(
145150
filter((pointerEvent) => pointerEvent.isPrimary),

projects/demo-app/src/app/real-life-example/table-sorting/table-sorting.component.scss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
width: 100%;
44
height: 100%;
55
overflow-y: auto;
6+
touch-action: none; // This is needed to make drag and drop on touch devices possible without interfering with the inner scroll.
67
}
78

89
table {

0 commit comments

Comments
 (0)