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.
This commit is contained in:
Kristiyan Kostadinov
2018-11-03 01:22:17 +01:00
committed by Jeremy Elbourn
parent 89701ef2ae
commit 436809cba0
2 changed files with 19 additions and 2 deletions
+14
View File
@@ -412,6 +412,20 @@ describe('CdkDrag', () => {
expect(dragElement.style.transform).toBeFalsy();
}));
it('should stop propagation for the drag sequence start event', fakeAsync(() => {
const fixture = createComponent(StandaloneDraggable);
fixture.detectChanges();
const dragElement = fixture.componentInstance.dragElement.nativeElement;
const event = createMouseEvent('mousedown');
spyOn(event, 'stopPropagation').and.callThrough();
dispatchEvent(dragElement, event);
fixture.detectChanges();
expect(event.stopPropagation).toHaveBeenCalled();
}));
});
describe('draggable with a handle', () => {
+5 -2
View File
@@ -329,10 +329,13 @@ export class CdkDrag<T = any> implements AfterViewInit, OnDestroy {
* @param event Browser event object that started the sequence.
*/
private _initializeDragSequence(referenceElement: HTMLElement, event: MouseEvent | TouchEvent) {
const isDragging = this._isDragging();
// Always stop propagation for the event that initializes
// the dragging sequence, in order to prevent it from potentially
// starting another sequence for a draggable parent somewhere up the DOM tree.
event.stopPropagation();
// Abort if the user is already dragging or is using a mouse button other than the primary one.
if (isDragging || (!this._isTouchEvent(event) && event.button !== 0)) {
if (this._isDragging() || (!this._isTouchEvent(event) && event.button !== 0)) {
return;
}