Skip to content

fix: move drag-and-drop handlers from display:contents wrapper to Tab element (fixes PlatformNetwork/bounty-challenge#21924)#31

Merged
echobt merged 1 commit intomainfrom
fix/issue-21924-v2
Feb 27, 2026
Merged

fix: move drag-and-drop handlers from display:contents wrapper to Tab element (fixes PlatformNetwork/bounty-challenge#21924)#31
echobt merged 1 commit intomainfrom
fix/issue-21924-v2

Conversation

@echobt
Copy link
Copy Markdown
Contributor

@echobt echobt commented Feb 27, 2026

Fix for PlatformNetwork/bounty-challenge#21924: Tab drag-and-drop reordering non-functional

Root Cause

The drag-event handlers (onDragOver, onDragLeave, onDrop) were attached to a wrapper <div> with display: contents (line 1067), which does not generate a CSS box. In Chromium-based renderers (Tauri WebView2), drag events do not properly fire on display: contents elements. Because handleDragOver never fires, e.preventDefault() is never called, so the browser treats the area as an invalid drop zone and shows the not-allowed (🚫) cursor.

Additionally, dragState() was captured as a stale const inside the SolidJS <For> callback body (line 1051), so isDraggedOver and dropPosition props were frozen at their initial values and never updated reactively.

Changes

  • Move drag handlers to Tab element: onDragOver, onDragLeave, and onDrop are now props on the Tab component and are attached directly to the tab's root <div> element (which has a real CSS box)
  • Add ref prop to Tab: Passes tabRef for getBoundingClientRect() calculation in handleDragOver drop-position detection
  • Fix reactive dragState: Call dragState() directly in JSX expressions instead of capturing it as a stale const
  • Remove display:contents wrapper: Replace with a fragment (<>) since the wrapper is no longer needed

Files Modified

  • src/components/editor/TabBar.tsx

… element (fixes PlatformNetwork/bounty-challenge#21924)

The drag-event handlers (onDragOver, onDragLeave, onDrop) were attached to a
wrapper div with display:contents, which does not generate a CSS box. In
Chromium-based renderers (Tauri WebView2), drag events do not properly fire on
display:contents elements, causing e.preventDefault() to never be called in
handleDragOver. Without that call, the browser treats the area as an invalid
drop zone and shows the not-allowed cursor.

Additionally, dragState() was captured as a stale const inside the <For>
callback body, so isDraggedOver and dropPosition props were frozen at their
initial values and never updated reactively.

Changes:
- Move onDragOver, onDragLeave, onDrop props into the Tab component itself
  so they fire on the actual rendered tab div element
- Add ref prop to Tab to pass tabRef for getBoundingClientRect() in
  handleDragOver position calculation
- Call dragState() directly in JSX expressions for reactive updates
- Remove the display:contents wrapper div entirely, use fragment (<>)
@echobt echobt merged commit d306b5f into main Feb 27, 2026
9 checks passed
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