@@ -246,7 +246,7 @@ const WorkflowContent = React.memo(
246246 const [ selectedEdges , setSelectedEdges ] = useState < SelectedEdgesMap > ( new Map ( ) )
247247 const [ isErrorConnectionDrag , setIsErrorConnectionDrag ] = useState ( false )
248248 const canvasContainerRef = useRef < HTMLDivElement > ( null )
249- const selectedIdsRef = useRef < string [ ] | null > ( null )
249+ const displayNodesRef = useRef < Node [ ] > ( [ ] )
250250 const embeddedFitFrameRef = useRef < number | null > ( null )
251251 const hasCompletedInitialEmbeddedFitRef = useRef ( false )
252252 const canvasMode = useCanvasModeStore ( ( state ) => state . mode )
@@ -2477,6 +2477,10 @@ const WorkflowContent = React.memo(
24772477 // Local state for nodes - allows smooth drag without store updates on every frame
24782478 const [ displayNodes , setDisplayNodes ] = useState < Node [ ] > ( [ ] )
24792479
2480+ useEffect ( ( ) => {
2481+ displayNodesRef . current = displayNodes
2482+ } , [ displayNodes ] )
2483+
24802484 useEffect ( ( ) => {
24812485 // Check for pending selection (from paste/duplicate), otherwise preserve existing selection
24822486 if ( pendingSelection && pendingSelection . length > 0 ) {
@@ -2709,17 +2713,17 @@ const WorkflowContent = React.memo(
27092713 /** Handles node changes - applies changes and resolves parent-child selection conflicts. */
27102714 const onNodesChange = useCallback (
27112715 ( changes : NodeChange [ ] ) => {
2712- selectedIdsRef . current = null
2713- setDisplayNodes ( ( nds ) => {
2714- const updated = applyNodeChanges ( changes , nds )
2715- const hasSelectionChange = changes . some ( ( c ) => c . type === 'select' )
2716- if ( ! hasSelectionChange ) return updated
2717- const resolved = resolveParentChildSelectionConflicts ( updated , blocks )
2718- selectedIdsRef . current = resolved . filter ( ( node ) => node . selected ) . map ( ( node ) => node . id )
2719- return resolved
2720- } )
2721- const selectedIds = selectedIdsRef . current as string [ ] | null
2722- if ( selectedIds !== null ) {
2716+ const updated = applyNodeChanges ( changes , displayNodesRef . current )
2717+ const hasSelectionChange = changes . some ( ( c ) => c . type === 'select' )
2718+ const nextNodes = hasSelectionChange
2719+ ? resolveParentChildSelectionConflicts ( updated , blocks )
2720+ : updated
2721+
2722+ displayNodesRef . current = nextNodes
2723+ setDisplayNodes ( nextNodes )
2724+
2725+ if ( hasSelectionChange ) {
2726+ const selectedIds = nextNodes . filter ( ( node ) => node . selected ) . map ( ( node ) => node . id )
27232727 syncPanelWithSelection ( selectedIds )
27242728 }
27252729
@@ -3610,22 +3614,22 @@ const WorkflowContent = React.memo(
36103614 const handleNodeClick = useCallback (
36113615 ( event : React . MouseEvent , node : Node ) => {
36123616 const isMultiSelect = event . shiftKey || event . metaKey || event . ctrlKey
3613- selectedIdsRef . current = null
3614- setDisplayNodes ( ( nodes ) => {
3615- const updated = nodes . map ( ( n ) => ( {
3616- ... n ,
3617- selected : isMultiSelect ? ( n . id === node . id ? true : n . selected ) : n . id === node . id ,
3618- } ) )
3619- const resolved = resolveParentChildSelectionConflicts ( updated , blocks )
3620- selectedIdsRef . current = resolved
3621- . filter ( ( selectedNode ) => selectedNode . selected )
3622- . map ( ( selectedNode ) => selectedNode . id )
3623- return resolved
3624- } )
3625- const selectedIds = selectedIdsRef . current as string [ ] | null
3626- if ( selectedIds !== null ) {
3627- syncPanelWithSelection ( selectedIds )
3628- }
3617+ const updated = displayNodesRef . current . map ( ( currentNode ) => ( {
3618+ ... currentNode ,
3619+ selected : isMultiSelect
3620+ ? currentNode . id === node . id
3621+ ? true
3622+ : currentNode . selected
3623+ : currentNode . id === node . id ,
3624+ } ) )
3625+ const resolved = resolveParentChildSelectionConflicts ( updated , blocks )
3626+ const selectedIds = resolved
3627+ . filter ( ( selectedNode ) => selectedNode . selected )
3628+ . map ( ( selectedNode ) => selectedNode . id )
3629+
3630+ displayNodesRef . current = resolved
3631+ setDisplayNodes ( resolved )
3632+ syncPanelWithSelection ( selectedIds )
36293633 } ,
36303634 [ blocks ]
36313635 )
0 commit comments