feat(EditableCell): improve handling of external updates and user input
This commit is contained in:
parent
afc70a56ba
commit
5f5d8f00d9
1 changed files with 24 additions and 22 deletions
|
@ -26,65 +26,67 @@ export function EditableCell({
|
|||
className = ''
|
||||
}: EditableCellProps) {
|
||||
const [localValue, setLocalValue] = useState(value);
|
||||
const [isExternalUpdate, setIsExternalUpdate] = useState(false);
|
||||
const inputRef = useRef<HTMLInputElement>(null);
|
||||
const textareaRef = useRef<HTMLTextAreaElement>(null);
|
||||
const lastExternalValueRef = useRef(value);
|
||||
const isUserInputRef = useRef(false);
|
||||
|
||||
// Update local value when prop changes (including external updates)
|
||||
// Update local value when prop changes (only for genuine external updates)
|
||||
useEffect(() => {
|
||||
if (value !== localValue) {
|
||||
// Only update if this is a genuine external change (not from user input)
|
||||
if (value !== lastExternalValueRef.current && !isUserInputRef.current) {
|
||||
console.log('External value change detected for cell:', cellKey, value);
|
||||
setLocalValue(value);
|
||||
setIsExternalUpdate(true);
|
||||
}
|
||||
}, [value, localValue]);
|
||||
|
||||
// Reset external update flag after a short delay
|
||||
useEffect(() => {
|
||||
if (isExternalUpdate) {
|
||||
lastExternalValueRef.current = value;
|
||||
|
||||
// Reset user input flag after a short delay
|
||||
if (isUserInputRef.current) {
|
||||
const timer = setTimeout(() => {
|
||||
setIsExternalUpdate(false);
|
||||
isUserInputRef.current = false;
|
||||
}, 100);
|
||||
return () => clearTimeout(timer);
|
||||
}
|
||||
}, [isExternalUpdate]);
|
||||
}, [value, cellKey]);
|
||||
|
||||
// Handle focus when this cell becomes focused
|
||||
useEffect(() => {
|
||||
if (focusedCell === cellKey) {
|
||||
const element = inputType === 'textarea' ? textareaRef.current : inputRef.current;
|
||||
if (element) {
|
||||
if (element && document.activeElement !== element) {
|
||||
element.focus();
|
||||
// Select all text when focusing, but not during external updates
|
||||
if (!isExternalUpdate) {
|
||||
// Only select text if this is not from user input
|
||||
if (!isUserInputRef.current) {
|
||||
element.select();
|
||||
}
|
||||
}
|
||||
}
|
||||
}, [focusedCell, cellKey, inputType, isExternalUpdate]);
|
||||
}, [focusedCell, cellKey, inputType]);
|
||||
|
||||
const handleInput = useCallback((e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
|
||||
const newValue = e.target.value;
|
||||
console.log('Input event:', newValue);
|
||||
console.log('Input event for cell:', cellKey, newValue);
|
||||
isUserInputRef.current = true; // Mark as user input
|
||||
setLocalValue(newValue);
|
||||
}, []);
|
||||
}, [cellKey]);
|
||||
|
||||
const commitInput = useCallback(() => {
|
||||
console.log('Committing input:', localValue);
|
||||
console.log('Committing input for cell:', cellKey, localValue);
|
||||
onInput(localValue);
|
||||
}, [localValue, onInput]);
|
||||
}, [localValue, onInput, cellKey]);
|
||||
|
||||
const handleFocus = useCallback(() => {
|
||||
console.log('Focus gained for key:', cellKey);
|
||||
console.log('Focus gained for cell:', cellKey);
|
||||
setFocusedCell(cellKey);
|
||||
onFocus?.();
|
||||
}, [cellKey, setFocusedCell, onFocus]);
|
||||
|
||||
const handleBlur = useCallback(() => {
|
||||
console.log('Focus lost');
|
||||
console.log('Focus lost for cell:', cellKey);
|
||||
setFocusedCell(null);
|
||||
commitInput();
|
||||
onBlur?.();
|
||||
}, [setFocusedCell, commitInput, onBlur]);
|
||||
}, [setFocusedCell, commitInput, onBlur, cellKey]);
|
||||
|
||||
const handleKeyDown = useCallback((e: React.KeyboardEvent) => {
|
||||
if (e.key === 'Enter' && inputType === 'text') {
|
||||
|
|
Loading…
Add table
Reference in a new issue