Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[flow-strict] Flow strict ScrollView; get rid of InternalScrollViewType #22301

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
46 changes: 0 additions & 46 deletions Libraries/Components/ScrollView/InternalScrollViewType.js

This file was deleted.

89 changes: 46 additions & 43 deletions Libraries/Components/ScrollView/ScrollView.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* LICENSE file in the root directory of this source tree.
*
* @format
* @flow
* @flow strict-local
*/

'use strict';
Expand All @@ -18,7 +18,6 @@ const ScrollResponder = require('ScrollResponder');
const ScrollViewStickyHeader = require('ScrollViewStickyHeader');
const StyleSheet = require('StyleSheet');
const View = require('View');
const InternalScrollViewType = require('InternalScrollViewType');

const dismissKeyboard = require('dismissKeyboard');
const flattenStyle = require('flattenStyle');
Expand All @@ -27,7 +26,7 @@ const processDecelerationRate = require('processDecelerationRate');
const requireNativeComponent = require('requireNativeComponent');
const resolveAssetSource = require('resolveAssetSource');

import type {PressEvent} from 'CoreEventTypes';
import type {PressEvent, ScrollEvent, LayoutEvent} from 'CoreEventTypes';
import type {EdgeInsetsProp} from 'EdgeInsetsPropType';
import type {NativeMethodsMixinType} from 'ReactNativeTypes';
import type {ViewStyleProp} from 'StyleSheet';
Expand Down Expand Up @@ -220,7 +219,7 @@ type IOSProps = $ReadOnly<{|
* Fires when the scroll view scrolls to top after the status bar has been tapped
* @platform ios
*/
onScrollToTop?: ?Function,
onScrollToTop?: (event: ScrollEvent) => void,
/**
* When true, shows a horizontal scroll indicator.
* The default value is true.
Expand Down Expand Up @@ -403,33 +402,30 @@ export type Props = $ReadOnly<{|
* - `false`, deprecated, use 'never' instead
* - `true`, deprecated, use 'always' instead
*/
/* $FlowFixMe(>=0.92.0 site=react_native_fb) This comment suppresses an error
* found when Flow v0.92 was deployed. To see the error, delete this comment
* and run Flow. */
keyboardShouldPersistTaps?: ?('always' | 'never' | 'handled' | false | true),
/**
* Called when the momentum scroll starts (scroll which occurs as the ScrollView glides to a stop).
*/
onMomentumScrollBegin?: ?Function,
onMomentumScrollBegin?: (event: ScrollEvent) => void,
/**
* Called when the momentum scroll ends (scroll which occurs as the ScrollView glides to a stop).
*/
onMomentumScrollEnd?: ?Function,
onMomentumScrollEnd?: (event: ScrollEvent) => void,

/**
* Fires at most once per frame during scrolling. The frequency of the
* events can be controlled using the `scrollEventThrottle` prop.
*/
onScroll?: ?Function,
onScroll?: (event: ScrollEvent) => void,
/**
* Called when the user begins to drag the scroll view.
*/
onScrollBeginDrag?: ?Function,
onScrollBeginDrag?: (event: ScrollEvent) => void,
/**
* Called when the user stops dragging the scroll view and it either stops
* or begins to glide.
*/
onScrollEndDrag?: ?Function,
onScrollEndDrag?: (event: ScrollEvent) => void,
/**
* Called when scrollable content view of the ScrollView changes.
*
Expand All @@ -439,7 +435,7 @@ export type Props = $ReadOnly<{|
* It's implemented using onLayout handler attached to the content container
* which this ScrollView renders.
*/
onContentSizeChange?: ?Function,
onContentSizeChange?: (contentWidth: number, contentHeight: number) => void,
onKeyboardDidShow?: (event: PressEvent) => void,
/**
* When true, the scroll view stops on multiples of the scroll view's size
Expand Down Expand Up @@ -518,6 +514,7 @@ export type Props = $ReadOnly<{|
*
* See [RefreshControl](docs/refreshcontrol.html).
*/
// $FlowFixMe - how to handle generic type without existential opereator?
refreshControl?: ?React.Element<any>,
children?: React.Node,
|}>;
Expand Down Expand Up @@ -591,8 +588,8 @@ class ScrollView extends React.Component<Props, State> {
*/
_scrollResponder: typeof ScrollResponder.Mixin = createScrollResponder(this);

constructor(...args) {
super(...args);
constructor(props: Props) {
super(props);

/**
* Part 2: Removing ScrollResponder.Mixin
Expand All @@ -610,6 +607,7 @@ class ScrollView extends React.Component<Props, State> {
typeof ScrollResponder.Mixin[key] === 'function' &&
key.startsWith('scrollResponder')
) {
// $FlowFixMe - dynamically adding properties to a class
(this: any)[key] = ScrollResponder.Mixin[key].bind(this);
}
}
Expand All @@ -623,6 +621,7 @@ class ScrollView extends React.Component<Props, State> {
Object.keys(ScrollResponder.Mixin)
.filter(key => typeof ScrollResponder.Mixin[key] !== 'function')
.forEach(key => {
// $FlowFixMe - dynamically adding properties to a class
(this: any)[key] = ScrollResponder.Mixin[key];
});
}
Expand Down Expand Up @@ -666,7 +665,7 @@ class ScrollView extends React.Component<Props, State> {
}
}

setNativeProps(props: Object) {
setNativeProps(props: {[key: string]: mixed}) {
this._scrollViewRef && this._scrollViewRef.setNativeProps(props);
}

Expand All @@ -680,17 +679,18 @@ class ScrollView extends React.Component<Props, State> {
...typeof ScrollView,
...typeof ScrollResponder.Mixin,
} {
// $FlowFixMe - overriding type to include ScrollResponder.Mixin
return ((this: any): {
...typeof ScrollView,
...typeof ScrollResponder.Mixin,
});
}

getScrollableNode(): any {
getScrollableNode(): ?number {
return ReactNative.findNodeHandle(this._scrollViewRef);
}

getInnerViewNode(): any {
getInnerViewNode(): ?number {
return ReactNative.findNodeHandle(this._innerViewRef);
}

Expand All @@ -706,17 +706,23 @@ class ScrollView extends React.Component<Props, State> {
* This is deprecated due to ambiguity (y before x), and SHOULD NOT BE USED.
*/
scrollTo(
y?: number | {x?: number, y?: number, animated?: boolean},
x?: number,
animated?: boolean,
options?: {x?: number, y?: number, animated?: boolean} | number,
deprecatedX?: number,
deprecatedAnimated?: boolean,
) {
if (typeof y === 'number') {
let x, y, animated;
if (typeof options === 'number') {
console.warn(
'`scrollTo(y, x, animated)` is deprecated. Use `scrollTo({x: 5, y: 5, ' +
'animated: true})` instead.',
);
} else {
({x, y, animated} = y || {});
y = options;
x = deprecatedX;
animated = deprecatedAnimated;
} else if (options) {
y = options.y;
x = options.x;
animated = options.animated;
}
this._scrollResponder.scrollResponderScrollTo({
x: x || 0,
Expand Down Expand Up @@ -813,7 +819,7 @@ class ScrollView extends React.Component<Props, State> {
}
}

_handleScroll = (e: Object) => {
_handleScroll = (e: ScrollEvent) => {
if (__DEV__) {
if (
this.props.onScroll &&
Expand All @@ -840,16 +846,16 @@ class ScrollView extends React.Component<Props, State> {
this._scrollResponder.scrollResponderHandleScroll(e);
};

_handleLayout = (e: Object) => {
if (this.props.invertStickyHeaders) {
_handleLayout = (e: LayoutEvent) => {
if (this.props.invertStickyHeaders === true) {
this.setState({layoutHeight: e.nativeEvent.layout.height});
}
if (this.props.onLayout) {
this.props.onLayout(e);
}
};

_handleContentOnLayout = (e: Object) => {
_handleContentOnLayout = (e: LayoutEvent) => {
const {width, height} = e.nativeEvent.layout;
this.props.onContentSizeChange &&
this.props.onContentSizeChange(width, height);
Expand All @@ -869,7 +875,7 @@ class ScrollView extends React.Component<Props, State> {
let ScrollViewClass;
let ScrollContentContainerViewClass;
if (Platform.OS === 'android') {
if (this.props.horizontal) {
if (this.props.horizontal === true) {
ScrollViewClass = AndroidHorizontalScrollView;
ScrollContentContainerViewClass = AndroidHorizontalScrollContentView;
} else {
Expand All @@ -892,10 +898,10 @@ class ScrollView extends React.Component<Props, State> {
);

const contentContainerStyle = [
this.props.horizontal && styles.contentContainerHorizontal,
this.props.horizontal === true && styles.contentContainerHorizontal,
this.props.contentContainerStyle,
];
if (__DEV__ && this.props.style) {
if (__DEV__ && this.props.style !== undefined) {
const style = flattenStyle(this.props.style);
const childLayoutProps = ['alignItems', 'justifyContent'].filter(
prop => style && style[prop] !== undefined,
Expand Down Expand Up @@ -947,7 +953,7 @@ class ScrollView extends React.Component<Props, State> {
}

const hasStickyHeaders =
stickyHeaderIndices && stickyHeaderIndices.length > 0;
Array.isArray(stickyHeaderIndices) && stickyHeaderIndices.length > 0;

const contentContainer = (
<ScrollContentContainerViewClass
Expand Down Expand Up @@ -980,14 +986,15 @@ class ScrollView extends React.Component<Props, State> {
const DEPRECATED_sendUpdatedChildFrames = !!this.props
.DEPRECATED_sendUpdatedChildFrames;

const baseStyle = this.props.horizontal
? styles.baseHorizontal
: styles.baseVertical;
const baseStyle =
this.props.horizontal === true
? styles.baseHorizontal
: styles.baseVertical;
const props = {
...this.props,
alwaysBounceHorizontal,
alwaysBounceVertical,
style: ([baseStyle, this.props.style]: ?Array<any>),
style: [baseStyle, this.props.style],
// Override the onContentSizeChange from props, since this event can
// bubble up from TextInputs
onContentSizeChange: null,
Expand Down Expand Up @@ -1038,12 +1045,12 @@ class ScrollView extends React.Component<Props, State> {
pagingEnabled: Platform.select({
// on iOS, pagingEnabled must be set to false to have snapToInterval / snapToOffsets work
ios:
this.props.pagingEnabled &&
this.props.pagingEnabled === true &&
this.props.snapToInterval == null &&
this.props.snapToOffsets == null,
// on Android, pagingEnabled must be set to true to have snapToInterval / snapToOffsets work
android:
this.props.pagingEnabled ||
this.props.pagingEnabled === true ||
this.props.snapToInterval != null ||
this.props.snapToOffsets != null,
}),
Expand Down Expand Up @@ -1096,10 +1103,6 @@ class ScrollView extends React.Component<Props, State> {
}
}

const TypedScrollView = ((ScrollView: any): Class<
cpojer marked this conversation as resolved.
Show resolved Hide resolved
InternalScrollViewType<Props>,
>);

const styles = StyleSheet.create({
baseVertical: {
flexGrow: 1,
Expand All @@ -1118,4 +1121,4 @@ const styles = StyleSheet.create({
},
});

module.exports = TypedScrollView;
module.exports = ScrollView;
1 change: 1 addition & 0 deletions Libraries/Experimental/WindowedListView.js
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,7 @@ class WindowedListView extends React.Component<Props, State> {
return (
this._scrollRef &&
this._scrollRef.getScrollResponder &&
// $FlowFixMe - it actually returns ScrollView & ScrollResponder.Mixin
this._scrollRef.getScrollResponder()
);
}
Expand Down
2 changes: 1 addition & 1 deletion Libraries/Lists/ListView/ListView.js
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,7 @@ const ListView = createReactClass({
*
* See `ScrollView#scrollToEnd`.
*/
scrollToEnd: function(options?: ?{animated?: boolean}) {
scrollToEnd: function(options?: {animated?: boolean}) {
if (this._scrollComponent) {
if (this._scrollComponent.scrollToEnd) {
this._scrollComponent.scrollToEnd(options);
Expand Down
3 changes: 2 additions & 1 deletion Libraries/Types/CoreEventTypes.js
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,8 @@ export type ScrollEvent = SyntheticEvent<
y: number,
x: number,
|}>,
zoomScale: number,
zoomScale?: number,
responderIgnoreScroll?: boolean,
|}>,
>;

Expand Down