@@ -172,15 +172,20 @@ export function RemoteSelectionOverlay({
172172 const focusCol = columnIndexByIdRef . current . get ( focus . columnId )
173173 const anchorRow = rowIndexByIdRef . current . get ( anchor . rowId )
174174 const focusRow = rowIndexByIdRef . current . get ( focus . rowId )
175- const cells = [
176- cellElement ( scrollEl , anchor . rowId , anchorCol ) ,
177- cellElement ( scrollEl , focus . rowId , focusCol ) ,
178- ] . filter ( ( cell ) : cell is HTMLElement => cell !== null )
175+ const anchorCell = cellElement ( scrollEl , anchor . rowId , anchorCol )
176+ const focusCell = cellElement ( scrollEl , focus . rowId , focusCol )
177+ const cells = [ anchorCell , focusCell ] . filter ( ( cell ) : cell is HTMLElement => cell !== null )
179178 if ( cells . length === 0 ) continue
180179 const rects = cells . map ( ( cell ) => cell . getBoundingClientRect ( ) )
181- // A range straddling the boundary defers to the frozen zone, so its scrolled-away half
182- // can't bleed over the gutter — the conservative half of the trade, and the rarer case.
183- const pinned = cells . every ( ( cell ) => cell . hasAttribute ( 'data-pinned' ) )
180+ // Both endpoints must be resolved AND pinned. Anything else — a range straddling the
181+ // boundary, or one whose other endpoint is virtualized off-window and so can't be
182+ // classified — defers to the frozen zone, where the worst case is a selection the zone
183+ // hides rather than one painting over the gutter.
184+ const pinned =
185+ anchorCell !== null &&
186+ focusCell !== null &&
187+ anchorCell . hasAttribute ( 'data-pinned' ) &&
188+ focusCell . hasAttribute ( 'data-pinned' )
184189
185190 const viewportTop = Math . min ( ...rects . map ( ( r ) => r . top ) )
186191 const viewportLeft = Math . min ( ...rects . map ( ( r ) => r . left ) )
0 commit comments