refactor(drag-drop): add sorted event (#13887)

Adds a new `cdkDropListSorted` event that emits the item's previous index and current index as it's being sorted in a list.

Fixes #13863.
This commit is contained in:
Kristiyan Kostadinov
2018-11-10 00:48:22 +00:00
committed by vivian-hu
parent df5d18f283
commit 26c73e0435
3 changed files with 56 additions and 1 deletions
+12
View File
@@ -71,3 +71,15 @@ export interface CdkDragMove<T = any> {
*/
delta: {x: -1 | 0 | 1, y: -1 | 0 | 1};
}
/** Event emitted when the user swaps the position of two drag items. */
export interface CdkDragSortEvent<T = any, I = T> {
/** Index from which the item was sorted previously. */
previousIndex: number;
/** Index that the item is currently in. */
currentIndex: number;
/** Container that the item belongs to. */
container: CdkDropListContainer<T>;
/** Item that is being sorted. */
item: CdkDrag<I>;
}
+32
View File
@@ -698,6 +698,36 @@ describe('CdkDrag', () => {
.toEqual(['One', 'Two', 'Zero', 'Three']);
}));
it('should dispatch the `sorted` event as an item is being sorted', fakeAsync(() => {
const fixture = createComponent(DraggableInDropZone);
fixture.detectChanges();
const items = fixture.componentInstance.dragItems.map(item => item.element.nativeElement);
const draggedItem = items[0];
const {top, left} = draggedItem.getBoundingClientRect();
startDraggingViaMouse(fixture, draggedItem, left, top);
// Drag over each item one-by-one going downwards.
for (let i = 1; i < items.length; i++) {
const elementRect = items[i].getBoundingClientRect();
dispatchMouseEvent(document, 'mousemove', elementRect.left, elementRect.top + 5);
fixture.detectChanges();
expect(fixture.componentInstance.sortedSpy.calls.mostRecent().args[0]).toEqual({
previousIndex: i - 1,
currentIndex: i,
item: fixture.componentInstance.dragItems.first,
container: fixture.componentInstance.dropInstance
});
}
dispatchMouseEvent(document, 'mouseup');
fixture.detectChanges();
flush();
}));
it('should not move items in a vertical list if the pointer is too far away', fakeAsync(() => {
const fixture = createComponent(DraggableInDropZone);
fixture.detectChanges();
@@ -2192,6 +2222,7 @@ const DROP_ZONE_FIXTURE_TEMPLATE = `
style="width: 100px; background: pink;"
[id]="dropZoneId"
[cdkDropListData]="items"
(cdkDropListSorted)="sortedSpy($event)"
(cdkDropListDropped)="droppedSpy($event)">
<div
*ngFor="let item of items"
@@ -2214,6 +2245,7 @@ class DraggableInDropZone {
{value: 'Three', height: ITEM_HEIGHT, margin: 0}
];
dropZoneId = 'items';
sortedSpy = jasmine.createSpy('sorted spy');
droppedSpy = jasmine.createSpy('dropped spy').and.callFake((event: CdkDragDrop<string[]>) => {
moveItemInArray(this.items, event.previousIndex, event.currentIndex);
});
+12 -1
View File
@@ -24,7 +24,7 @@ import {
import {Directionality} from '@angular/cdk/bidi';
import {CdkDrag} from './drag';
import {DragDropRegistry} from './drag-drop-registry';
import {CdkDragDrop, CdkDragEnter, CdkDragExit} from './drag-events';
import {CdkDragDrop, CdkDragEnter, CdkDragExit, CdkDragSortEvent} from './drag-events';
import {moveItemInArray} from './drag-utils';
import {CDK_DROP_LIST_CONTAINER} from './drop-list-container';
import {CdkDropListGroup} from './drop-list-group';
@@ -140,6 +140,10 @@ export class CdkDropList<T = any> implements OnInit, OnDestroy {
@Output('cdkDropListExited')
exited: EventEmitter<CdkDragExit<T>> = new EventEmitter<CdkDragExit<T>>();
/** Emits as the user is swapping items while actively dragging. */
@Output('cdkDropListSorted')
sorted: EventEmitter<CdkDragSortEvent<T>> = new EventEmitter<CdkDragSortEvent<T>>();
constructor(
public element: ElementRef<HTMLElement>,
private _dragDropRegistry: DragDropRegistry<CdkDrag, CdkDropList<T>>,
@@ -321,6 +325,13 @@ export class CdkDropList<T = any> implements OnInit, OnDestroy {
// Shuffle the array in place.
moveItemInArray(siblings, currentIndex, newIndex);
this.sorted.emit({
previousIndex: currentIndex,
currentIndex: newIndex,
container: this,
item
});
siblings.forEach((sibling, index) => {
// Don't do anything if the position hasn't changed.
if (oldOrder[index] === sibling) {