diff --git a/src/components/LayoutStep.tsx b/src/components/LayoutStep.tsx index 00a620a..bee175d 100644 --- a/src/components/LayoutStep.tsx +++ b/src/components/LayoutStep.tsx @@ -1,7 +1,7 @@ import React, { useRef, useState, useMemo } from 'react'; import { AppConfig, LayoutSplits } from '../types'; -// ИСПРАВЛЕНИЕ: Используем безопасные иконки -import { Grid, MousePointer2, Trash2, RotateCcw, LayoutGrid, X, Plus, Minus, RectangleHorizontal, RectangleVertical } from 'lucide-react'; +// Заменили иконки на Columns/Rows (они есть везде) +import { Grid, MousePointer2, Trash2, RotateCcw, LayoutGrid, X, Plus, Minus, Columns, Rows } from 'lucide-react'; interface Props { config: AppConfig; @@ -23,16 +23,20 @@ export const LayoutStep: React.FC = ({ config, splits, onChange }) => { const [isButtonHovered, setIsButtonHovered] = useState(false); const [selectedCell, setSelectedCell] = useState<{ i: number, j: number } | null>(null); + // --- ЗАЩИТА ОТ СБОЕВ --- + // Если splits или массивы не инициализированы, используем пустые значения + const safeX = splits?.x || []; + const safeY = splits?.y || []; + const safeSubdivisions = splits?.subdivisions || {}; + const viewBoxW = 1000; - const aspectRatio = config.drawer.depth / config.drawer.width; + // Защита от деления на ноль + const aspectRatio = (config.drawer.depth || 1) / (config.drawer.width || 1); const viewBoxH = viewBoxW * aspectRatio; - const sortedX = useMemo(() => [0, ...splits.x, 1].sort((a, b) => a - b), [splits.x]); - const sortedY = useMemo(() => [0, ...splits.y, 1].sort((a, b) => a - b), [splits.y]); + const sortedX = useMemo(() => [0, ...safeX, 1].sort((a, b) => a - b), [safeX]); + const sortedY = useMemo(() => [0, ...safeY, 1].sort((a, b) => a - b), [safeY]); - // ИСПРАВЛЕНИЕ: Безопасное получение subdivisions (если вдруг undefined) - const safeSubdivisions = splits.subdivisions || {}; - const getSubdivision = (i: number, j: number) => { return safeSubdivisions[`${i}-${j}`] || { rows: 1, cols: 1 }; }; @@ -63,7 +67,7 @@ export const LayoutStep: React.FC = ({ config, splits, onChange }) => { if (mode === 'lines') { if (dragging) { - const newSplits = { ...splits, x: [...splits.x], y: [...splits.y] }; + const newSplits = { ...splits, x: [...safeX], y: [...safeY] }; const val = dragging.axis === 'x' ? nx : ny; newSplits[dragging.axis][dragging.index] = val; onChange(newSplits); @@ -75,8 +79,8 @@ export const LayoutStep: React.FC = ({ config, splits, onChange }) => { setHoveredSplit(null); const SNAP = 0.02; - const closeToX = splits.x.some(val => Math.abs(nx - val) < SNAP); - const closeToY = splits.y.some(val => Math.abs(ny - val) < SNAP); + const closeToX = safeX.some(val => Math.abs(nx - val) < SNAP); + const closeToY = safeY.some(val => Math.abs(ny - val) < SNAP); const closeToEdgeX = nx < SNAP || nx > (1 - SNAP); const closeToEdgeY = ny < SNAP || ny > (1 - SNAP); @@ -105,7 +109,7 @@ export const LayoutStep: React.FC = ({ config, splits, onChange }) => { else if (e.button === 2) removeSplit(hoveredSplit.axis, hoveredSplit.index); } else if (phantomAxis && !isButtonHovered) { const val = phantomAxis === 'x' ? mousePos.x : mousePos.y; - const newSplits = { ...splits }; + const newSplits = { ...splits, x: [...safeX], y: [...safeY] }; newSplits[phantomAxis] = [...newSplits[phantomAxis], val]; onChange(newSplits); setDragging({ axis: phantomAxis, index: newSplits[phantomAxis].length - 1 }); @@ -116,7 +120,7 @@ export const LayoutStep: React.FC = ({ config, splits, onChange }) => { }; const removeSplit = (axis: Axis, index: number) => { - const newSplits = { ...splits }; + const newSplits = { ...splits, x: [...safeX], y: [...safeY] }; newSplits[axis] = newSplits[axis].filter((_, i) => i !== index); onChange(newSplits); setHoveredSplit(null); @@ -261,7 +265,7 @@ export const LayoutStep: React.FC = ({ config, splits, onChange }) => { }); })} - {splits.x.map((x, i) => ( + {safeX.map((x, i) => ( handleSplitHover(e, 'x', i)}> @@ -276,7 +280,7 @@ export const LayoutStep: React.FC = ({ config, splits, onChange }) => { ))} - {splits.y.map((y, i) => ( + {safeY.map((y, i) => ( handleSplitHover(e, 'y', i)}> @@ -305,7 +309,6 @@ export const LayoutStep: React.FC = ({ config, splits, onChange }) => { )} - {/* --- МЕНЮ ДЛЯ ЯЧЕЙКИ (С ИСПРАВЛЕННЫМИ ИКОНКАМИ) --- */} {mode === 'cells' && selectedCell && (
= ({ config, splits, onChange }) => { }} onMouseDown={(e) => e.stopPropagation()} > - {/* Ряды */}
- + {getSubdivision(selectedCell.i, selectedCell.j).cols}
- {/* Колонки */}
- + {getSubdivision(selectedCell.i, selectedCell.j).rows}