1 | import React from 'react';
|
2 | import omit from 'lodash.omit';
|
3 | import pick from 'lodash.pick';
|
4 | import PropTypes from 'prop-types';
|
5 | import { requireNativeComponent, ViewPropTypes, UIManager, NativeModules } from 'react-native';
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 | const ViewPropTypesKeys = Object.keys(ViewPropTypes);
|
20 |
|
21 | const getViewManagerAdapterNameForViewName = name => `ViewManagerAdapter_${name}`;
|
22 |
|
23 | const createNativeComponentClass = name => {
|
24 | class NativeComponent extends React.Component {
|
25 | static propTypes = { ...ViewPropTypes, proxiedProperties: PropTypes.object };
|
26 | render() {
|
27 | return <UnderlyingNativeComponent {...this.props} />;
|
28 | }
|
29 | }
|
30 |
|
31 | const nativeComponentName = getViewManagerAdapterNameForViewName(name);
|
32 |
|
33 | const UnderlyingNativeComponent = requireNativeComponent(nativeComponentName, NativeComponent, {
|
34 | nativeOnly: Object.keys(UIManager[nativeComponentName].NativeProps).reduce(
|
35 | (acc, key) => ({ ...acc, [key]: true }),
|
36 | {}
|
37 | ),
|
38 | });
|
39 |
|
40 | NativeComponent.displayName = name;
|
41 | return NativeComponent;
|
42 | };
|
43 |
|
44 | export const requireNativeViewManager = (name, component) => {
|
45 | if (!NativeModules.ExpoNativeModuleProxy.viewManagersNames.includes(name)) {
|
46 | console.warn(
|
47 | "It seems the native view manager which you're trying to require by name" +
|
48 | "from NativeViewManagerAdapter isn't exported by expo-react-native-adapter." +
|
49 | ' Things may not work properly. Exported view managers: [' +
|
50 | NativeModules.ExpoNativeModuleProxy.viewManagersNames.join(', ') +
|
51 | `], and you required "${name}".`
|
52 | );
|
53 | }
|
54 |
|
55 | const NativeComponent = createNativeComponentClass(name);
|
56 | const PropTypesKeys = [
|
57 | 'children',
|
58 | ...ViewPropTypesKeys,
|
59 | ...Object.keys(UIManager[getViewManagerAdapterNameForViewName(name)].NativeProps),
|
60 | ...Object.keys(UIManager[getViewManagerAdapterNameForViewName(name)].directEventTypes),
|
61 | ];
|
62 | class NativeComponentWrapper extends React.Component {
|
63 | render() {
|
64 | const nativeProps = pick(this.props, PropTypesKeys);
|
65 | const proxiedProps = omit(this.props, PropTypesKeys);
|
66 | return <NativeComponent proxiedProperties={proxiedProps} {...nativeProps} />;
|
67 | }
|
68 | }
|
69 | NativeComponentWrapper.displayName = `ViewWrapper<${name}>`;
|
70 | return NativeComponentWrapper;
|
71 | };
|