Skip to content

Commit 9fa3376

Browse files
crisbetojelbourn
authored andcommitted
fix(drag-drop): don't disable native drag interactions if dragging is disabled (#14233)
Since consumers can use the `cdkDragDisabled` binding to disable dragging on an element, we shouldn't be disabling the native interactions unless we have to. These changes will only disable native interactions if dragging is enabled and there are no handles.
1 parent 37a7080 commit 9fa3376

File tree

3 files changed

+31
-10
lines changed

3 files changed

+31
-10
lines changed

src/cdk/drag-drop/directives/drag.spec.ts

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -522,6 +522,20 @@ describe('CdkDrag', () => {
522522
expect(dragElement.style.transform).toBeFalsy();
523523
}));
524524

525+
it('should enable native drag interactions if dragging is disabled', fakeAsync(() => {
526+
const fixture = createComponent(StandaloneDraggable);
527+
fixture.detectChanges();
528+
const dragElement = fixture.componentInstance.dragElement.nativeElement;
529+
const styles = dragElement.style;
530+
531+
expect(styles.touchAction || (styles as any).webkitUserDrag).toBe('none');
532+
533+
fixture.componentInstance.dragInstance.disabled = true;
534+
fixture.detectChanges();
535+
536+
expect(styles.touchAction || (styles as any).webkitUserDrag).toBeFalsy();
537+
}));
538+
525539
it('should stop propagation for the drag sequence start event', fakeAsync(() => {
526540
const fixture = createComponent(StandaloneDraggable);
527541
fixture.detectChanges();
@@ -544,12 +558,11 @@ describe('CdkDrag', () => {
544558
}).not.toThrow();
545559
}));
546560

547-
it('should not disable native drag interactions when there is a drag handle', () => {
561+
it('should enable native drag interactions when there is a drag handle', () => {
548562
const fixture = createComponent(StandaloneDraggableWithHandle);
549563
fixture.detectChanges();
550564
const dragElement = fixture.componentInstance.dragElement.nativeElement;
551-
expect(dragElement.style.touchAction)
552-
.not.toEqual('none', 'should not disable touchAction on when there is a drag handle');
565+
expect(dragElement.style.touchAction).not.toBe('none');
553566
});
554567

555568
it('should be able to reset a freely-dragged item to its initial position', fakeAsync(() => {

src/cdk/drag-drop/directives/drag.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ export class CdkDrag<T = any> implements AfterViewInit, OnChanges, OnDestroy {
115115
}
116116
set disabled(value: boolean) {
117117
this._disabled = coerceBooleanProperty(value);
118+
this._dragRef.disabled = this._disabled;
118119
}
119120
private _disabled = false;
120121

src/cdk/drag-drop/drag-ref.ts

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,9 @@ export class DragRef<T = any> {
177177
/** Cached reference to the boundary element. */
178178
private _boundaryElement: HTMLElement | null = null;
179179

180+
/** Whether the native dragging interactions have been enabled on the root element. */
181+
private _nativeInteractionsEnabled = true;
182+
180183
/** Cached dimensions of the preview element. */
181184
private _previewRect?: ClientRect;
182185

@@ -192,9 +195,6 @@ export class DragRef<T = any> {
192195
/** Elements that can be used to drag the draggable item. */
193196
private _handles: DragHandle[] = [];
194197

195-
/** Whether the native interactions on the element are enabled. */
196-
private _nativeInteractionsEnabled = true;
197-
198198
/** Axis along which dragging is locked. */
199199
lockAxis: 'x' | 'y';
200200

@@ -203,7 +203,12 @@ export class DragRef<T = any> {
203203
return this._disabled || !!(this.dropContainer && this.dropContainer.disabled);
204204
}
205205
set disabled(value: boolean) {
206-
this._disabled = coerceBooleanProperty(value);
206+
const newValue = coerceBooleanProperty(value);
207+
208+
if (newValue !== this._disabled) {
209+
this._disabled = newValue;
210+
this._toggleNativeDragInteractions();
211+
}
207212
}
208213
private _disabled = false;
209214

@@ -911,10 +916,12 @@ export class DragRef<T = any> {
911916

912917
/** Toggles the native drag interactions, based on how many handles are registered. */
913918
private _toggleNativeDragInteractions() {
914-
const shouldEnable = this._handles.length > 0;
919+
if (!this._rootElement || !this._handles) {
920+
return;
921+
}
922+
923+
const shouldEnable = this.disabled || this._handles.length > 0;
915924

916-
// We go through the trouble of keeping track of whether the interactions are enabled,
917-
// because we want to avoid triggering style recalculations unless we really have to.
918925
if (shouldEnable !== this._nativeInteractionsEnabled) {
919926
this._nativeInteractionsEnabled = shouldEnable;
920927
toggleNativeDragInteractions(this._rootElement, shouldEnable);

0 commit comments

Comments
 (0)