Skip to content

Commit 14f77b3

Browse files
committed
fix(files): stabilize setInputRef callback and guard against double-commit in DataTable
Wrap setInputRef in useCallback([], []) so React doesn't tear down and re-mount the input ref on every keystroke. Without stable identity, every editValue state change caused node.focus()/node.select() to fire, resetting the cursor selection to "select all" on each character typed. Add isCommittedRef to guard both the imperative commitEdit handle and the inline commitEdit (called by onBlur) against double-application. The ref is cleared in startEdit and set to true on the first commit, so a concurrent onBlur cannot re-apply the same edit.
1 parent 638dfc3 commit 14f77b3

1 file changed

Lines changed: 11 additions & 4 deletions

File tree

  • apps/sim/app/workspace/[workspaceId]/files/components/file-viewer

apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/data-table.tsx

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
'use client'
22

3-
import { forwardRef, memo, useImperativeHandle, useRef, useState } from 'react'
3+
import { forwardRef, memo, useCallback, useImperativeHandle, useRef, useState } from 'react'
44
import { cn } from '@/lib/core/utils/cn'
55

66
interface EditConfig {
@@ -31,12 +31,17 @@ const DataTableBase = forwardRef<DataTableHandle, DataTableProps>(function DataT
3131
const editStateRef = useRef({ editingCell, editValue, editConfig })
3232
editStateRef.current = { editingCell, editValue, editConfig }
3333

34+
// Prevents double-commit if onBlur and imperative commitEdit fire concurrently
35+
const isCommittedRef = useRef(false)
36+
3437
useImperativeHandle(
3538
ref,
3639
() => ({
3740
commitEdit: () => {
41+
if (isCommittedRef.current) return
3842
const { editingCell, editValue, editConfig } = editStateRef.current
3943
if (!editingCell || !editConfig) return
44+
isCommittedRef.current = true
4045
const { row, col } = editingCell
4146
if (row === -1) {
4247
editConfig.onHeaderChange(col, editValue)
@@ -49,21 +54,23 @@ const DataTableBase = forwardRef<DataTableHandle, DataTableProps>(function DataT
4954
[]
5055
)
5156

52-
const setInputRef = (node: HTMLInputElement | null) => {
57+
const setInputRef = useCallback((node: HTMLInputElement | null) => {
5358
if (node) {
5459
node.focus()
5560
node.select()
5661
}
57-
}
62+
}, [])
5863

5964
const startEdit = (row: number, col: number, currentValue: string) => {
6065
if (!editConfig) return
66+
isCommittedRef.current = false
6167
setEditingCell({ row, col })
6268
setEditValue(currentValue)
6369
}
6470

6571
const commitEdit = () => {
66-
if (!editingCell || !editConfig) return
72+
if (isCommittedRef.current || !editingCell || !editConfig) return
73+
isCommittedRef.current = true
6774
const { row, col } = editingCell
6875
if (row === -1) {
6976
editConfig.onHeaderChange(col, editValue)

0 commit comments

Comments
 (0)