From d2270a6908e24f442ac1f6cf7619706bedc0bd7f Mon Sep 17 00:00:00 2001 From: Theodore Li Date: Mon, 13 Apr 2026 16:59:27 -0700 Subject: [PATCH 1/2] fix(ui): stop scrolling on leaving workflow sidebar for drag-drop --- .../w/components/sidebar/hooks/use-drag-drop.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/hooks/use-drag-drop.ts b/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/hooks/use-drag-drop.ts index 30dd068ef5f..13d57f071f8 100644 --- a/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/hooks/use-drag-drop.ts +++ b/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/hooks/use-drag-drop.ts @@ -616,6 +616,18 @@ export function useDragDrop(options: UseDragDropOptions = {}) { siblingsCacheRef.current.clear() }, []) + useEffect(() => { + if (!isDragging) return + const container = scrollContainerRef.current + if (!container) return + const onLeave = (e: DragEvent) => { + const related = e.relatedTarget as Node | null + if (!related || !container.contains(related)) handleDragEnd() + } + container.addEventListener('dragleave', onLeave) + return () => container.removeEventListener('dragleave', onLeave) + }, [isDragging, handleDragEnd]) + const setScrollContainer = useCallback((element: HTMLDivElement | null) => { scrollContainerRef.current = element }, []) From 6d5cad052a1c5e6dd22e0fe15e067838cd016eaf Mon Sep 17 00:00:00 2001 From: Theodore Li Date: Tue, 14 Apr 2026 15:40:37 -0700 Subject: [PATCH 2/2] Address comments, fix hover state --- .../components/sidebar/hooks/use-drag-drop.ts | 21 ++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/hooks/use-drag-drop.ts b/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/hooks/use-drag-drop.ts index 13d57f071f8..9dbb8794230 100644 --- a/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/hooks/use-drag-drop.ts +++ b/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/hooks/use-drag-drop.ts @@ -252,11 +252,13 @@ export function useDragDrop(options: UseDragDropOptions = {}) { if (!isDragging) { isDraggingRef.current = true setIsDragging(true) + } else if (scrollAnimationRef.current === null) { + scrollAnimationRef.current = requestAnimationFrame(handleAutoScroll) } return true }, - [isDragging] + [isDragging, handleAutoScroll] ) const getSiblingItems = useCallback( @@ -622,10 +624,23 @@ export function useDragDrop(options: UseDragDropOptions = {}) { if (!container) return const onLeave = (e: DragEvent) => { const related = e.relatedTarget as Node | null - if (!related || !container.contains(related)) handleDragEnd() + if (related && container.contains(related)) return + if (scrollAnimationRef.current !== null) { + cancelAnimationFrame(scrollAnimationRef.current) + scrollAnimationRef.current = null + } + dropIndicatorRef.current = null + setDropIndicator(null) + setHoverFolderId(null) } container.addEventListener('dragleave', onLeave) - return () => container.removeEventListener('dragleave', onLeave) + window.addEventListener('drop', handleDragEnd, true) + window.addEventListener('dragend', handleDragEnd, true) + return () => { + container.removeEventListener('dragleave', onLeave) + window.removeEventListener('drop', handleDragEnd, true) + window.removeEventListener('dragend', handleDragEnd, true) + } }, [isDragging, handleDragEnd]) const setScrollContainer = useCallback((element: HTMLDivElement | null) => {