diff --git a/src/cdk/drag-drop/drag.spec.ts b/src/cdk/drag-drop/drag.spec.ts index a927d090ecaa..a76739f3eba5 100644 --- a/src/cdk/drag-drop/drag.spec.ts +++ b/src/cdk/drag-drop/drag.spec.ts @@ -1579,6 +1579,46 @@ describe('CdkDrag', () => { expect(fixture.componentInstance.droppedSpy).not.toHaveBeenCalled(); })); + it('should be able to move the element over a new container and return it to the initial ' + + 'one, even if it no longer matches the enterPredicate', fakeAsync(() => { + const fixture = createComponent(ConnectedDropZones); + fixture.detectChanges(); + + const groups = fixture.componentInstance.groupedDragItems; + const dropZones = fixture.componentInstance.dropInstances.map(d => d.element.nativeElement); + const item = groups[0][1]; + const initialRect = item.element.nativeElement.getBoundingClientRect(); + const targetRect = groups[1][2].element.nativeElement.getBoundingClientRect(); + + fixture.componentInstance.dropInstances.first.enterPredicate = () => false; + fixture.detectChanges(); + + startDraggingViaMouse(fixture, item.element.nativeElement); + + const placeholder = dropZones[0].querySelector('.cdk-drag-placeholder')!; + + expect(placeholder).toBeTruthy(); + expect(dropZones[0].contains(placeholder)) + .toBe(true, 'Expected placeholder to be inside the first container.'); + + dispatchMouseEvent(document, 'mousemove', targetRect.left + 1, targetRect.top + 1); + fixture.detectChanges(); + + expect(dropZones[1].contains(placeholder)) + .toBe(true, 'Expected placeholder to be inside second container.'); + + dispatchMouseEvent(document, 'mousemove', initialRect.left + 1, initialRect.top + 1); + fixture.detectChanges(); + + expect(dropZones[0].contains(placeholder)) + .toBe(true, 'Expected placeholder to be back inside first container.'); + + dispatchMouseEvent(document, 'mouseup'); + fixture.detectChanges(); + + expect(fixture.componentInstance.droppedSpy).not.toHaveBeenCalled(); + })); + it('should transfer the DOM element from one drop zone to another', fakeAsync(() => { const fixture = createComponent(ConnectedDropZones); fixture.detectChanges(); diff --git a/src/cdk/drag-drop/drag.ts b/src/cdk/drag-drop/drag.ts index 5dc354f4b9dd..78028bbc4339 100644 --- a/src/cdk/drag-drop/drag.ts +++ b/src/cdk/drag-drop/drag.ts @@ -513,7 +513,7 @@ export class CdkDrag implements AfterViewInit, OnDestroy { // This handles the case where two containers are connected one way and the user tries to // undo dragging an item into a new container. if (!newContainer && this.dropContainer !== this._initialContainer && - this._initialContainer._canReturnItem(this, x, y)) { + this._initialContainer._canReturnItem(x, y)) { newContainer = this._initialContainer; } diff --git a/src/cdk/drag-drop/drop-list-container.ts b/src/cdk/drag-drop/drop-list-container.ts index b270ac64711b..5fd02d414087 100644 --- a/src/cdk/drag-drop/drop-list-container.ts +++ b/src/cdk/drag-drop/drop-list-container.ts @@ -60,7 +60,7 @@ export interface CdkDropListContainer { _draggables: QueryList; _getSiblingContainerFromPosition(item: CdkDrag, x: number, y: number): CdkDropListContainer | null; - _canReturnItem(item: CdkDrag, x: number, y: number): boolean; + _canReturnItem(x: number, y: number): boolean; } /** diff --git a/src/cdk/drag-drop/drop-list.ts b/src/cdk/drag-drop/drop-list.ts index 0d396499ac5f..549e8a0c0da8 100644 --- a/src/cdk/drag-drop/drop-list.ts +++ b/src/cdk/drag-drop/drop-list.ts @@ -353,12 +353,11 @@ export class CdkDropList implements OnInit, OnDestroy { /** * Checks whether an item that started in this container can be returned to it, * after it was moved out into another container. - * @param item Item that is being checked. * @param x Position of the item along the X axis. * @param y Position of the item along the Y axis. */ - _canReturnItem(item: CdkDrag, x: number, y: number): boolean { - return isInsideClientRect(this._positionCache.self, x, y) && this.enterPredicate(item, this); + _canReturnItem(x: number, y: number): boolean { + return isInsideClientRect(this._positionCache.self, x, y); } /** Refreshes the position cache of the items and sibling containers. */