diff --git a/Libraries/Components/ActivityIndicator/ActivityIndicator.js b/Libraries/Components/ActivityIndicator/ActivityIndicator.js index 65809a323..f2a648797 100644 --- a/Libraries/Components/ActivityIndicator/ActivityIndicator.js +++ b/Libraries/Components/ActivityIndicator/ActivityIndicator.js @@ -11,7 +11,6 @@ 'use strict'; const Platform = require('Platform'); -const ProgressBarAndroid = require('ProgressBarAndroid'); const React = require('React'); const StyleSheet = require('StyleSheet'); const View = require('View'); @@ -21,7 +20,10 @@ const requireNativeComponent = require('requireNativeComponent'); import type {NativeComponent} from 'ReactNative'; import type {ViewProps} from 'ViewPropTypes'; -let RCTActivityIndicator; +const RCTActivityIndicator = + Platform.OS === 'android' + ? require('ProgressBarAndroid') + : requireNativeComponent('RCTActivityIndicatorView'); const GRAY = '#999999'; @@ -98,11 +100,7 @@ const ActivityIndicator = ( return ( - {Platform.OS === 'ios' ? ( - - ) : ( - - )} + ); }; @@ -120,14 +118,6 @@ ActivityIndicatorWithRef.defaultProps = { }; ActivityIndicatorWithRef.displayName = 'ActivityIndicator'; -if (Platform.OS === 'ios') { - RCTActivityIndicator = requireNativeComponent( - 'RCTActivityIndicatorView', - null, - {nativeOnly: {activityIndicatorViewStyle: true}}, - ); -} - const styles = StyleSheet.create({ container: { alignItems: 'center', diff --git a/Libraries/Components/DatePicker/DatePickerIOS.ios.js b/Libraries/Components/DatePicker/DatePickerIOS.ios.js index f76902d85..120236466 100644 --- a/Libraries/Components/DatePicker/DatePickerIOS.ios.js +++ b/Libraries/Components/DatePicker/DatePickerIOS.ios.js @@ -22,6 +22,8 @@ const requireNativeComponent = require('requireNativeComponent'); import type {ViewProps} from 'ViewPropTypes'; +const RCTDatePickerIOS = requireNativeComponent('RCTDatePicker'); + type Event = Object; type Props = $ReadOnly<{| @@ -177,6 +179,4 @@ const styles = StyleSheet.create({ }, }); -const RCTDatePickerIOS = requireNativeComponent('RCTDatePicker'); - module.exports = DatePickerIOS; diff --git a/Libraries/Components/MaskedView/MaskedViewIOS.ios.js b/Libraries/Components/MaskedView/MaskedViewIOS.ios.js index b0d1ab490..c65822a64 100644 --- a/Libraries/Components/MaskedView/MaskedViewIOS.ios.js +++ b/Libraries/Components/MaskedView/MaskedViewIOS.ios.js @@ -17,6 +17,8 @@ const requireNativeComponent = require('requireNativeComponent'); import type {ViewProps} from 'ViewPropTypes'; +const RCTMaskedView = requireNativeComponent('RCTMaskedView'); + type Props = { ...ViewProps, @@ -97,12 +99,4 @@ class MaskedViewIOS extends React.Component { } } -const RCTMaskedView = requireNativeComponent('RCTMaskedView', { - name: 'RCTMaskedView', - displayName: 'RCTMaskedView', - propTypes: { - ...ViewPropTypes, - }, -}); - module.exports = MaskedViewIOS; diff --git a/Libraries/Components/ProgressViewIOS/ProgressViewIOS.ios.js b/Libraries/Components/ProgressViewIOS/ProgressViewIOS.ios.js index a7d6d61e5..ea92fccb9 100644 --- a/Libraries/Components/ProgressViewIOS/ProgressViewIOS.ios.js +++ b/Libraries/Components/ProgressViewIOS/ProgressViewIOS.ios.js @@ -25,6 +25,8 @@ import type {ImageSource} from 'ImageSource'; import type {ColorValue} from 'StyleSheetTypes'; import type {ViewProps} from 'ViewPropTypes'; +const RCTProgressView = requireNativeComponent('RCTProgressView'); + type Props = $ReadOnly<{| ...ViewProps, progressViewStyle?: ?('default' | 'bar'), @@ -91,11 +93,6 @@ const styles = StyleSheet.create({ }, }); -const RCTProgressView = requireNativeComponent( - 'RCTProgressView', - ProgressViewIOS, -); - module.exports = ((ProgressViewIOS: any): Class< ReactNative.NativeComponent, >); diff --git a/Libraries/Components/SafeAreaView/SafeAreaView.ios.js b/Libraries/Components/SafeAreaView/SafeAreaView.ios.js index 65daa32fd..5fb0406b8 100644 --- a/Libraries/Components/SafeAreaView/SafeAreaView.ios.js +++ b/Libraries/Components/SafeAreaView/SafeAreaView.ios.js @@ -14,6 +14,8 @@ const requireNativeComponent = require('requireNativeComponent'); import type {ViewProps} from 'ViewPropTypes'; +const RCTSafeAreaView = requireNativeComponent('RCTSafeAreaView'); + type Props = ViewProps & { children: any, }; @@ -34,12 +36,4 @@ class SafeAreaView extends React.Component { } } -const RCTSafeAreaView = requireNativeComponent('RCTSafeAreaView', { - name: 'RCTSafeAreaView', - displayName: 'RCTSafeAreaView', - propTypes: { - ...ViewPropTypes, - }, -}); - module.exports = SafeAreaView; diff --git a/Libraries/Components/ScrollView/ScrollView.js b/Libraries/Components/ScrollView/ScrollView.js index 4b1b76848..6e9e40d60 100644 --- a/Libraries/Components/ScrollView/ScrollView.js +++ b/Libraries/Components/ScrollView/ScrollView.js @@ -45,6 +45,28 @@ import type {PointProp} from 'PointPropType'; import type {ColorValue} from 'StyleSheetTypes'; +let AndroidScrollView; +let AndroidHorizontalScrollContentView; +let AndroidHorizontalScrollView; +let RCTScrollView; +let RCTScrollContentView; + +if (Platform.OS === 'android') { + AndroidScrollView = requireNativeComponent('RCTScrollView'); + AndroidHorizontalScrollView = requireNativeComponent( + 'AndroidHorizontalScrollView', + ); + AndroidHorizontalScrollContentView = requireNativeComponent( + 'AndroidHorizontalScrollContentView', + ); +} else if (Platform.OS === 'ios') { + RCTScrollView = requireNativeComponent('RCTScrollView'); + RCTScrollContentView = requireNativeComponent('RCTScrollContentView'); +} else { + RCTScrollView = requireNativeComponent('RCTScrollView'); + RCTScrollContentView = requireNativeComponent('RCTScrollContentView'); +} + type TouchableProps = $ReadOnly<{| onTouchStart?: (event: PressEvent) => void, onTouchMove?: (event: PressEvent) => void, @@ -1074,56 +1096,4 @@ const styles = StyleSheet.create({ }, }); -let nativeOnlyProps, - AndroidScrollView, - AndroidHorizontalScrollContentView, - AndroidHorizontalScrollView, - RCTScrollView, - RCTScrollContentView; -if (Platform.OS === 'android') { - nativeOnlyProps = { - nativeOnly: { - sendMomentumEvents: true, - }, - }; - AndroidScrollView = requireNativeComponent( - 'RCTScrollView', - (ScrollView: React.ComponentType), - nativeOnlyProps, - ); - AndroidHorizontalScrollView = requireNativeComponent( - 'AndroidHorizontalScrollView', - (ScrollView: React.ComponentType), - nativeOnlyProps, - ); - AndroidHorizontalScrollContentView = requireNativeComponent( - 'AndroidHorizontalScrollContentView', - ); -} else if (Platform.OS === 'ios') { - nativeOnlyProps = { - nativeOnly: { - onMomentumScrollBegin: true, - onMomentumScrollEnd: true, - onScrollBeginDrag: true, - onScrollEndDrag: true, - }, - }; - RCTScrollView = requireNativeComponent( - 'RCTScrollView', - (ScrollView: React.ComponentType), - nativeOnlyProps, - ); - RCTScrollContentView = requireNativeComponent('RCTScrollContentView', View); -} else { - nativeOnlyProps = { - nativeOnly: {}, - }; - RCTScrollView = requireNativeComponent( - 'RCTScrollView', - null, - nativeOnlyProps, - ); - RCTScrollContentView = requireNativeComponent('RCTScrollContentView', View); -} - module.exports = TypedScrollView; diff --git a/Libraries/Components/SegmentedControlIOS/SegmentedControlIOS.ios.js b/Libraries/Components/SegmentedControlIOS/SegmentedControlIOS.ios.js index f0a407245..b4635f13f 100644 --- a/Libraries/Components/SegmentedControlIOS/SegmentedControlIOS.ios.js +++ b/Libraries/Components/SegmentedControlIOS/SegmentedControlIOS.ios.js @@ -22,6 +22,8 @@ const requireNativeComponent = require('requireNativeComponent'); import type {ViewProps} from 'ViewPropTypes'; +const RCTSegmentedControl = requireNativeComponent('RCTSegmentedControl'); + type DefaultProps = { values: $ReadOnlyArray, enabled: boolean, @@ -139,11 +141,6 @@ const styles = StyleSheet.create({ }, }); -const RCTSegmentedControl = requireNativeComponent( - 'RCTSegmentedControl', - SegmentedControlIOS, -); - module.exports = ((SegmentedControlIOS: any): Class< ReactNative.NativeComponent, >); diff --git a/Libraries/Components/Slider/Slider.js b/Libraries/Components/Slider/Slider.js index 4c4c0b979..efe22529f 100644 --- a/Libraries/Components/Slider/Slider.js +++ b/Libraries/Components/Slider/Slider.js @@ -29,6 +29,8 @@ import type {ViewStyleProp} from 'StyleSheet'; import type {ColorValue} from 'StyleSheetTypes'; import type {ViewProps} from 'ViewPropTypes'; +const RCTSlider = requireNativeComponent('RCTSlider'); + type Event = Object; type IOSProps = $ReadOnly<{| @@ -306,14 +308,4 @@ if (Platform.OS === 'ios') { }); } -let options = {}; -if (Platform.OS === 'android') { - options = { - nativeOnly: { - enabled: true, - }, - }; -} -const RCTSlider = requireNativeComponent('RCTSlider', Slider, options); - module.exports = ((Slider: any): Class>); diff --git a/Libraries/Components/Switch/Switch.js b/Libraries/Components/Switch/Switch.js index 1730e7cbf..c2288d25c 100644 --- a/Libraries/Components/Switch/Switch.js +++ b/Libraries/Components/Switch/Switch.js @@ -25,6 +25,11 @@ const requireNativeComponent = require('requireNativeComponent'); import type {ColorValue} from 'StyleSheetTypes'; import type {ViewProps} from 'ViewPropTypes'; +const RCTSwitch = + Platform.OS === 'android' + ? requireNativeComponent('AndroidSwitch') + : requireNativeComponent('RCTSwitch'); + type DefaultProps = $ReadOnly<{| value: boolean, disabled: boolean, @@ -40,6 +45,7 @@ type Props = $ReadOnly<{| onTintColor?: ?ColorValue, thumbTintColor?: ?ColorValue, |}>; + /** * Renders a boolean input. * @@ -158,21 +164,4 @@ const styles = StyleSheet.create({ }, }); -if (Platform.OS === 'android') { - var RCTSwitch = requireNativeComponent('AndroidSwitch', Switch, { - nativeOnly: { - onChange: true, - on: true, - enabled: true, - trackTintColor: true, - }, - }); -} else { - var RCTSwitch = requireNativeComponent('RCTSwitch', Switch, { - nativeOnly: { - onChange: true, - }, - }); -} - module.exports = ((Switch: any): Class>); diff --git a/Libraries/Components/TabBarIOS/TabBarIOS.ios.js b/Libraries/Components/TabBarIOS/TabBarIOS.ios.js index 42d6cb238..6cbe213f7 100644 --- a/Libraries/Components/TabBarIOS/TabBarIOS.ios.js +++ b/Libraries/Components/TabBarIOS/TabBarIOS.ios.js @@ -22,6 +22,8 @@ const requireNativeComponent = require('requireNativeComponent'); import type {DangerouslyImpreciseStyleProp} from 'StyleSheet'; import type {ViewProps} from 'ViewPropTypes'; +const RCTTabBar = requireNativeComponent('RCTTabBar'); + type Props = $ReadOnly<{| ...ViewProps, style?: DangerouslyImpreciseStyleProp, @@ -102,6 +104,4 @@ const styles = StyleSheet.create({ }, }); -const RCTTabBar = requireNativeComponent('RCTTabBar', TabBarIOS); - module.exports = TabBarIOS; diff --git a/Libraries/Components/TextInput/TextInput.js b/Libraries/Components/TextInput/TextInput.js index 7909b5a8f..c08033e8d 100644 --- a/Libraries/Components/TextInput/TextInput.js +++ b/Libraries/Components/TextInput/TextInput.js @@ -40,24 +40,22 @@ let AndroidTextInput; let RCTMultilineTextInputView; let RCTSinglelineTextInputView; +if (Platform.OS === 'android') { + AndroidTextInput = requireNativeComponent('AndroidTextInput'); +} else if (Platform.OS === 'ios') { + RCTMultilineTextInputView = requireNativeComponent( + 'RCTMultilineTextInputView', + ); + RCTSinglelineTextInputView = requireNativeComponent( + 'RCTSinglelineTextInputView', + ); +} + const onlyMultiline = { onTextInput: true, children: true, }; -if (Platform.OS === 'android') { - AndroidTextInput = requireNativeComponent('AndroidTextInput', null); -} else if (Platform.OS === 'ios') { - RCTMultilineTextInputView = requireNativeComponent( - 'RCTMultilineTextInputView', - null, - ); - RCTSinglelineTextInputView = requireNativeComponent( - 'RCTSinglelineTextInputView', - null, - ); -} - type Event = Object; type Selection = { start: number, diff --git a/Libraries/Components/View/View.js b/Libraries/Components/View/View.js index 5e1b6bdb5..c494643c4 100644 --- a/Libraries/Components/View/View.js +++ b/Libraries/Components/View/View.js @@ -10,11 +10,8 @@ 'use strict'; -const Platform = require('Platform'); const React = require('React'); -const ReactNativeStyleAttributes = require('ReactNativeStyleAttributes'); const TextAncestor = require('TextAncestor'); -const ViewPropTypes = require('ViewPropTypes'); const invariant = require('fbjs/lib/invariant'); const requireNativeComponent = require('requireNativeComponent'); @@ -31,31 +28,7 @@ export type Props = ViewProps; * * @see http://facebook.github.io/react-native/docs/view.html */ -const RCTView = requireNativeComponent( - 'RCTView', - { - propTypes: ViewPropTypes, - }, - { - nativeOnly: { - nativeBackgroundAndroid: true, - nativeForegroundAndroid: true, - }, - }, -); - -if (__DEV__) { - const UIManager = require('UIManager'); - const viewConfig = - (UIManager.viewConfigs && UIManager.viewConfigs.RCTView) || {}; - for (const prop in viewConfig.nativeProps) { - if (!ViewPropTypes[prop] && !ReactNativeStyleAttributes[prop]) { - throw new Error( - 'View is missing propType for native prop `' + prop + '`', - ); - } - } -} +const RCTView = requireNativeComponent('RCTView'); let ViewToExport = RCTView; if (__DEV__) { diff --git a/Libraries/Image/Image.ios.js b/Libraries/Image/Image.ios.js index 86a552537..e3f153242 100644 --- a/Libraries/Image/Image.ios.js +++ b/Libraries/Image/Image.ios.js @@ -23,6 +23,8 @@ const resolveAssetSource = require('resolveAssetSource'); const ImageViewManager = NativeModules.ImageViewManager; +const RCTImageView = requireNativeComponent('RCTImageView'); + /** * A React component for displaying different types of images, * including network images, static resources, temporary local images, and @@ -139,6 +141,4 @@ const styles = StyleSheet.create({ }, }); -const RCTImageView = requireNativeComponent('RCTImageView', Image); - module.exports = Image; diff --git a/Libraries/Modal/Modal.js b/Libraries/Modal/Modal.js index d414a288f..fcc3900da 100644 --- a/Libraries/Modal/Modal.js +++ b/Libraries/Modal/Modal.js @@ -22,7 +22,9 @@ const View = require('View'); const deprecatedPropType = require('deprecatedPropType'); const requireNativeComponent = require('requireNativeComponent'); -const RCTModalHostView = requireNativeComponent('RCTModalHostView', null); + +const RCTModalHostView = requireNativeComponent('RCTModalHostView'); + const ModalEventEmitter = Platform.OS === 'ios' && NativeModules.ModalManager ? new NativeEventEmitter(NativeModules.ModalManager) diff --git a/Libraries/RCTTest/SnapshotViewIOS.ios.js b/Libraries/RCTTest/SnapshotViewIOS.ios.js index f2a53511b..9fbc70302 100644 --- a/Libraries/RCTTest/SnapshotViewIOS.ios.js +++ b/Libraries/RCTTest/SnapshotViewIOS.ios.js @@ -21,6 +21,13 @@ const ViewPropTypes = require('ViewPropTypes'); const requireNativeComponent = require('requireNativeComponent'); +// Verify that RCTSnapshot is part of the UIManager since it is only loaded +// if you have linked against RCTTest like in tests, otherwise we will have +// a warning printed out +const RCTSnapshot = UIManager.RCTSnapshot + ? requireNativeComponent('RCTSnapshot') + : View; + class SnapshotViewIOS extends React.Component<{ onSnapshotReady?: Function, testIdentifier?: string, @@ -59,11 +66,4 @@ const style = StyleSheet.create({ }, }); -// Verify that RCTSnapshot is part of the UIManager since it is only loaded -// if you have linked against RCTTest like in tests, otherwise we will have -// a warning printed out -const RCTSnapshot = UIManager.RCTSnapshot - ? requireNativeComponent('RCTSnapshot', SnapshotViewIOS) - : View; - module.exports = SnapshotViewIOS; diff --git a/Libraries/ReactNative/requireNativeComponent.js b/Libraries/ReactNative/requireNativeComponent.js index c6f2a35d3..dce6a900b 100644 --- a/Libraries/ReactNative/requireNativeComponent.js +++ b/Libraries/ReactNative/requireNativeComponent.js @@ -10,7 +10,6 @@ 'use strict'; -const Platform = require('Platform'); const ReactNativeStyleAttributes = require('ReactNativeStyleAttributes'); const UIManager = require('UIManager'); @@ -21,51 +20,25 @@ const pointsDiffer = require('pointsDiffer'); const processColor = require('processColor'); const resolveAssetSource = require('resolveAssetSource'); const sizesDiffer = require('sizesDiffer'); -const verifyPropTypes = require('verifyPropTypes'); const invariant = require('fbjs/lib/invariant'); const warning = require('fbjs/lib/warning'); -type ComponentInterface = - | React$ComponentType - | $ReadOnly<{ - propTypes?: $ReadOnly<{ - [propName: string]: mixed, - }>, - }>; - -type ExtraOptions = $ReadOnly<{| - nativeOnly?: $ReadOnly<{ - [propName: string]: boolean, - }>, -|}>; - /** - * Used to create React components that directly wrap native component - * implementations. Config information is extracted from data exported from the - * UIManager module. You should also wrap the native component in a - * hand-written component with full propTypes definitions and other - * documentation - pass the hand-written component in as `componentInterface` to - * verify all the native props are documented via `propTypes`. + * Creates values that can be used like React components which represent native + * view managers. You should create JavaScript modules that wrap these values so + * that the results are memoized. Example: * - * If some native props shouldn't be exposed in the wrapper interface, you can - * pass null for `componentInterface` and call `verifyPropTypes` directly - * with `nativePropsToIgnore`; + * const View = requireNativeComponent('RCTView'); * - * Common types are lined up with the appropriate prop differs with - * `TypeToDifferMap`. Non-scalar types not in the map default to `deepDiffer`. */ -const requireNativeComponent = ( - viewName: string, - componentInterface?: ?ComponentInterface, - extraConfig?: ?ExtraOptions, -): string => - createReactNativeComponentClass(viewName, () => { - const viewConfig = UIManager[viewName]; +const requireNativeComponent = (uiViewClassName: string): string => + createReactNativeComponentClass(uiViewClassName, () => { + const viewConfig = UIManager[uiViewClassName]; invariant( viewConfig != null && viewConfig.NativeProps != null, 'requireNativeComponent: "%s" was not found in the UIManager.', - viewName, + uiViewClassName, ); // TODO: This seems like a whole lot of runtime initialization for every @@ -94,14 +67,14 @@ const requireNativeComponent = ( } } - const viewAttributes = {}; + const validAttributes = {}; for (const key in nativeProps) { const typeName = nativeProps[key]; const diff = getDifferForType(typeName); const process = getProcessorForType(typeName); - viewAttributes[key] = + validAttributes[key] = diff == null && process == null ? true : {diff, process}; } @@ -109,24 +82,15 @@ const requireNativeComponent = ( // props. This makes it so we allow style properties in the `style` prop. // TODO: Move style properties into a `style` prop and disallow them as // top-level props on the native side. - viewAttributes.style = ReactNativeStyleAttributes; + validAttributes.style = ReactNativeStyleAttributes; Object.assign(viewConfig, { - uiViewClassName: viewName, - validAttributes: viewAttributes, - propTypes: - componentInterface == null ? null : componentInterface.propTypes, + uiViewClassName, + validAttributes, bubblingEventTypes, directEventTypes, }); - if (__DEV__) { - verifyPropTypes( - viewConfig, - extraConfig == null ? null : extraConfig.nativeOnly, - ); - } - if (!hasAttachedDefaultEventTypes) { attachDefaultEventTypes(viewConfig); hasAttachedDefaultEventTypes = true; diff --git a/Libraries/ReactNative/verifyPropTypes.js b/Libraries/ReactNative/verifyPropTypes.js deleted file mode 100644 index 6193b1ac1..000000000 --- a/Libraries/ReactNative/verifyPropTypes.js +++ /dev/null @@ -1,64 +0,0 @@ -/** - * 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 - */ - -'use strict'; - -const ReactNativeStyleAttributes = require('ReactNativeStyleAttributes'); - -function verifyPropTypes( - viewConfig: $ReadOnly<{ - NativeProps: $ReadOnly<{ - [propName: string]: mixed, - }>, - propTypes: ?$ReadOnly<{ - [propName: string]: mixed, - }>, - uiViewClassName: string, - }>, - nativePropsToIgnore: ?$ReadOnly<{ - [propName: string]: boolean, - }>, -) { - const {NativeProps, propTypes, uiViewClassName} = viewConfig; - - if (propTypes == null) { - return; - } - - for (const propName in NativeProps) { - if ( - propTypes[propName] || - ReactNativeStyleAttributes[propName] || - (nativePropsToIgnore && nativePropsToIgnore[propName]) - ) { - continue; - } - const prettyName = `${uiViewClassName}.${propName}`; - const nativeType = String(NativeProps[propName]); - const suggestion = - '\n\nIf you have not changed this prop yourself, this usually means ' + - 'that the versions of your native and JavaScript code are out of sync. ' + - 'Updating both should make this error go away.'; - - if (propTypes.hasOwnProperty(propName)) { - console.error( - `Invalid propType to configure \`${prettyName}\` (${nativeType}).` + - suggestion, - ); - } else { - console.error( - `Missing a propType to configure \`${prettyName}\` (${nativeType}).` + - suggestion, - ); - } - } -} - -module.exports = verifyPropTypes;