Skip to content

fix(ui): stop scrolling on leaving workflow sidebar for drag-drop#4139

Open
TheodoreSpeaks wants to merge 2 commits intostagingfrom
fix/infinite-scroll-sidebar
Open

fix(ui): stop scrolling on leaving workflow sidebar for drag-drop#4139
TheodoreSpeaks wants to merge 2 commits intostagingfrom
fix/infinite-scroll-sidebar

Conversation

@TheodoreSpeaks
Copy link
Copy Markdown
Collaborator

Summary

Currently dragging and dropping a file past a scrollable workflow sidebar causes the sidebar to continuously scroll. Switched this to stop scrolling on leaving the container to prevent the issue.

Type of Change

  • Bug fix
  • New feature
  • Breaking change
  • Documentation
  • Other: ___________

Testing

  • Tested that dragging and dropping into mothership and copilot works as intended.

Checklist

  • Code follows project style guidelines
  • Self-reviewed my changes
  • Tests added/updated and passing
  • No new warnings introduced
  • I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)

Screenshots/Videos

@vercel
Copy link
Copy Markdown

vercel bot commented Apr 14, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
docs Ready Ready Preview, Comment Apr 14, 2026 1:29am

Request Review

@cursor
Copy link
Copy Markdown

cursor bot commented Apr 14, 2026

PR Summary

Low Risk
Low risk UI-only change that tweaks drag lifecycle handling; main risk is ending a drag session prematurely due to browser dragleave/relatedTarget quirks.

Overview
Fixes a drag-drop bug where the workflow sidebar could keep auto-scrolling after the cursor leaves the scrollable container.

When a drag is active, the hook now listens for dragleave on the sidebar scroll container and triggers handleDragEnd() when the drag exits the container, clearing drag state and stopping the auto-scroll loop.

Reviewed by Cursor Bugbot for commit 6035091. Bugbot is set up for automated code reviews on this repo. Configure here.

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Apr 14, 2026

Greptile Summary

This PR adds a useEffect to the useDragDrop hook that listens for native dragleave events on the scroll container and calls handleDragEnd() when the drag cursor exits the container boundary (i.e., relatedTarget is null or outside the container). This cleanly stops the auto-scroll loop that was previously left running whenever a file drag passed over the sidebar and then exited.

Confidence Score: 5/5

Safe to merge — the fix is minimal, correctly scoped, and idempotent.

The new useEffect is correctly structured: it only attaches when isDragging is true, uses the container.contains(relatedTarget) guard to avoid false positives from intra-container drag events, and the cleanup reliably removes the listener. handleDragEnd is idempotent so duplicate calls are harmless. All remaining observations are P2 or below.

No files require special attention.

Important Files Changed

Filename Overview
apps/sim/app/workspace/[workspaceId]/w/components/sidebar/hooks/use-drag-drop.ts Adds a useEffect that attaches a native dragleave listener to the scroll container while dragging; calls handleDragEnd() when the drag leaves the container boundary, stopping the runaway auto-scroll loop.

Sequence Diagram

sequenceDiagram
    participant User
    participant Browser
    participant ScrollContainer
    participant useDragDrop

    User->>Browser: Drag file/item over sidebar
    Browser->>ScrollContainer: dragover event
    ScrollContainer->>useDragDrop: initDragOver() → isDragging = true
    useDragDrop->>useDragDrop: useEffect attaches dragleave listener

    loop Auto-scroll loop (while isDragging)
        useDragDrop->>ScrollContainer: requestAnimationFrame(handleAutoScroll)
    end

    User->>Browser: Drag cursor leaves container boundary
    Browser->>ScrollContainer: dragleave (relatedTarget = null or outside)
    ScrollContainer->>useDragDrop: onLeave() → !container.contains(related)
    useDragDrop->>useDragDrop: handleDragEnd() → isDragging = false
    useDragDrop->>useDragDrop: useEffect cleanup removes dragleave listener
    useDragDrop->>ScrollContainer: cancelAnimationFrame (auto-scroll stops)
Loading

Reviews (1): Last reviewed commit: "fix(ui): stop scrolling on leaving workf..." | Re-trigger Greptile

Copy link
Copy Markdown

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit d2270a6. Configure here.

}
container.addEventListener('dragleave', onLeave)
return () => container.removeEventListener('dragleave', onLeave)
}, [isDragging, handleDragEnd])
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Full drag state reset corrupts re-entry behavior

Medium Severity

The dragleave handler calls handleDragEnd() which resets all drag state — including draggedSourceFolderRef, dropIndicatorRef, and siblingsCacheRef. But the browser's native drag operation continues (user is still holding the mouse). If the cursor re-enters the container, initDragOver re-sets isDragging to true, but draggedSourceFolderRef stays null. This causes isSameFolder/isSameParent checks in createWorkflowDragHandlers and createFolderDragHandlers to return incorrect results, leading to wrong drop indicators and potentially incorrect item reordering for non-root items.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit d2270a6. Configure here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant