diff --git a/.circleci/config.yml b/.circleci/config.yml index 2cfbaf4f6a3958..1b75edce484827 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -211,27 +211,27 @@ aliases: mkdir -p ~/react-native/reports/junit/ - &build-objc-ios-test-app - name: Build Objective-C iOS Test App + name: Build iOS Test App command: ./scripts/objc-test-ios.sh - &run-objc-ios-tests - name: Objective-C iOS Test Suite + name: iOS Test Suite command: ./scripts/objc-test-ios.sh test - &build-objc-tvos-test-app - name: Build Objective-C tvOS Test App + name: Build tvOS Test App command: ./scripts/objc-test-tvos.sh - &run-objc-tvos-tests - name: Objective-C tvOS Test Suite + name: tvOS Test Suite command: ./scripts/objc-test-tvos.sh test - &run-objc-ios-e2e-tests - name: Objective-C iOS End-to-End Test Suite + name: iOS End-to-End Test Suite command: node ./scripts/run-ci-e2e-tests.js --ios --js --retries 3; - &run-objc-tvos-e2e-tests - name: Objective-C tvOS End-to-End Test Suite + name: tvOS End-to-End Test Suite command: node ./scripts/run-ci-e2e-tests.js --tvos --js --retries 3; defaults: &defaults @@ -292,8 +292,6 @@ jobs: - store_test_results: path: ~/react-native/reports/junit - - store_artifacts: - path: ~/react-native/reports/junit - store_artifacts: path: ~/react-native/yarn.lock @@ -308,8 +306,6 @@ jobs: - store_test_results: path: ~/react-native/reports/junit - - store_artifacts: - path: ~/react-native/reports/junit # Runs JavaScript tests on Node 6 test_javascript_node6_compatibility: @@ -328,83 +324,47 @@ jobs: - store_test_results: path: ~/react-native/reports/junit - - store_artifacts: - path: ~/react-native/reports/junit - - # Builds iOS test app - build_objc_ios_test_app: - <<: *macos_defaults - dependencies: - pre: - - xcrun instruments -w "iPhone 5s (11.1)" || true - steps: - - attach_workspace: - at: ~/react-native - - - run: *build-objc-ios-test-app # Runs unit tests on iOS devices - test_objc_ios: + test_ios: <<: *macos_defaults - dependencies: - pre: - - xcrun instruments -w "iPhone 5s (11.1)" || true steps: - attach_workspace: at: ~/react-native + - run: xcrun instruments -w "iPhone 5s (11.1)" || true + - run: brew install watchman - run: *run-objc-ios-tests - store_test_results: path: ~/react-native/reports/junit - - store_artifacts: - path: ~/react-native/reports/junit - - # Builds tvOS test app - build_objc_tvos_test_app: - <<: *macos_defaults - dependencies: - pre: - - xcrun instruments -w "Apple TV 1080p (11.1)" || true - steps: - - attach_workspace: - at: ~/react-native - - - run: *build-objc-tvos-test-app # Runs unit tests on tvOS devices - test_objc_tvos: + test_tvos: <<: *macos_defaults - dependencies: - pre: - - xcrun instruments -w "Apple TV 1080p (11.1)" || true steps: - attach_workspace: at: ~/react-native + - run: xcrun instruments -w "Apple TV 1080p (11.1)" || true + - run: brew install watchman - run: *run-objc-tvos-tests - store_test_results: path: ~/react-native/reports/junit - - store_artifacts: - path: ~/react-native/reports/junit # Runs end to end tests - test_objc_ios_e2e: + test_ios_e2e: <<: *macos_defaults - dependencies: - pre: - - xcrun instruments -w "iPhone 5s (11.1)" || true steps: - attach_workspace: at: ~/react-native + - run: xcrun instruments -w "iPhone 5s (11.1)" || true - run: *run-objc-ios-e2e-tests - store_test_results: path: ~/react-native/reports/junit - - store_artifacts: - path: ~/react-native/reports/junit # Checks podspec test_podspec: @@ -523,8 +483,6 @@ jobs: - run: *collect-android-test-results - store_test_results: path: ~/react-native/reports/junit - - store_artifacts: - path: ~/react-native/reports/junit # Analyze pull request and raise any lint/flow issues. @@ -604,18 +562,18 @@ workflows: requires: - checkout_code - # Build iOS & tvOS test apps - - build_objc_ios_test_app: + # Test iOS & tvOS + - test_ios: filters: *filter-ignore-gh-pages requires: - checkout_code - - build_objc_tvos_test_app: + - test_tvos: filters: *filter-ignore-gh-pages requires: - checkout_code # End-to-end tests - - test_objc_ios_e2e: + - test_ios_e2e: filters: *filter-ignore-gh-pages requires: - checkout_code @@ -657,15 +615,6 @@ workflows: # # The following were DISABLED because they have not run since # # the migration from Travis, and they have broken since then, - # # Test iOS & tvOS - # - test_objc_ios: - # filters: *filter-ignore-gh-pages - # requires: - # - checkout_code - # - test_objc_tvos: - # filters: *filter-ignore-gh-pages - # requires: - # - checkout_code # # CocoaPods # - test_podspec: # filters: *filter-ignore-gh-pages diff --git a/Libraries/Components/Touchable/TouchableOpacity.js b/Libraries/Components/Touchable/TouchableOpacity.js index abb77ac95a3854..cbffbb59784972 100644 --- a/Libraries/Components/Touchable/TouchableOpacity.js +++ b/Libraries/Components/Touchable/TouchableOpacity.js @@ -160,6 +160,12 @@ const TouchableOpacity = createReactClass({ ensurePositiveDelayProps(nextProps); }, + componentDidUpdate: function(prevProps, prevState) { + if (this.props.disabled !== prevProps.disabled) { + this._opacityInactive(250); + } + }, + /** * Animate the touchable to a new opacity. */ diff --git a/Libraries/LayoutAnimation/LayoutAnimation.js b/Libraries/LayoutAnimation/LayoutAnimation.js index fe4a2cc2b84328..f04feca9331afb 100644 --- a/Libraries/LayoutAnimation/LayoutAnimation.js +++ b/Libraries/LayoutAnimation/LayoutAnimation.js @@ -32,6 +32,8 @@ const Types = keyMirror(TypesEnum); const PropertiesEnum = { opacity: true, + scaleX: true, + scaleY: true, scaleXY: true, }; const Properties = keyMirror(PropertiesEnum); diff --git a/Libraries/Lists/VirtualizedList.js b/Libraries/Lists/VirtualizedList.js index f40b44e404c4f6..e6acee9e77c271 100644 --- a/Libraries/Lists/VirtualizedList.js +++ b/Libraries/Lists/VirtualizedList.js @@ -442,6 +442,7 @@ class VirtualizedList extends React.PureComponent { getScrollMetrics: PropTypes.func, horizontal: PropTypes.bool, getOutermostParentListRef: PropTypes.func, + getNestedChildState: PropTypes.func, registerAsNestedChild: PropTypes.func, unregisterAsNestedChild: PropTypes.func, }), @@ -452,6 +453,7 @@ class VirtualizedList extends React.PureComponent { getScrollMetrics: PropTypes.func, horizontal: PropTypes.bool, getOutermostParentListRef: PropTypes.func, + getNestedChildState: PropTypes.func, registerAsNestedChild: PropTypes.func, unregisterAsNestedChild: PropTypes.func, }), @@ -463,6 +465,7 @@ class VirtualizedList extends React.PureComponent { getScrollMetrics: this._getScrollMetrics, horizontal: this.props.horizontal, getOutermostParentListRef: this._getOutermostParentListRef, + getNestedChildState: this._getNestedChildState, registerAsNestedChild: this._registerAsNestedChild, unregisterAsNestedChild: this._unregisterAsNestedChild, }, @@ -492,6 +495,11 @@ class VirtualizedList extends React.PureComponent { } }; + _getNestedChildState = (key: string): ?ChildListState => { + const existingChildData = this._nestedChildLists.get(key); + return existingChildData && existingChildData.state; + }; + _registerAsNestedChild = (childList: { cellKey: string, key: string, @@ -518,8 +526,6 @@ class VirtualizedList extends React.PureComponent { if (this._hasInteracted) { childList.ref.recordInteraction(); } - - return existingChildData && existingChildData.state; }; _unregisterAsNestedChild = (childList: { @@ -577,11 +583,9 @@ class VirtualizedList extends React.PureComponent { }; if (this._isNestedWithSameOrientation()) { - const storedState = this.context.virtualizedList.registerAsNestedChild({ - cellKey: this._getCellKey(), - key: this.props.listKey || this._getCellKey(), - ref: this, - }); + const storedState = this.context.virtualizedList.getNestedChildState( + this.props.listKey || this._getCellKey(), + ); if (storedState) { initialState = storedState; this.state = storedState; @@ -592,6 +596,16 @@ class VirtualizedList extends React.PureComponent { this.state = initialState; } + componentDidMount() { + if (this._isNestedWithSameOrientation()) { + this.context.virtualizedList.registerAsNestedChild({ + cellKey: this._getCellKey(), + key: this.props.listKey || this._getCellKey(), + ref: this, + }); + } + } + componentWillUnmount() { if (this._isNestedWithSameOrientation()) { this.context.virtualizedList.unregisterAsNestedChild({ @@ -611,29 +625,17 @@ class VirtualizedList extends React.PureComponent { this._fillRateHelper.deactivateAndFlush(); } - UNSAFE_componentWillReceiveProps(newProps: Props) { + static getDerivedStateFromProps(newProps: Props, prevState: State) { const {data, extraData, getItemCount, maxToRenderPerBatch} = newProps; // first and last could be stale (e.g. if a new, shorter items props is passed in), so we make // sure we're rendering a reasonable range here. - this.setState({ + return { first: Math.max( 0, - Math.min( - this.state.first, - getItemCount(data) - 1 - maxToRenderPerBatch, - ), + Math.min(prevState.first, getItemCount(data) - 1 - maxToRenderPerBatch), ), - last: Math.max(0, Math.min(this.state.last, getItemCount(data) - 1)), - }); - if (data !== this.props.data || extraData !== this.props.extraData) { - this._hasDataChangedSinceEndReached = true; - - // clear the viewableIndices cache to also trigger - // the onViewableItemsChanged callback with the new data - this._viewabilityTuples.forEach(tuple => { - tuple.viewabilityHelper.resetViewableIndices(); - }); - } + last: Math.max(0, Math.min(prevState.last, getItemCount(data) - 1)), + }; } _pushCells( @@ -916,7 +918,17 @@ class VirtualizedList extends React.PureComponent { } } - componentDidUpdate() { + componentDidUpdate(prevProps: Props) { + const {data, extraData} = this.props; + if (data !== prevProps.data || extraData !== prevProps.extraData) { + this._hasDataChangedSinceEndReached = true; + + // clear the viewableIndices cache to also trigger + // the onViewableItemsChanged callback with the new data + this._viewabilityTuples.forEach(tuple => { + tuple.viewabilityHelper.resetViewableIndices(); + }); + } this._scheduleCellsToRenderUpdate(); } diff --git a/Libraries/StyleSheet/StyleSheet.js b/Libraries/StyleSheet/StyleSheet.js index 3971365c98e9c8..48f4418b8ed214 100644 --- a/Libraries/StyleSheet/StyleSheet.js +++ b/Libraries/StyleSheet/StyleSheet.js @@ -139,10 +139,10 @@ module.exports = { * PureComponent checks. */ compose(style1: ?StyleProp, style2: ?StyleProp): ?StyleProp { - if (style1 && style2) { + if (style1 != null && style2 != null) { return [style1, style2]; } else { - return style1 || style2; + return style1 != null ? style1 : style2; } }, diff --git a/Libraries/StyleSheet/StyleSheetTypes.js b/Libraries/StyleSheet/StyleSheetTypes.js index cfd0f50bba2ccf..0964a9446dbb3b 100644 --- a/Libraries/StyleSheet/StyleSheetTypes.js +++ b/Libraries/StyleSheet/StyleSheetTypes.js @@ -18,153 +18,155 @@ export opaque type StyleSheetStyle: number = number; export type ColorValue = null | string; export type DimensionValue = null | number | string | AnimatedNode; -export type LayoutStyle<+Dimension = DimensionValue> = { - +display?: 'none' | 'flex', - +width?: Dimension, - +height?: Dimension, - +bottom?: Dimension, - +end?: Dimension, - +left?: Dimension, - +right?: Dimension, - +start?: Dimension, - +top?: Dimension, - +minWidth?: Dimension, - +maxWidth?: Dimension, - +minHeight?: Dimension, - +maxHeight?: Dimension, - +margin?: Dimension, - +marginBottom?: Dimension, - +marginEnd?: Dimension, - +marginHorizontal?: Dimension, - +marginLeft?: Dimension, - +marginRight?: Dimension, - +marginStart?: Dimension, - +marginTop?: Dimension, - +marginVertical?: Dimension, - +padding?: Dimension, - +paddingBottom?: Dimension, - +paddingEnd?: Dimension, - +paddingHorizontal?: Dimension, - +paddingLeft?: Dimension, - +paddingRight?: Dimension, - +paddingStart?: Dimension, - +paddingTop?: Dimension, - +paddingVertical?: Dimension, - +borderWidth?: number, - +borderBottomWidth?: number, - +borderEndWidth?: number, - +borderLeftWidth?: number, - +borderRightWidth?: number, - +borderStartWidth?: number, - +borderTopWidth?: number, - +position?: 'absolute' | 'relative', - +flexDirection?: 'row' | 'row-reverse' | 'column' | 'column-reverse', - +flexWrap?: 'wrap' | 'nowrap', - +justifyContent?: +export type LayoutStyle = $ReadOnly<{| + display?: 'none' | 'flex', + width?: DimensionValue, + height?: DimensionValue, + bottom?: DimensionValue, + end?: DimensionValue, + left?: DimensionValue, + right?: DimensionValue, + start?: DimensionValue, + top?: DimensionValue, + minWidth?: DimensionValue, + maxWidth?: DimensionValue, + minHeight?: DimensionValue, + maxHeight?: DimensionValue, + margin?: DimensionValue, + marginBottom?: DimensionValue, + marginEnd?: DimensionValue, + marginHorizontal?: DimensionValue, + marginLeft?: DimensionValue, + marginRight?: DimensionValue, + marginStart?: DimensionValue, + marginTop?: DimensionValue, + marginVertical?: DimensionValue, + padding?: DimensionValue, + paddingBottom?: DimensionValue, + paddingEnd?: DimensionValue, + paddingHorizontal?: DimensionValue, + paddingLeft?: DimensionValue, + paddingRight?: DimensionValue, + paddingStart?: DimensionValue, + paddingTop?: DimensionValue, + paddingVertical?: DimensionValue, + borderWidth?: number, + borderBottomWidth?: number, + borderEndWidth?: number, + borderLeftWidth?: number, + borderRightWidth?: number, + borderStartWidth?: number, + borderTopWidth?: number, + position?: 'absolute' | 'relative', + flexDirection?: 'row' | 'row-reverse' | 'column' | 'column-reverse', + flexWrap?: 'wrap' | 'nowrap', + justifyContent?: | 'flex-start' | 'flex-end' | 'center' | 'space-between' | 'space-around' | 'space-evenly', - +alignItems?: 'flex-start' | 'flex-end' | 'center' | 'stretch' | 'baseline', - +alignSelf?: + alignItems?: 'flex-start' | 'flex-end' | 'center' | 'stretch' | 'baseline', + alignSelf?: | 'auto' | 'flex-start' | 'flex-end' | 'center' | 'stretch' | 'baseline', - +alignContent?: + alignContent?: | 'flex-start' | 'flex-end' | 'center' | 'stretch' | 'space-between' | 'space-around', - +overflow?: 'visible' | 'hidden' | 'scroll', - +flex?: number, - +flexGrow?: number, - +flexShrink?: number, - +flexBasis?: number | string, - +aspectRatio?: number, - +zIndex?: number, - +direction?: 'inherit' | 'ltr' | 'rtl', -}; + overflow?: 'visible' | 'hidden' | 'scroll', + flex?: number, + flexGrow?: number, + flexShrink?: number, + flexBasis?: number | string, + aspectRatio?: number, + zIndex?: number, + direction?: 'inherit' | 'ltr' | 'rtl', +|}>; -export type TransformStyle = { - +transform?: $ReadOnlyArray< - | {+perspective: number | AnimatedNode} - | {+rotate: string} - | {+rotateX: string} - | {+rotateY: string} - | {+rotateZ: string} - | {+scale: number | AnimatedNode} - | {+scaleX: number | AnimatedNode} - | {+scaleY: number | AnimatedNode} - | {+translateX: number | AnimatedNode} - | {+translateY: number | AnimatedNode} - | { +export type TransformStyle = $ReadOnly<{| + transform?: $ReadOnlyArray< + | {|+perspective: number | AnimatedNode|} + | {|+rotate: string|} + | {|+rotateX: string|} + | {|+rotateY: string|} + | {|+rotateZ: string|} + | {|+scale: number | AnimatedNode|} + | {|+scaleX: number | AnimatedNode|} + | {|+scaleY: number | AnimatedNode|} + | {|+translateX: number | AnimatedNode|} + | {|+translateY: number | AnimatedNode|} + | {| +translate: [number | AnimatedNode, number | AnimatedNode] | AnimatedNode, - } - | {+skewX: string} - | {+skewY: string} + |} + | {|+skewX: string|} + | {|+skewY: string|} // TODO: what is the actual type it expects? - | {+matrix: $ReadOnlyArray | AnimatedNode}, + | {| + +matrix: $ReadOnlyArray | AnimatedNode, + |}, >, -}; +|}>; -export type ShadowStyle<+Color = ColorValue> = { - +shadowColor?: Color, - +shadowOffset?: { - +width?: number, - +height?: number, - }, - +shadowOpacity?: number | AnimatedNode, - +shadowRadius?: number, -}; +export type ShadowStyle = $ReadOnly<{| + shadowColor?: ColorValue, + shadowOffset?: $ReadOnly<{| + width?: number, + height?: number, + |}>, + shadowOpacity?: number | AnimatedNode, + shadowRadius?: number, +|}>; -export type ViewStyle<+Dimension = DimensionValue, +Color = ColorValue> = { - ...$Exact>, - ...$Exact>, +export type ViewStyle = $ReadOnly<{| + ...$Exact, + ...$Exact, ...$Exact, - +backfaceVisibility?: 'visible' | 'hidden', - +backgroundColor?: Color, - +borderColor?: Color, - +borderBottomColor?: Color, - +borderEndColor?: Color, - +borderLeftColor?: Color, - +borderRightColor?: Color, - +borderStartColor?: Color, - +borderTopColor?: Color, - +borderRadius?: number, - +borderBottomEndRadius?: number, - +borderBottomLeftRadius?: number, - +borderBottomRightRadius?: number, - +borderBottomStartRadius?: number, - +borderTopEndRadius?: number, - +borderTopLeftRadius?: number, - +borderTopRightRadius?: number, - +borderTopStartRadius?: number, - +borderStyle?: 'solid' | 'dotted' | 'dashed', - +borderWidth?: number, - +borderBottomWidth?: number, - +borderEndWidth?: number, - +borderLeftWidth?: number, - +borderRightWidth?: number, - +borderStartWidth?: number, - +borderTopWidth?: number, - +opacity?: number | AnimatedNode, - +elevation?: number, -}; + backfaceVisibility?: 'visible' | 'hidden', + backgroundColor?: ColorValue, + borderColor?: ColorValue, + borderBottomColor?: ColorValue, + borderEndColor?: ColorValue, + borderLeftColor?: ColorValue, + borderRightColor?: ColorValue, + borderStartColor?: ColorValue, + borderTopColor?: ColorValue, + borderRadius?: number, + borderBottomEndRadius?: number, + borderBottomLeftRadius?: number, + borderBottomRightRadius?: number, + borderBottomStartRadius?: number, + borderTopEndRadius?: number, + borderTopLeftRadius?: number, + borderTopRightRadius?: number, + borderTopStartRadius?: number, + borderStyle?: 'solid' | 'dotted' | 'dashed', + borderWidth?: number, + borderBottomWidth?: number, + borderEndWidth?: number, + borderLeftWidth?: number, + borderRightWidth?: number, + borderStartWidth?: number, + borderTopWidth?: number, + opacity?: number | AnimatedNode, + elevation?: number, +|}>; -export type TextStyle<+Dimension = DimensionValue, +Color = ColorValue> = { - ...$Exact>, - +color?: Color, - +fontFamily?: string, - +fontSize?: number, - +fontStyle?: 'normal' | 'italic', - +fontWeight?: +export type TextStyle = $ReadOnly<{| + ...$Exact, + color?: ColorValue, + fontFamily?: string, + fontSize?: number, + fontStyle?: 'normal' | 'italic', + fontWeight?: | 'normal' | 'bold' | '100' @@ -176,42 +178,45 @@ export type TextStyle<+Dimension = DimensionValue, +Color = ColorValue> = { | '700' | '800' | '900', - +fontVariant?: $ReadOnlyArray< + fontVariant?: $ReadOnlyArray< | 'small-caps' | 'oldstyle-nums' | 'lining-nums' | 'tabular-nums' | 'proportional-nums', >, - +textShadowOffset?: {+width?: number, +height?: number}, - +textShadowRadius?: number, - +textShadowColor?: Color, - +letterSpacing?: number, - +lineHeight?: number, - +textAlign?: 'auto' | 'left' | 'right' | 'center' | 'justify', - +textAlignVertical?: 'auto' | 'top' | 'bottom' | 'center', - +includeFontPadding?: boolean, - +textDecorationLine?: + textShadowOffset?: $ReadOnly<{| + width?: number, + height?: number, + |}>, + textShadowRadius?: number, + textShadowColor?: ColorValue, + letterSpacing?: number, + lineHeight?: number, + textAlign?: 'auto' | 'left' | 'right' | 'center' | 'justify', + textAlignVertical?: 'auto' | 'top' | 'bottom' | 'center', + includeFontPadding?: boolean, + textDecorationLine?: | 'none' | 'underline' | 'line-through' | 'underline line-through', - +textDecorationStyle?: 'solid' | 'double' | 'dotted' | 'dashed', - +textDecorationColor?: Color, - +writingDirection?: 'auto' | 'ltr' | 'rtl', -}; + textDecorationStyle?: 'solid' | 'double' | 'dotted' | 'dashed', + textDecorationColor?: ColorValue, + writingDirection?: 'auto' | 'ltr' | 'rtl', +|}>; -export type ImageStyle<+Dimension = DimensionValue, +Color = ColorValue> = { - ...$Exact>, - +resizeMode?: 'contain' | 'cover' | 'stretch' | 'center' | 'repeat', - +tintColor?: Color, - +overlayColor?: string, -}; +export type ImageStyle = $ReadOnly<{| + ...$Exact, + resizeMode?: 'contain' | 'cover' | 'stretch' | 'center' | 'repeat', + tintColor?: ColorValue, + overlayColor?: string, +|}>; -export type Style<+Dimension = DimensionValue, +Color = ColorValue> = { - ...$Exact>, +export type Style = { + ...$Exact, +resizeMode?: 'contain' | 'cover' | 'stretch' | 'center' | 'repeat', - +tintColor?: Color, + +tintColor?: ColorValue, +overlayColor?: string, }; @@ -233,7 +238,7 @@ export type StyleProp<+T> = // $Shape>, // >; -export type StyleObj = StyleProp<$Shape>>; +export type StyleObj = StyleProp<$Shape