Skip to content

Commit bf451a8

Browse files
authored
feat(Table): support table scrolling through keyboard arrow keys (#463)
1 parent 0e0c8dc commit bf451a8

File tree

3 files changed

+65
-3
lines changed

3 files changed

+65
-3
lines changed

src/Table.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -476,7 +476,8 @@ const Table = React.forwardRef(<Row extends RowDataType, Key>(props: TableProps<
476476
onScrollBody,
477477
onScrollTop,
478478
onScrollLeft,
479-
onScrollTo
479+
onScrollTo,
480+
onScrollByKeydown
480481
} = useScrollListener({
481482
rtl,
482483
data: dataProp,
@@ -1110,6 +1111,8 @@ const Table = React.forwardRef(<Row extends RowDataType, Key>(props: TableProps<
11101111
className={classes}
11111112
style={styles}
11121113
ref={tableRef}
1114+
tabIndex={-1}
1115+
onKeyDown={onScrollByKeydown}
11131116
>
11141117
{showHeader && renderTableHeader(headerCells, rowWidth)}
11151118
{children && renderTableBody(bodyCells, rowWidth)}

src/utils/useScrollListener.ts

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -504,6 +504,31 @@ const useScrollListener = (props: ScrollListenerProps) => {
504504
tableBodyRef
505505
]);
506506

507+
const onScrollByKeydown = useCallback(
508+
(event: React.KeyboardEvent) => {
509+
if (event.currentTarget === event.target) {
510+
event.preventDefault();
511+
const step = 40;
512+
513+
switch (event.key) {
514+
case 'ArrowUp':
515+
onWheel(0, -step);
516+
break;
517+
case 'ArrowDown':
518+
onWheel(0, step);
519+
break;
520+
case 'ArrowLeft':
521+
onWheel(-step, 0);
522+
break;
523+
case 'ArrowRight':
524+
onWheel(step, 0);
525+
break;
526+
}
527+
}
528+
},
529+
[onWheel]
530+
);
531+
507532
useMount(() => {
508533
if (rtl) {
509534
// Initialize scroll position
@@ -526,7 +551,8 @@ const useScrollListener = (props: ScrollListenerProps) => {
526551
onScrollBody,
527552
onScrollTop,
528553
onScrollLeft,
529-
onScrollTo
554+
onScrollTo,
555+
onScrollByKeydown
530556
};
531557
};
532558

test/TableSpec.js

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import React from 'react';
2-
import { render, waitFor, act, fireEvent } from '@testing-library/react';
2+
import { render, waitFor, act, fireEvent, screen } from '@testing-library/react';
33
import getHeight from 'dom-lib/getHeight';
44
import getWidth from 'dom-lib/getWidth';
55
import Table from '../src/Table';
@@ -1391,4 +1391,37 @@ describe('Table', () => {
13911391
expect(width).not.equal(100);
13921392
expect(width).to.equal(instance.getBoundingClientRect().width);
13931393
});
1394+
1395+
it('Should call `onScroll` callback when trigger keyboard event', () => {
1396+
const onScrollSpy = sinon.spy();
1397+
render(
1398+
<Table onScroll={onScrollSpy} data={[{ id: 1, name: 'a' }]} height={10} width={100}>
1399+
<Column width={100}>
1400+
<HeaderCell>11</HeaderCell>
1401+
<Cell dataKey="id" />
1402+
</Column>
1403+
<Column width={100}>
1404+
<HeaderCell>11</HeaderCell>
1405+
<Cell dataKey="id" />
1406+
</Column>
1407+
</Table>
1408+
);
1409+
1410+
fireEvent.keyDown(screen.getByRole('grid'), { key: 'ArrowDown' });
1411+
1412+
expect(onScrollSpy).to.have.been.calledOnce;
1413+
expect(onScrollSpy).to.be.calledWith(0, 40);
1414+
1415+
fireEvent.keyDown(screen.getByRole('grid'), { key: 'ArrowUp' });
1416+
expect(onScrollSpy).to.have.been.calledTwice;
1417+
expect(onScrollSpy).to.be.calledWith(0, 0);
1418+
1419+
fireEvent.keyDown(screen.getByRole('grid'), { key: 'ArrowRight' });
1420+
expect(onScrollSpy).to.have.been.calledThrice;
1421+
expect(onScrollSpy).to.be.calledWith(40, 0);
1422+
1423+
fireEvent.keyDown(screen.getByRole('grid'), { key: 'ArrowLeft' });
1424+
expect(onScrollSpy).to.have.callCount(4);
1425+
expect(onScrollSpy).to.be.calledWith(0, 0);
1426+
});
13941427
});

0 commit comments

Comments
 (0)