diff --git a/src/cdk/drag-drop/directives/drag.spec.ts b/src/cdk/drag-drop/directives/drag.spec.ts index 9a085349d50..64db4880263 100644 --- a/src/cdk/drag-drop/directives/drag.spec.ts +++ b/src/cdk/drag-drop/directives/drag.spec.ts @@ -522,6 +522,20 @@ describe('CdkDrag', () => { expect(dragElement.style.transform).toBeFalsy(); })); + it('should enable native drag interactions if dragging is disabled', fakeAsync(() => { + const fixture = createComponent(StandaloneDraggable); + fixture.detectChanges(); + const dragElement = fixture.componentInstance.dragElement.nativeElement; + const styles = dragElement.style; + + expect(styles.touchAction || (styles as any).webkitUserDrag).toBe('none'); + + fixture.componentInstance.dragInstance.disabled = true; + fixture.detectChanges(); + + expect(styles.touchAction || (styles as any).webkitUserDrag).toBeFalsy(); + })); + it('should stop propagation for the drag sequence start event', fakeAsync(() => { const fixture = createComponent(StandaloneDraggable); fixture.detectChanges(); @@ -544,12 +558,11 @@ describe('CdkDrag', () => { }).not.toThrow(); })); - it('should not disable native drag interactions when there is a drag handle', () => { + it('should enable 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'); + expect(dragElement.style.touchAction).not.toBe('none'); }); it('should be able to reset a freely-dragged item to its initial position', fakeAsync(() => { diff --git a/src/cdk/drag-drop/directives/drag.ts b/src/cdk/drag-drop/directives/drag.ts index bfbaf292e06..d0f23bc31e8 100644 --- a/src/cdk/drag-drop/directives/drag.ts +++ b/src/cdk/drag-drop/directives/drag.ts @@ -115,6 +115,7 @@ export class CdkDrag implements AfterViewInit, OnChanges, OnDestroy { } set disabled(value: boolean) { this._disabled = coerceBooleanProperty(value); + this._dragRef.disabled = this._disabled; } private _disabled = false; diff --git a/src/cdk/drag-drop/drag-ref.ts b/src/cdk/drag-drop/drag-ref.ts index b42119a4edf..dcf01427467 100644 --- a/src/cdk/drag-drop/drag-ref.ts +++ b/src/cdk/drag-drop/drag-ref.ts @@ -177,6 +177,9 @@ export class DragRef { /** Cached reference to the boundary element. */ private _boundaryElement: HTMLElement | null = null; + /** Whether the native dragging interactions have been enabled on the root element. */ + private _nativeInteractionsEnabled = true; + /** Cached dimensions of the preview element. */ private _previewRect?: ClientRect; @@ -192,9 +195,6 @@ export class DragRef { /** Elements that can be used to drag the draggable item. */ private _handles: DragHandle[] = []; - /** Whether the native interactions on the element are enabled. */ - private _nativeInteractionsEnabled = true; - /** Axis along which dragging is locked. */ lockAxis: 'x' | 'y'; @@ -203,7 +203,12 @@ export class DragRef { return this._disabled || !!(this.dropContainer && this.dropContainer.disabled); } set disabled(value: boolean) { - this._disabled = coerceBooleanProperty(value); + const newValue = coerceBooleanProperty(value); + + if (newValue !== this._disabled) { + this._disabled = newValue; + this._toggleNativeDragInteractions(); + } } private _disabled = false; @@ -911,10 +916,12 @@ export class DragRef { /** Toggles the native drag interactions, based on how many handles are registered. */ private _toggleNativeDragInteractions() { - const shouldEnable = this._handles.length > 0; + if (!this._rootElement || !this._handles) { + return; + } + + const shouldEnable = this.disabled || this._handles.length > 0; - // We go through the trouble of keeping track of whether the interactions are enabled, - // because we want to avoid triggering style recalculations unless we really have to. if (shouldEnable !== this._nativeInteractionsEnabled) { this._nativeInteractionsEnabled = shouldEnable; toggleNativeDragInteractions(this._rootElement, shouldEnable);