ERP-node/frontend/components/screen/layout/ContainerComponent.tsx

89 lines
2.7 KiB
TypeScript
Raw Normal View History

2025-09-01 11:48:12 +09:00
"use client";
import { cn } from "@/lib/utils";
import { ContainerComponent as ContainerComponentType } from "@/types/screen";
2025-10-13 18:28:03 +09:00
import { buildGridClasses, COLUMN_SPAN_VALUES } from "@/lib/constants/columnSpans";
2025-09-01 11:48:12 +09:00
interface ContainerComponentProps {
component: ContainerComponentType;
children?: React.ReactNode;
className?: string;
onClick?: () => void;
isSelected?: boolean;
onMouseDown?: (e: React.MouseEvent) => void;
isMoving?: boolean;
}
export default function ContainerComponent({
component,
children,
className,
onClick,
isSelected,
onMouseDown,
isMoving,
}: ContainerComponentProps) {
2025-10-13 18:28:03 +09:00
// 그리드 클래스 생성
const gridClasses = component.gridColumnSpan
? buildGridClasses(component.gridColumnSpan, component.gridColumnStart)
: "";
2025-09-01 11:48:12 +09:00
// 스타일 객체 생성
const style: React.CSSProperties = {
2025-10-13 18:28:03 +09:00
// 🔄 레거시 호환: gridColumnSpan이 없으면 기존 width 사용
...(!component.gridColumnSpan && {
gridColumn: `span ${component.size.width}`,
}),
2025-09-01 11:48:12 +09:00
minHeight: `${component.size.height}px`,
...(component.style && {
2025-10-13 18:28:03 +09:00
// ❌ width는 제거 (그리드 클래스로 제어)
2025-09-01 11:48:12 +09:00
height: component.style.height,
margin: component.style.margin,
padding: component.style.padding,
backgroundColor: component.style.backgroundColor,
border: component.style.border,
borderRadius: component.style.borderRadius,
boxShadow: component.style.boxShadow,
display: component.style.display,
flexDirection: component.style.flexDirection,
justifyContent: component.style.justifyContent,
alignItems: component.style.alignItems,
gap: component.style.gap,
color: component.style.color,
fontSize: component.style.fontSize,
fontWeight: component.style.fontWeight,
textAlign: component.style.textAlign,
position: component.style.position,
zIndex: component.style.zIndex,
opacity: component.style.opacity,
overflow: component.style.overflow,
cursor: component.style.cursor,
transition: component.style.transition,
transform: component.style.transform,
}),
...(isMoving && {
zIndex: 50,
opacity: 0.8,
transform: "scale(1.02)",
}),
};
return (
<div
className={cn(
"rounded-lg border-2 border-dashed border-gray-300 bg-gray-50 p-4",
2025-10-13 18:28:03 +09:00
gridClasses, // 🆕 그리드 클래스 추가
isSelected && "border-primary bg-accent",
2025-09-29 13:29:03 +09:00
isMoving && "cursor-move",
2025-09-01 11:48:12 +09:00
className,
)}
style={style}
onClick={onClick}
onMouseDown={onMouseDown}
>
<div className="mb-2 text-xs text-gray-500">{component.title || "컨테이너"}</div>
{children}
</div>
);
}