Skip to content

Commit 2a5065e

Browse files
fix(eui): add a ref and pointerup event listener
1 parent a97cf21 commit 2a5065e

1 file changed

Lines changed: 35 additions & 10 deletions

File tree

packages/eui/src/components/datagrid/utils/scrolling.tsx

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import React, {
1111
useEffect,
1212
useCallback,
1313
useMemo,
14+
useRef,
1415
MutableRefObject,
1516
ReactNode,
1617
} from 'react';
@@ -53,22 +54,46 @@ export const useScroll = (args: Dependencies) => {
5354
const { focusedCell } = useContext(DataGridFocusContext);
5455
const isPointerDownRef = useIsPointerDown(args.outerGridRef);
5556

57+
/**
58+
* Set when `focusedCell` changes while the pointer is held down (e.g. clicking a cell).
59+
* Allows the `pointerup` listener below to scroll on release without
60+
* causing snap-back when the user scrolls the grid without changing focus.
61+
*/
62+
const pendingScrollRef = useRef(false);
63+
5664
useEffect(() => {
57-
if (focusedCell) {
58-
// do not scroll if text is being selected
59-
if (
60-
isPointerDownRef.current ||
61-
window?.getSelection()?.type === 'Range'
62-
) {
63-
return;
64-
}
65+
if (!focusedCell) return;
66+
if (isPointerDownRef.current) {
67+
// Pointer is down - defer scroll decision to the pointerup listener
68+
pendingScrollRef.current = true;
69+
return;
70+
}
71+
72+
scrollCellIntoView({ rowIndex: focusedCell[1], colIndex: focusedCell[0] });
73+
}, [focusedCell, scrollCellIntoView, isPointerDownRef]);
74+
75+
useEffect(() => {
76+
const handlePointerUp = () => {
77+
if (!pendingScrollRef.current || !focusedCell) return;
78+
79+
pendingScrollRef.current = false;
80+
81+
// Skip if the interaction resulted in text being selected
82+
if (window?.getSelection()?.type === 'Range') return;
6583

6684
scrollCellIntoView({
6785
rowIndex: focusedCell[1],
6886
colIndex: focusedCell[0],
6987
});
70-
}
71-
}, [focusedCell, scrollCellIntoView, isPointerDownRef]);
88+
};
89+
90+
document.addEventListener('pointerup', handlePointerUp, { capture: true });
91+
92+
return () =>
93+
document.removeEventListener('pointerup', handlePointerUp, {
94+
capture: true,
95+
});
96+
}, [focusedCell, scrollCellIntoView]);
7297

7398
const { popoverIsOpen, cellLocation } = useContext(
7499
DataGridCellPopoverContext

0 commit comments

Comments
 (0)