@@ -188,6 +188,8 @@ type ActiveCallback = (
188188 gestureState : GestureState ,
189189) => boolean ;
190190
191+ type InteractionState = { handle : ?number , shouldCancelClick : boolean , timeout : ?TimeoutID } ;
192+
191193type PassiveCallback = ( event : PressEvent , gestureState : GestureState ) => mixed ;
192194
193195type PanResponderConfig = $ReadOnly < { |
@@ -384,9 +386,12 @@ const PanResponder = {
384386 * are the responder.
385387 */
386388 create ( config : PanResponderConfig ) {
387- const interactionState = {
388- handle : ( null : ?number ) ,
389+ const interactionState : InteractionState = {
390+ handle : null ,
391+ shouldCancelClick : false ,
392+ timeout : null ,
389393 } ;
394+
390395 const gestureState : GestureState = {
391396 // Useful for debugging
392397 stateID : Math . random ( ) ,
@@ -427,15 +432,6 @@ const PanResponder = {
427432
428433 onMoveShouldSetResponderCapture ( event : PressEvent ) : boolean {
429434 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- }
439435 PanResponder . _updateGestureStateOnMove ( gestureState , touchHistory ) ;
440436 return config . onMoveShouldSetPanResponderCapture
441437 ? config . onMoveShouldSetPanResponderCapture ( event , gestureState )
@@ -446,6 +442,10 @@ const PanResponder = {
446442 if ( ! interactionState . handle ) {
447443 interactionState . handle = InteractionManager . createInteractionHandle ( ) ;
448444 }
445+ if ( interactionState . timeout ) {
446+ clearInteractionTimeout ( interactionState ) ;
447+ }
448+ interactionState . shouldCancelClick = true ;
449449 gestureState . x0 = currentCentroidX ( event . touchHistory ) ;
450450 gestureState . y0 = currentCentroidY ( event . touchHistory ) ;
451451 gestureState . dx = 0 ;
@@ -475,6 +475,7 @@ const PanResponder = {
475475 event ,
476476 gestureState ,
477477 ) ;
478+ setInteractionTimeout ( interactionState ) ;
478479 PanResponder . _initializeGestureState ( gestureState ) ;
479480 } ,
480481
@@ -488,14 +489,6 @@ const PanResponder = {
488489
489490 onResponderMove ( event : PressEvent ) : void {
490491 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- }
499492 // Filter out any touch moves past the first one - we would have
500493 // already processed multi-touch geometry during the first event.
501494 PanResponder . _updateGestureStateOnMove ( gestureState , touchHistory ) ;
@@ -522,6 +515,7 @@ const PanResponder = {
522515 event ,
523516 gestureState ,
524517 ) ;
518+ setInteractionTimeout ( interactionState ) ;
525519 PanResponder . _initializeGestureState ( gestureState ) ;
526520 } ,
527521
@@ -530,7 +524,19 @@ const PanResponder = {
530524 ? true
531525 : config . onPanResponderTerminationRequest ( event , gestureState ) ;
532526 } ,
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+ } ,
533538 } ;
539+
534540 return {
535541 panHandlers ,
536542 getInteractionHandle ( ) : ?number {
@@ -541,7 +547,7 @@ const PanResponder = {
541547} ;
542548
543549function clearInteractionHandle (
544- interactionState : { handle : ? number } ,
550+ interactionState : InteractionState ,
545551 callback : ?( ActiveCallback | PassiveCallback ) ,
546552 event : PressEvent ,
547553 gestureState : GestureState ,
@@ -555,6 +561,16 @@ function clearInteractionHandle(
555561 }
556562}
557563
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+
558574export type PanResponderInstance = $Call <
559575 $PropertyType < typeof PanResponder , 'create' > ,
560576 PanResponderConfig ,
0 commit comments