"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();
};