Skip to content

Commit 436809c

Browse files
crisbetojelbourn
authored andcommitted
fix(drag-drop): multiple parallel drag sequences when dragging nested drag items (#13820)
Currently if we have a `cdkDrag` nested inside another `cdkDrag`, the user can start dragging both of the items at the same time if they starting dragging from the appropriate area. These change stop event propagation so only one drag sequence can be started from a certain area at a time.
1 parent 89701ef commit 436809c

File tree

2 files changed

+19
-2
lines changed

2 files changed

+19
-2
lines changed

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

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -412,6 +412,20 @@ describe('CdkDrag', () => {
412412
expect(dragElement.style.transform).toBeFalsy();
413413
}));
414414

415+
it('should stop propagation for the drag sequence start event', fakeAsync(() => {
416+
const fixture = createComponent(StandaloneDraggable);
417+
fixture.detectChanges();
418+
const dragElement = fixture.componentInstance.dragElement.nativeElement;
419+
420+
const event = createMouseEvent('mousedown');
421+
spyOn(event, 'stopPropagation').and.callThrough();
422+
423+
dispatchEvent(dragElement, event);
424+
fixture.detectChanges();
425+
426+
expect(event.stopPropagation).toHaveBeenCalled();
427+
}));
428+
415429
});
416430

417431
describe('draggable with a handle', () => {

src/cdk/drag-drop/drag.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -329,10 +329,13 @@ export class CdkDrag<T = any> implements AfterViewInit, OnDestroy {
329329
* @param event Browser event object that started the sequence.
330330
*/
331331
private _initializeDragSequence(referenceElement: HTMLElement, event: MouseEvent | TouchEvent) {
332-
const isDragging = this._isDragging();
332+
// Always stop propagation for the event that initializes
333+
// the dragging sequence, in order to prevent it from potentially
334+
// starting another sequence for a draggable parent somewhere up the DOM tree.
335+
event.stopPropagation();
333336

334337
// Abort if the user is already dragging or is using a mouse button other than the primary one.
335-
if (isDragging || (!this._isTouchEvent(event) && event.button !== 0)) {
338+
if (this._isDragging() || (!this._isTouchEvent(event) && event.button !== 0)) {
336339
return;
337340
}
338341

0 commit comments

Comments
 (0)