diff --git a/docs/core/components/datatable.component.md b/docs/core/components/datatable.component.md index c799727857..5049053576 100644 --- a/docs/core/components/datatable.component.md +++ b/docs/core/components/datatable.component.md @@ -464,6 +464,8 @@ Learn more about styling your datatable: [Customizing the component's styles](#c ## Details +This component supports rows reordering via keyboard. To enable it first set `enableDragRows` to `true`, focus any selected row and use shift + ArrowUp/ArrowDown combination to reorder selected row. + ### Supplying data for the table The column layout and row data are supplied to the table using an object that implements the diff --git a/lib/core/src/lib/datatable/components/datatable/datatable.component.spec.ts b/lib/core/src/lib/datatable/components/datatable/datatable.component.spec.ts index 8a1a0a2853..8beedf4913 100644 --- a/lib/core/src/lib/datatable/components/datatable/datatable.component.spec.ts +++ b/lib/core/src/lib/datatable/components/datatable/datatable.component.spec.ts @@ -1824,6 +1824,62 @@ describe('Accessibility', () => { expect(focusTrap.destroy).toHaveBeenCalled(); expect(dataTable.focusTrap).toBeNull(); }); + + it('should support drag&drop with shift + arrow keys', () => { + dataTable.showHeader = ShowHeaderMode.Never; + dataTable.enableDragRows = true; + const dataRows = [{ name: 'test1' }, { name: 'test2' }, { name: 'test3' }, { name: 'test4' }]; + dataTable.data = new ObjectDataTableAdapter([], [new ObjectDataColumn({ key: 'name' })]); + + const keyDownEvent = new KeyboardEvent('keyup', { + code: 'ArrowDown', + key: 'ArrowDown', + keyCode: 40 + } as KeyboardEventInit); + + dataTable.ngOnChanges({ + rows: new SimpleChange(null, dataRows, false) + }); + + fixture.detectChanges(); + dataTable.ngAfterViewInit(); + + const rowElement = testingUtils.getAllByCSS('.adf-datatable-body .adf-datatable-row')[0]; + testingUtils.setDebugElement(rowElement); + testingUtils.clickByCSS('.adf-datatable-cell'); + + fixture.debugElement.nativeElement.dispatchEvent(keyDownEvent); + fixture.detectChanges(); + + spyOn(dataTable.dragDropped, 'emit').and.callThrough(); + const shiftDownEvent = new KeyboardEvent('keyup', { + code: 'ArrowDown', + key: 'ArrowDown', + shiftKey: true, + keyCode: 40 + } as KeyboardEventInit); + fixture.debugElement.nativeElement.dispatchEvent(shiftDownEvent); + fixture.detectChanges(); + + expect(dataTable.dragDropped.emit).toHaveBeenCalledWith({ previousIndex: -1, currentIndex: 0 }); + + testingUtils.clickByCSS('.adf-datatable-cell'); + fixture.debugElement.nativeElement.dispatchEvent(keyDownEvent); + fixture.debugElement.nativeElement.dispatchEvent(keyDownEvent); + fixture.detectChanges(); + + const shiftUpEvent = new KeyboardEvent('keyup', { + code: 'ArrowUp', + key: 'ArrowUp', + shiftKey: true, + keyCode: 38 + } as KeyboardEventInit); + + fixture.debugElement.nativeElement.dispatchEvent(shiftUpEvent); + fixture.detectChanges(); + + expect(dataTable.dragDropped.emit).toHaveBeenCalledWith({ previousIndex: 1, currentIndex: 0 }); + }); }); describe('Drag&Drop column header', () => { diff --git a/lib/core/src/lib/datatable/components/datatable/datatable.component.ts b/lib/core/src/lib/datatable/components/datatable/datatable.component.ts index 3238bf18ad..d73d66a8fa 100644 --- a/lib/core/src/lib/datatable/components/datatable/datatable.component.ts +++ b/lib/core/src/lib/datatable/components/datatable/datatable.component.ts @@ -342,7 +342,35 @@ export class DataTableComponent implements OnInit, AfterContentInit, OnChanges, @HostListener('keyup', ['$event']) onKeydown(event: KeyboardEvent): void { - this.keyManager.onKeydown(event); + if (event.shiftKey && this.enableDragRows) { + switch (event.key) { + case 'ArrowUp': { + if (this.keyManager.activeItemIndex > 1) { + this.dragDropped.emit({ + previousIndex: this.keyManager.activeItemIndex - 1, + currentIndex: this.keyManager.activeItemIndex - 2 + }); + setTimeout(() => { + this.keyManager.setActiveItem(this.keyManager.activeItemIndex - 1); + }); + } + break; + } + case 'ArrowDown': { + if (this.keyManager.activeItemIndex < this.rowsList.length - 1) { + this.dragDropped.emit({ previousIndex: this.keyManager.activeItemIndex - 1, currentIndex: this.keyManager.activeItemIndex }); + setTimeout(() => { + this.keyManager.setActiveItem(this.keyManager.activeItemIndex + 1); + }); + } + break; + } + default: + break; + } + } else { + this.keyManager.onKeydown(event); + } } constructor(