@@ -143,7 +143,7 @@ const WorkflowContent = React.memo(() => {
143143
144144 const params = useParams ( )
145145 const router = useRouter ( )
146- const { screenToFlowPosition, getNodes, fitView } = useReactFlow ( )
146+ const { screenToFlowPosition, getNodes, fitView, getIntersectingNodes } = useReactFlow ( )
147147 const { emitCursorUpdate } = useSocket ( )
148148
149149 const workspaceId = params . workspaceId as string
@@ -200,7 +200,6 @@ const WorkflowContent = React.memo(() => {
200200
201201 const {
202202 getNodeDepth,
203- getNodeHierarchy,
204203 getNodeAbsolutePosition,
205204 isPointInLoopNode,
206205 resizeLoopNodes,
@@ -343,7 +342,6 @@ const WorkflowContent = React.memo(() => {
343342 collaborativeRemoveEdge : removeEdge ,
344343 collaborativeUpdateBlockPosition,
345344 collaborativeUpdateParentId : updateParentId ,
346- collaborativeSetSubblockValue,
347345 undo,
348346 redo,
349347 } = useCollaborativeWorkflow ( )
@@ -407,7 +405,6 @@ const WorkflowContent = React.memo(() => {
407405 if ( newParentId ) {
408406 const nodeAbsPos = getNodeAbsolutePosition ( nodeId )
409407 const parentAbsPos = getNodeAbsolutePosition ( newParentId )
410- // Account for header (50px), left padding (16px), and top padding (16px)
411408 const headerHeight = 50
412409 const leftPadding = 16
413410 const topPadding = 16
@@ -448,7 +445,6 @@ const WorkflowContent = React.memo(() => {
448445 getNodes ,
449446 collaborativeUpdateBlockPosition ,
450447 updateParentId ,
451- updateNodeDimensions ,
452448 blocks ,
453449 edgesForDisplay ,
454450 getNodeAbsolutePosition ,
@@ -1706,37 +1702,45 @@ const WorkflowContent = React.memo(() => {
17061702 )
17071703
17081704 /**
1709- * Finds a node at a given flow position for drop-on-block connection.
1705+ * Finds the best node at a given flow position for drop-on-block connection.
17101706 * Skips subflow containers as they have their own connection logic.
17111707 */
17121708 const findNodeAtPosition = useCallback (
17131709 ( position : { x : number ; y : number } ) => {
1714- const nodes = getNodes ( )
1710+ const cursorRect = {
1711+ x : position . x - 1 ,
1712+ y : position . y - 1 ,
1713+ width : 2 ,
1714+ height : 2 ,
1715+ }
1716+
1717+ const intersecting = getIntersectingNodes ( cursorRect , true ) . filter (
1718+ ( node ) => node . type !== 'subflowNode'
1719+ )
17151720
1716- return nodes . find ( ( node ) => {
1717- // Skip subflow containers for drop targets
1718- if ( node . type === 'subflowNode' ) return false
1721+ if ( intersecting . length === 0 ) return undefined
1722+ if ( intersecting . length === 1 ) return intersecting [ 0 ]
17191723
1720- const absPos = getNodeAbsolutePosition ( node . id )
1721- const dims = getBlockDimensions ( node . id )
1724+ return intersecting . reduce ( ( closest , node ) => {
1725+ const getDistance = ( n : Node ) => {
1726+ const absPos = getNodeAbsolutePosition ( n . id )
1727+ const dims = getBlockDimensions ( n . id )
1728+ const centerX = absPos . x + dims . width / 2
1729+ const centerY = absPos . y + dims . height / 2
1730+ return Math . hypot ( position . x - centerX , position . y - centerY )
1731+ }
17221732
1723- return (
1724- position . x >= absPos . x &&
1725- position . x <= absPos . x + dims . width &&
1726- position . y >= absPos . y &&
1727- position . y <= absPos . y + dims . height
1728- )
1733+ return getDistance ( node ) < getDistance ( closest ) ? node : closest
17291734 } )
17301735 } ,
1731- [ getNodes , getNodeAbsolutePosition , getBlockDimensions ]
1736+ [ getIntersectingNodes , getNodeAbsolutePosition , getBlockDimensions ]
17321737 )
17331738
17341739 /**
17351740 * Captures the source handle when a connection drag starts
17361741 */
17371742 const onConnectStart = useCallback ( ( _event : any , params : any ) => {
17381743 const handleId : string | undefined = params ?. handleId
1739- // Treat explicit error handle (id === 'error') as error connection
17401744 setIsErrorConnectionDrag ( handleId === 'error' )
17411745 connectionSourceRef . current = {
17421746 nodeId : params ?. nodeId ,
0 commit comments