[ReactNative] introduce requireNativeComponent

This commit is contained in:
Spencer Ahrens
2015-04-16 17:14:11 -07:00
parent baed197a7d
commit 764854c04a
6 changed files with 165 additions and 2 deletions

View File

@@ -0,0 +1,37 @@
/**
* Common implementation for a simple stubbed view. Simply applies the view's styles to the inner
* View component and renders its children.
*
* @providesModule UnimplementedView
*/
'use strict';
var React = require('React');
var StyleSheet = require('StyleSheet');
var View = require('View');
var UnimplementedView = React.createClass({
setNativeProps: function() {
// Do nothing.
// This method is required in order to use this view as a Touchable* child.
// See ensureComponentIsNative.js for more info
},
render: function() {
return (
<View style={[styles.unimplementedView, this.props.style]}>
{this.props.children}
</View>
);
},
});
var styles = StyleSheet.create({
unimplementedView: {
borderWidth: 1,
borderColor: 'red',
alignSelf: 'flex-start',
}
});
module.exports = UnimplementedView;

View File

@@ -0,0 +1,62 @@
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* @providesModule requireNativeComponent
* @flow
*/
'use strict';
var RCTUIManager = require('NativeModules').UIManager;
var UnimplementedView = require('UnimplementedView');
var createReactIOSNativeComponentClass = require('createReactIOSNativeComponentClass');
var deepDiffer = require('deepDiffer');
var insetsDiffer = require('insetsDiffer');
var pointsDiffer = require('pointsDiffer');
var matricesDiffer = require('matricesDiffer');
var sizesDiffer = require('sizesDiffer');
/**
* Used to create React components that directly wrap native component
* implementations. Config information is extracted from data exported from the
* RCTUIManager module. It is still strongly preferred that you wrap the native
* component in a hand-written component with full propTypes definitions and
* other documentation.
*
* Common types are lined up with the appropriate prop differs with
* `TypeToDifferMap`. Non-scalar types not in the map default to `deepDiffer`.
*/
function requireNativeComponent(viewName: string): Function {
var viewConfig = RCTUIManager.viewConfigs && RCTUIManager.viewConfigs[viewName];
if (!viewConfig) {
return UnimplementedView;
}
var nativeProps = {
...RCTUIManager.viewConfigs.RCTView.nativeProps,
...viewConfig.nativeProps,
};
viewConfig.validAttributes = {};
for (var key in nativeProps) {
// TODO: deep diff by default in diffRawProperties instead of setting it here
var differ = TypeToDifferMap[nativeProps[key].type] || deepDiffer;
viewConfig.validAttributes[key] = {diff: differ};
}
return createReactIOSNativeComponentClass(viewConfig);
}
var TypeToDifferMap = {
// iOS Types
CATransform3D: matricesDiffer,
CGPoint: pointsDiffer,
CGSize: sizesDiffer,
UIEdgeInsets: insetsDiffer,
// Android Types
// (not yet implemented)
};
module.exports = requireNativeComponent;

View File

@@ -0,0 +1,19 @@
/**
* Copyright 2004-present Facebook. All Rights Reserved.
*
* @providesModule sizesDiffer
*/
'use strict';
var dummySize = {w: undefined, h: undefined};
var sizesDiffer = function(one, two) {
one = one || dummySize;
two = two || dummySize;
return one !== two && (
one.w !== two.w ||
one.h !== two.h
);
};
module.exports = sizesDiffer;

View File

@@ -59,6 +59,7 @@ var ReactNative = Object.assign(Object.create(require('React')), {
// Plugins
DeviceEventEmitter: require('RCTDeviceEventEmitter'),
NativeModules: require('NativeModules'),
requireNativeComponent: require('requireNativeComponent'),
addons: {
LinkedStateMixin: require('LinkedStateMixin'),