53 lines
1.6 KiB
TypeScript
53 lines
1.6 KiB
TypeScript
"use client";
|
|
|
|
import { useDrag } from "react-dnd";
|
|
import { Type, Table, Image, Minus, PenLine, Stamp as StampIcon, Hash } from "lucide-react";
|
|
|
|
interface ComponentItem {
|
|
type: string;
|
|
label: string;
|
|
icon: React.ReactNode;
|
|
}
|
|
|
|
const COMPONENTS: ComponentItem[] = [
|
|
{ type: "text", label: "텍스트", icon: <Type className="h-4 w-4" /> },
|
|
{ type: "table", label: "테이블", icon: <Table className="h-4 w-4" /> },
|
|
{ type: "image", label: "이미지", icon: <Image className="h-4 w-4" /> },
|
|
{ type: "divider", label: "구분선", icon: <Minus className="h-4 w-4" /> },
|
|
{ type: "signature", label: "서명란", icon: <PenLine className="h-4 w-4" /> },
|
|
{ type: "stamp", label: "도장란", icon: <StampIcon className="h-4 w-4" /> },
|
|
{ type: "pageNumber", label: "페이지번호", icon: <Hash className="h-4 w-4" /> },
|
|
];
|
|
|
|
function DraggableComponentItem({ type, label, icon }: ComponentItem) {
|
|
const [{ isDragging }, drag] = useDrag(() => ({
|
|
type: "component",
|
|
item: { componentType: type },
|
|
collect: (monitor) => ({
|
|
isDragging: monitor.isDragging(),
|
|
}),
|
|
}));
|
|
|
|
return (
|
|
<div
|
|
ref={drag}
|
|
className={`flex cursor-move items-center gap-2 rounded border p-2 text-sm transition-all hover:border-blue-500 hover:bg-blue-50 ${
|
|
isDragging ? "opacity-50" : ""
|
|
}`}
|
|
>
|
|
{icon}
|
|
<span>{label}</span>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
export function ComponentPalette() {
|
|
return (
|
|
<div className="space-y-2">
|
|
{COMPONENTS.map((component) => (
|
|
<DraggableComponentItem key={component.type} {...component} />
|
|
))}
|
|
</div>
|
|
);
|
|
}
|