Skip to content

Commit a7f94a4

Browse files
waleedlatif1claude
andcommitted
feat(tables): add Shift+Space row selection and Ctrl+D fill down
Shift+Space now selects the entire row (all columns) instead of toggling a checkbox, matching Google Sheets behavior. Ctrl+D copies the top cell's value down through the selected range with full undo/redo support. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent d90d90e commit a7f94a4

1 file changed

Lines changed: 40 additions & 11 deletions

File tree

  • apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/table

apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/table/table.tsx

Lines changed: 40 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1028,18 +1028,13 @@ export function Table({
10281028
if (e.key === ' ' && e.shiftKey) {
10291029
const a = selectionAnchorRef.current
10301030
if (!a || editingCellRef.current) return
1031+
const currentCols = columnsRef.current
1032+
if (currentCols.length === 0) return
10311033
e.preventDefault()
1032-
setSelectionFocus(null)
1033-
setCheckedRows((prev) => {
1034-
const next = new Set(prev)
1035-
if (next.has(a.rowIndex)) {
1036-
next.delete(a.rowIndex)
1037-
} else {
1038-
next.add(a.rowIndex)
1039-
}
1040-
return next
1041-
})
1042-
lastCheckboxRowRef.current = a.rowIndex
1034+
setCheckedRows((prev) => (prev.size === 0 ? prev : EMPTY_CHECKED_ROWS))
1035+
setIsColumnSelection(false)
1036+
setSelectionAnchor({ rowIndex: a.rowIndex, colIndex: 0 })
1037+
setSelectionFocus({ rowIndex: a.rowIndex, colIndex: currentCols.length - 1 })
10431038
return
10441039
}
10451040

@@ -1225,6 +1220,40 @@ export function Table({
12251220
return
12261221
}
12271222

1223+
if ((e.metaKey || e.ctrlKey) && e.key === 'd') {
1224+
if (!canEditRef.current) return
1225+
const sel = computeNormalizedSelection(anchor, selectionFocusRef.current)
1226+
if (!sel || sel.startRow === sel.endRow) return
1227+
e.preventDefault()
1228+
const pMap = positionMapRef.current
1229+
const sourceRow = pMap.get(sel.startRow)
1230+
if (!sourceRow) return
1231+
const undoCells: Array<{
1232+
rowId: string
1233+
oldData: Record<string, unknown>
1234+
newData: Record<string, unknown>
1235+
}> = []
1236+
for (let r = sel.startRow + 1; r <= sel.endRow; r++) {
1237+
const row = pMap.get(r)
1238+
if (!row) continue
1239+
const oldData: Record<string, unknown> = {}
1240+
const newData: Record<string, unknown> = {}
1241+
for (let c = sel.startCol; c <= sel.endCol; c++) {
1242+
if (c < cols.length) {
1243+
const colName = cols[c].name
1244+
oldData[colName] = row.data[colName] ?? null
1245+
newData[colName] = sourceRow.data[colName] ?? null
1246+
}
1247+
}
1248+
undoCells.push({ rowId: row.id, oldData, newData })
1249+
mutateRef.current({ rowId: row.id, data: newData })
1250+
}
1251+
if (undoCells.length > 0) {
1252+
pushUndoRef.current({ type: 'update-cells', cells: undoCells })
1253+
}
1254+
return
1255+
}
1256+
12281257
if (e.key === 'Delete' || e.key === 'Backspace') {
12291258
if (!canEditRef.current) return
12301259
e.preventDefault()

0 commit comments

Comments
 (0)