From eed17bb1181020afbd3edec0164f12bf471e3b28 Mon Sep 17 00:00:00 2001 From: wuxh Date: Fri, 7 Jul 2023 15:17:48 +0800 Subject: [PATCH 1/3] feat: scrolling uses smooth transition effects by default --- src/utils/domUtils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/domUtils.ts b/src/utils/domUtils.ts index ce16126f3e..a96b473931 100644 --- a/src/utils/domUtils.ts +++ b/src/utils/domUtils.ts @@ -5,5 +5,5 @@ export function stopPropagation(event: React.SyntheticEvent) { } export function scrollIntoView(element: Maybe) { - element?.scrollIntoView({ inline: 'nearest', block: 'nearest' }); + element?.scrollIntoView({ inline: 'nearest', block: 'nearest', behavior: 'smooth' }); } From df29585a9e93840e5ae238d097e6c8dfae4990ae Mon Sep 17 00:00:00 2001 From: wuxh Date: Thu, 13 Jul 2023 17:13:08 +0800 Subject: [PATCH 2/3] feat: support options --- src/DataGrid.tsx | 15 +++++++++++---- src/ScrollToCell.tsx | 6 ++++-- src/utils/domUtils.ts | 13 +++++++++++-- website/demos/ScrollToCell.tsx | 2 +- 4 files changed, 27 insertions(+), 9 deletions(-) diff --git a/src/DataGrid.tsx b/src/DataGrid.tsx index 7da949062d..875f6c0f76 100644 --- a/src/DataGrid.tsx +++ b/src/DataGrid.tsx @@ -85,7 +85,7 @@ type DefaultColumnOptions = Pick< export interface DataGridHandle { element: HTMLDivElement | null; - scrollToCell: (position: PartialPosition) => void; + scrollToCell: (position: PartialPosition, scrollIntoViewOptions?: boolean | ScrollIntoViewOptions) => void; selectCell: (position: Position, enableEditor?: Maybe) => void; } @@ -293,6 +293,7 @@ function DataGrid( const lastSelectedRowIdx = useRef(-1); const focusSinkRef = useRef(null); const shouldFocusCellRef = useRef(false); + const scrollIntoViewOptions = useRef(); /** * computed values @@ -441,13 +442,14 @@ function DataGrid( useImperativeHandle(ref, () => ({ element: gridRef.current, - scrollToCell({ idx, rowIdx }) { + scrollToCell({ idx, rowIdx }, options) { const scrollToIdx = idx !== undefined && idx > lastFrozenColumnIndex && idx < columns.length ? idx : undefined; const scrollToRowIdx = rowIdx !== undefined && isRowIdxWithinViewportBounds(rowIdx) ? rowIdx : undefined; if (scrollToIdx !== undefined || scrollToRowIdx !== undefined) { + scrollIntoViewOptions.current = options; setScrollToPosition({ idx: scrollToIdx, rowIdx: scrollToRowIdx }); } }, @@ -678,7 +680,11 @@ function DataGrid( ); } - function selectCell(position: Position, enableEditor?: Maybe): void { + function selectCell( + position: Position, + enableEditor?: Maybe, + scrollIntoViewOptions?: boolean | ScrollIntoViewOptions + ): void { if (!isCellWithinSelectionBounds(position)) return; commitEditorChanges(); @@ -687,7 +693,7 @@ function DataGrid( setSelectedPosition({ ...position, mode: 'EDIT', row, originalRow: row }); } else if (isSamePosition(selectedPosition, position)) { // Avoid re-renders if the selected cell state is the same - scrollIntoView(getCellToScroll(gridRef.current!)); + scrollIntoView(getCellToScroll(gridRef.current!), scrollIntoViewOptions); } else { shouldFocusCellRef.current = true; setSelectedPosition({ ...position, mode: 'SELECT' }); @@ -1125,6 +1131,7 @@ function DataGrid( scrollToPosition={scrollToPosition} setScrollToCellPosition={setScrollToPosition} gridElement={gridRef.current!} + scrollIntoViewOptions={scrollIntoViewOptions.current} /> )} diff --git a/src/ScrollToCell.tsx b/src/ScrollToCell.tsx index 7fca2ce353..f9aeb80869 100644 --- a/src/ScrollToCell.tsx +++ b/src/ScrollToCell.tsx @@ -11,18 +11,20 @@ export interface PartialPosition { export default function ScrollToCell({ scrollToPosition: { idx, rowIdx }, gridElement, - setScrollToCellPosition + setScrollToCellPosition, + scrollIntoViewOptions }: { scrollToPosition: PartialPosition; gridElement: HTMLDivElement; setScrollToCellPosition: (cell: null) => void; + scrollIntoViewOptions?: boolean | ScrollIntoViewOptions | undefined; }) { const ref = useRef(null); useLayoutEffect(() => { // scroll until the cell is completely visible // this is needed if the grid has auto-sized columns - scrollIntoView(ref.current); + scrollIntoView(ref.current, scrollIntoViewOptions); }); useLayoutEffect(() => { diff --git a/src/utils/domUtils.ts b/src/utils/domUtils.ts index a96b473931..510610c02e 100644 --- a/src/utils/domUtils.ts +++ b/src/utils/domUtils.ts @@ -4,6 +4,15 @@ export function stopPropagation(event: React.SyntheticEvent) { event.stopPropagation(); } -export function scrollIntoView(element: Maybe) { - element?.scrollIntoView({ inline: 'nearest', block: 'nearest', behavior: 'smooth' }); +export function scrollIntoView( + element: Maybe, + coverOptions?: boolean | ScrollIntoViewOptions +) { + let options: boolean | ScrollIntoViewOptions = { inline: 'nearest', block: 'nearest' }; + if (typeof coverOptions === 'boolean') { + options = coverOptions; + } else if(typeof coverOptions === 'object') { + options = Object.assign(options, coverOptions); + } + element?.scrollIntoView(options); } diff --git a/website/demos/ScrollToCell.tsx b/website/demos/ScrollToCell.tsx index 050e754de5..9b541f7db1 100644 --- a/website/demos/ScrollToCell.tsx +++ b/website/demos/ScrollToCell.tsx @@ -41,7 +41,7 @@ export default function ScrollToCell({ direction }: Props) { } function scrollToCell() { - gridRef.current!.scrollToCell({ idx, rowIdx }); + gridRef.current!.scrollToCell({ idx, rowIdx }, { behavior: 'smooth' }); // smooth transition } return ( From 59e6cee676e20746cf5717b5cd0b9f86c6b9ba9c Mon Sep 17 00:00:00 2001 From: wuxh Date: Thu, 13 Jul 2023 17:39:34 +0800 Subject: [PATCH 3/3] perf: update logic --- src/utils/domUtils.ts | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/utils/domUtils.ts b/src/utils/domUtils.ts index 510610c02e..30ce52d747 100644 --- a/src/utils/domUtils.ts +++ b/src/utils/domUtils.ts @@ -8,11 +8,13 @@ export function scrollIntoView( element: Maybe, coverOptions?: boolean | ScrollIntoViewOptions ) { - let options: boolean | ScrollIntoViewOptions = { inline: 'nearest', block: 'nearest' }; - if (typeof coverOptions === 'boolean') { - options = coverOptions; - } else if(typeof coverOptions === 'object') { - options = Object.assign(options, coverOptions); + if(element?.scrollIntoView) { + let options: typeof coverOptions = { inline: 'nearest', block: 'nearest' }; + if (typeof coverOptions === 'boolean') { + options = coverOptions; + } else if(typeof coverOptions === 'object') { + options = Object.assign(options, coverOptions); + } + element.scrollIntoView(options); } - element?.scrollIntoView(options); }