You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
93 lines
2.7 KiB
93 lines
2.7 KiB
"use client";
|
|
|
|
import { useMemo } from "react";
|
|
import {
|
|
BaseEdge,
|
|
EdgeProps,
|
|
getBezierPath,
|
|
} from "@xyflow/react";
|
|
import { useWorkflowStore } from "@/store/workflowStore";
|
|
|
|
// Grey color for reference connections (dimmed for softer appearance)
|
|
const REFERENCE_COLOR = "#52525b";
|
|
|
|
export function ReferenceEdge({
|
|
id,
|
|
sourceX,
|
|
sourceY,
|
|
targetX,
|
|
targetY,
|
|
sourcePosition,
|
|
targetPosition,
|
|
style,
|
|
markerEnd,
|
|
source,
|
|
target,
|
|
}: EdgeProps) {
|
|
const edgeStyle = useWorkflowStore((state) => state.edgeStyle);
|
|
const nodes = useWorkflowStore((state) => state.nodes);
|
|
|
|
// Check if any node is selected and if this edge is connected to it
|
|
const isConnectedToSelection = useMemo(() => {
|
|
const selectedNodes = nodes.filter((n) => n.selected);
|
|
if (selectedNodes.length === 0) return false; // No selection, show all dimmed
|
|
|
|
// Check if this edge connects to any selected node
|
|
return selectedNodes.some((n) => n.id === source || n.id === target);
|
|
}, [nodes, source, target]);
|
|
|
|
// Calculate the path - always use curved for reference edges for softer look
|
|
const [edgePath] = useMemo(() => {
|
|
return getBezierPath({
|
|
sourceX,
|
|
sourceY,
|
|
sourcePosition,
|
|
targetX,
|
|
targetY,
|
|
targetPosition,
|
|
curvature: 0.25,
|
|
});
|
|
}, [sourceX, sourceY, sourcePosition, targetX, targetY, targetPosition]);
|
|
|
|
// Generate a unique gradient ID based on selection state
|
|
const gradientId = useMemo(() => {
|
|
const selectionKey = isConnectedToSelection ? "active" : "dimmed";
|
|
return `reference-gradient-${selectionKey}-${id}`;
|
|
}, [isConnectedToSelection, id]);
|
|
|
|
return (
|
|
<>
|
|
{/* SVG gradient definition for bright-dim-bright effect */}
|
|
<defs>
|
|
<linearGradient id={gradientId} x1="0%" y1="0%" x2="100%" y2="0%">
|
|
<stop offset="0%" stopColor={REFERENCE_COLOR} stopOpacity={isConnectedToSelection ? 1 : 0.25} />
|
|
<stop offset="50%" stopColor={REFERENCE_COLOR} stopOpacity={isConnectedToSelection ? 0.55 : 0.1} />
|
|
<stop offset="100%" stopColor={REFERENCE_COLOR} stopOpacity={isConnectedToSelection ? 1 : 0.25} />
|
|
</linearGradient>
|
|
</defs>
|
|
|
|
<BaseEdge
|
|
id={id}
|
|
path={edgePath}
|
|
markerEnd={markerEnd}
|
|
style={{
|
|
...style,
|
|
stroke: `url(#${gradientId})`,
|
|
strokeWidth: 2,
|
|
strokeDasharray: "6 4",
|
|
strokeLinecap: "round",
|
|
strokeLinejoin: "round",
|
|
}}
|
|
/>
|
|
|
|
{/* Invisible wider path for easier selection */}
|
|
<path
|
|
d={edgePath}
|
|
fill="none"
|
|
strokeWidth={10}
|
|
stroke="transparent"
|
|
className="react-flow__edge-interaction"
|
|
/>
|
|
</>
|
|
);
|
|
}
|
|
|