From b1276622791d5dbe4199bb075f473908c3e62b31 Mon Sep 17 00:00:00 2001 From: Eli White Date: Sat, 12 May 2018 10:25:18 -0700 Subject: [PATCH] Flow Type ScrollView Reviewed By: yungsters Differential Revision: D7981073 fbshipit-source-id: 38c100f37e46683da1e34b335d476e706baae238 --- .../ScrollView/InternalScrollViewType.js | 46 +++++++ Libraries/Components/ScrollView/ScrollView.js | 114 +++++++++++++++++- Libraries/StyleSheet/EdgeInsetsPropType.js | 12 +- Libraries/StyleSheet/PointPropType.js | 5 + 4 files changed, 165 insertions(+), 12 deletions(-) create mode 100644 Libraries/Components/ScrollView/InternalScrollViewType.js diff --git a/Libraries/Components/ScrollView/InternalScrollViewType.js b/Libraries/Components/ScrollView/InternalScrollViewType.js new file mode 100644 index 00000000000000..a97ca9f4364127 --- /dev/null +++ b/Libraries/Components/ScrollView/InternalScrollViewType.js @@ -0,0 +1,46 @@ +/** + * Copyright (c) 2015-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @format + * @flow + */ + +const React = require('React'); + +// This class is purely a facsimile of ScrollView so that we can +// properly type it with Flow before migrating ScrollView off of +// createReactClass. If there are things missing here that are in +// ScrollView, that is unintentional. +class InternalScrollViewType extends React.Component { + scrollTo( + y?: number | {x?: number, y?: number, animated?: boolean}, + x?: number, + animated?: boolean, + ) {} + + flashScrollIndicators() {} + scrollToEnd(options?: {animated?: boolean}) {} + scrollWithoutAnimationTo(y: number = 0, x: number = 0) {} + setNativeProps(props: Object) {} + + getScrollResponder(): any {} + getScrollableNode(): any {} + getInnerViewNode(): any {} + + scrollResponderScrollNativeHandleToKeyboard( + nodeHandle: any, + additionalOffset?: number, + preventNegativeScrollOffset?: boolean, + ) {} + + scrollResponderScrollTo( + x?: number | {x?: number, y?: number, animated?: boolean}, + y?: number, + animated?: boolean, + ) {} +} + +module.exports = InternalScrollViewType; diff --git a/Libraries/Components/ScrollView/ScrollView.js b/Libraries/Components/ScrollView/ScrollView.js index 682809a1ad465d..3038f4cfff033b 100644 --- a/Libraries/Components/ScrollView/ScrollView.js +++ b/Libraries/Components/ScrollView/ScrollView.js @@ -25,6 +25,7 @@ const StyleSheetPropType = require('StyleSheetPropType'); const View = require('View'); const ViewPropTypes = require('ViewPropTypes'); const ViewStylePropTypes = require('ViewStylePropTypes'); +const InternalScrollViewType = require('InternalScrollViewType'); const createReactClass = require('create-react-class'); const dismissKeyboard = require('dismissKeyboard'); @@ -38,7 +39,104 @@ const requireNativeComponent = require('requireNativeComponent'); const warning = require('fbjs/lib/warning'); const resolveAssetSource = require('resolveAssetSource'); +import type {PressEvent} from 'CoreEventTypes'; +import type {EdgeInsetsProp} from 'EdgeInsetsPropType'; import type {NativeMethodsMixinType} from 'ReactNativeTypes'; +import type {ViewStyleProp} from 'StyleSheet'; +import type {ViewProps} from 'ViewPropTypes'; +import type {PointProp} from 'PointPropType'; + +import type {ColorValue} from 'StyleSheetTypes'; + +type TouchableProps = $ReadOnly<{| + onTouchStart?: (event: PressEvent) => void, + onTouchMove?: (event: PressEvent) => void, + onTouchEnd?: (event: PressEvent) => void, + onTouchCancel?: (event: PressEvent) => void, + onTouchEndCapture?: (event: PressEvent) => void, +|}>; + +type IOSProps = $ReadOnly<{| + automaticallyAdjustContentInsets?: ?boolean, + contentInset?: ?EdgeInsetsProp, + contentOffset?: ?PointProp, + bounces?: ?boolean, + bouncesZoom?: ?boolean, + alwaysBounceHorizontal?: ?boolean, + alwaysBounceVertical?: ?boolean, + centerContent?: ?boolean, + decelerationRate?: ?('fast' | 'normal' | number), + indicatorStyle?: ?('default' | 'black' | 'white'), + directionalLockEnabled?: ?boolean, + canCancelContentTouches?: ?boolean, + maintainVisibleContentPosition?: ?$ReadOnly<{| + minIndexForVisible: number, + autoscrollToTopThreshold?: ?number, + |}>, + maximumZoomScale?: ?number, + minimumZoomScale?: ?number, + pinchGestureEnabled?: ?boolean, + scrollEventThrottle?: ?number, + scrollIndicatorInsets?: ?EdgeInsetsProp, + scrollsToTop?: ?boolean, + showsHorizontalScrollIndicator?: ?boolean, + snapToAlignment?: ?('start' | 'center' | 'end'), + zoomScale?: ?number, + contentInsetAdjustmentBehavior?: ?( + | 'automatic' + | 'scrollableAxes' + | 'never' + | 'always' + ), + DEPRECATED_sendUpdatedChildFrames?: ?boolean, +|}>; + +type AndroidProps = $ReadOnly<{| + nestedScrollEnabled?: ?boolean, + endFillColor?: ?ColorValue, + scrollPerfTag?: ?string, + overScrollMode?: ?('auto' | 'always' | 'never'), +|}>; + +type VRProps = $ReadOnly<{| + scrollBarThumbImage?: ?($ReadOnly<{||}> | number), +|}>; + +type Props = $ReadOnly<{| + ...ViewProps, + ...TouchableProps, + ...IOSProps, + ...AndroidProps, + ...VRProps, + + contentContainerStyle?: ?ViewStyleProp, + horizontal?: ?boolean, + invertStickyHeaders?: ?boolean, + keyboardDismissMode?: ?( + | 'none' // default + | 'on-drag' // cross-platform + | 'interactive' + ), // ios only + // $FlowFixMe Issues found when typing ScrollView + keyboardShouldPersistTaps?: ?('always' | 'never' | 'handled' | false | true), + onMomentumScrollBegin?: ?Function, + onMomentumScrollEnd?: ?Function, + + onScroll?: ?Function, + onScrollBeginDrag?: ?Function, + onScrollEndDrag?: ?Function, + onContentSizeChange?: ?Function, + onKeyboardDidShow?: (event: PressEvent) => void, + pagingEnabled?: ?boolean, + scrollEnabled?: ?boolean, + showsVerticalScrollIndicator?: ?boolean, + stickyHeaderIndices?: ?$ReadOnlyArray, + snapToInterval?: ?number, + removeClippedSubviews?: ?boolean, + refreshControl?: ?React.Element, + style?: ?ViewStyleProp, + children?: React.Node, +|}>; /** * Component that wraps platform ScrollView while providing @@ -75,7 +173,6 @@ import type {NativeMethodsMixinType} from 'ReactNativeTypes'; * multiple columns, infinite scroll loading, or any number of other features it * supports out of the box. */ -// $FlowFixMe(>=0.41.0) const ScrollView = createReactClass({ displayName: 'ScrollView', propTypes: { @@ -806,8 +903,8 @@ const ScrollView = createReactClass({ // $FlowFixMe Invalid prop usage hasStickyHeaders && React.Children.toArray(this.props.children); const children = hasStickyHeaders - // $FlowFixMe Invalid prop usage - ? childArray.map((child, index) => { + ? // $FlowFixMe Invalid prop usage + childArray.map((child, index) => { // $FlowFixMe Invalid prop usage const indexOfIndex = child ? stickyHeaderIndices.indexOf(index) : -1; if (indexOfIndex > -1) { @@ -834,8 +931,8 @@ const ScrollView = createReactClass({ return child; } }) - // $FlowFixMe Invalid prop usage - : this.props.children; + : // $FlowFixMe Invalid prop usage + this.props.children; const contentContainer = ( , +>); + const styles = StyleSheet.create({ baseVertical: { flexGrow: 1, @@ -1028,4 +1130,4 @@ if (Platform.OS === 'android') { RCTScrollContentView = requireNativeComponent('RCTScrollContentView', View); } -module.exports = ScrollView; +module.exports = TypedScrollView; diff --git a/Libraries/StyleSheet/EdgeInsetsPropType.js b/Libraries/StyleSheet/EdgeInsetsPropType.js index 8f6a594c368ba8..10a6bf6104eb6e 100644 --- a/Libraries/StyleSheet/EdgeInsetsPropType.js +++ b/Libraries/StyleSheet/EdgeInsetsPropType.js @@ -19,11 +19,11 @@ const EdgeInsetsPropType = PropTypes.shape({ right: PropTypes.number, }); -export type EdgeInsetsProp = {| - +top: number, - +left: number, - +bottom: number, - +right: number, -|}; +export type EdgeInsetsProp = $ReadOnly<{| + top?: ?number, + left?: ?number, + bottom?: ?number, + right?: ?number, +|}>; module.exports = EdgeInsetsPropType; diff --git a/Libraries/StyleSheet/PointPropType.js b/Libraries/StyleSheet/PointPropType.js index 3be09b1100618e..008c675048dabf 100644 --- a/Libraries/StyleSheet/PointPropType.js +++ b/Libraries/StyleSheet/PointPropType.js @@ -17,4 +17,9 @@ const PointPropType = PropTypes.shape({ y: PropTypes.number, }); +export type PointProp = $ReadOnly<{ + x: number, + y: number, +}>; + module.exports = PointPropType;