diff --git a/src/cdk/drag-drop/drag.spec.ts b/src/cdk/drag-drop/drag.spec.ts index b92cf03558d..d131461ed73 100644 --- a/src/cdk/drag-drop/drag.spec.ts +++ b/src/cdk/drag-drop/drag.spec.ts @@ -435,6 +435,14 @@ describe('CdkDrag', () => { }).not.toThrow(); })); + it('should not disable native drag interactions when there is a drag handle', () => { + const fixture = createComponent(StandaloneDraggableWithHandle); + fixture.detectChanges(); + const dragElement = fixture.componentInstance.dragElement.nativeElement; + expect(dragElement.style.touchAction) + .not.toEqual('none', 'should not disable touchAction on when there is a drag handle'); + }); + }); describe('draggable with a handle', () => { diff --git a/src/cdk/drag-drop/drag.ts b/src/cdk/drag-drop/drag.ts index e99744d3d91..35c9a5f29ea 100644 --- a/src/cdk/drag-drop/drag.ts +++ b/src/cdk/drag-drop/drag.ts @@ -30,7 +30,7 @@ import { } from '@angular/core'; import {normalizePassiveListenerOptions} from '@angular/cdk/platform'; import {Observable, Subject, Subscription, Observer} from 'rxjs'; -import {take} from 'rxjs/operators'; +import {startWith, take} from 'rxjs/operators'; import {DragDropRegistry} from './drag-drop-registry'; import { CdkDragDrop, @@ -274,7 +274,8 @@ export class CdkDrag implements AfterViewInit, OnDestroy { const rootElement = this._rootElement = this._getRootElement(); rootElement.addEventListener('mousedown', this._pointerDown, passiveEventListenerOptions); rootElement.addEventListener('touchstart', this._pointerDown, passiveEventListenerOptions); - toggleNativeDragInteractions(rootElement , false); + this._handles.changes.pipe(startWith(null)).subscribe(() => + toggleNativeDragInteractions(rootElement, this.getChildHandles().length > 0)); }); } @@ -309,10 +310,14 @@ export class CdkDrag implements AfterViewInit, OnDestroy { return this._dragDropRegistry.isDragging(this); } + /** Gets only handles that are not inside descendant `CdkDrag` instances. */ + private getChildHandles() { + return this._handles.filter(handle => handle._parentDrag === this); + } + /** Handler for the `mousedown`/`touchstart` events. */ _pointerDown = (event: MouseEvent | TouchEvent) => { - // Skip handles inside descendant `CdkDrag` instances. - const handles = this._handles.filter(handle => handle._parentDrag === this); + const handles = this.getChildHandles(); // Delegate the event based on whether it started from a handle or the element itself. if (handles.length) {