@@ -11,7 +11,11 @@ import type { UploadDropZone } from '../src/vaadin-upload-drop-zone.js';
1111import { UploadManager } from '../src/vaadin-upload-manager.js' ;
1212import { createFiles } from './helpers.js' ;
1313
14- function createDragEvent ( type : string , files : File [ ] = [ ] , relatedTarget ?: EventTarget | null ) : DragEvent {
14+ function createDragEvent (
15+ type : string ,
16+ files : File [ ] = [ ] ,
17+ options ?: { clientX ?: number ; clientY ?: number } ,
18+ ) : DragEvent {
1519 const dataTransfer = {
1620 files,
1721 items : files . map ( ( file ) => ( {
@@ -29,8 +33,11 @@ function createDragEvent(type: string, files: File[] = [], relatedTarget?: Event
2933
3034 const event = new Event ( type , { bubbles : true , cancelable : true } ) as DragEvent ;
3135 Object . defineProperty ( event , 'dataTransfer' , { value : dataTransfer } ) ;
32- if ( relatedTarget !== undefined ) {
33- Object . defineProperty ( event , 'relatedTarget' , { value : relatedTarget } ) ;
36+ if ( options ?. clientX !== undefined ) {
37+ Object . defineProperty ( event , 'clientX' , { value : options . clientX } ) ;
38+ }
39+ if ( options ?. clientY !== undefined ) {
40+ Object . defineProperty ( event , 'clientY' , { value : options . clientY } ) ;
3441 }
3542 return event ;
3643}
@@ -142,7 +149,7 @@ describe('vaadin-upload-drop-zone', () => {
142149 await nextFrame ( ) ;
143150 expect ( dropZone . hasAttribute ( 'dragover' ) ) . to . be . true ;
144151
145- // Then trigger dragleave
152+ // Then trigger dragleave (coordinates default to 0,0 which is outside the element)
146153 dropZone . dispatchEvent ( createDragEvent ( 'dragleave' ) ) ;
147154 await nextFrame ( ) ;
148155 expect ( dropZone . hasAttribute ( 'dragover' ) ) . to . be . false ;
@@ -155,46 +162,41 @@ describe('vaadin-upload-drop-zone', () => {
155162 expect ( event . defaultPrevented ) . to . be . true ;
156163 } ) ;
157164
158- it ( 'should not remove dragover when dragleave fires for child element' , async ( ) => {
159- // Add a child element to the drop zone
160- const child = document . createElement ( 'p' ) ;
161- child . textContent = 'Child element' ;
162- dropZone . appendChild ( child ) ;
163- await nextFrame ( ) ;
164-
165+ it ( 'should not remove dragover when cursor is still inside the drop zone' , async ( ) => {
165166 // Trigger dragover on drop zone
166167 dropZone . dispatchEvent ( createDragEvent ( 'dragover' ) ) ;
167168 await nextFrame ( ) ;
168169 expect ( dropZone . hasAttribute ( 'dragover' ) ) . to . be . true ;
169170
170- // Simulate dragleave when entering child element (relatedTarget is the child)
171- const dragleaveEvent = createDragEvent ( 'dragleave' , [ ] , child ) ;
171+ // Simulate dragleave with cursor coordinates still inside the drop zone
172+ const rect = dropZone . getBoundingClientRect ( ) ;
173+ const dragleaveEvent = createDragEvent ( 'dragleave' , [ ] , {
174+ clientX : rect . left + rect . width / 2 ,
175+ clientY : rect . top + rect . height / 2 ,
176+ } ) ;
172177 dropZone . dispatchEvent ( dragleaveEvent ) ;
173178 await nextFrame ( ) ;
174179
175- // Should still have dragover because we're still inside the drop zone
180+ // Should still have dragover because cursor is inside the drop zone
176181 expect ( dropZone . hasAttribute ( 'dragover' ) ) . to . be . true ;
177182 } ) ;
178183
179- it ( 'should only remove dragover when leaving the drop zone entirely' , async ( ) => {
180- // Add a child element
181- const child = document . createElement ( 'p' ) ;
182- child . textContent = 'Child element' ;
183- dropZone . appendChild ( child ) ;
184- await nextFrame ( ) ;
185-
184+ it ( 'should remove dragover when cursor leaves the drop zone' , async ( ) => {
186185 // Trigger dragover
187186 dropZone . dispatchEvent ( createDragEvent ( 'dragover' ) ) ;
188187 await nextFrame ( ) ;
189188 expect ( dropZone . hasAttribute ( 'dragover' ) ) . to . be . true ;
190189
191- // Simulate dragleave when leaving the drop zone entirely (relatedTarget is outside)
192- const outsideElement = document . body ;
193- const dragleaveEvent = createDragEvent ( 'dragleave' , [ ] , outsideElement ) ;
190+ // Simulate dragleave with cursor coordinates outside the drop zone
191+ const rect = dropZone . getBoundingClientRect ( ) ;
192+ const dragleaveEvent = createDragEvent ( 'dragleave' , [ ] , {
193+ clientX : rect . right + 10 ,
194+ clientY : rect . bottom + 10 ,
195+ } ) ;
194196 dropZone . dispatchEvent ( dragleaveEvent ) ;
195197 await nextFrame ( ) ;
196198
197- // Should remove dragover because we left the drop zone
199+ // Should remove dragover because cursor left the drop zone
198200 expect ( dropZone . hasAttribute ( 'dragover' ) ) . to . be . false ;
199201 } ) ;
200202
0 commit comments