Skip to content

Commit 6d86f0f

Browse files
authored
fix(cdk/drag-drop): error if dragging starts from active sibling container (#20704)
Currently we have a restriction that prevents users from starting a new drag sequence if an item within the same container is being dragged, however they can start one from a connected container and pull the item into the active one and start dragging it there. This can cause an error if it happens while the item's drop animation is running. These changes add an extra check so that dragging can't be started out of a connected container either. Relates to #20623.
1 parent 5eb1035 commit 6d86f0f

File tree

2 files changed

+22
-1
lines changed

2 files changed

+22
-1
lines changed

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

+19
Original file line numberDiff line numberDiff line change
@@ -5406,6 +5406,25 @@ describe('CdkDrag', () => {
54065406
expect(console.warn).toHaveBeenCalledWith(`CdkDropList could not find connected drop ` +
54075407
`list with id "does-not-exist"`);
54085408
}));
5409+
5410+
it('should not be able to start a drag sequence while a connected container is active',
5411+
fakeAsync(() => {
5412+
const fixture = createComponent(ConnectedDropZones);
5413+
fixture.detectChanges();
5414+
const item = fixture.componentInstance.groupedDragItems[0][0];
5415+
const itemInOtherList = fixture.componentInstance.groupedDragItems[1][0];
5416+
5417+
startDraggingViaMouse(fixture, item.element.nativeElement);
5418+
5419+
expect(document.querySelectorAll('.cdk-drag-dragging').length)
5420+
.toBe(1, 'Expected one item to be dragged initially.');
5421+
5422+
startDraggingViaMouse(fixture, itemInOtherList.element.nativeElement);
5423+
5424+
expect(document.querySelectorAll('.cdk-drag-dragging').length)
5425+
.toBe(1, 'Expected only one item to continue to be dragged.');
5426+
}));
5427+
54095428
});
54105429

54115430
describe('with nested drags', () => {

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

+3-1
Original file line numberDiff line numberDiff line change
@@ -585,6 +585,8 @@ export class DragRef<T = any> {
585585
// per pixel of movement (e.g. if the user moves their pointer quickly).
586586
if (isOverThreshold) {
587587
const isDelayElapsed = Date.now() >= this._dragStartTime + this._getDragStartDelay(event);
588+
const container = this._dropContainer;
589+
588590
if (!isDelayElapsed) {
589591
this._endDragSequence(event);
590592
return;
@@ -593,7 +595,7 @@ export class DragRef<T = any> {
593595
// Prevent other drag sequences from starting while something in the container is still
594596
// being dragged. This can happen while we're waiting for the drop animation to finish
595597
// and can cause errors, because some elements might still be moving around.
596-
if (!this._dropContainer || !this._dropContainer.isDragging()) {
598+
if (!container || (!container.isDragging() && !container.isReceiving())) {
597599
this._hasStartedDragging = true;
598600
this._ngZone.run(() => this._startDragSequence(event));
599601
}

0 commit comments

Comments
 (0)