@@ -1331,10 +1334,24 @@ export default function ScreenList({ onScreenSelect, selectedScreen, onDesignScr
const screenHeight = previewLayout.screenResolution?.height || 800;
// 모달 내부 가용 공간 계산 (헤더, 푸터, 패딩 제외)
- const availableWidth = typeof window !== "undefined" ? window.innerWidth * 0.95 - 100 : 1800; // 95vw - 패딩
+ const modalPadding = 100; // 헤더 + 푸터 + 패딩
+ const availableWidth = typeof window !== "undefined" ? window.innerWidth * 0.95 - modalPadding : 1700;
+ const availableHeight = typeof window !== "undefined" ? window.innerHeight * 0.95 - modalPadding : 900;
- // 가로폭 기준으로 스케일 계산 (가로폭에 맞춤)
- const scale = availableWidth / screenWidth;
+ // 가로/세로 비율을 모두 고려하여 작은 쪽에 맞춤 (화면이 잘리지 않도록)
+ const scaleX = availableWidth / screenWidth;
+ const scaleY = availableHeight / screenHeight;
+ const scale = Math.min(scaleX, scaleY, 1); // 최대 1배율 (확대 방지)
+
+ console.log("📐 미리보기 스케일 계산:", {
+ screenWidth,
+ screenHeight,
+ availableWidth,
+ availableHeight,
+ scaleX,
+ scaleY,
+ finalScale: scale,
+ });
return (
- {/* 라벨을 외부에 별도로 렌더링 */}
- {shouldShowLabel && (
-
- {labelText}
- {component.required && *}
-
- )}
+
{}}
+ screenId={screenToPreview!.screenId}
+ tableName={screenToPreview?.tableName}
+ formData={previewFormData}
+ onFormDataChange={(fieldName, value) => {
+ setPreviewFormData((prev) => ({
+ ...prev,
+ [fieldName]: value,
+ }));
+ }}
+ >
+ {/* 자식 컴포넌트들 */}
+ {(component.type === "group" ||
+ component.type === "container" ||
+ component.type === "area") &&
+ previewLayout.components
+ .filter((child: any) => child.parentId === component.id)
+ .map((child: any) => {
+ // 자식 컴포넌트의 위치를 부모 기준 상대 좌표로 조정
+ const relativeChildComponent = {
+ ...child,
+ position: {
+ x: child.position.x - component.position.x,
+ y: child.position.y - component.position.y,
+ z: child.position.z || 1,
+ },
+ };
- {/* 실제 컴포넌트 */}
- {
- const style = {
- position: "absolute" as const,
- left: `${component.position.x}px`,
- top: `${component.position.y}px`,
- width: component.style?.width || `${component.size.width}px`,
- height: component.style?.height || `${component.size.height}px`,
- zIndex: component.position.z || 1,
- };
-
- return style;
- })()}
- >
- {/* 위젯 컴포넌트가 아닌 경우 DynamicComponentRenderer 사용 */}
- {component.type !== "widget" ? (
- {
- setPreviewFormData((prev) => ({
- ...prev,
- [fieldName]: value,
- }));
- }}
- screenId={screenToPreview!.screenId}
- tableName={screenToPreview?.tableName}
- />
- ) : (
- {
- // 유틸리티 함수로 파일 컴포넌트 감지
- if (isFileComponent(component)) {
- return "file";
- }
- // 다른 컴포넌트는 유틸리티 함수로 webType 결정
- return getComponentWebType(component) || "text";
- })()}
- config={component.webTypeConfig}
- props={{
- component: component,
- value: previewFormData[component.columnName || component.id] || "",
- onChange: (value: any) => {
- const fieldName = component.columnName || component.id;
- setPreviewFormData((prev) => ({
- ...prev,
- [fieldName]: value,
- }));
- },
- onFormDataChange: (fieldName, value) => {
- setPreviewFormData((prev) => ({
- ...prev,
- [fieldName]: value,
- }));
- },
- isInteractive: true,
- formData: previewFormData,
- readonly: component.readonly,
- required: component.required,
- placeholder: component.placeholder,
- className: "w-full h-full",
- }}
- />
- )}
-
-
+ return (
+
{}}
+ screenId={screenToPreview!.screenId}
+ tableName={screenToPreview?.tableName}
+ formData={previewFormData}
+ onFormDataChange={(fieldName, value) => {
+ setPreviewFormData((prev) => ({
+ ...prev,
+ [fieldName]: value,
+ }));
+ }}
+ />
+ );
+ })}
+
);
})}
@@ -1538,8 +1501,9 @@ export default function ScreenList({ onScreenSelect, selectedScreen, onDesignScr