Skip to content

Commit 1bfc501

Browse files
committed
fix(tables): classify an off-window selection endpoint by its column
1 parent 97470bd commit 1bfc501

1 file changed

Lines changed: 21 additions & 8 deletions

File tree

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

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,23 @@ interface RemoteSelectionOverlayProps {
5050
scrollElement: HTMLElement | null
5151
}
5252

53+
/**
54+
* Whether a selection endpoint lands in the frozen left zone. Rows are virtualized, so an
55+
* endpoint's own cell may not exist; fall back to any rendered row's cell in that column,
56+
* since pinning is a per-column property. An endpoint whose column is gone entirely (hidden
57+
* or deleted locally) can't be classified and is treated as unpinned — the safe direction,
58+
* since the frozen zone then occludes it rather than being painted over.
59+
*/
60+
function endpointIsPinned(
61+
scrollEl: HTMLElement,
62+
cell: HTMLElement | null,
63+
columnIndex: number | undefined
64+
): boolean {
65+
if (cell !== null) return cell.hasAttribute('data-pinned')
66+
if (columnIndex === undefined) return false
67+
return scrollEl.querySelector(`[data-col="${columnIndex}"][data-pinned]`) !== null
68+
}
69+
5370
/** The cell `<td>` for a (rowId, columnIndex), or null when virtualized off-window. */
5471
function cellElement(
5572
scrollEl: HTMLElement,
@@ -177,15 +194,11 @@ export function RemoteSelectionOverlay({
177194
const cells = [anchorCell, focusCell].filter((cell): cell is HTMLElement => cell !== null)
178195
if (cells.length === 0) continue
179196
const rects = cells.map((cell) => cell.getBoundingClientRect())
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.
197+
// Only a selection pinned at BOTH ends renders above the frozen zone. One that straddles
198+
// the boundary goes below it, so its unpinned half can't paint over the gutter.
184199
const pinned =
185-
anchorCell !== null &&
186-
focusCell !== null &&
187-
anchorCell.hasAttribute('data-pinned') &&
188-
focusCell.hasAttribute('data-pinned')
200+
endpointIsPinned(scrollEl, anchorCell, anchorCol) &&
201+
endpointIsPinned(scrollEl, focusCell, focusCol)
189202

190203
const viewportTop = Math.min(...rects.map((r) => r.top))
191204
const viewportLeft = Math.min(...rects.map((r) => r.left))

0 commit comments

Comments
 (0)