@@ -347,6 +347,8 @@ export function ToolInput({
347347 const [ customToolModalOpen , setCustomToolModalOpen ] = useState ( false )
348348 const [ editingToolIndex , setEditingToolIndex ] = useState < number | null > ( null )
349349 const [ searchQuery , setSearchQuery ] = useState ( '' )
350+ const [ draggedIndex , setDraggedIndex ] = useState < number | null > ( null )
351+ const [ dragOverIndex , setDragOverIndex ] = useState < number | null > ( null )
350352 const isWide = useWorkflowStore ( ( state ) => state . blocks [ blockId ] ?. isWide )
351353 const customTools = useCustomToolsStore ( ( state ) => state . getAllTools ( ) )
352354 const subBlockStore = useSubBlockStore ( )
@@ -668,6 +670,46 @@ export function ToolInput({
668670 )
669671 }
670672
673+ const handleDragStart = ( e : React . DragEvent , index : number ) => {
674+ if ( isPreview || disabled ) return
675+ setDraggedIndex ( index )
676+ e . dataTransfer . effectAllowed = 'move'
677+ e . dataTransfer . setData ( 'text/html' , '' )
678+ }
679+
680+ const handleDragOver = ( e : React . DragEvent , index : number ) => {
681+ if ( isPreview || disabled || draggedIndex === null ) return
682+ e . preventDefault ( )
683+ e . dataTransfer . dropEffect = 'move'
684+ setDragOverIndex ( index )
685+ }
686+
687+ const handleDragEnd = ( ) => {
688+ setDraggedIndex ( null )
689+ setDragOverIndex ( null )
690+ }
691+
692+ const handleDrop = ( e : React . DragEvent , dropIndex : number ) => {
693+ if ( isPreview || disabled || draggedIndex === null || draggedIndex === dropIndex ) return
694+ e . preventDefault ( )
695+
696+ const newTools = [ ...selectedTools ]
697+ const draggedTool = newTools [ draggedIndex ]
698+
699+ newTools . splice ( draggedIndex , 1 )
700+
701+ if ( dropIndex === selectedTools . length ) {
702+ newTools . push ( draggedTool )
703+ } else {
704+ const adjustedDropIndex = draggedIndex < dropIndex ? dropIndex - 1 : dropIndex
705+ newTools . splice ( adjustedDropIndex , 0 , draggedTool )
706+ }
707+
708+ setStoreValue ( newTools )
709+ setDraggedIndex ( null )
710+ setDragOverIndex ( null )
711+ }
712+
671713 const IconComponent = ( { icon : Icon , className } : { icon : any ; className ?: string } ) => {
672714 if ( ! Icon ) return null
673715 return < Icon className = { className } />
@@ -827,9 +869,34 @@ export function ToolInput({
827869 return (
828870 < div
829871 key = { `${ tool . type } -${ toolIndex } ` }
830- className = { cn ( 'group flex flex-col' , isWide ? 'w-[calc(50%-0.25rem)]' : 'w-full' ) }
872+ className = { cn (
873+ 'group relative flex flex-col transition-all duration-200 ease-in-out' ,
874+ isWide ? 'w-[calc(50%-0.25rem)]' : 'w-full' ,
875+ draggedIndex === toolIndex ? 'scale-95 opacity-40' : '' ,
876+ dragOverIndex === toolIndex && draggedIndex !== toolIndex && draggedIndex !== null
877+ ? 'translate-y-1 transform'
878+ : '' ,
879+ selectedTools . length > 1 && ! isPreview && ! disabled
880+ ? 'cursor-grab active:cursor-grabbing'
881+ : ''
882+ ) }
883+ draggable = { ! isPreview && ! disabled }
884+ onDragStart = { ( e ) => handleDragStart ( e , toolIndex ) }
885+ onDragOver = { ( e ) => handleDragOver ( e , toolIndex ) }
886+ onDragEnd = { handleDragEnd }
887+ onDrop = { ( e ) => handleDrop ( e , toolIndex ) }
831888 >
832- < div className = 'flex flex-col overflow-visible rounded-md border bg-card' >
889+ { /* Subtle drop indicator - use border highlight instead of separate line */ }
890+ < div
891+ className = { cn (
892+ 'flex flex-col overflow-visible rounded-md border bg-card' ,
893+ dragOverIndex === toolIndex &&
894+ draggedIndex !== toolIndex &&
895+ draggedIndex !== null
896+ ? 'border-t-2 border-t-muted-foreground/40'
897+ : ''
898+ ) }
899+ >
833900 < div
834901 className = { cn (
835902 'flex items-center justify-between bg-accent/50 p-2' ,
@@ -1091,6 +1158,20 @@ export function ToolInput({
10911158 )
10921159 } ) }
10931160
1161+ { /* Drop zone for the end of the list */ }
1162+ { selectedTools . length > 0 && draggedIndex !== null && (
1163+ < div
1164+ className = { cn (
1165+ 'h-2 w-full rounded transition-all duration-200 ease-in-out' ,
1166+ dragOverIndex === selectedTools . length
1167+ ? 'border-b-2 border-b-muted-foreground/40'
1168+ : ''
1169+ ) }
1170+ onDragOver = { ( e ) => handleDragOver ( e , selectedTools . length ) }
1171+ onDrop = { ( e ) => handleDrop ( e , selectedTools . length ) }
1172+ />
1173+ ) }
1174+
10941175 < Popover open = { open } onOpenChange = { setOpen } >
10951176 < PopoverTrigger asChild >
10961177 < Button
0 commit comments