Refactor RealtimePreviewDynamic and ResponsiveGridRenderer components to enhance rendering logic using CSS scale for improved layout consistency. Update SplitPanelLayoutComponent to handle drag events more effectively by passing the event object. This ensures better user interaction during column dragging.

This commit is contained in:
DDD1542 2026-03-17 22:24:47 +09:00
parent f36638e53e
commit ba8a2fec2b
3 changed files with 46 additions and 32 deletions

View File

@ -592,10 +592,10 @@ const RealtimePreviewDynamicComponent: React.FC<RealtimePreviewProps> = ({
isResizing ? "none" :
isOnSplitPanel ? (isDraggingSplitPanel ? "none" : "left 0.15s ease-out, width 0.15s ease-out") : undefined,
} : {
// 런타임 모드: 부모(ResponsiveGridRenderer)가 위치/너비 관리
// 런타임 모드: CSS scale 기반 - 캔버스 픽셀 크기 그대로 사용, 부모가 scale()로 축소
...safeComponentStyle,
width: "100%",
height: displayHeight,
height: "100%",
position: "relative" as const,
};

View File

@ -23,8 +23,9 @@ function getComponentTypeId(component: ComponentData): string {
}
/**
* .
* , .
* CSS transform scale .
* (px) CSS scale로 /.
* , , WYSIWYG .
*/
function ProportionalRenderer({
components,
@ -47,7 +48,7 @@ function ProportionalRenderer({
}, []);
const topLevel = components.filter((c) => !c.parentId);
const ratio = containerW > 0 ? containerW / canvasWidth : 1;
const scale = containerW > 0 ? containerW / canvasWidth : 1;
const maxBottom = topLevel.reduce((max, c) => {
const bottom = c.position.y + (c.size?.height || 40);
@ -58,30 +59,41 @@ function ProportionalRenderer({
<div
ref={containerRef}
data-screen-runtime="true"
className="bg-background relative w-full overflow-x-hidden"
style={{ minHeight: containerW > 0 ? `${maxBottom * ratio}px` : "200px" }}
className="bg-background w-full overflow-hidden"
style={{ height: containerW > 0 ? `${maxBottom * scale}px` : "200px" }}
>
{containerW > 0 &&
topLevel.map((component) => {
const typeId = getComponentTypeId(component);
return (
<div
key={component.id}
data-component-id={component.id}
data-component-type={typeId}
style={{
position: "absolute",
left: `${(component.position.x / canvasWidth) * 100}%`,
top: `${component.position.y * ratio}px`,
width: `${((component.size?.width || 100) / canvasWidth) * 100}%`,
height: `${(component.size?.height || 40) * ratio}px`,
zIndex: component.position.z || 1,
}}
>
{renderComponent(component)}
</div>
);
})}
{containerW > 0 && (
<div
style={{
width: `${canvasWidth}px`,
height: `${maxBottom}px`,
transform: `scale(${scale})`,
transformOrigin: "top left",
position: "relative",
}}
>
{topLevel.map((component) => {
const typeId = getComponentTypeId(component);
return (
<div
key={component.id}
data-component-id={component.id}
data-component-type={typeId}
style={{
position: "absolute",
left: `${component.position.x}px`,
top: `${component.position.y}px`,
width: `${component.size?.width || 100}px`,
height: `${component.size?.height || 40}px`,
zIndex: component.position.z || 1,
}}
>
{renderComponent(component)}
</div>
);
})}
</div>
)}
</div>
);
}

View File

@ -2522,9 +2522,11 @@ export const SplitPanelLayoutComponent: React.FC<SplitPanelLayoutComponentProps>
// 우측 패널 컬럼 헤더 드래그 (디자인 모드에서 컬럼 순서 변경)
const handleRightColumnDragStart = useCallback(
(columnIndex: number, source: "main" | number) => {
(e: React.DragEvent, columnIndex: number, source: "main" | number) => {
setRightDraggedColumnIndex(columnIndex);
setRightDragSource(source);
e.dataTransfer.effectAllowed = "move";
e.dataTransfer.setData("text/plain", `col-${source}-${columnIndex}`);
},
[],
);
@ -4181,7 +4183,7 @@ export const SplitPanelLayoutComponent: React.FC<SplitPanelLayoutComponentProps>
isDragging && "opacity-50",
)}
draggable={canDragTabColumns}
onDragStart={() => canDragTabColumns && handleRightColumnDragStart(idx, tabIndex)}
onDragStart={(e) => canDragTabColumns && handleRightColumnDragStart(e, idx, tabIndex)}
onDragOver={(e) => canDragTabColumns && handleRightColumnDragOver(e, idx)}
onDragEnd={handleRightColumnDragEnd}
onDrop={(e) => canDragTabColumns && handleRightColumnDrop(e, idx, tabIndex)}
@ -4318,7 +4320,7 @@ export const SplitPanelLayoutComponent: React.FC<SplitPanelLayoutComponentProps>
isDragging && "opacity-50",
)}
draggable={canDragListTabColumns}
onDragStart={() => canDragListTabColumns && handleRightColumnDragStart(idx, listTabIndex)}
onDragStart={(e) => canDragListTabColumns && handleRightColumnDragStart(e, idx, listTabIndex)}
onDragOver={(e) => canDragListTabColumns && handleRightColumnDragOver(e, idx)}
onDragEnd={handleRightColumnDragEnd}
onDrop={(e) => canDragListTabColumns && handleRightColumnDrop(e, idx, listTabIndex)}
@ -4745,7 +4747,7 @@ export const SplitPanelLayoutComponent: React.FC<SplitPanelLayoutComponentProps>
textAlign: col.align || "left",
}}
draggable={isDraggable}
onDragStart={() => isDraggable && handleRightColumnDragStart(configColIndex, "main")}
onDragStart={(e) => isDraggable && handleRightColumnDragStart(e, configColIndex, "main")}
onDragOver={(e) => isDraggable && handleRightColumnDragOver(e, configColIndex)}
onDragEnd={handleRightColumnDragEnd}
onDrop={(e) => isDraggable && handleRightColumnDrop(e, configColIndex, "main")}