ERP-node/frontend/components/dataflow/node-editor/nodes/CompactNodeShell.tsx

104 lines
2.8 KiB
TypeScript
Raw Normal View History

"use client";
/**
*
*
*/
import { memo, ReactNode } from "react";
import { Handle, Position } from "reactflow";
interface CompactNodeShellProps {
color: string;
label: string;
summary?: string;
icon: ReactNode;
selected?: boolean;
children?: ReactNode;
hasInput?: boolean;
hasOutput?: boolean;
inputHandleId?: string;
outputHandleId?: string;
/** 커스텀 출력 핸들(ConditionNode 등)을 사용할 경우 true */
customOutputHandles?: boolean;
/** 커스텀 입력 핸들을 사용할 경우 true */
customInputHandles?: boolean;
minWidth?: string;
}
export const CompactNodeShell = memo(
({
color,
label,
summary,
icon,
selected = false,
children,
hasInput = true,
hasOutput = true,
inputHandleId,
outputHandleId,
customOutputHandles = false,
customInputHandles = false,
minWidth = "260px",
}: CompactNodeShellProps) => {
return (
<div
className={`rounded-lg border bg-zinc-900 shadow-lg transition-all ${
selected
? "border-violet-500 shadow-violet-500/20"
: "border-zinc-700 hover:border-zinc-600"
}`}
style={{ minWidth, maxWidth: "320px" }}
>
{/* 기본 입력 핸들 */}
{hasInput && !customInputHandles && (
<Handle
type="target"
position={Position.Left}
id={inputHandleId}
className="!h-2.5 !w-2.5 !border-2 !bg-zinc-900"
style={{ borderColor: color }}
/>
)}
{/* 컬러바 + 헤더 */}
<div className="flex items-center gap-2.5 px-3 py-2.5">
<div
className="flex h-7 w-7 flex-shrink-0 items-center justify-center rounded-md"
style={{ backgroundColor: `${color}20` }}
>
<div className="text-zinc-200" style={{ color }}>{icon}</div>
</div>
<div className="min-w-0 flex-1">
<div className="text-xs font-semibold text-zinc-200">{label}</div>
{summary && (
<div className="line-clamp-2 text-[10px] leading-relaxed text-zinc-500">{summary}</div>
)}
</div>
</div>
{/* 바디 (옵셔널) */}
{children && (
<div className="border-t border-zinc-800 px-3 py-2 text-[10px] text-zinc-400">
{children}
</div>
)}
{/* 기본 출력 핸들 */}
{hasOutput && !customOutputHandles && (
<Handle
type="source"
position={Position.Right}
id={outputHandleId}
className="!h-2.5 !w-2.5 !border-2 !bg-zinc-900"
style={{ borderColor: color }}
/>
)}
</div>
);
},
);
CompactNodeShell.displayName = "CompactNodeShell";