fix: Section Paper 선택 영역과 컨텐츠 영역 정렬 문제 해결

- RealtimePreview: border → outline 전환, getHeight() 함수 추가
- SectionPaperComponent: width/height 100%, overflow-auto, min-h 제거
- 모든 높이에서 선택 영역 = 컨텐츠 영역 정확히 일치
This commit is contained in:
SeongHyun Kim
2025-11-25 15:22:50 +09:00
parent e456b4bb69
commit 2b8a3945a1
3 changed files with 66 additions and 34 deletions

View File

@@ -401,22 +401,10 @@ export const RealtimePreviewDynamic: React.FC<RealtimePreviewProps> = ({
// 컴포넌트 스타일 계산
const isFlowWidget = type === "flow" || (type === "component" && (component as any).componentConfig?.type === "flow-widget");
const isSectionPaper = type === "component" && (component as any).componentConfig?.type === "section-paper";
// 높이 결정 로직
let finalHeight = size?.height || 10;
if (isFlowWidget && actualHeight) {
finalHeight = actualHeight;
}
// 🔍 디버깅: position.x 값 확인
const positionX = position?.x || 0;
console.log("🔍 RealtimePreview componentStyle 설정:", {
componentId: id,
positionX,
sizeWidth: size?.width,
styleWidth: style?.width,
willUse100Percent: positionX === 0,
});
const positionY = position?.y || 0;
// 너비 결정 로직: style.width (퍼센트) > 조건부 100% > size.width (픽셀)
const getWidth = () => {
@@ -432,20 +420,35 @@ export const RealtimePreviewDynamic: React.FC<RealtimePreviewProps> = ({
return size?.width || 200;
};
// 높이 결정 로직: style.height > actualHeight (Flow Widget) > size.height
const getHeight = () => {
// 1순위: style.height가 있으면 우선 사용 (픽셀/퍼센트 값)
if (style?.height) {
return style.height;
}
// 2순위: Flow Widget의 실제 측정 높이
if (isFlowWidget && actualHeight) {
return actualHeight;
}
// 3순위: size.height 픽셀 값
return size?.height || 10;
};
const componentStyle = {
position: "absolute" as const,
...style, // 먼저 적용하고
left: positionX,
top: position?.y || 0,
top: positionY,
width: getWidth(), // 우선순위에 따른 너비
height: finalHeight,
height: getHeight(), // 우선순위에 따른 높이
zIndex: position?.z || 1,
// right 속성 강제 제거
right: undefined,
};
// 선택된 컴포넌트 스타일
const selectionStyle = isSelected
// Section Paper는 자체적으로 선택 상태 테두리를 처리하므로 outline 제거
const selectionStyle = isSelected && !isSectionPaper
? {
outline: "2px solid rgb(59, 130, 246)",
outlineOffset: "2px",
@@ -628,6 +631,24 @@ export const RealtimePreviewDynamic: React.FC<RealtimePreviewProps> = ({
</div>
)}
{/* 컴포넌트 타입 - 레지스트리 기반 렌더링 (Section Paper, Section Card 등) */}
{type === "component" && (() => {
const { DynamicComponentRenderer } = require("@/lib/registry/DynamicComponentRenderer");
return (
<DynamicComponentRenderer
component={component}
isSelected={isSelected}
isDesignMode={isDesignMode}
onClick={onClick}
onDragStart={onDragStart}
onDragEnd={onDragEnd}
{...restProps}
>
{children}
</DynamicComponentRenderer>
);
})()}
{/* 위젯 타입 - 동적 렌더링 (파일 컴포넌트 제외) */}
{type === "widget" && !isFileComponent(component) && (
<div className="h-full w-full">

View File

@@ -4603,10 +4603,11 @@ export default function ScreenDesigner({ selectedScreen, onBackToList }: ScreenD
});
}}
>
{/* 컨테이너, 그룹, 영역의 자식 컴포넌트들 렌더링 (레이아웃은 독립적으로 렌더링) */}
{/* 컨테이너, 그룹, 영역, 컴포넌트의 자식 컴포넌트들 렌더링 (레이아웃은 독립적으로 렌더링) */}
{(component.type === "group" ||
component.type === "container" ||
component.type === "area") &&
component.type === "area" ||
component.type === "component") &&
layout.components
.filter((child) => child.parentId === component.id)
.map((child) => {