From 25e2887a64b99a5bd5c145ef62ecc98c71d3deb6 Mon Sep 17 00:00:00 2001 From: Yosuke Saito Date: Wed, 21 Nov 2018 14:32:49 -0800 Subject: [PATCH] Flow strict ScrollResponder (#22181) Summary: Related to #22100 Enhance Flow types for Libraries/Components/ScrollResponder.js Pull Request resolved: https://github.com/facebook/react-native/pull/22181 Reviewed By: TheSavior Differential Revision: D13032699 Pulled By: RSNara fbshipit-source-id: ca0ce178a96008a71016d033ee1154ad807d6599 --- Libraries/Components/ScrollResponder.js | 58 +++++++++++++------------ 1 file changed, 31 insertions(+), 27 deletions(-) diff --git a/Libraries/Components/ScrollResponder.js b/Libraries/Components/ScrollResponder.js index 42079dec32abfa..46fe2a7f566330 100644 --- a/Libraries/Components/ScrollResponder.js +++ b/Libraries/Components/ScrollResponder.js @@ -24,6 +24,8 @@ const warning = require('fbjs/lib/warning'); const {ScrollViewManager} = require('NativeModules'); +import type {PressEvent, ScrollEvent} from 'CoreEventTypes'; +import type {KeyboardEvent} from 'Keyboard'; import type EmitterSubscription from 'EmitterSubscription'; /** @@ -113,7 +115,6 @@ type State = { observedScrollSinceBecomingResponder: boolean, becameResponderWhileAnimating: boolean, }; -type Event = Object; const ScrollResponderMixin = { _subscriptionKeyboardWillShow: (null: ?EmitterSubscription), @@ -168,7 +169,9 @@ const ScrollResponderMixin = { * true. * */ - scrollResponderHandleStartShouldSetResponder: function(e: Event): boolean { + scrollResponderHandleStartShouldSetResponder: function( + e: PressEvent, + ): boolean { const currentlyFocusedTextInput = TextInputState.currentlyFocusedField(); if ( @@ -193,7 +196,7 @@ const ScrollResponderMixin = { * Invoke this from an `onStartShouldSetResponderCapture` event. */ scrollResponderHandleStartShouldSetResponderCapture: function( - e: Event, + e: PressEvent, ): boolean { // The scroll view should receive taps instead of its descendants if: // * it is already animating/decelerating @@ -212,6 +215,7 @@ const ScrollResponderMixin = { if ( keyboardNeverPersistTaps && currentlyFocusedTextInput != null && + e.target && !TextInputState.isTextInput(e.target) ) { return true; @@ -254,9 +258,9 @@ const ScrollResponderMixin = { /** * Invoke this from an `onTouchEnd` event. * - * @param {SyntheticEvent} e Event. + * @param {PressEvent} e Event. */ - scrollResponderHandleTouchEnd: function(e: Event) { + scrollResponderHandleTouchEnd: function(e: PressEvent) { const nativeEvent = e.nativeEvent; this.state.isTouching = nativeEvent.touches.length !== 0; this.props.onTouchEnd && this.props.onTouchEnd(e); @@ -265,9 +269,9 @@ const ScrollResponderMixin = { /** * Invoke this from an `onTouchCancel` event. * - * @param {SyntheticEvent} e Event. + * @param {PressEvent} e Event. */ - scrollResponderHandleTouchCancel: function(e: Event) { + scrollResponderHandleTouchCancel: function(e: PressEvent) { this.state.isTouching = false; this.props.onTouchCancel && this.props.onTouchCancel(e); }, @@ -275,7 +279,7 @@ const ScrollResponderMixin = { /** * Invoke this from an `onResponderRelease` event. */ - scrollResponderHandleResponderRelease: function(e: Event) { + scrollResponderHandleResponderRelease: function(e: PressEvent) { this.props.onResponderRelease && this.props.onResponderRelease(e); // By default scroll views will unfocus a textField @@ -295,7 +299,7 @@ const ScrollResponderMixin = { } }, - scrollResponderHandleScroll: function(e: Event) { + scrollResponderHandleScroll: function(e: ScrollEvent) { this.state.observedScrollSinceBecomingResponder = true; this.props.onScroll && this.props.onScroll(e); }, @@ -303,7 +307,7 @@ const ScrollResponderMixin = { /** * Invoke this from an `onResponderGrant` event. */ - scrollResponderHandleResponderGrant: function(e: Event) { + scrollResponderHandleResponderGrant: function(e: ScrollEvent) { this.state.observedScrollSinceBecomingResponder = false; this.props.onResponderGrant && this.props.onResponderGrant(e); this.state.becameResponderWhileAnimating = this.scrollResponderIsAnimating(); @@ -316,7 +320,7 @@ const ScrollResponderMixin = { * * Invoke this from an `onScrollBeginDrag` event. */ - scrollResponderHandleScrollBeginDrag: function(e: Event) { + scrollResponderHandleScrollBeginDrag: function(e: ScrollEvent) { FrameRateLogger.beginScroll(); // TODO: track all scrolls after implementing onScrollEndAnimation this.props.onScrollBeginDrag && this.props.onScrollBeginDrag(e); }, @@ -324,7 +328,7 @@ const ScrollResponderMixin = { /** * Invoke this from an `onScrollEndDrag` event. */ - scrollResponderHandleScrollEndDrag: function(e: Event) { + scrollResponderHandleScrollEndDrag: function(e: ScrollEvent) { const {velocity} = e.nativeEvent; // - If we are animating, then this is a "drag" that is stopping the scrollview and momentum end // will fire. @@ -343,7 +347,7 @@ const ScrollResponderMixin = { /** * Invoke this from an `onMomentumScrollBegin` event. */ - scrollResponderHandleMomentumScrollBegin: function(e: Event) { + scrollResponderHandleMomentumScrollBegin: function(e: ScrollEvent) { this.state.lastMomentumScrollBeginTime = performanceNow(); this.props.onMomentumScrollBegin && this.props.onMomentumScrollBegin(e); }, @@ -351,7 +355,7 @@ const ScrollResponderMixin = { /** * Invoke this from an `onMomentumScrollEnd` event. */ - scrollResponderHandleMomentumScrollEnd: function(e: Event) { + scrollResponderHandleMomentumScrollEnd: function(e: ScrollEvent) { FrameRateLogger.endScroll(); this.state.lastMomentumScrollEndTime = performanceNow(); this.props.onMomentumScrollEnd && this.props.onMomentumScrollEnd(e); @@ -366,9 +370,9 @@ const ScrollResponderMixin = { * responder). The `onResponderReject` won't fire in that case - it only * fires when a *current* responder rejects our request. * - * @param {SyntheticEvent} e Touch Start event. + * @param {PressEvent} e Touch Start event. */ - scrollResponderHandleTouchStart: function(e: Event) { + scrollResponderHandleTouchStart: function(e: PressEvent) { this.state.isTouching = true; this.props.onTouchStart && this.props.onTouchStart(e); }, @@ -382,9 +386,9 @@ const ScrollResponderMixin = { * responder). The `onResponderReject` won't fire in that case - it only * fires when a *current* responder rejects our request. * - * @param {SyntheticEvent} e Touch Start event. + * @param {PressEvent} e Touch Start event. */ - scrollResponderHandleTouchMove: function(e: Event) { + scrollResponderHandleTouchMove: function(e: PressEvent) { this.props.onTouchMove && this.props.onTouchMove(e); }, @@ -409,7 +413,7 @@ const ScrollResponderMixin = { * Components can pass what node to use by defining a `getScrollableNode` * function otherwise `this` is used. */ - scrollResponderGetScrollableNode: function(): any { + scrollResponderGetScrollableNode: function(): ?number { return this.getScrollableNode ? this.getScrollableNode() : ReactNative.findNodeHandle(this); @@ -527,14 +531,14 @@ const ScrollResponderMixin = { * This method should be used as the callback to onFocus in a TextInputs' * parent view. Note that any module using this mixin needs to return * the parent view's ref in getScrollViewRef() in order to use this method. - * @param {any} nodeHandle The TextInput node handle + * @param {number} nodeHandle The TextInput node handle * @param {number} additionalOffset The scroll view's bottom "contentInset". * Default is 0. * @param {bool} preventNegativeScrolling Whether to allow pulling the content * down to make it meet the keyboard's top. Default is false. */ scrollResponderScrollNativeHandleToKeyboard: function( - nodeHandle: any, + nodeHandle: number, additionalOffset?: number, preventNegativeScrollOffset?: boolean, ) { @@ -584,8 +588,8 @@ const ScrollResponderMixin = { this.preventNegativeScrollOffset = false; }, - scrollResponderTextInputFocusError: function(e: Event) { - console.error('Error measuring text field: ', e); + scrollResponderTextInputFocusError: function(msg: string) { + console.error('Error measuring text field: ', msg); }, /** @@ -667,17 +671,17 @@ const ScrollResponderMixin = { * relevant to you. (For example, only if you receive these callbacks after * you had explicitly focused a node etc). */ - scrollResponderKeyboardWillShow: function(e: Event) { + scrollResponderKeyboardWillShow: function(e: KeyboardEvent) { this.keyboardWillOpenTo = e; this.props.onKeyboardWillShow && this.props.onKeyboardWillShow(e); }, - scrollResponderKeyboardWillHide: function(e: Event) { + scrollResponderKeyboardWillHide: function(e: KeyboardEvent) { this.keyboardWillOpenTo = null; this.props.onKeyboardWillHide && this.props.onKeyboardWillHide(e); }, - scrollResponderKeyboardDidShow: function(e: Event) { + scrollResponderKeyboardDidShow: function(e: KeyboardEvent) { // TODO(7693961): The event for DidShow is not available on iOS yet. // Use the one from WillShow and do not assign. if (e) { @@ -686,7 +690,7 @@ const ScrollResponderMixin = { this.props.onKeyboardDidShow && this.props.onKeyboardDidShow(e); }, - scrollResponderKeyboardDidHide: function(e: Event) { + scrollResponderKeyboardDidHide: function(e: KeyboardEvent) { this.keyboardWillOpenTo = null; this.props.onKeyboardDidHide && this.props.onKeyboardDidHide(e); },