diff --git a/projects/angular-resizable-element/src/lib/resize-handle.directive.ts b/projects/angular-resizable-element/src/lib/resize-handle.directive.ts index 3367a5b..20451a4 100644 --- a/projects/angular-resizable-element/src/lib/resize-handle.directive.ts +++ b/projects/angular-resizable-element/src/lib/resize-handle.directive.ts @@ -12,6 +12,7 @@ import { fromEvent, merge, Subject } from 'rxjs'; import { takeUntil } from 'rxjs/operators'; import { ResizableDirective } from './resizable.directive'; import { Edges } from './interfaces/edges.interface'; +import { getListenOptions } from './util/get-listen-options'; import { IS_TOUCH_DEVICE } from './util/is-touch-device'; /** @@ -173,8 +174,10 @@ export class ResizeHandleDirective implements OnInit, OnDestroy { } private listenOnTheHost(eventName: string) { - return fromEvent(this.element.nativeElement, eventName).pipe( - takeUntil(this.destroy$), - ); + return fromEvent( + this.element.nativeElement, + eventName, + getListenOptions(eventName), + ).pipe(takeUntil(this.destroy$)); } } diff --git a/projects/angular-resizable-element/src/lib/util/get-listen-options.ts b/projects/angular-resizable-element/src/lib/util/get-listen-options.ts new file mode 100644 index 0000000..1f34a3c --- /dev/null +++ b/projects/angular-resizable-element/src/lib/util/get-listen-options.ts @@ -0,0 +1,14 @@ +/** + * Options for fromEvent when listening on the host. + * Touch events need passive: false so preventDefault can be called. + * @hidden + */ +export function getListenOptions( + eventName: string, +): { passive: false } | Record { + const isTouchEvent = + eventName === 'touchstart' || + eventName === 'touchend' || + eventName === 'touchcancel'; + return isTouchEvent ? { passive: false } : {}; +} diff --git a/projects/angular-resizable-element/src/test/resizable.spec.ts b/projects/angular-resizable-element/src/test/resizable.spec.ts index 0abee81..6231ff1 100644 --- a/projects/angular-resizable-element/src/test/resizable.spec.ts +++ b/projects/angular-resizable-element/src/test/resizable.spec.ts @@ -5,6 +5,7 @@ import { ResizeEvent, ResizeHandleDirective, } from 'angular-resizable-element'; +import { getListenOptions } from '../lib/util/get-listen-options'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { expect } from 'chai'; import * as sinon from 'sinon'; @@ -506,6 +507,20 @@ describe('resizable directive', () => { }); }); + describe('touch event listeners', () => { + ['touchstart', 'touchend', 'touchcancel'].forEach((eventName) => { + it(`when eventName is ${eventName}, getListenOptions returns passive: false so fromEvent is called with passive: false`, () => { + expect(getListenOptions(eventName)).to.deep.equal({ passive: false }); + }); + }); + + ['mousedown', 'mouseup'].forEach((eventName) => { + it(`when eventName is ${eventName}, getListenOptions returns empty options`, () => { + expect(getListenOptions(eventName)).to.deep.equal({}); + }); + }); + }); + describe('handle outside of element', () => { let domEvents: Array<{ name: string;