@@ -16,7 +16,7 @@ import {DragEndEvent, DragItem, DropActivateEvent, DropEnterEvent, DropEvent, Dr
16
16
import { getDragModality , getTypes } from './utils' ;
17
17
import { isVirtualClick , isVirtualPointerEvent } from '@react-aria/utils' ;
18
18
import type { LocalizedStringFormatter } from '@internationalized/string' ;
19
- import { RefObject , useEffect , useState } from 'react' ;
19
+ import { useEffect , useState } from 'react' ;
20
20
21
21
let dropTargets = new Map < Element , DropTarget > ( ) ;
22
22
let dropItems = new Map < Element , DroppableItem > ( ) ;
@@ -32,8 +32,7 @@ interface DropTarget {
32
32
onDropTargetEnter ?: ( target : DroppableCollectionTarget | null ) => void ,
33
33
onDropActivate ?: ( e : DropActivateEvent , target : DroppableCollectionTarget | null ) => void ,
34
34
onDrop ?: ( e : DropEvent , target : DroppableCollectionTarget | null ) => void ,
35
- onKeyDown ?: ( e : KeyboardEvent , dragTarget : DragTarget ) => void ,
36
- activateButtonRef ?: RefObject < FocusableElement | null >
35
+ onKeyDown ?: ( e : KeyboardEvent , dragTarget : DragTarget ) => void
37
36
}
38
37
39
38
export function registerDropTarget ( target : DropTarget ) {
@@ -48,8 +47,7 @@ export function registerDropTarget(target: DropTarget) {
48
47
interface DroppableItem {
49
48
element : FocusableElement ,
50
49
target : DroppableCollectionTarget ,
51
- getDropOperation ?: ( types : Set < string > , allowedOperations : DropOperation [ ] ) => DropOperation ,
52
- activateButtonRef ?: RefObject < FocusableElement | null >
50
+ getDropOperation ?: ( types : Set < string > , allowedOperations : DropOperation [ ] ) => DropOperation
53
51
}
54
52
55
53
export function registerDropItem ( item : DroppableItem ) {
@@ -243,26 +241,15 @@ class DragSession {
243
241
this . cancelEvent ( e ) ;
244
242
245
243
if ( e . key === 'Enter' ) {
246
- if ( e . altKey || this . getCurrentActivateButton ( ) ?. contains ( e . target as Node ) ) {
247
- this . activate ( this . currentDropTarget , this . currentDropItem ) ;
244
+ if ( e . altKey ) {
245
+ this . activate ( ) ;
248
246
} else {
249
247
this . drop ( ) ;
250
248
}
251
249
}
252
250
}
253
251
254
- getCurrentActivateButton ( ) : FocusableElement | null {
255
- return this . currentDropItem ?. activateButtonRef ?. current ?? this . currentDropTarget ?. activateButtonRef ?. current ?? null ;
256
- }
257
-
258
252
onFocus ( e : FocusEvent ) {
259
- let activateButton = this . getCurrentActivateButton ( ) ;
260
- if ( e . target === activateButton ) {
261
- // TODO: canceling this breaks the focus ring. Revisit when we support tabbing.
262
- this . cancelEvent ( e ) ;
263
- return ;
264
- }
265
-
266
253
// Prevent focus events, except to the original drag target.
267
254
if ( e . target !== this . dragTarget . element ) {
268
255
this . cancelEvent ( e ) ;
@@ -278,9 +265,6 @@ class DragSession {
278
265
this . validDropTargets . find ( target => target . element . contains ( e . target as HTMLElement ) ) ;
279
266
280
267
if ( ! dropTarget ) {
281
- // if (e.target === activateButton) {
282
- // activateButton.focus();
283
- // }
284
268
if ( this . currentDropTarget ) {
285
269
this . currentDropTarget . element . focus ( ) ;
286
270
} else {
@@ -290,18 +274,10 @@ class DragSession {
290
274
}
291
275
292
276
let item = dropItems . get ( e . target as HTMLElement ) ;
293
- if ( dropTarget ) {
294
- this . setCurrentDropTarget ( dropTarget , item ) ;
295
- }
277
+ this . setCurrentDropTarget ( dropTarget , item ) ;
296
278
}
297
279
298
280
onBlur ( e : FocusEvent ) {
299
- let activateButton = this . getCurrentActivateButton ( ) ;
300
- if ( e . relatedTarget === activateButton ) {
301
- this . cancelEvent ( e ) ;
302
- return ;
303
- }
304
-
305
281
if ( e . target !== this . dragTarget . element ) {
306
282
this . cancelEvent ( e ) ;
307
283
}
@@ -320,21 +296,14 @@ class DragSession {
320
296
onClick ( e : MouseEvent ) {
321
297
this . cancelEvent ( e ) ;
322
298
if ( isVirtualClick ( e ) || this . isVirtualClick ) {
323
- let dropElements = dropItems . values ( ) ;
324
- let item = [ ...dropElements ] . find ( item => item . element === e . target as HTMLElement || item . activateButtonRef ?. current ?. contains ( e . target as HTMLElement ) ) ;
325
- let dropTarget = this . validDropTargets . find ( target => target . element . contains ( e . target as HTMLElement ) ) ;
326
- let activateButton = item ?. activateButtonRef ?. current ?? dropTarget ?. activateButtonRef ?. current ;
327
- if ( activateButton ?. contains ( e . target as HTMLElement ) && dropTarget ) {
328
- this . activate ( dropTarget , item ) ;
329
- return ;
330
- }
331
-
332
299
if ( e . target === this . dragTarget . element ) {
333
300
this . cancel ( ) ;
334
301
return ;
335
302
}
336
303
304
+ let dropTarget = this . validDropTargets . find ( target => target . element . contains ( e . target as HTMLElement ) ) ;
337
305
if ( dropTarget ) {
306
+ let item = dropItems . get ( e . target as HTMLElement ) ;
338
307
this . setCurrentDropTarget ( dropTarget , item ) ;
339
308
this . drop ( item ) ;
340
309
}
@@ -350,7 +319,7 @@ class DragSession {
350
319
351
320
cancelEvent ( e : Event ) {
352
321
// Allow focusin and focusout on the drag target so focus ring works properly.
353
- if ( ( e . type === 'focusin' || e . type === 'focusout' ) && ( e . target === this . dragTarget ?. element || e . target === this . getCurrentActivateButton ( ) ) ) {
322
+ if ( ( e . type === 'focusin' || e . type === 'focusout' ) && e . target === this . dragTarget ?. element ) {
354
323
return ;
355
324
}
356
325
@@ -406,23 +375,14 @@ class DragSession {
406
375
407
376
this . restoreAriaHidden = ariaHideOutside ( [
408
377
this . dragTarget . element ,
409
- ...validDropItems . flatMap ( item => item . activateButtonRef ?. current ? [ item . element , item . activateButtonRef ?. current ] : [ item . element ] ) ,
410
- ...visibleDropTargets . flatMap ( target => target . activateButtonRef ?. current ? [ target . element , target . activateButtonRef ?. current ] : [ target . element ] )
378
+ ...validDropItems . map ( item => item . element ) ,
379
+ ...visibleDropTargets . map ( target => target . element )
411
380
] ) ;
412
381
413
382
this . mutationObserver . observe ( document . body , { subtree : true , attributes : true , attributeFilter : [ 'aria-hidden' ] } ) ;
414
383
}
415
384
416
385
next ( ) {
417
- // TODO: Allow tabbing to the activate button. Revisit once we fix the focus ring.
418
- // For now, the activate button is reachable by screen readers and ArrowLeft/ArrowRight
419
- // is usable specifically by Tree. Will need tabbing for other components.
420
- // let activateButton = this.getCurrentActivateButton();
421
- // if (activateButton && document.activeElement !== activateButton) {
422
- // activateButton.focus();
423
- // return;
424
- // }
425
-
426
386
if ( ! this . currentDropTarget ) {
427
387
this . setCurrentDropTarget ( this . validDropTargets [ 0 ] ) ;
428
388
return ;
@@ -449,15 +409,6 @@ class DragSession {
449
409
}
450
410
451
411
previous ( ) {
452
- // let activateButton = this.getCurrentActivateButton();
453
- // if (activateButton && document.activeElement === activateButton) {
454
- // let target = this.currentDropItem ?? this.currentDropTarget;
455
- // if (target) {
456
- // target.element.focus();
457
- // return;
458
- // }
459
- // }
460
-
461
412
if ( ! this . currentDropTarget ) {
462
413
this . setCurrentDropTarget ( this . validDropTargets [ this . validDropTargets . length - 1 ] ) ;
463
414
return ;
@@ -536,6 +487,7 @@ class DragSession {
536
487
if ( this . currentDropTarget && typeof this . currentDropTarget . onDropTargetEnter === 'function' ) {
537
488
this . currentDropTarget . onDropTargetEnter ( item . target ) ;
538
489
}
490
+
539
491
item . element . focus ( ) ;
540
492
this . currentDropItem = item ;
541
493
@@ -624,15 +576,14 @@ class DragSession {
624
576
announce ( this . stringFormatter . format ( 'dropComplete' ) ) ;
625
577
}
626
578
627
- activate ( dropTarget : DropTarget | null , dropItem : DroppableItem | null | undefined ) {
628
- if ( dropTarget && typeof dropTarget . onDropActivate === 'function' ) {
629
- let target = dropItem ?. target ?? null ;
630
- let rect = dropTarget . element . getBoundingClientRect ( ) ;
631
- dropTarget . onDropActivate ( {
579
+ activate ( ) {
580
+ if ( this . currentDropTarget && typeof this . currentDropTarget . onDropActivate === 'function' ) {
581
+ let rect = this . currentDropTarget . element . getBoundingClientRect ( ) ;
582
+ this . currentDropTarget . onDropActivate ( {
632
583
type : 'dropactivate' ,
633
584
x : rect . left + ( rect . width / 2 ) ,
634
585
y : rect . top + ( rect . height / 2 )
635
- } , target ) ;
586
+ } , null ) ;
636
587
}
637
588
}
638
589
}
0 commit comments