File size: 2,822 Bytes
8934ee3 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 | import clsx from 'clsx';
import { useState } from 'react';
import { useTableStore } from '@/store/tableStore';
import { Input } from './ui/input';
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from './ui/select';
interface TableCellInputProps {
tableId: string;
options?: string[];
rowIndex: number;
columnId: string;
columnType: 'text' | 'number' | 'select';
initialValue: string;
}
export default function TableCellInput({
tableId,
options,
rowIndex,
columnId,
columnType,
initialValue,
}: TableCellInputProps) {
const { editCell } = useTableStore();
const [value, setValue] = useState(initialValue);
const [isEditable, setIsEditable] = useState(false);
const finishEditing = () => {
editCell(tableId, rowIndex, columnId, value);
setIsEditable(false);
};
const onKeyDown = (
e: React.KeyboardEvent<HTMLInputElement | HTMLSelectElement>
) => {
if (e.key === 'Enter' || e.key === 'Escape') {
e.preventDefault();
finishEditing();
}
};
const handleDoubleClick = (
e: React.MouseEvent<HTMLInputElement | HTMLSelectElement>
) => {
e.preventDefault();
if (isEditable) return;
setIsEditable(true);
};
const renderInput = () => {
switch (columnType) {
case 'number':
return (
<Input
type="number"
value={value}
onBlur={finishEditing}
onChange={(e) => setValue(e.target.value)}
onKeyDown={onKeyDown}
readOnly={!isEditable}
className={clsx('border-none', { 'cursor-pointer': !isEditable })}
onDoubleClick={handleDoubleClick}
/>
);
case 'select':
return (
<Select
value={value}
onOpenChange={(open) => {
if (!open) {
finishEditing();
}
}}
onValueChange={(newValue) => setValue(newValue)}
>
<SelectTrigger className="w-[180px]">
<SelectValue placeholder="Select" />
</SelectTrigger>
<SelectContent>
{options?.map((option) => (
<SelectItem key={option} value={option}>
{option}
</SelectItem>
))}
</SelectContent>
</Select>
);
case 'text':
default:
return (
<Input
value={value}
onBlur={finishEditing}
onChange={(e) => setValue(e.target.value)}
onKeyDown={onKeyDown}
readOnly={!isEditable}
className={clsx('border-none', { 'cursor-pointer': !isEditable })}
onDoubleClick={handleDoubleClick}
/>
);
}
};
return renderInput();
}
|