This commit is contained in:
Artyom Tsyrulnikov
2025-07-13 11:37:43 +03:00
parent 137033ef7e
commit 79e5a07376

View File

@@ -14,6 +14,8 @@ const Spreadsheet: FC = () => {
}); });
const [selectedCell, setSelectedCell] = useState<{row: number, col: number} | null>(null); const [selectedCell, setSelectedCell] = useState<{row: number, col: number} | null>(null);
const [columnWidths, setColumnWidths] = useState<number[]>(Array(10).fill(96)); // 96px = w-24
const [rowHeights, setRowHeights] = useState<number[]>(Array(20).fill(32)); // 32px = h-8
const handleCellClick = (row: number, col: number) => { const handleCellClick = (row: number, col: number) => {
setSelectedCell({ row, col }); setSelectedCell({ row, col });
@@ -31,6 +33,22 @@ const Spreadsheet: FC = () => {
return String.fromCharCode(65 + index); // A, B, C, ... return String.fromCharCode(65 + index); // A, B, C, ...
}; };
const handleResize = (colIndex: number, newWidth: number) => {
setColumnWidths(prev => {
const newWidths = [...prev];
newWidths[colIndex] = Math.max(60, newWidth); // Минимальная ширина 60px
return newWidths;
});
};
const handleRowResize = (rowIndex: number, newHeight: number) => {
setRowHeights(prev => {
const newHeights = [...prev];
newHeights[rowIndex] = Math.max(24, newHeight); // Минимальная высота 24px
return newHeights;
});
};
return ( return (
<div className="w-full h-full bg-white"> <div className="w-full h-full bg-white">
{/* Formula bar */} {/* Formula bar */}
@@ -66,9 +84,32 @@ const Spreadsheet: FC = () => {
{Array.from({ length: 10 }, (_, i) => ( {Array.from({ length: 10 }, (_, i) => (
<th <th
key={i} key={i}
className="w-24 h-8 bg-gray-100 border border-gray-300 text-xs text-gray-600 font-medium text-center sticky top-0 z-10" className="h-8 bg-gray-100 border border-gray-300 text-xs text-gray-600 font-medium text-center sticky top-0 z-10 relative"
style={{ width: columnWidths[i] }}
> >
{getColumnLabel(i)} {getColumnLabel(i)}
{/* Resize handle */}
<div
className="absolute top-0 right-0 w-1 h-full cursor-col-resize hover:bg-blue-500 hover:bg-opacity-50"
onMouseDown={(e) => {
e.preventDefault();
const startX = e.clientX;
const startWidth = columnWidths[i];
const handleMouseMove = (e: MouseEvent) => {
const newWidth = startWidth + (e.clientX - startX);
handleResize(i, newWidth);
};
const handleMouseUp = () => {
document.removeEventListener('mousemove', handleMouseMove);
document.removeEventListener('mouseup', handleMouseUp);
};
document.addEventListener('mousemove', handleMouseMove);
document.addEventListener('mouseup', handleMouseUp);
}}
/>
</th> </th>
))} ))}
</tr> </tr>
@@ -77,18 +118,44 @@ const Spreadsheet: FC = () => {
{cells.map((row, rowIndex) => ( {cells.map((row, rowIndex) => (
<tr key={rowIndex}> <tr key={rowIndex}>
{/* Row header */} {/* Row header */}
<td className="w-12 h-8 bg-gray-100 border border-gray-300 text-xs text-gray-600 font-medium text-center sticky left-0 z-10"> <td
className="w-12 bg-gray-100 border border-gray-300 text-xs text-gray-600 font-medium text-center sticky left-0 z-10 relative"
style={{ height: rowHeights[rowIndex] }}
>
{rowIndex + 1} {rowIndex + 1}
{/* Resize handle */}
<div
className="absolute bottom-0 left-0 w-full h-1 cursor-row-resize hover:bg-blue-500 hover:bg-opacity-50"
onMouseDown={(e) => {
e.preventDefault();
const startY = e.clientY;
const startHeight = rowHeights[rowIndex];
const handleMouseMove = (e: MouseEvent) => {
const newHeight = startHeight + (e.clientY - startY);
handleRowResize(rowIndex, newHeight);
};
const handleMouseUp = () => {
document.removeEventListener('mousemove', handleMouseMove);
document.removeEventListener('mouseup', handleMouseUp);
};
document.addEventListener('mousemove', handleMouseMove);
document.addEventListener('mouseup', handleMouseUp);
}}
/>
</td> </td>
{/* Data cells */} {/* Data cells */}
{row.map((cell, colIndex) => ( {row.map((cell, colIndex) => (
<td <td
key={colIndex} key={colIndex}
className={`w-24 h-8 border border-gray-300 relative cursor-cell ${ className={`border border-gray-300 relative cursor-cell ${
selectedCell?.row === rowIndex && selectedCell?.col === colIndex selectedCell?.row === rowIndex && selectedCell?.col === colIndex
? 'bg-blue-100 border-blue-500 border-2' ? 'bg-blue-100 border-blue-500 border-2'
: 'hover:bg-gray-50' : 'hover:bg-gray-50'
}`} }`}
style={{ width: columnWidths[colIndex], height: rowHeights[rowIndex] }}
onClick={() => handleCellClick(rowIndex, colIndex)} onClick={() => handleCellClick(rowIndex, colIndex)}
> >
<input <input