diff --git a/app/src/components/SimulationDashboard/DashboardEditor.tsx b/app/src/components/SimulationDashboard/DashboardEditor.tsx index 0bd4efb..bb6ba7e 100644 --- a/app/src/components/SimulationDashboard/DashboardEditor.tsx +++ b/app/src/components/SimulationDashboard/DashboardEditor.tsx @@ -252,12 +252,20 @@ const DashboardEditor: React.FC = () => { if (blockElement && elementToDrag) { const blockRect = blockElement.getBoundingClientRect(); + const elementRect = elementToDrag.getBoundingClientRect(); const newX = e.clientX - blockRect.left - elementDragOffset.x; const newY = e.clientY - blockRect.top - elementDragOffset.y; - // Direct DOM manipulation - elementToDrag.style.left = `${Math.max(0, Math.min(blockRect.width - 50, newX))}px`; - elementToDrag.style.top = `${Math.max(0, Math.min(blockRect.height - 30, newY))}px`; + // Constrain element to stay within block bounds using actual element dimensions + // Add 20px padding on all sides to match the padding used in calculateMinBlockSize + const minX = 20; // Left padding + const minY = 20; // Top padding + const maxX = blockRect.width - elementRect.width - 20; // Right padding + const maxY = blockRect.height - elementRect.height - 20; // Bottom padding + + // Direct DOM manipulation with padding on all sides + elementToDrag.style.left = `${Math.max(minX, Math.min(maxX, newX))}px`; + elementToDrag.style.top = `${Math.max(minY, Math.min(maxY, newY))}px`; } } @@ -318,10 +326,32 @@ const DashboardEditor: React.FC = () => { const deltaY = e.clientY - resizeStart.y; const currentBlock = blocks.find((b) => b.blockUuid === resizingBlock); - const minSize = currentBlock ? calculateMinBlockSize(currentBlock) : { width: 100, height: 50 }; - const newWidth = Math.max(minSize.width, resizeStart.width + deltaX); - const newHeight = Math.max(minSize.height, resizeStart.height + deltaY); + // Calculate minimum size based on ALL elements in the block + const minSize = currentBlock ? calculateMinBlockSize(currentBlock) : { width: 100, height: 50 }; + const minWidth = minSize.width; + const minHeight = minSize.height; + + let newWidth = Math.max(minWidth, resizeStart.width + deltaX); + let newHeight = Math.max(minHeight, resizeStart.height + deltaY); + + // Constrain block to editor bounds if it has absolute or fixed positioning + if (currentBlock && (currentBlock.positionType === "absolute" || currentBlock.positionType === "fixed")) { + const editorElement = editorRef.current; + if (editorElement) { + const editorRect = editorElement.getBoundingClientRect(); + const blockX = currentBlock.position?.x || 0; + const blockY = currentBlock.position?.y || 0; + + // Calculate max allowed dimensions based on position + const maxAllowedWidth = editorRect.width - blockX; + const maxAllowedHeight = editorRect.height - blockY; + + // Constrain width and height to editor bounds, but not below minimum + newWidth = Math.max(minWidth, Math.min(newWidth, maxAllowedWidth)); + newHeight = Math.max(minHeight, Math.min(newHeight, maxAllowedHeight)); + } + } // Direct DOM manipulation blockToResize.style.width = `${newWidth}px`; diff --git a/app/src/components/SimulationDashboard/functions/block/calculateMinBlockSize.ts b/app/src/components/SimulationDashboard/functions/block/calculateMinBlockSize.ts index fb63e7f..4a5cbe0 100644 --- a/app/src/components/SimulationDashboard/functions/block/calculateMinBlockSize.ts +++ b/app/src/components/SimulationDashboard/functions/block/calculateMinBlockSize.ts @@ -3,6 +3,7 @@ import type { Block } from "../../../../types/exportedTypes"; export const calculateMinBlockSize = (block: Block): Size => { let minWidth = 100; let minHeight = 50; + let stackedHeight = 0; // Track cumulative height for stacked elements block.elements.forEach((element) => { if (element.positionType === "absolute") { @@ -11,10 +12,18 @@ export const calculateMinBlockSize = (block: Block): Size => { minWidth = Math.max(minWidth, elementRight + 20); minHeight = Math.max(minHeight, elementBottom + 20); } else { + // For relative/static elements, they stack vertically + // Width: take the maximum minWidth = Math.max(minWidth, (element.size?.width || 200) + 40); - minHeight = Math.max(minHeight, (element.size?.height || 60) + 40); + // Height: sum them up since they stack + stackedHeight += element.size?.height || 60; } }); + // Add padding to stacked height and compare with minHeight from absolute elements + if (stackedHeight > 0) { + minHeight = Math.max(minHeight, stackedHeight + 40); + } + return { width: minWidth, height: minHeight }; };