react-native/Libraries/ReactIOS/requireNativeComponent.js
Sebastian Markbage 8e3ce0ff98 Refactor Attribute Processing (Step 2)
Summary: Move the ViewAttributes and StyleAttributes configuration into the
Components library since they're coupled and change with the
native component configuration.

This also decouples StyleAttributes from the reconciler by adding it
to the ReactViewAttributes.

To do that, I refactored the property diffing to allow for recursive
configurations. Now an attribute configuration can be a nested object,
a custom configuration (diff/process) or true.

The requireNativeComponent path incorrectly gets its attributes set up
on the root validAttributes instead of the nested style object.
So I also have to add the nested form. Effectively these currently allow
these attributes on props or nested.

@​public

Reviewed By: @vjeux

Differential Revision: D2456842

fb-gh-sync-id: cd5405bd8316c2fcb016d06c61244ce7719c26c0
2015-10-06 10:28:35 -07:00

118 lines
3.8 KiB
JavaScript

/**
* 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 ReactNativeStyleAttributes = require('ReactNativeStyleAttributes');
var UnimplementedView = require('UnimplementedView');
var createReactNativeComponentClass = require('createReactNativeComponentClass');
var insetsDiffer = require('insetsDiffer');
var pointsDiffer = require('pointsDiffer');
var matricesDiffer = require('matricesDiffer');
var processColor = require('processColor');
var sizesDiffer = require('sizesDiffer');
var verifyPropTypes = require('verifyPropTypes');
var warning = require('warning');
/**
* Used to create React components that directly wrap native component
* implementations. Config information is extracted from data exported from the
* RCTUIManager 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`.
*
* If some native props shouldn't be exposed in the wrapper interface, you can
* pass null for `componentInterface` and call `verifyPropTypes` directly
* with `nativePropsToIgnore`;
*
* Common types are lined up with the appropriate prop differs with
* `TypeToDifferMap`. Non-scalar types not in the map default to `deepDiffer`.
*/
import type { ComponentInterface } from 'verifyPropTypes';
function requireNativeComponent(
viewName: string,
componentInterface?: ?ComponentInterface,
extraConfig?: ?{nativeOnly?: Object},
): Function {
var viewConfig = RCTUIManager[viewName];
if (!viewConfig || !viewConfig.NativeProps) {
warning(false, 'Native component for "%s" does not exist', viewName);
return UnimplementedView;
}
var nativeProps = {
...RCTUIManager.RCTView.NativeProps,
...viewConfig.NativeProps,
};
viewConfig.uiViewClassName = viewName;
viewConfig.validAttributes = {};
viewConfig.propTypes = componentInterface && componentInterface.propTypes;
for (var key in nativeProps) {
var useAttribute = false;
var attribute = {};
var differ = TypeToDifferMap[nativeProps[key]];
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;
}
// 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;
if (__DEV__) {
componentInterface && verifyPropTypes(
componentInterface,
viewConfig,
extraConfig && extraConfig.nativeOnly
);
}
return createReactNativeComponentClass(viewConfig);
}
var TypeToDifferMap = {
// iOS Types
CATransform3D: matricesDiffer,
CGPoint: pointsDiffer,
CGSize: sizesDiffer,
UIEdgeInsets: insetsDiffer,
// Android Types
// (not yet implemented)
};
var TypeToProcessorMap = {
// iOS Types
CGColor: processColor,
CGColorArray: processColor,
UIColor: processColor,
UIColorArray: processColor,
// Android Types
Color: processColor,
};
module.exports = requireNativeComponent;