@@ -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