@@ -2,7 +2,7 @@ import {TASK_DISPATCHER_NAMES} from '@/shared/constants';
2
2
import { NodeDataType } from '@/shared/types' ;
3
3
import { BaseEdge , EdgeLabelRenderer , EdgeProps , getSmoothStepPath } from '@xyflow/react' ;
4
4
import { PlusIcon } from 'lucide-react' ;
5
- import { useMemo , useState } from 'react' ;
5
+ import { useEffect , useMemo , useState } from 'react' ;
6
6
import { twMerge } from 'tailwind-merge' ;
7
7
import { useShallow } from 'zustand/react/shallow' ;
8
8
@@ -101,6 +101,20 @@ export default function WorkflowEdge({
101
101
edgeCenterY ,
102
102
] ) ;
103
103
104
+ useEffect ( ( ) => {
105
+ const handleGlobalDragEnd = ( ) => {
106
+ setDropzoneActive ( false ) ;
107
+ } ;
108
+
109
+ document . addEventListener ( 'dragend' , handleGlobalDragEnd ) ;
110
+ document . addEventListener ( 'drop' , handleGlobalDragEnd ) ;
111
+
112
+ return ( ) => {
113
+ document . removeEventListener ( 'dragend' , handleGlobalDragEnd ) ;
114
+ document . removeEventListener ( 'drop' , handleGlobalDragEnd ) ;
115
+ } ;
116
+ } , [ ] ) ;
117
+
104
118
return (
105
119
< >
106
120
< BaseEdge
@@ -129,20 +143,37 @@ export default function WorkflowEdge({
129
143
>
130
144
< div
131
145
className = { twMerge (
132
- 'flex size-6 cursor-pointer items-center justify-center rounded border-2 border-gray-300 bg-white transition-all hover:scale-110 hover:border-gray-400' ,
133
- isDropzoneActive && 'z-40 size-14 scale-150 border-blue-100 bg-blue-100'
146
+ 'flex cursor-pointer items-center justify-center rounded transition-all' ,
147
+ isDropzoneActive
148
+ ? 'size-16 border-2 border-blue-100 bg-blue-100'
149
+ : 'size-6 border-2 border-gray-300 bg-white hover:scale-110 hover:border-gray-400'
134
150
) }
135
151
id = { `${ id } -button` }
136
152
onDragEnter = { ( ) => setDropzoneActive ( true ) }
137
- onDragLeave = { ( ) => setDropzoneActive ( false ) }
138
- onDragOver = { ( ) => {
139
- if ( ! isDropzoneActive ) {
140
- setDropzoneActive ( true ) ;
153
+ onDragLeave = { ( event ) => {
154
+ const relatedTarget = event . relatedTarget as Node | null ;
155
+
156
+ if ( ! relatedTarget || ! event . currentTarget . contains ( relatedTarget ) ) {
157
+ setDropzoneActive ( false ) ;
141
158
}
142
159
} }
143
- onDrop = { ( ) => setDropzoneActive ( false ) }
160
+ onDragOver = { ( event ) => {
161
+ event . preventDefault ( ) ;
162
+
163
+ setDropzoneActive ( true ) ;
164
+ } }
165
+ onDrop = { ( event ) => {
166
+ event . preventDefault ( ) ;
167
+
168
+ setDropzoneActive ( false ) ;
169
+ } }
144
170
>
145
- < PlusIcon className = "size-3.5 text-muted-foreground" />
171
+ < PlusIcon
172
+ className = { twMerge (
173
+ `text-muted-foreground` ,
174
+ isDropzoneActive ? 'size-14 text-muted-foreground/50' : 'size-3.5'
175
+ ) }
176
+ />
146
177
</ div >
147
178
</ div >
148
179
</ WorkflowNodesPopoverMenu >
0 commit comments