@@ -11,20 +11,27 @@ const logger = createLogger('WorkflowList:DragDrop')
1111const SCROLL_THRESHOLD = 60 // Distance from edge to trigger scroll
1212const SCROLL_SPEED = 8 // Pixels per frame
1313
14+ /**
15+ * Constants for folder auto-expand on hover during drag
16+ */
17+ const HOVER_EXPAND_DELAY = 400 // Milliseconds to wait before expanding folder
18+
1419/**
1520 * Custom hook for handling drag and drop operations for workflows and folders.
16- * Includes auto-scrolling and drop target highlighting.
21+ * Includes auto-scrolling, drop target highlighting, and hover-to-expand .
1722 *
1823 * @returns Drag and drop state and event handlers
1924 */
2025export function useDragDrop ( ) {
2126 const [ dropTargetId , setDropTargetId ] = useState < string | null > ( null )
2227 const [ isDragging , setIsDragging ] = useState ( false )
28+ const [ hoverFolderId , setHoverFolderId ] = useState < string | null > ( null )
2329 const scrollContainerRef = useRef < HTMLDivElement | null > ( null )
2430 const scrollIntervalRef = useRef < number | null > ( null )
31+ const hoverExpandTimerRef = useRef < number | null > ( null )
2532 const lastDragYRef = useRef < number > ( 0 )
2633
27- const { updateFolderAPI, getFolderPath } = useFolderStore ( )
34+ const { updateFolderAPI, getFolderPath, setExpanded , expandedFolders } = useFolderStore ( )
2835 const { updateWorkflow } = useWorkflowRegistry ( )
2936
3037 /**
@@ -85,6 +92,49 @@ export function useDragDrop() {
8592 }
8693 } , [ isDragging , handleAutoScroll ] )
8794
95+ /**
96+ * Handle hover folder changes - start/clear expand timer
97+ */
98+ useEffect ( ( ) => {
99+ // Clear existing timer when hover folder changes
100+ if ( hoverExpandTimerRef . current ) {
101+ clearTimeout ( hoverExpandTimerRef . current )
102+ hoverExpandTimerRef . current = null
103+ }
104+
105+ // Don't start timer if not dragging or no folder is hovered
106+ if ( ! isDragging || ! hoverFolderId ) {
107+ return
108+ }
109+
110+ // Don't expand if folder is already expanded
111+ if ( expandedFolders . has ( hoverFolderId ) ) {
112+ return
113+ }
114+
115+ // Start timer to expand folder after delay
116+ hoverExpandTimerRef . current = window . setTimeout ( ( ) => {
117+ setExpanded ( hoverFolderId , true )
118+ logger . info ( `Auto-expanded folder ${ hoverFolderId } during drag` )
119+ } , HOVER_EXPAND_DELAY )
120+
121+ return ( ) => {
122+ if ( hoverExpandTimerRef . current ) {
123+ clearTimeout ( hoverExpandTimerRef . current )
124+ hoverExpandTimerRef . current = null
125+ }
126+ }
127+ } , [ hoverFolderId , isDragging , expandedFolders , setExpanded ] )
128+
129+ /**
130+ * Cleanup hover state when dragging stops
131+ */
132+ useEffect ( ( ) => {
133+ if ( ! isDragging ) {
134+ setHoverFolderId ( null )
135+ }
136+ } , [ isDragging ] )
137+
88138 /**
89139 * Moves one or more workflows to a target folder
90140 *
@@ -269,6 +319,32 @@ export function useDragDrop() {
269319 [ handleFolderDrop ]
270320 )
271321
322+ /**
323+ * Creates drag event handlers for folder header (the clickable part)
324+ * These handlers trigger folder expansion on hover during drag
325+ *
326+ * @param folderId - Folder ID to handle hover for
327+ * @returns Object containing drag event handlers for folder header
328+ */
329+ const createFolderHeaderHoverHandlers = useCallback (
330+ ( folderId : string ) => ( {
331+ onDragEnter : ( e : React . DragEvent < HTMLElement > ) => {
332+ if ( isDragging ) {
333+ setHoverFolderId ( folderId )
334+ }
335+ } ,
336+ onDragLeave : ( e : React . DragEvent < HTMLElement > ) => {
337+ const relatedTarget = e . relatedTarget as HTMLElement | null
338+ const currentTarget = e . currentTarget as HTMLElement
339+ // Only clear if we're leaving the folder header completely
340+ if ( ! relatedTarget || ! currentTarget . contains ( relatedTarget ) ) {
341+ setHoverFolderId ( null )
342+ }
343+ } ,
344+ } ) ,
345+ [ isDragging ]
346+ )
347+
272348 /**
273349 * Set the scroll container ref for auto-scrolling
274350 *
@@ -285,5 +361,6 @@ export function useDragDrop() {
285361 createFolderDragHandlers,
286362 createItemDragHandlers,
287363 createRootDragHandlers,
364+ createFolderHeaderHoverHandlers,
288365 }
289366}
0 commit comments