139 lines
3.3 KiB
TypeScript
139 lines
3.3 KiB
TypeScript
"use client";
|
|
|
|
import React from "react";
|
|
import { cn } from "@/lib/utils";
|
|
|
|
export interface SectionPaperProps {
|
|
component?: {
|
|
id: string;
|
|
componentConfig?: {
|
|
backgroundColor?: "default" | "muted" | "accent" | "primary" | "custom";
|
|
customColor?: string;
|
|
showBorder?: boolean;
|
|
borderStyle?: "none" | "subtle";
|
|
padding?: "none" | "sm" | "md" | "lg";
|
|
roundedCorners?: "none" | "sm" | "md" | "lg";
|
|
shadow?: "none" | "sm" | "md";
|
|
};
|
|
style?: React.CSSProperties;
|
|
};
|
|
children?: React.ReactNode;
|
|
className?: string;
|
|
onClick?: (e?: React.MouseEvent) => void;
|
|
isSelected?: boolean;
|
|
isDesignMode?: boolean;
|
|
}
|
|
|
|
/**
|
|
* Section Paper 컴포넌트
|
|
* 배경색만 있는 미니멀한 그룹화 컨테이너 (색종이 컨셉)
|
|
*/
|
|
export function SectionPaperComponent({
|
|
component,
|
|
children,
|
|
className,
|
|
onClick,
|
|
isSelected = false,
|
|
isDesignMode = false,
|
|
}: SectionPaperProps) {
|
|
const config = component?.componentConfig || {};
|
|
|
|
// 배경색 매핑
|
|
const backgroundColorMap = {
|
|
default: "bg-muted/20",
|
|
muted: "bg-muted/30",
|
|
accent: "bg-accent/20",
|
|
primary: "bg-primary/5",
|
|
custom: "",
|
|
};
|
|
|
|
// 패딩 매핑
|
|
const paddingMap = {
|
|
none: "p-0",
|
|
sm: "p-3",
|
|
md: "p-4",
|
|
lg: "p-6",
|
|
};
|
|
|
|
// 둥근 모서리 매핑
|
|
const roundedMap = {
|
|
none: "rounded-none",
|
|
sm: "rounded-sm",
|
|
md: "rounded-md",
|
|
lg: "rounded-lg",
|
|
};
|
|
|
|
// 그림자 매핑
|
|
const shadowMap = {
|
|
none: "",
|
|
sm: "shadow-sm",
|
|
md: "shadow-md",
|
|
};
|
|
|
|
const backgroundColor = config.backgroundColor || "default";
|
|
const padding = config.padding || "md";
|
|
const rounded = config.roundedCorners || "md";
|
|
const shadow = config.shadow || "none";
|
|
const showBorder = config.showBorder || false;
|
|
const borderStyle = config.borderStyle || "subtle";
|
|
|
|
// 커스텀 배경색 처리
|
|
const customBgStyle =
|
|
backgroundColor === "custom" && config.customColor
|
|
? { backgroundColor: config.customColor }
|
|
: {};
|
|
|
|
return (
|
|
<div
|
|
className={cn(
|
|
// 기본 스타일
|
|
"relative transition-colors",
|
|
|
|
// 배경색
|
|
backgroundColor !== "custom" && backgroundColorMap[backgroundColor],
|
|
|
|
// 패딩
|
|
paddingMap[padding],
|
|
|
|
// 둥근 모서리
|
|
roundedMap[rounded],
|
|
|
|
// 그림자
|
|
shadowMap[shadow],
|
|
|
|
// 테두리 (선택)
|
|
showBorder &&
|
|
borderStyle === "subtle" &&
|
|
"border border-border/30",
|
|
|
|
// 디자인 모드에서 선택된 상태
|
|
isDesignMode && isSelected && "ring-2 ring-primary ring-offset-2",
|
|
|
|
// 디자인 모드에서 빈 상태 표시
|
|
isDesignMode && !children && "min-h-[100px] border-2 border-dashed border-muted-foreground/30",
|
|
|
|
className
|
|
)}
|
|
style={{
|
|
...customBgStyle,
|
|
...component?.style,
|
|
}}
|
|
onClick={onClick}
|
|
>
|
|
{/* 디자인 모드에서 빈 상태 안내 */}
|
|
{isDesignMode && !children && (
|
|
<div className="flex items-center justify-center h-full text-muted-foreground text-sm">
|
|
<div className="text-center">
|
|
<div className="mb-1">📄 Section Paper</div>
|
|
<div className="text-xs">컴포넌트를 이곳에 배치하세요</div>
|
|
</div>
|
|
</div>
|
|
)}
|
|
|
|
{/* 자식 컴포넌트들 */}
|
|
{children}
|
|
</div>
|
|
);
|
|
}
|
|
|