@@ -137,12 +137,19 @@ export function useDashboardDropZone(
137137 // over every tab, dimming the page and visually blocking every
138138 // interaction even though pointer-events:none lets clicks through.
139139 //
140- // Three independent resets:
141- // 1. `dragend` fires on the drag SOURCE when the operation ends
142- // for any reason (drop, ESC, cancel). Always reset.
143- // 2. window `blur` — user switched apps mid-drag. Reset so the
140+ // Four independent resets:
141+ // 1. `drop` safety pass — the main onDrop handler returns early
142+ // when payload isn't files or when a local zone owns the
143+ // drop, so this unconditional reset runs after it to guarantee
144+ // isDragging clears no matter which branch onDrop took.
145+ // 2. `dragend` fires on the drag SOURCE when an in-page drag ends
146+ // for any reason (drop, ESC, cancel). Does NOT fire for
147+ // external OS-originated file drags (where the source is the
148+ // Finder/Explorer, not the window) — those are covered by the
149+ // drop safety pass above and the blur/pointerover fallbacks.
150+ // 3. window `blur` — user switched apps mid-drag. Reset so the
144151 // overlay doesn't survive the focus loss.
145- // 3 . `pointerover` outside any drag — if the cursor is moving
152+ // 4 . `pointerover` outside any drag — if the cursor is moving
146153 // around the page without an active drag, there can't be one
147154 // in progress; reset to safe state.
148155 const reset = ( ) => {
@@ -156,6 +163,11 @@ export function useDashboardDropZone(
156163 window . addEventListener ( 'dragover' , onDragOver ) ;
157164 window . addEventListener ( 'dragleave' , onDragLeave ) ;
158165 window . addEventListener ( 'drop' , onDrop ) ;
166+ // Unconditional reset runs AFTER onDrop. Both listeners fire on the
167+ // same event; React's event ordering preserves attachment order so
168+ // onDrop processes the file first, then this pass clears state
169+ // even if onDrop took an early-return path that skipped the reset.
170+ window . addEventListener ( 'drop' , reset ) ;
159171 window . addEventListener ( 'dragend' , reset ) ;
160172 window . addEventListener ( 'blur' , reset ) ;
161173 window . addEventListener ( 'pointerover' , onPointerOverIdle ) ;
@@ -164,6 +176,7 @@ export function useDashboardDropZone(
164176 window . removeEventListener ( 'dragover' , onDragOver ) ;
165177 window . removeEventListener ( 'dragleave' , onDragLeave ) ;
166178 window . removeEventListener ( 'drop' , onDrop ) ;
179+ window . removeEventListener ( 'drop' , reset ) ;
167180 window . removeEventListener ( 'dragend' , reset ) ;
168181 window . removeEventListener ( 'blur' , reset ) ;
169182 window . removeEventListener ( 'pointerover' , onPointerOverIdle ) ;
0 commit comments