Spaces:
Sleeping
Sleeping
| import { memo } from 'react'; | |
| import { Handle, Position } from '@xyflow/react'; | |
| import { AlertTriangle, Files } from 'lucide-react'; | |
| function CustomNode({ data, selected }) { | |
| const linkedFiles = Array.isArray(data.files) ? data.files : data.files ? [data.files] : []; | |
| return ( | |
| <div | |
| className="min-w-[178px] max-w-[230px] rounded-lg border px-4 py-3 shadow-xl transition-transform" | |
| style={{ | |
| background: `linear-gradient(145deg, ${data.color || '#38bdf8'}18, rgba(15,23,42,0.96))`, | |
| borderColor: selected ? data.color || '#38bdf8' : `${data.color || '#38bdf8'}55`, | |
| transform: selected ? 'translateY(-2px)' : 'none', | |
| }} | |
| > | |
| <Handle type="target" position={Position.Top} style={{ background: data.color, border: 'none', width: 8, height: 8 }} /> | |
| <div className="mb-2 flex items-start gap-2"> | |
| <span className="mt-1 h-2.5 w-2.5 flex-shrink-0 rounded-full" style={{ background: data.color }} /> | |
| <div className="min-w-0"> | |
| <p className="break-words text-xs font-semibold leading-snug text-white">{data.label}</p> | |
| <span className="mt-1 inline-flex rounded-full px-2 py-0.5 text-[10px] font-bold uppercase tracking-wide" style={{ background: `${data.color}24`, color: data.color }}> | |
| {data.type} | |
| </span> | |
| </div> | |
| {data.critical && <AlertTriangle className="h-3.5 w-3.5 flex-shrink-0 text-amber-300" />} | |
| </div> | |
| {data.description && <p className="text-[11px] leading-snug text-slate-400">{data.description}</p>} | |
| {linkedFiles.length > 0 && ( | |
| <div className="mt-2 flex items-center gap-1.5 text-[10px] text-slate-500"> | |
| <Files className="h-3 w-3" /> | |
| {linkedFiles.length} linked files | |
| </div> | |
| )} | |
| <Handle type="source" position={Position.Bottom} style={{ background: data.color, border: 'none', width: 8, height: 8 }} /> | |
| </div> | |
| ); | |
| } | |
| export default memo(CustomNode); | |