Skip to content

Commit

Permalink
fix: prevent browser drag event in custom handles example
Browse files Browse the repository at this point in the history
* 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>
  • Loading branch information
manolumjm and llorenspujol authored Aug 19, 2024
1 parent a1a40a5 commit 7f6426e
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,17 @@ import {
AfterContentInit, ChangeDetectionStrategy, Component, ContentChild, ContentChildren, ElementRef, Inject, Input, NgZone, OnDestroy, OnInit,
QueryList, Renderer2, ViewChild
} from '@angular/core';
import { BehaviorSubject, iif, merge, NEVER, Observable, Subject, Subscription } from 'rxjs';
import { exhaustMap, filter, map, startWith, switchMap, take, takeUntil } from 'rxjs/operators';
import { ktdPointerDown, ktdPointerUp, ktdPointerClient } from '../utils/pointer.utils';
import { GRID_ITEM_GET_RENDER_DATA_TOKEN, KtdGridItemRenderDataTokenType } from '../grid.definitions';
import { BehaviorSubject, NEVER, Observable, Subject, Subscription, iif, merge } from 'rxjs';
import { exhaustMap, filter, map, startWith, switchMap, take, takeUntil, tap } from 'rxjs/operators';
import { BooleanInput, coerceBooleanProperty } from '../coercion/boolean-property';
import { NumberInput, coerceNumberProperty } from '../coercion/number-property';
import { KTD_GRID_DRAG_HANDLE, KtdGridDragHandle } from '../directives/drag-handle';
import { KTD_GRID_ITEM_PLACEHOLDER, KtdGridItemPlaceholder } from '../directives/placeholder';
import { KTD_GRID_RESIZE_HANDLE, KtdGridResizeHandle } from '../directives/resize-handle';
import { GRID_ITEM_GET_RENDER_DATA_TOKEN, KtdGridItemRenderDataTokenType } from '../grid.definitions';
import { KtdGridService } from '../grid.service';
import { ktdOutsideZone } from '../utils/operators';
import { BooleanInput, coerceBooleanProperty } from '../coercion/boolean-property';
import { coerceNumberProperty, NumberInput } from '../coercion/number-property';
import { KTD_GRID_ITEM_PLACEHOLDER, KtdGridItemPlaceholder } from '../directives/placeholder';
import { ktdIsMouseEventOrMousePointerEvent, ktdPointerClient, ktdPointerDown, ktdPointerUp } from '../utils/pointer.utils';

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

Expand Down Expand Up @@ -216,6 +216,11 @@ export class KtdGridItemComponent implements OnInit, OnDestroy, AfterContentInit
this.renderer.setStyle(this.resizeElem.nativeElement, 'display', 'block');
return ktdPointerDown(this.resizeElem.nativeElement);
}
}),
tap((startEvent) => {
if (ktdIsMouseEventOrMousePointerEvent(startEvent)) {
startEvent.preventDefault();
}
})
);
}
Expand Down
11 changes: 8 additions & 3 deletions projects/angular-grid-layout/src/lib/utils/pointer.utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,11 @@ export function ktdPointerClient(event: MouseEvent | TouchEvent): { clientX: num
};
}

export function ktdIsMouseEventOrMousePointerEvent(event: MouseEvent | TouchEvent | PointerEvent): boolean {
return event.type === 'mousedown'
|| (event.type === 'pointerdown' && (event as PointerEvent).pointerType === 'mouse');
}

/** Returns true if browser supports pointer events */
export function ktdSupportsPointerEvents(): boolean {
return !!window.PointerEvent;
Expand Down Expand Up @@ -84,7 +89,7 @@ function ktdMouseOrTouchDown(element, touchNumber = 1): Observable<MouseEvent |
* @param element, html element where to listen the events.
* @param touchNumber number of the touch to track the event, default to the first one.
*/
function ktdMouserOrTouchMove(element: HTMLElement, touchNumber = 1): Observable<MouseEvent | TouchEvent> {
function ktdMouseOrTouchMove(element: HTMLElement, touchNumber = 1): Observable<MouseEvent | TouchEvent> {
return iif(
() => ktdIsMobileOrTablet(),
fromEvent<TouchEvent>(element, 'touchmove', activeEventListenerOptions as AddEventListenerOptions).pipe(
Expand Down Expand Up @@ -128,7 +133,7 @@ export function ktdPointerDown(element): Observable<MouseEvent | TouchEvent | Po
return ktdMouseOrTouchDown(element);
}

return fromEvent<PointerEvent>(element, 'pointerdown', passiveEventListenerOptions as AddEventListenerOptions).pipe(
return fromEvent<PointerEvent>(element, 'pointerdown', activeEventListenerOptions as AddEventListenerOptions).pipe(
filter((pointerEvent) => pointerEvent.isPrimary)
)
}
Expand All @@ -139,7 +144,7 @@ export function ktdPointerDown(element): Observable<MouseEvent | TouchEvent | Po
*/
export function ktdPointerMove(element): Observable<MouseEvent | TouchEvent | PointerEvent> {
if (!ktdSupportsPointerEvents()) {
return ktdMouserOrTouchMove(element);
return ktdMouseOrTouchMove(element);
}
return fromEvent<PointerEvent>(element, 'pointermove', activeEventListenerOptions as AddEventListenerOptions).pipe(
filter((pointerEvent) => pointerEvent.isPrimary),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
width: 100%;
height: 100%;
overflow-y: auto;
touch-action: none; // This is needed to make drag and drop on touch devices possible without interfering with the inner scroll.
}

table {
Expand Down

0 comments on commit 7f6426e

Please sign in to comment.