mirror of
https://github.com/simstudioai/sim.git
synced 2026-09-24 15:45:35 +08:00
Fixed custom edge implementation to match ReactFlow
This commit is contained in:
@@ -1,70 +1,70 @@
|
||||
import { X } from 'lucide-react'
|
||||
import { EdgeProps, getSmoothStepPath } from 'reactflow'
|
||||
import { BaseEdge, EdgeLabelRenderer, EdgeProps, getSmoothStepPath } from 'reactflow'
|
||||
|
||||
export const CustomEdge = (props: EdgeProps) => {
|
||||
const isHorizontal = props.sourcePosition === 'right' || props.sourcePosition === 'left'
|
||||
export const CustomEdge = ({
|
||||
id,
|
||||
sourceX,
|
||||
sourceY,
|
||||
targetX,
|
||||
targetY,
|
||||
sourcePosition,
|
||||
targetPosition,
|
||||
data,
|
||||
}: EdgeProps) => {
|
||||
const isHorizontal = sourcePosition === 'right' || sourcePosition === 'left'
|
||||
|
||||
// For horizontal handles, we'll add a minimum extension to ensure the path
|
||||
// always goes outward before going up/down
|
||||
const [edgePath, labelX, labelY] = getSmoothStepPath({
|
||||
sourceX: props.sourceX,
|
||||
sourceY: props.sourceY,
|
||||
sourcePosition: props.sourcePosition,
|
||||
targetX: props.targetX,
|
||||
targetY: props.targetY,
|
||||
targetPosition: props.targetPosition,
|
||||
sourceX,
|
||||
sourceY,
|
||||
sourcePosition,
|
||||
targetX,
|
||||
targetY,
|
||||
targetPosition,
|
||||
borderRadius: 8,
|
||||
offset: isHorizontal ? 30 : 20,
|
||||
})
|
||||
|
||||
const isSelected = props.id === props.data?.selectedEdgeId
|
||||
const isSelected = id === data?.selectedEdgeId
|
||||
|
||||
return (
|
||||
<g style={{ zIndex: 1 }}>
|
||||
<path
|
||||
d={edgePath}
|
||||
strokeWidth={20}
|
||||
stroke="transparent"
|
||||
fill="none"
|
||||
className="react-flow__edge-interaction"
|
||||
style={{ pointerEvents: 'all' }}
|
||||
<>
|
||||
<BaseEdge
|
||||
path={edgePath}
|
||||
style={{
|
||||
strokeWidth: 2,
|
||||
stroke: isSelected ? '#475569' : '#94a3b8',
|
||||
strokeDasharray: '5,5',
|
||||
}}
|
||||
interactionWidth={20}
|
||||
/>
|
||||
<animate
|
||||
attributeName="stroke-dashoffset"
|
||||
from="10"
|
||||
to="0"
|
||||
dur="1s"
|
||||
repeatCount="indefinite"
|
||||
/>
|
||||
<path
|
||||
d={edgePath}
|
||||
strokeWidth={2}
|
||||
stroke={isSelected ? '#475569' : '#94a3b8'}
|
||||
fill="none"
|
||||
strokeDasharray="5,5"
|
||||
>
|
||||
<animate
|
||||
attributeName="stroke-dashoffset"
|
||||
from="10"
|
||||
to="0"
|
||||
dur="1s"
|
||||
repeatCount="indefinite"
|
||||
/>
|
||||
</path>
|
||||
|
||||
{isSelected && (
|
||||
<foreignObject
|
||||
width={24}
|
||||
height={24}
|
||||
x={labelX - 12}
|
||||
y={labelY - 12}
|
||||
className="overflow-visible"
|
||||
style={{ zIndex: 999 }}
|
||||
>
|
||||
<EdgeLabelRenderer>
|
||||
<div
|
||||
className="flex h-6 w-6 cursor-pointer items-center justify-center rounded-full bg-[#FAFBFC] relative z-[9999]"
|
||||
className="flex h-6 w-6 cursor-pointer items-center justify-center rounded-full bg-[#FAFBFC] nodrag nopan"
|
||||
style={{
|
||||
transform: `translate(-50%, -50%) translate(${labelX}px,${labelY}px)`,
|
||||
pointerEvents: 'all',
|
||||
}}
|
||||
onClick={(e) => {
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
props.data?.onDelete?.(props.id)
|
||||
if (data?.onDelete) {
|
||||
data.onDelete(id)
|
||||
}
|
||||
}}
|
||||
>
|
||||
<X className="h-5 w-5 text-red-500 hover:text-red-600" />
|
||||
</div>
|
||||
</foreignObject>
|
||||
</EdgeLabelRenderer>
|
||||
)}
|
||||
</g>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user