58 lines
2.1 KiB
TypeScript
58 lines
2.1 KiB
TypeScript
"use client";
|
|
|
|
import React, { useState } from "react";
|
|
import { ComponentData } from "@/types/screen";
|
|
import { componentRegistry, ComponentRenderer } from "../DynamicComponentRenderer";
|
|
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
|
import { Button } from "@/components/ui/button";
|
|
import { ChevronDown, ChevronUp } from "lucide-react";
|
|
|
|
// 접을 수 있는 패널 컴포넌트 렌더러
|
|
const PanelRenderer: ComponentRenderer = ({ component, children, ...props }) => {
|
|
const config = component.componentConfig || {};
|
|
const { title = "패널 제목", collapsible = true, defaultExpanded = true, style = {} } = config;
|
|
|
|
const [isExpanded, setIsExpanded] = useState(defaultExpanded);
|
|
|
|
return (
|
|
<Card className="h-full w-full" style={style}>
|
|
<CardHeader className="pb-2">
|
|
<div className="flex items-center justify-between">
|
|
<CardTitle className="text-lg">{title}</CardTitle>
|
|
{collapsible && (
|
|
<Button
|
|
variant="ghost"
|
|
size="sm"
|
|
onClick={() => setIsExpanded(!isExpanded)}
|
|
className="pointer-events-none h-6 w-6 p-0"
|
|
disabled
|
|
>
|
|
{isExpanded ? <ChevronUp className="h-4 w-4" /> : <ChevronDown className="h-4 w-4" />}
|
|
</Button>
|
|
)}
|
|
</div>
|
|
</CardHeader>
|
|
{isExpanded && (
|
|
<CardContent className="flex-1">
|
|
{children && React.Children.count(children) > 0 ? (
|
|
children
|
|
) : (
|
|
<div className="flex h-full items-center justify-center text-center">
|
|
<div>
|
|
<div className="text-sm text-gray-600">패널 내용 영역</div>
|
|
<div className="mt-1 text-xs text-gray-400">컴포넌트를 여기에 배치하세요</div>
|
|
</div>
|
|
</div>
|
|
)}
|
|
</CardContent>
|
|
)}
|
|
</Card>
|
|
);
|
|
};
|
|
|
|
// 레지스트리에 등록
|
|
componentRegistry.register("panel", PanelRenderer);
|
|
componentRegistry.register("panel-collapsible", PanelRenderer);
|
|
|
|
export { PanelRenderer };
|