ERP-node/frontend/lib/registry/pop-components/pop-dashboard/modes/GridMode.tsx

76 lines
1.8 KiB
TypeScript
Raw Normal View History

"use client";
/**
*
*
* CSS Grid로 ( / )
* @container
*/
import React from "react";
import type { DashboardCell } from "../../types";
// ===== Props =====
export interface GridModeProps {
/** 셀 배치 정보 */
cells: DashboardCell[];
/** 열 수 */
columns: number;
/** 행 수 */
rows: number;
/** 아이템 간 간격 (px) */
gap?: number;
/** 셀의 아이템 렌더링. itemId가 null이면 빈 셀 */
renderItem: (itemId: string) => React.ReactNode;
}
// ===== 메인 컴포넌트 =====
export function GridModeComponent({
cells,
columns,
rows,
gap = 8,
renderItem,
}: GridModeProps) {
if (!cells.length) {
return (
<div className="flex h-full w-full items-center justify-center">
<span className="text-xs text-muted-foreground"> </span>
</div>
);
}
return (
<div
className="h-full w-full"
style={{
display: "grid",
gridTemplateColumns: `repeat(${columns}, 1fr)`,
gridTemplateRows: `repeat(${rows}, 1fr)`,
gap: `${gap}px`,
}}
>
{cells.map((cell) => (
<div
key={cell.id}
className="@container min-h-0 min-w-0 overflow-hidden rounded-md border border-border/50 bg-card"
style={{
gridColumn: cell.gridColumn,
gridRow: cell.gridRow,
}}
>
{cell.itemId ? (
renderItem(cell.itemId)
) : (
<div className="flex h-full w-full items-center justify-center">
<span className="text-[10px] text-muted-foreground/50"> </span>
</div>
)}
</div>
))}
</div>
);
}