71 lines
1.4 KiB
TypeScript
71 lines
1.4 KiB
TypeScript
import { useEffect, useRef, useState } from "react";
|
|
import { Input } from "../../components/ui/input";
|
|
|
|
type EditableCell = {
|
|
value: string | number | null | undefined;
|
|
id: string;
|
|
field: string;
|
|
className?: string;
|
|
onSubmit: (args: { id: string; field: string; value: string }) => void;
|
|
};
|
|
|
|
export default function EditableCellInput({
|
|
value,
|
|
id,
|
|
field,
|
|
className = "w-32",
|
|
onSubmit,
|
|
}: EditableCell) {
|
|
const initialValue = String(value ?? "");
|
|
const [localValue, setLocalValue] = useState(initialValue);
|
|
const submitting = useRef(false);
|
|
|
|
useEffect(() => {
|
|
setLocalValue(initialValue);
|
|
}, [initialValue]);
|
|
|
|
const handleSubmit = (nextValue: string) => {
|
|
const trimmedValue = nextValue.trim();
|
|
|
|
if (trimmedValue === initialValue) return;
|
|
|
|
onSubmit({
|
|
id,
|
|
field,
|
|
value: trimmedValue,
|
|
});
|
|
};
|
|
|
|
return (
|
|
<Input
|
|
value={localValue}
|
|
className={className}
|
|
onChange={(e) => setLocalValue(e.currentTarget.value)}
|
|
onBlur={(e) => {
|
|
if (submitting.current) return;
|
|
|
|
submitting.current = true;
|
|
handleSubmit(e.currentTarget.value);
|
|
setTimeout(() => {
|
|
submitting.current = false;
|
|
}, 100);
|
|
}}
|
|
onKeyDown={(e) => {
|
|
if (e.key !== "Enter") return;
|
|
|
|
e.preventDefault();
|
|
|
|
if (submitting.current) return;
|
|
|
|
submitting.current = true;
|
|
handleSubmit(e.currentTarget.value);
|
|
e.currentTarget.blur();
|
|
|
|
setTimeout(() => {
|
|
submitting.current = false;
|
|
}, 100);
|
|
}}
|
|
/>
|
|
);
|
|
}
|