Skip to content

feat(drag-drop): include dragged distance in events #15947

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 13, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
116 changes: 99 additions & 17 deletions src/cdk/drag-drop/directives/drag.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -356,7 +356,31 @@ describe('CdkDrag', () => {

// Assert the event like this, rather than `toHaveBeenCalledWith`, because Jasmine will
// go into an infinite loop trying to stringify the event, if the test fails.
expect(event).toEqual({source: fixture.componentInstance.dragInstance});
expect(event).toEqual({
source: fixture.componentInstance.dragInstance,
distance: {x: jasmine.any(Number), y: jasmine.any(Number)}
});
}));

it('should include the drag distance in the ended event', fakeAsync(() => {
const fixture = createComponent(StandaloneDraggable);
fixture.detectChanges();

dragElementViaMouse(fixture, fixture.componentInstance.dragElement.nativeElement, 25, 30);
let event = fixture.componentInstance.endedSpy.calls.mostRecent().args[0];

expect(event).toEqual({
source: jasmine.anything(),
distance: {x: 25, y: 30}
});

dragElementViaMouse(fixture, fixture.componentInstance.dragElement.nativeElement, 40, 50);
event = fixture.componentInstance.endedSpy.calls.mostRecent().args[0];

expect(event).toEqual({
source: jasmine.anything(),
distance: {x: 40, y: 50}
});
}));

it('should emit when the user is moving the drag element', () => {
Expand Down Expand Up @@ -844,6 +868,30 @@ describe('CdkDrag', () => {
expect(dragElement.style.transform).toBe('translate3d(150px, 300px, 0px)');
}));

it('should include the dragged distance as the user is dragging', fakeAsync(() => {
const fixture = createComponent(StandaloneDraggable);
fixture.detectChanges();
const dragElement = fixture.componentInstance.dragElement.nativeElement;
const spy = jasmine.createSpy('moved spy');
const subscription = fixture.componentInstance.dragInstance.moved.subscribe(spy);

startDraggingViaMouse(fixture, dragElement);

dispatchMouseEvent(document, 'mousemove', 50, 100);
fixture.detectChanges();

let event = spy.calls.mostRecent().args[0];
expect(event.distance).toEqual({x: 50, y: 100});

dispatchMouseEvent(document, 'mousemove', 75, 50);
fixture.detectChanges();

event = spy.calls.mostRecent().args[0];
expect(event.distance).toEqual({x: 75, y: 50});

subscription.unsubscribe();
}));

});

describe('draggable with a handle', () => {
Expand Down Expand Up @@ -1149,7 +1197,8 @@ describe('CdkDrag', () => {
item: firstItem,
container: fixture.componentInstance.dropInstance,
previousContainer: fixture.componentInstance.dropInstance,
isPointerOverContainer: true
isPointerOverContainer: true,
distance: {x: jasmine.any(Number), y: jasmine.any(Number)}
});

expect(dragItems.map(drag => drag.element.nativeElement.textContent!.trim()))
Expand All @@ -1176,6 +1225,24 @@ describe('CdkDrag', () => {
expect(event.isPointerOverContainer).toBe(true);
}));

it('should expose the drag distance when an item is dropped', fakeAsync(() => {
const fixture = createComponent(DraggableInDropZone);
fixture.detectChanges();
const dragItems = fixture.componentInstance.dragItems;
const firstItem = dragItems.first;

dragElementViaMouse(fixture, firstItem.element.nativeElement, 50, 60);
flush();
fixture.detectChanges();

expect(fixture.componentInstance.droppedSpy).toHaveBeenCalledTimes(1);

const event: CdkDragDrop<any> =
fixture.componentInstance.droppedSpy.calls.mostRecent().args[0];

expect(event.distance).toEqual({x: 50, y: 60});
}));

it('should expose whether an item was dropped outside of a container', fakeAsync(() => {
const fixture = createComponent(DraggableInDropZone);
fixture.detectChanges();
Expand Down Expand Up @@ -1256,7 +1323,8 @@ describe('CdkDrag', () => {
item: firstItem,
container: fixture.componentInstance.dropInstance,
previousContainer: fixture.componentInstance.dropInstance,
isPointerOverContainer: false
isPointerOverContainer: false,
distance: {x: jasmine.any(Number), y: jasmine.any(Number)}
});

expect(dragItems.map(drag => drag.element.nativeElement.textContent!.trim()))
Expand Down Expand Up @@ -1314,7 +1382,8 @@ describe('CdkDrag', () => {
item: firstItem,
container: fixture.componentInstance.dropInstance,
previousContainer: fixture.componentInstance.dropInstance,
isPointerOverContainer: true
isPointerOverContainer: true,
distance: {x: jasmine.any(Number), y: jasmine.any(Number)}
});

expect(dragItems.map(drag => drag.element.nativeElement.textContent!.trim()))
Expand Down Expand Up @@ -1354,7 +1423,8 @@ describe('CdkDrag', () => {
item: firstItem,
container: fixture.componentInstance.dropInstance,
previousContainer: fixture.componentInstance.dropInstance,
isPointerOverContainer: true
isPointerOverContainer: true,
distance: {x: jasmine.any(Number), y: jasmine.any(Number)}
});

expect(dragItems.map(drag => drag.element.nativeElement.textContent!.trim()))
Expand Down Expand Up @@ -1390,7 +1460,8 @@ describe('CdkDrag', () => {
item: firstItem,
container: fixture.componentInstance.dropInstance,
previousContainer: fixture.componentInstance.dropInstance,
isPointerOverContainer: false
isPointerOverContainer: false,
distance: {x: jasmine.any(Number), y: jasmine.any(Number)}
});

expect(dragItems.map(drag => drag.element.nativeElement.textContent!.trim()))
Expand Down Expand Up @@ -2508,7 +2579,8 @@ describe('CdkDrag', () => {
item: firstItem,
container: dropInstance,
previousContainer: dropInstance,
isPointerOverContainer: true
isPointerOverContainer: true,
distance: {x: jasmine.any(Number), y: jasmine.any(Number)}
});

expect(dragItems.map(drag => drag.element.nativeElement.textContent!.trim()))
Expand Down Expand Up @@ -2543,7 +2615,8 @@ describe('CdkDrag', () => {
item,
container: fixture.componentInstance.dropInstances.toArray()[1],
previousContainer: fixture.componentInstance.dropInstances.first,
isPointerOverContainer: true
isPointerOverContainer: true,
distance: {x: jasmine.any(Number), y: jasmine.any(Number)}
});
}));

Expand Down Expand Up @@ -2645,7 +2718,8 @@ describe('CdkDrag', () => {
item: groups[0][1],
container: dropInstances[1],
previousContainer: dropInstances[0],
isPointerOverContainer: true
isPointerOverContainer: true,
distance: {x: jasmine.any(Number), y: jasmine.any(Number)}
});
}));

Expand Down Expand Up @@ -2675,7 +2749,8 @@ describe('CdkDrag', () => {
item: groups[0][1],
container: dropInstances[0],
previousContainer: dropInstances[0],
isPointerOverContainer: false
isPointerOverContainer: false,
distance: {x: jasmine.any(Number), y: jasmine.any(Number)}
});
}));

Expand Down Expand Up @@ -2705,7 +2780,8 @@ describe('CdkDrag', () => {
item: groups[0][1],
container: dropInstances[0],
previousContainer: dropInstances[0],
isPointerOverContainer: false
isPointerOverContainer: false,
distance: {x: jasmine.any(Number), y: jasmine.any(Number)}
});
}));

Expand Down Expand Up @@ -2828,7 +2904,8 @@ describe('CdkDrag', () => {
item: groups[0][1],
container: dropInstances[1],
previousContainer: dropInstances[0],
isPointerOverContainer: true
isPointerOverContainer: true,
distance: {x: jasmine.any(Number), y: jasmine.any(Number)}
});
}));

Expand All @@ -2854,7 +2931,8 @@ describe('CdkDrag', () => {
item: groups[0][1],
container: dropInstances[1],
previousContainer: dropInstances[0],
isPointerOverContainer: true
isPointerOverContainer: true,
distance: {x: jasmine.any(Number), y: jasmine.any(Number)}
});
}));

Expand Down Expand Up @@ -2885,7 +2963,8 @@ describe('CdkDrag', () => {
item: groups[0][1],
container: dropInstances[1],
previousContainer: dropInstances[0],
isPointerOverContainer: true
isPointerOverContainer: true,
distance: {x: jasmine.any(Number), y: jasmine.any(Number)}
});
}));

Expand Down Expand Up @@ -2920,7 +2999,8 @@ describe('CdkDrag', () => {
item,
container: fixture.componentInstance.dropInstances.toArray()[1],
previousContainer: fixture.componentInstance.dropInstances.first,
isPointerOverContainer: true
isPointerOverContainer: true,
distance: {x: jasmine.any(Number), y: jasmine.any(Number)}
});

expect(dropContainers[0].contains(item.element.nativeElement)).toBe(true,
Expand Down Expand Up @@ -3016,7 +3096,8 @@ describe('CdkDrag', () => {
item: groups[0][1],
container: dropInstances[0],
previousContainer: dropInstances[0],
isPointerOverContainer: false
isPointerOverContainer: false,
distance: {x: jasmine.any(Number), y: jasmine.any(Number)}
});
}));

Expand Down Expand Up @@ -3136,7 +3217,8 @@ describe('CdkDrag', () => {
item: groups[0][1],
container: dropInstances[2],
previousContainer: dropInstances[0],
isPointerOverContainer: false
isPointerOverContainer: false,
distance: {x: jasmine.any(Number), y: jasmine.any(Number)}
}));

}));
Expand Down
10 changes: 6 additions & 4 deletions src/cdk/drag-drop/directives/drag.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,8 @@ export class CdkDrag<T = any> implements AfterViewInit, OnChanges, OnDestroy {
source: this,
pointerPosition: movedEvent.pointerPosition,
event: movedEvent.event,
delta: movedEvent.delta
delta: movedEvent.delta,
distance: movedEvent.distance
}))).subscribe(observer);

return () => {
Expand Down Expand Up @@ -344,8 +345,8 @@ export class CdkDrag<T = any> implements AfterViewInit, OnChanges, OnDestroy {
this.released.emit({source: this});
});

ref.ended.subscribe(() => {
this.ended.emit({source: this});
ref.ended.subscribe(event => {
this.ended.emit({source: this, distance: event.distance});

// Since all of these events run outside of change detection,
// we need to ensure that everything is marked correctly.
Expand Down Expand Up @@ -373,7 +374,8 @@ export class CdkDrag<T = any> implements AfterViewInit, OnChanges, OnDestroy {
previousContainer: event.previousContainer.data,
container: event.container.data,
isPointerOverContainer: event.isPointerOverContainer,
item: this
item: this,
distance: event.distance
});
});
}
Expand Down
3 changes: 2 additions & 1 deletion src/cdk/drag-drop/directives/drop-list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,8 @@ export class CdkDropList<T = any> implements CdkDropListContainer, AfterContentI
previousContainer: event.previousContainer.data,
container: event.container.data,
item: event.item.data,
isPointerOverContainer: event.isPointerOverContainer
isPointerOverContainer: event.isPointerOverContainer,
distance: event.distance
});

// Mark for check since all of these events run outside of change
Expand Down
6 changes: 6 additions & 0 deletions src/cdk/drag-drop/drag-events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ export interface CdkDragRelease<T = any> {
export interface CdkDragEnd<T = any> {
/** Draggable that emitted the event. */
source: CdkDrag<T>;
/** Distance in pixels that the user has dragged since the drag sequence started. */
distance: {x: number, y: number};
}

/** Event emitted when the user moves an item into a new drop container. */
Expand Down Expand Up @@ -61,6 +63,8 @@ export interface CdkDragDrop<T, O = T> {
previousContainer: CdkDropList<O>;
/** Whether the user's pointer was over the container when the item was dropped. */
isPointerOverContainer: boolean;
/** Distance in pixels that the user has dragged since the drag sequence started. */
distance: {x: number, y: number};
}

/** Event emitted as the user is dragging a draggable item. */
Expand All @@ -71,6 +75,8 @@ export interface CdkDragMove<T = any> {
pointerPosition: {x: number, y: number};
/** Native event that is causing the dragging. */
event: MouseEvent | TouchEvent;
/** Distance in pixels that the user has dragged since the drag sequence started. */
distance: {x: number, y: number};
/**
* Indicates the direction in which the user is dragging the element along each axis.
* `1` means that the position is increasing (e.g. the user is moving to the right or downwards),
Expand Down
Loading