Skip to content

Commit 32a0010

Browse files
crisbetojelbourn
authored andcommitted
fix(drag-drop): not dropping immediately for failed drag after a successful one (#13097)
Fixes the `CdkDrag` having to fall back to waiting for the animation to time out, rather than exiting immediately if the user does a successful dragging sequence, followed by an unsuccessful one. The issue comes from the fact that the `_hasMoved` flag was never being reset. Fixes #13091.
1 parent 22cd3ed commit 32a0010

File tree

2 files changed

+35
-1
lines changed

2 files changed

+35
-1
lines changed

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

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -683,6 +683,39 @@ describe('CdkDrag', () => {
683683
.toBeFalsy('Expected preview to be removed from the DOM if the transition timed out');
684684
}));
685685

686+
it('should reset immediately when failed drag happens after a successful one', fakeAsync(() => {
687+
const fixture = createComponent(DraggableInDropZone);
688+
fixture.detectChanges();
689+
690+
const itemInstance = fixture.componentInstance.dragItems.toArray()[1];
691+
const item = itemInstance.element.nativeElement;
692+
const spy = jasmine.createSpy('dropped spy');
693+
const subscription = itemInstance.dropped.asObservable().subscribe(spy);
694+
695+
// Do an initial drag and drop sequence.
696+
dragElementViaMouse(fixture, item, 50, 50);
697+
tick(0); // Important to tick with 0 since we don't want to flush any pending timeouts.
698+
699+
expect(spy).toHaveBeenCalledTimes(1);
700+
701+
// Start another drag.
702+
dispatchMouseEvent(item, 'mousedown');
703+
fixture.detectChanges();
704+
705+
// Add a duration since the tests won't include one.
706+
const preview = document.querySelector('.cdk-drag-preview')! as HTMLElement;
707+
preview.style.transitionDuration = '500ms';
708+
709+
// Dispatch the mouseup immediately to simulate the user not moving the element.
710+
dispatchMouseEvent(document, 'mouseup');
711+
fixture.detectChanges();
712+
tick(0); // Important to tick with 0 since we don't want to flush any pending timeouts.
713+
714+
expect(spy).toHaveBeenCalledTimes(2);
715+
716+
subscription.unsubscribe();
717+
}));
718+
686719
it('should not wait for transition that are not on the `transform` property', fakeAsync(() => {
687720
const fixture = createComponent(DraggableInDropZone);
688721
fixture.detectChanges();

src/cdk/drag-drop/drag.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ export class CdkDrag<T = any> implements AfterViewInit, OnDestroy {
103103
private _activeTransform: Point = {x: 0, y: 0};
104104

105105
/** Whether the element has moved since the user started dragging it. */
106-
private _hasMoved = false;
106+
private _hasMoved: boolean;
107107

108108
/** Drop container in which the CdkDrag resided when dragging began. */
109109
private _initialContainer: CdkDropContainer;
@@ -284,6 +284,7 @@ export class CdkDrag<T = any> implements AfterViewInit, OnDestroy {
284284

285285
const endedOrDestroyed = merge(this.ended, this._destroyed);
286286

287+
this._hasMoved = false;
287288
this._dragDropRegistry.pointerMove
288289
.pipe(takeUntil(endedOrDestroyed))
289290
.subscribe(this._pointerMove);

0 commit comments

Comments
 (0)