Skip to content
This repository was archived by the owner on Aug 8, 2024. It is now read-only.

Commit

Permalink
feat: update
Browse files Browse the repository at this point in the history
  • Loading branch information
LiKang6688 committed Aug 10, 2022
1 parent 871c14f commit 57c9b0d
Show file tree
Hide file tree
Showing 5 changed files with 26 additions and 22 deletions.
2 changes: 1 addition & 1 deletion src/table/components/TableTotals.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ function TableTotals({ rootElement, tableData, theme, layout, keyboard }) {
const isTop = totalsPosition === 'top';

return (
<StyledHeadRow paginationNeeded={paginationNeeded} className="sn-table-row">
<StyledHeadRow paginationNeeded={paginationNeeded} className="sn-table-totals sn-table-row">
{columns.map((column, columnIndex) => {
const cellCoord = [isTop ? 1 : rows.length + 1, columnIndex];
return (
Expand Down
3 changes: 2 additions & 1 deletion src/table/components/TableWrapper.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ export default function TableWrapper(props) {

useFocusListener(tableWrapperRef, shouldRefocus, keyboard);
useScrollListener(tableContainerRef, direction);
useKeyDownListener(tableBodyWrapperRef, tableContainerRef, focusedCellCoord, rootElement, totalsPosition);
useKeyDownListener(tableBodyWrapperRef, focusedCellCoord, rootElement, totalsPosition);

useDidUpdateEffect(() => {
// When nebula handles keyboard navigation and keyboard.active changes,
Expand Down Expand Up @@ -112,6 +112,7 @@ export default function TableWrapper(props) {
>
<AnnounceElements />
<StyledTableContainer
className="sn-table-container"
ref={tableContainerRef}
fullHeight={footerContainer || constraints.active || !paginationNeeded} // the footerContainer always wants height: 100%
constraints={constraints}
Expand Down
10 changes: 5 additions & 5 deletions src/table/hooks/use-key-down-listener.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
import { useEffect } from 'react';
import { handleNavigateTop } from '../utils/handle-scroll';

const useKeyDownListener = (tableBodyWrapperRef, tableContainerRef, focusedCellCoord, rootElement, totalsPosition) => {
const useKeyDownListener = (tableBodyWrapperRef, focusedCellCoord, rootElement, totalsPosition) => {
useEffect(() => {
const memoedContainer = tableBodyWrapperRef.current;
if (!memoedContainer) return undefined;

const keyDownHandler = (evt) =>
evt.key === 'ArrowUp' && handleNavigateTop({ tableContainerRef, focusedCellCoord, rootElement, totalsPosition });
memoedContainer.addEventListener('keydown', keyDownHandler);
evt.key === 'ArrowUp' && handleNavigateTop({ focusedCellCoord, rootElement, totalsPosition });
memoedContainer.addEventListener('keyup', keyDownHandler);

return () => {
memoedContainer.removeEventListener('keydown', keyDownHandler);
memoedContainer.removeEventListener('keyup', keyDownHandler);
};
}, [tableBodyWrapperRef, tableContainerRef, focusedCellCoord, rootElement, totalsPosition]);
}, [tableBodyWrapperRef, focusedCellCoord, rootElement, totalsPosition]);
};

export default useKeyDownListener;
19 changes: 10 additions & 9 deletions src/table/utils/__tests__/handle-scroll.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -112,33 +112,34 @@ describe('handle-scroll', () => {
describe('handleNavigateTop', () => {
let rowHeight;
let scrollTo;
let tableContainerRef;
let focusedCellCoord;
let rootElement;
let totalsPosition;

beforeEach(() => {
rowHeight = 100;
scrollTo = jest.fn();
tableContainerRef = { current: { scrollTo } };
focusedCellCoord = [0, 0];
rootElement = {};
rootElement = {
getElementsByClassName: () => [{}],
};
totalsPosition = 'bottom';
});

it('should not do anything when ref is not setup yet', () => {
tableContainerRef.current = {};

handleNavigateTop({ tableContainerRef, focusedCellCoord, rootElement, totalsPosition });
it('should not do anything when tableContainer is not setup yet', () => {
handleNavigateTop({ focusedCellCoord, rootElement, totalsPosition });
expect(scrollTo).not.toHaveBeenCalled();
});

it('should scroll upwards automatically if it detects the cursor gets behind <TableHead />', () => {
const SCROLL_TOP_IDX = 7;
focusedCellCoord = [8, 0];
tableContainerRef = { current: { scrollTo, scrollTop: SCROLL_TOP_IDX * rowHeight } };
rootElement = {
getElementsByClassName: (query) => {
if (query === 'sn-table-container') {
return [{ scrollTo, scrollTop: SCROLL_TOP_IDX * rowHeight }];
}

if (query === 'sn-table-head-cell') {
return [{ offsetHeight: 128 }];
}
Expand All @@ -157,7 +158,7 @@ describe('handle-scroll', () => {
// 700 - 100 - 128 = 472 => so our scrollTo function might be called with 600
const targetOffsetTop = 472;

handleNavigateTop({ tableContainerRef, focusedCellCoord, rootElement, totalsPosition });
handleNavigateTop({ focusedCellCoord, rootElement, totalsPosition });
expect(scrollTo).toHaveBeenCalledTimes(1);
expect(scrollTo).toHaveBeenCalledWith({ top: targetOffsetTop, behavior: 'instant' });
});
Expand Down
14 changes: 8 additions & 6 deletions src/table/utils/handle-scroll.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,22 +26,24 @@ export const handleHorizontalScroll = (evt, isRTL, memoedContainer) => {
}
};

export const handleNavigateTop = ({ tableContainerRef, focusedCellCoord, rootElement, totalsPosition }) => {
if (!tableContainerRef.current.scrollTo) return;
export const handleNavigateTop = ({ focusedCellCoord, rootElement, totalsPosition }) => {
const tableContainer = rootElement.getElementsByClassName('sn-table-container')[0];
if (!tableContainer.scrollTo) return;

const [x, y] = focusedCellCoord;
const tableHead = rootElement.getElementsByClassName('sn-table-head-cell')[0];
const rowElements = rootElement.getElementsByClassName('sn-table-row');
const cell = rowElements[x]?.getElementsByClassName('sn-table-cell')[y];
const totals = rootElement.getElementsByClassName('sn-table-totals')[0];

// when totalsPosition is 'top', the table head should include the totals row
// when totalsPosition is 'bottom' or 'noTotals', the table head should not include the totals row
const tableHeadHeight =
totalsPosition === 'top' ? tableHead.offsetHeight + cell.offsetHeight : tableHead.offsetHeight;
totalsPosition === 'top' ? totals.offsetHeight + tableHead.offsetHeight : tableHead.offsetHeight;

if (cell.offsetTop - tableHeadHeight - cell.offsetHeight < tableContainerRef.current.scrollTop) {
const targetOffsetTop = tableContainerRef.current.scrollTop - cell.offsetHeight - tableHead.offsetHeight;
tableContainerRef.current.scrollTo({
if (cell.offsetTop - tableHeadHeight - cell.offsetHeight <= tableContainer.scrollTop) {
const targetOffsetTop = tableContainer.scrollTop - tableHeadHeight;
tableContainer.scrollTo({
top: Math.max(0, targetOffsetTop),
behavior: 'instant',
});
Expand Down

0 comments on commit 57c9b0d

Please sign in to comment.