@@ -188,6 +188,8 @@ type ActiveCallback = (
188
188
gestureState : GestureState ,
189
189
) => boolean ;
190
190
191
+ type InteractionState = { handle : ?number , shouldCancelClick : boolean , timeout : ?TimeoutID } ;
192
+
191
193
type PassiveCallback = ( event : PressEvent , gestureState : GestureState ) => mixed ;
192
194
193
195
type PanResponderConfig = $ReadOnly < { |
@@ -384,9 +386,12 @@ const PanResponder = {
384
386
* are the responder.
385
387
*/
386
388
create ( config : PanResponderConfig ) {
387
- const interactionState = {
388
- handle : ( null : ?number ) ,
389
+ const interactionState : InteractionState = {
390
+ handle : null ,
391
+ shouldCancelClick : false ,
392
+ timeout : null ,
389
393
} ;
394
+
390
395
const gestureState : GestureState = {
391
396
// Useful for debugging
392
397
stateID : Math . random ( ) ,
@@ -427,15 +432,6 @@ const PanResponder = {
427
432
428
433
onMoveShouldSetResponderCapture ( event : PressEvent ) : boolean {
429
434
const touchHistory = event . touchHistory ;
430
- // Responder system incorrectly dispatches should* to current responder
431
- // Filter out any touch moves past the first one - we would have
432
- // already processed multi-touch geometry during the first event.
433
- if (
434
- gestureState . _accountsForMovesUpTo ===
435
- touchHistory . mostRecentTimeStamp
436
- ) {
437
- return false ;
438
- }
439
435
PanResponder . _updateGestureStateOnMove ( gestureState , touchHistory ) ;
440
436
return config . onMoveShouldSetPanResponderCapture
441
437
? config . onMoveShouldSetPanResponderCapture ( event , gestureState )
@@ -446,6 +442,10 @@ const PanResponder = {
446
442
if ( ! interactionState . handle ) {
447
443
interactionState . handle = InteractionManager . createInteractionHandle ( ) ;
448
444
}
445
+ if ( interactionState . timeout ) {
446
+ clearInteractionTimeout ( interactionState ) ;
447
+ }
448
+ interactionState . shouldCancelClick = true ;
449
449
gestureState . x0 = currentCentroidX ( event . touchHistory ) ;
450
450
gestureState . y0 = currentCentroidY ( event . touchHistory ) ;
451
451
gestureState . dx = 0 ;
@@ -475,6 +475,7 @@ const PanResponder = {
475
475
event ,
476
476
gestureState ,
477
477
) ;
478
+ setInteractionTimeout ( interactionState ) ;
478
479
PanResponder . _initializeGestureState ( gestureState ) ;
479
480
} ,
480
481
@@ -488,14 +489,6 @@ const PanResponder = {
488
489
489
490
onResponderMove ( event : PressEvent ) : void {
490
491
const touchHistory = event . touchHistory ;
491
- // Guard against the dispatch of two touch moves when there are two
492
- // simultaneously changed touches.
493
- if (
494
- gestureState . _accountsForMovesUpTo ===
495
- touchHistory . mostRecentTimeStamp
496
- ) {
497
- return ;
498
- }
499
492
// Filter out any touch moves past the first one - we would have
500
493
// already processed multi-touch geometry during the first event.
501
494
PanResponder . _updateGestureStateOnMove ( gestureState , touchHistory ) ;
@@ -522,6 +515,7 @@ const PanResponder = {
522
515
event ,
523
516
gestureState ,
524
517
) ;
518
+ setInteractionTimeout ( interactionState ) ;
525
519
PanResponder . _initializeGestureState ( gestureState ) ;
526
520
} ,
527
521
@@ -530,7 +524,19 @@ const PanResponder = {
530
524
? true
531
525
: config . onPanResponderTerminationRequest ( event , gestureState ) ;
532
526
} ,
527
+
528
+ // We do not want to trigger 'click' activated gestures or native behaviors
529
+ // on any pan target that is under a mouse cursor when it is released.
530
+ // Browsers will natively cancel 'click' events on a target if a non-mouse
531
+ // active pointer moves.
532
+ onClickCapture : ( event : any ) : void => {
533
+ if ( interactionState . shouldCancelClick === true ) {
534
+ event . stopPropagation ( ) ;
535
+ event . preventDefault ( ) ;
536
+ }
537
+ } ,
533
538
} ;
539
+
534
540
return {
535
541
panHandlers ,
536
542
getInteractionHandle ( ) : ?number {
@@ -541,7 +547,7 @@ const PanResponder = {
541
547
} ;
542
548
543
549
function clearInteractionHandle (
544
- interactionState : { handle : ? number } ,
550
+ interactionState : InteractionState ,
545
551
callback : ?( ActiveCallback | PassiveCallback ) ,
546
552
event : PressEvent ,
547
553
gestureState : GestureState ,
@@ -555,6 +561,16 @@ function clearInteractionHandle(
555
561
}
556
562
}
557
563
564
+ function clearInteractionTimeout ( interactionState : InteractionState ) {
565
+ clearTimeout ( interactionState . timeout ) ;
566
+ }
567
+
568
+ function setInteractionTimeout ( interactionState : InteractionState ) {
569
+ interactionState . timeout = setTimeout ( ( ) => {
570
+ interactionState . shouldCancelClick = false ;
571
+ } , 250 ) ;
572
+ }
573
+
558
574
export type PanResponderInstance = $Call <
559
575
$PropertyType < typeof PanResponder , 'create' > ,
560
576
PanResponderConfig ,
0 commit comments