2015-04-17 00:14:11 +00:00
|
|
|
/**
|
|
|
|
* 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;
|
2015-10-06 03:21:48 +00:00
|
|
|
var ReactNativeStyleAttributes = require('ReactNativeStyleAttributes');
|
2015-04-17 00:14:11 +00:00
|
|
|
var UnimplementedView = require('UnimplementedView');
|
|
|
|
|
2015-05-08 16:45:43 +00:00
|
|
|
var createReactNativeComponentClass = require('createReactNativeComponentClass');
|
2015-04-17 00:14:11 +00:00
|
|
|
var insetsDiffer = require('insetsDiffer');
|
|
|
|
var pointsDiffer = require('pointsDiffer');
|
|
|
|
var matricesDiffer = require('matricesDiffer');
|
2015-09-17 15:36:08 +00:00
|
|
|
var processColor = require('processColor');
|
2015-04-17 00:14:11 +00:00
|
|
|
var sizesDiffer = require('sizesDiffer');
|
2015-04-17 01:17:19 +00:00
|
|
|
var verifyPropTypes = require('verifyPropTypes');
|
2015-05-22 23:16:47 +00:00
|
|
|
var warning = require('warning');
|
2015-04-17 00:14:11 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Used to create React components that directly wrap native component
|
|
|
|
* implementations. Config information is extracted from data exported from the
|
2015-04-17 01:17:19 +00:00
|
|
|
* RCTUIManager module. You should also wrap the native component in a
|
|
|
|
* hand-written component with full propTypes definitions and other
|
2015-07-25 01:31:55 +00:00
|
|
|
* documentation - pass the hand-written component in as `componentInterface` to
|
2015-04-17 01:17:19 +00:00
|
|
|
* verify all the native props are documented via `propTypes`.
|
|
|
|
*
|
|
|
|
* If some native props shouldn't be exposed in the wrapper interface, you can
|
2015-07-25 01:31:55 +00:00
|
|
|
* pass null for `componentInterface` and call `verifyPropTypes` directly
|
2015-04-17 01:17:19 +00:00
|
|
|
* with `nativePropsToIgnore`;
|
2015-04-17 00:14:11 +00:00
|
|
|
*
|
|
|
|
* Common types are lined up with the appropriate prop differs with
|
|
|
|
* `TypeToDifferMap`. Non-scalar types not in the map default to `deepDiffer`.
|
|
|
|
*/
|
2015-07-25 01:31:55 +00:00
|
|
|
import type { ComponentInterface } from 'verifyPropTypes';
|
|
|
|
|
2015-04-17 01:17:19 +00:00
|
|
|
function requireNativeComponent(
|
|
|
|
viewName: string,
|
2015-07-25 01:31:55 +00:00
|
|
|
componentInterface?: ?ComponentInterface,
|
|
|
|
extraConfig?: ?{nativeOnly?: Object},
|
2015-04-17 01:17:19 +00:00
|
|
|
): Function {
|
2015-04-22 11:03:46 +00:00
|
|
|
var viewConfig = RCTUIManager[viewName];
|
2015-05-27 02:25:11 +00:00
|
|
|
if (!viewConfig || !viewConfig.NativeProps) {
|
2015-05-22 23:16:47 +00:00
|
|
|
warning(false, 'Native component for "%s" does not exist', viewName);
|
2015-04-17 00:14:11 +00:00
|
|
|
return UnimplementedView;
|
|
|
|
}
|
|
|
|
var nativeProps = {
|
2015-05-27 02:25:11 +00:00
|
|
|
...RCTUIManager.RCTView.NativeProps,
|
|
|
|
...viewConfig.NativeProps,
|
2015-04-17 00:14:11 +00:00
|
|
|
};
|
2015-04-22 11:03:46 +00:00
|
|
|
viewConfig.uiViewClassName = viewName;
|
2015-04-17 00:14:11 +00:00
|
|
|
viewConfig.validAttributes = {};
|
2015-07-25 01:31:55 +00:00
|
|
|
viewConfig.propTypes = componentInterface && componentInterface.propTypes;
|
2015-04-17 00:14:11 +00:00
|
|
|
for (var key in nativeProps) {
|
2015-09-17 15:36:08 +00:00
|
|
|
var useAttribute = false;
|
|
|
|
var attribute = {};
|
|
|
|
|
2015-07-15 00:06:03 +00:00
|
|
|
var differ = TypeToDifferMap[nativeProps[key]];
|
2015-09-17 15:36:08 +00:00
|
|
|
if (differ) {
|
|
|
|
attribute.diff = differ;
|
|
|
|
useAttribute = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
var processor = TypeToProcessorMap[nativeProps[key]];
|
|
|
|
if (processor) {
|
|
|
|
attribute.process = processor;
|
|
|
|
useAttribute = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
viewConfig.validAttributes[key] = useAttribute ? attribute : true;
|
2015-04-17 00:14:11 +00:00
|
|
|
}
|
2015-10-06 03:21:48 +00:00
|
|
|
|
|
|
|
// Unfortunately, the current set up puts the style properties on the top
|
|
|
|
// level props object. We also need to add the nested form for API
|
|
|
|
// compatibility. This allows these props on both the top level and the
|
|
|
|
// nested style level. TODO: Move these to nested declarations on the
|
|
|
|
// native side.
|
|
|
|
viewConfig.validAttributes.style = ReactNativeStyleAttributes;
|
|
|
|
|
2015-04-17 01:17:19 +00:00
|
|
|
if (__DEV__) {
|
2015-07-25 01:31:55 +00:00
|
|
|
componentInterface && verifyPropTypes(
|
|
|
|
componentInterface,
|
|
|
|
viewConfig,
|
|
|
|
extraConfig && extraConfig.nativeOnly
|
|
|
|
);
|
2015-04-17 01:17:19 +00:00
|
|
|
}
|
2015-05-08 16:45:43 +00:00
|
|
|
return createReactNativeComponentClass(viewConfig);
|
2015-04-17 00:14:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
var TypeToDifferMap = {
|
|
|
|
// iOS Types
|
|
|
|
CATransform3D: matricesDiffer,
|
|
|
|
CGPoint: pointsDiffer,
|
|
|
|
CGSize: sizesDiffer,
|
|
|
|
UIEdgeInsets: insetsDiffer,
|
|
|
|
// Android Types
|
|
|
|
// (not yet implemented)
|
|
|
|
};
|
|
|
|
|
2015-09-17 15:36:08 +00:00
|
|
|
var TypeToProcessorMap = {
|
|
|
|
// iOS Types
|
|
|
|
CGColor: processColor,
|
|
|
|
CGColorArray: processColor,
|
|
|
|
UIColor: processColor,
|
|
|
|
UIColorArray: processColor,
|
|
|
|
// Android Types
|
|
|
|
Color: processColor,
|
|
|
|
};
|
|
|
|
|
2015-04-17 00:14:11 +00:00
|
|
|
module.exports = requireNativeComponent;
|