"use client"; import React from "react"; import { BaseLayoutRenderer, LayoutRendererProps } from "./BaseLayoutRenderer"; export default class GridLayoutRenderer extends BaseLayoutRenderer { render(): React.ReactElement { const { layout, isDesignMode, isSelected, onClick, className } = this.props; if (!layout.layoutConfig.grid) { return
그리드 설정이 없습니다.
; } const gridConfig = layout.layoutConfig.grid; const containerStyle = this.getLayoutContainerStyle(); // 그리드 스타일 설정 const gridStyle: React.CSSProperties = { ...containerStyle, display: "grid", gridTemplateRows: `repeat(${gridConfig.rows}, 1fr)`, gridTemplateColumns: `repeat(${gridConfig.columns}, 1fr)`, gap: `${gridConfig.gap}px`, gridRowGap: gridConfig.rowGap ? `${gridConfig.rowGap}px` : undefined, gridColumnGap: gridConfig.columnGap ? `${gridConfig.columnGap}px` : undefined, gridAutoRows: gridConfig.autoRows, gridAutoColumns: gridConfig.autoColumns, }; // 디자인 모드 스타일 if (isDesignMode) { gridStyle.border = isSelected ? "2px solid #3b82f6" : "1px solid #e2e8f0"; gridStyle.borderRadius = "8px"; } return (
{layout.zones.map((zone) => { const zoneChildren = this.getZoneChildren(zone.id); // 그리드 위치 설정 const zoneStyle: React.CSSProperties = { gridRow: zone.position.row !== undefined ? zone.position.row + 1 : undefined, gridColumn: zone.position.column !== undefined ? zone.position.column + 1 : undefined, }; return this.renderZone(zone, zoneChildren, { style: zoneStyle, className: "grid-zone", }); })} {/* 디자인 모드에서 빈 그리드 셀 표시 */} {isDesignMode && this.renderEmptyGridCells()}
); } /** * 빈 그리드 셀들을 렌더링합니다. */ private renderEmptyGridCells(): React.ReactElement[] { const { layout } = this.props; const gridConfig = layout.layoutConfig.grid!; const totalCells = gridConfig.rows * gridConfig.columns; const occupiedCells = new Set( layout.zones .map((zone) => zone.position.row !== undefined && zone.position.column !== undefined ? zone.position.row * gridConfig.columns + zone.position.column : -1, ) .filter((index) => index >= 0), ); const emptyCells: React.ReactElement[] = []; for (let i = 0; i < totalCells; i++) { if (!occupiedCells.has(i)) { const row = Math.floor(i / gridConfig.columns); const column = i % gridConfig.columns; emptyCells.push(
{ e.currentTarget.style.backgroundColor = "rgba(59, 130, 246, 0.05)"; e.currentTarget.style.borderColor = "#3b82f6"; }} onMouseLeave={(e) => { e.currentTarget.style.backgroundColor = isDesignMode ? "rgba(148, 163, 184, 0.05)" : "rgba(248, 250, 252, 0.3)"; e.currentTarget.style.borderColor = isDesignMode ? "#cbd5e1" : "#f1f5f9"; }} > {isDesignMode ? `${row + 1},${column + 1}` : ""}
, ); } } return emptyCells; } } // React 컴포넌트로 래핑 export const GridLayout: React.FC = (props) => { const renderer = new GridLayoutRenderer(props); return renderer.render(); };