Skip to content

Commit 97470bd

Browse files
committed
fix(tables): classify a remote selection as pinned only when both endpoints resolve
1 parent f734c44 commit 97470bd

2 files changed

Lines changed: 17 additions & 9 deletions

File tree

apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/table-grid/data-row.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,11 @@ export const DataRow = React.memo(function DataRow({
306306
const isRightEdge = inRange ? colIndex === sel!.endCol : colIndex === columns.length - 1
307307

308308
const pinnedLeft = pinnedOffsets?.get(column.key)
309+
/**
310+
* Whether this cell is frozen in the sticky left zone. Drives the sticky offset and,
311+
* via the `data-pinned` attribute below, tells overlays measured off these cells
312+
* (see `remote-selection-overlay.tsx`) a frozen cell from one scrolled behind the zone.
313+
*/
309314
const isPinnedCell = pinnedLeft !== undefined
310315
const isPinnedSeparator = column.key === lastPinnedColKey
311316

@@ -315,8 +320,6 @@ export const DataRow = React.memo(function DataRow({
315320
data-row={rowIndex}
316321
data-row-id={row.id}
317322
data-col={colIndex}
318-
// Read by overlays measured off these cells (see remote-selection-overlay.tsx)
319-
// to tell a cell frozen in the sticky zone from one scrolled behind it.
320323
data-pinned={isPinnedCell ? '' : undefined}
321324
className={cn(
322325
CELL,

apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/table-grid/remote-selection-overlay.tsx

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)