diff --git a/src/components/DualSpreadsheet/DualSpreadsheet.tsx b/src/components/DualSpreadsheet/DualSpreadsheet.tsx index ce649ee..414cd0c 100644 --- a/src/components/DualSpreadsheet/DualSpreadsheet.tsx +++ b/src/components/DualSpreadsheet/DualSpreadsheet.tsx @@ -12,7 +12,7 @@ import { useMultiSheetEngine } from '../../hooks/useMultiSheetEngine' const ROW_COUNT = 90 const COL_COUNT = 20 -const ROW_HEIGHT = 32 +const ROW_HEIGHT = 28 const SHEET_NAMES = { report: 'L', @@ -66,9 +66,9 @@ const Cell = memo( setActiveSheet, activeCellRef, }: CellProps) => { - const className = `border border-gray-200 ${ - isSelected ? 'bg-blue-100' : '' - } ${isModified ? 'bg-yellow-50' : ''}` + const className = `border border-border ${isSelected ? 'bg-accent' : ''} ${ + isModified ? 'bg-yellow-50' : '' + }` const style = { minWidth: `${columnWidth}px`, @@ -112,12 +112,16 @@ const Cell = memo( stopEditing(false) } }} - className="absolute left-0 top-0 z-20 box-border h-full w-full border-2 border-blue-500 p-2" + className="absolute left-0 top-0 z-20 box-border h-full w-full border-2 border-primary px-2 py-1" /> ) : (
{displayValue}
@@ -157,43 +161,74 @@ const FormulaBar = memo( }: FormulaBarProps) => { if (activeSheet !== sheetType) { return ( -
-
+
+
) } return ( -
+
-
- +
+ {selectedCell ? `${getColumnLabel(selectedCell.col)}${selectedCell.row + 1}` - : ''} - + : 'A1'} +
- {isCalculating && ( -
- Вычисляется... +
+
+ + +
- )} -
onValueChange(e.target.value)} onFocus={onFocus} onBlur={onBlur} onKeyDown={onKeyDown} /> + {isCalculating && ( +
+ + + + +
+ )}
@@ -310,7 +345,7 @@ const DualSpreadsheet: FC = ({ templateData = {} }) => { } setIsEditing(false) setEditingValue('') // Очищаем временное значение - containerRefs.current[activeSheet]?.focus() + containerRefs.current[activeSheet]?.focus({ preventScroll: true }) }, [activeSheet, selectedCell, editingValue, multiSheetEngine], ) @@ -404,7 +439,7 @@ const DualSpreadsheet: FC = ({ templateData = {} }) => { stopEditing(true) } setSelectedCell({ row, col }) - containerRefs.current[activeSheet]?.focus() + containerRefs.current[activeSheet]?.focus({ preventScroll: true }) }, [isEditing, stopEditing, activeSheet], ) @@ -459,10 +494,14 @@ const DualSpreadsheet: FC = ({ templateData = {} }) => { e.preventDefault() stopEditing(true) moveSelection(1, 0) + // Предотвращаем прокрутку страницы + setTimeout(() => { + containerRefs.current[activeSheet]?.focus({ preventScroll: true }) + }, 0) } else if (e.key === 'Escape') { e.preventDefault() stopEditing(false) - containerRefs.current[activeSheet]?.focus() + containerRefs.current[activeSheet]?.focus({ preventScroll: true }) } }, [stopEditing, moveSelection, activeSheet], @@ -476,120 +515,129 @@ const DualSpreadsheet: FC = ({ templateData = {} }) => { return (
(containerRefs.current[sheetType] = el)} - className="overflow-auto rounded-lg border border-gray-300 bg-white shadow-md" - style={{ - width: '100%', - height: '100%', - position: 'relative', - }} + className="flex h-full flex-col overflow-hidden rounded-lg border bg-card shadow-sm" onKeyDown={handleKeyDown} tabIndex={0} > - - - - - {Array.from({ length: COL_COUNT }, (_, i) => { - const handleMouseDown = (e: React.MouseEvent) => { - e.preventDefault() - const startX = e.clientX - const startWidth = widths[i] +
+
+
+

+ {sheetType === 'report' ? 'Отчет' : 'Расчеты'} +

+
+
+
+
+ + + + {Array.from({ length: COL_COUNT }, (_, i) => { + const handleMouseDown = (e: React.MouseEvent) => { + e.preventDefault() + const startX = e.clientX + const startWidth = widths[i] - const handleMouseMove = (me: MouseEvent) => { - const newWidth = startWidth + (me.clientX - startX) - handleColumnResize(sheetType, i, newWidth) + const handleMouseMove = (me: MouseEvent) => { + const newWidth = startWidth + (me.clientX - startX) + handleColumnResize(sheetType, i, newWidth) + } + + const handleMouseUp = () => { + document.removeEventListener('mousemove', handleMouseMove) + document.removeEventListener('mouseup', handleMouseUp) + } + + document.addEventListener('mousemove', handleMouseMove) + document.addEventListener('mouseup', handleMouseUp) } - - const handleMouseUp = () => { - document.removeEventListener('mousemove', handleMouseMove) - document.removeEventListener('mouseup', handleMouseUp) - } - - document.addEventListener('mousemove', handleMouseMove) - document.addEventListener('mouseup', handleMouseUp) - } - return ( - - ) - })} - - - - {Array.from({ length: ROW_COUNT }).map((_, rowIndex) => ( - - - {Array.from({ length: COL_COUNT }).map((_, colIndex) => { - const isCellSelected = - selectedCell?.row === rowIndex && - selectedCell?.col === colIndex && - activeSheet === sheetType - const isCellEditing = isCellSelected && isEditing - - const rawValue = isCellEditing - ? editingValue - : multiSheetEngine.getCellRawValue( - sheetName, - rowIndex, - colIndex, - ) - const displayValue = isCellEditing - ? '' // Не показывать вычисленное значение во время редактирования - : String( - multiSheetEngine.getCellValue( - sheetName, - rowIndex, - colIndex, - ) || '', - ) - - const cellName = getColumnLabel(colIndex) + (rowIndex + 1) - const templateValue = - initialTemplateValues.current[cellName] ?? '' - const isModified = - sheetType === 'report' && - templateValue !== '' && - rawValue !== templateValue - return ( - + ) })} - ))} - -
- {getColumnLabel(i)} -
-
- {rowIndex + 1} - + {getColumnLabel(i)} +
+
+ + + {Array.from({ length: ROW_COUNT }).map((_, rowIndex) => ( + + + {rowIndex + 1} + + {Array.from({ length: COL_COUNT }).map((_, colIndex) => { + const isCellSelected = + selectedCell?.row === rowIndex && + selectedCell?.col === colIndex && + activeSheet === sheetType + const isCellEditing = isCellSelected && isEditing + + const rawValue = isCellEditing + ? editingValue + : multiSheetEngine.getCellRawValue( + sheetName, + rowIndex, + colIndex, + ) + const displayValue = isCellEditing + ? '' // Не показывать вычисленное значение во время редактирования + : String( + multiSheetEngine.getCellValue( + sheetName, + rowIndex, + colIndex, + ) || '', + ) + + const cellName = getColumnLabel(colIndex) + (rowIndex + 1) + const templateValue = + initialTemplateValues.current[cellName] ?? '' + const isModified = + sheetType === 'report' && + templateValue !== '' && + rawValue !== templateValue + + return ( + + ) + })} + + ))} + + +
) } @@ -623,22 +671,7 @@ const DualSpreadsheet: FC = ({ templateData = {} }) => { ) return ( -
- {/* Двойная панель */} -
- {/* Левая панель - Отчет */} -
-

Отчет

- {memoizedReportSheet} -
- - {/* Правая панель - Вычисления */} -
-

Расчеты

- {memoizedCalculationsSheet} -
-
- +
= ({ templateData = {} }) => { formulaBarRef={(el) => (formulaBarRefs.current[activeSheet] = el)} />
+ {/* Двойная панель */} +
+
{memoizedReportSheet}
+
{memoizedCalculationsSheet}
+
) }