"use client"; import React from "react"; import { LayoutRendererProps } from "../BaseLayoutRenderer"; /** * split 컴포넌트 */ export interface SplitLayoutProps extends LayoutRendererProps { renderer: any; // SplitLayoutRenderer 타입 } export const SplitLayout: React.FC = ({ layout, isDesignMode = false, isSelected = false, onClick, className = "", renderer, onZoneComponentDrop, onZoneClick, ...props }) => { if (!layout.layoutConfig.split) { return (
split 설정이 없습니다.
layoutConfig.split가 필요합니다.
); } const splitConfig = layout.layoutConfig.split; const containerStyle = renderer.getLayoutContainerStyle(); // split 컨테이너 스타일 const splitStyle: React.CSSProperties = { ...containerStyle, display: "flex", flexDirection: splitConfig.direction || "row", // 기본값: 가로 분할 height: "100%", width: "100%", gap: "8px", padding: "8px", }; // 디자인 모드 스타일 if (isDesignMode) { splitStyle.border = isSelected ? "2px solid #3b82f6" : "1px solid #e2e8f0"; splitStyle.borderRadius = "8px"; } // DOM props만 추출 (React DOM에서 인식하는 props만) const { children: propsChildren, onUpdateLayout, onSelectComponent, isDesignMode: _isDesignMode, allComponents, onComponentDrop, onDragStart, onDragEnd, selectedScreen, // DOM에 전달하지 않도록 제외 ...domProps } = props; return ( <>
{layout.zones.map((zone: any, index: number) => { const zoneChildren = renderer.getZoneChildren(zone.id); // 레이아웃 전체 높이 기준으로 존 높이 계산 const layoutHeight = layout.size?.height || 400; // 기본값 400px const defaultZoneHeight = splitConfig.direction === "vertical" ? Math.floor(layoutHeight / layout.zones.length) - 32 // 세로 분할시 존 개수로 나눔 : layoutHeight - 32; // 가로 분할시 전체 높이 사용 // 분할 레이아웃 존 스타일 const zoneStyle: React.CSSProperties = { flex: 1, // 동일한 크기로 분할 // 카드 레이아웃처럼 항상 명확한 경계 표시 backgroundColor: "white", border: "1px solid #e5e7eb", borderRadius: "8px", padding: "16px", boxShadow: "0 1px 3px 0 rgba(0, 0, 0, 0.1)", // 존의 높이: 개별 설정이 있으면 우선, 없으면 부모 높이를 100% 따라가도록 height: zone.size?.height ? typeof zone.size.height === "number" ? `${zone.size.height}px` : zone.size.height : "100%", // 분할 영역의 높이를 100% 따라감 minHeight: zone.size?.minHeight ? typeof zone.size.minHeight === "number" ? `${zone.size.minHeight}px` : zone.size.minHeight : "100px", maxHeight: zone.size?.maxHeight ? typeof zone.size.maxHeight === "number" ? `${zone.size.maxHeight}px` : zone.size.maxHeight : "none", position: "relative", transition: "all 0.2s ease", margin: "4px", overflow: "hidden", display: "flex", flexDirection: "column", }; return (
{ e.currentTarget.style.borderColor = "#3b82f6"; e.currentTarget.style.boxShadow = "0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 0 0 2px rgba(59, 130, 246, 0.1)"; }} onMouseLeave={(e) => { e.currentTarget.style.borderColor = "#e5e7eb"; e.currentTarget.style.boxShadow = "0 1px 3px 0 rgba(0, 0, 0, 0.1)"; }} > {/* 존 라벨 */} {isDesignMode && (
{zone.name || zone.id}
)} {/* 존 내용 */}
{renderer.renderZone(zone, zoneChildren, { style: { border: "none", backgroundColor: "transparent", flex: 1, minHeight: "0", }, className: "split-zone-content", })}
); })} {/* 디자인 모드에서 빈 영역 표시 */} {isDesignMode && layout.zones.length === 0 && (
split에 존을 추가하세요
)}
); };