|
@@ -12,11 +12,11 @@
|
|
|
import { kebabCase } from 'lodash';
|
|
import { kebabCase } from 'lodash';
|
|
|
import React from 'react';
|
|
import React from 'react';
|
|
|
import ReactDOM from 'react-dom';
|
|
import ReactDOM from 'react-dom';
|
|
|
-import angular from 'angular';
|
|
|
|
|
|
|
+import angular, { auto } from 'angular';
|
|
|
|
|
|
|
|
// get a react component from name (components can be an angular injectable e.g. value, factory or
|
|
// get a react component from name (components can be an angular injectable e.g. value, factory or
|
|
|
// available on window
|
|
// available on window
|
|
|
-function getReactComponent(name, $injector) {
|
|
|
|
|
|
|
+function getReactComponent(name: string, $injector: auto.IInjectorService) {
|
|
|
// if name is a function assume it is component and return it
|
|
// if name is a function assume it is component and return it
|
|
|
if (angular.isFunction(name)) {
|
|
if (angular.isFunction(name)) {
|
|
|
return name;
|
|
return name;
|
|
@@ -36,6 +36,7 @@ function getReactComponent(name, $injector) {
|
|
|
if (!reactComponent) {
|
|
if (!reactComponent) {
|
|
|
try {
|
|
try {
|
|
|
reactComponent = name.split('.').reduce((current, namePart) => {
|
|
reactComponent = name.split('.').reduce((current, namePart) => {
|
|
|
|
|
+ // @ts-ignore
|
|
|
return current[namePart];
|
|
return current[namePart];
|
|
|
}, window);
|
|
}, window);
|
|
|
} catch (e) {}
|
|
} catch (e) {}
|
|
@@ -49,7 +50,7 @@ function getReactComponent(name, $injector) {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// wraps a function with scope.$apply, if already applied just return
|
|
// wraps a function with scope.$apply, if already applied just return
|
|
|
-function applied(fn, scope) {
|
|
|
|
|
|
|
+function applied(fn: any, scope: any) {
|
|
|
if (fn.wrappedInApply) {
|
|
if (fn.wrappedInApply) {
|
|
|
return fn;
|
|
return fn;
|
|
|
}
|
|
}
|
|
@@ -81,7 +82,7 @@ function applied(fn, scope) {
|
|
|
* @param propsConfig configuration object for all properties
|
|
* @param propsConfig configuration object for all properties
|
|
|
* @returns {Object} props with the functions wrapped in scope.$apply
|
|
* @returns {Object} props with the functions wrapped in scope.$apply
|
|
|
*/
|
|
*/
|
|
|
-function applyFunctions(obj, scope, propsConfig?) {
|
|
|
|
|
|
|
+function applyFunctions(obj: any, scope: any, propsConfig?: any): object {
|
|
|
return Object.keys(obj || {}).reduce((prev, key) => {
|
|
return Object.keys(obj || {}).reduce((prev, key) => {
|
|
|
const value = obj[key];
|
|
const value = obj[key];
|
|
|
const config = (propsConfig || {})[key] || {};
|
|
const config = (propsConfig || {})[key] || {};
|
|
@@ -90,6 +91,7 @@ function applyFunctions(obj, scope, propsConfig?) {
|
|
|
* ensures that when function is called from a React component
|
|
* ensures that when function is called from a React component
|
|
|
* the Angular digest cycle is run
|
|
* the Angular digest cycle is run
|
|
|
*/
|
|
*/
|
|
|
|
|
+ // @ts-ignore
|
|
|
prev[key] = angular.isFunction(value) && config.wrapApply !== false ? applied(value, scope) : value;
|
|
prev[key] = angular.isFunction(value) && config.wrapApply !== false ? applied(value, scope) : value;
|
|
|
|
|
|
|
|
return prev;
|
|
return prev;
|
|
@@ -104,7 +106,7 @@ function applyFunctions(obj, scope, propsConfig?) {
|
|
|
* Uses the watchDepth attribute to determine how to watch props on scope.
|
|
* Uses the watchDepth attribute to determine how to watch props on scope.
|
|
|
* If watchDepth attribute is NOT reference or collection, watchDepth defaults to deep watching by value
|
|
* If watchDepth attribute is NOT reference or collection, watchDepth defaults to deep watching by value
|
|
|
*/
|
|
*/
|
|
|
-function watchProps(watchDepth, scope, watchExpressions, listener) {
|
|
|
|
|
|
|
+function watchProps(watchDepth: string, scope: any, watchExpressions: any[], listener: any) {
|
|
|
const supportsWatchCollection = angular.isFunction(scope.$watchCollection);
|
|
const supportsWatchCollection = angular.isFunction(scope.$watchCollection);
|
|
|
const supportsWatchGroup = angular.isFunction(scope.$watchGroup);
|
|
const supportsWatchGroup = angular.isFunction(scope.$watchGroup);
|
|
|
|
|
|
|
@@ -138,24 +140,24 @@ function watchProps(watchDepth, scope, watchExpressions, listener) {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// render React component, with scope[attrs.props] being passed in as the component props
|
|
// render React component, with scope[attrs.props] being passed in as the component props
|
|
|
-function renderComponent(component, props, scope, elem) {
|
|
|
|
|
|
|
+function renderComponent(component: any, props: object, scope: any, elem: Element[]) {
|
|
|
scope.$evalAsync(() => {
|
|
scope.$evalAsync(() => {
|
|
|
ReactDOM.render(React.createElement(component, props), elem[0]);
|
|
ReactDOM.render(React.createElement(component, props), elem[0]);
|
|
|
});
|
|
});
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// get prop name from prop (string or array)
|
|
// get prop name from prop (string or array)
|
|
|
-function getPropName(prop) {
|
|
|
|
|
|
|
+function getPropName(prop: any) {
|
|
|
return Array.isArray(prop) ? prop[0] : prop;
|
|
return Array.isArray(prop) ? prop[0] : prop;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// get prop name from prop (string or array)
|
|
// get prop name from prop (string or array)
|
|
|
-function getPropConfig(prop) {
|
|
|
|
|
|
|
+function getPropConfig(prop: any) {
|
|
|
return Array.isArray(prop) ? prop[1] : {};
|
|
return Array.isArray(prop) ? prop[1] : {};
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// get prop expression from prop (string or array)
|
|
// get prop expression from prop (string or array)
|
|
|
-function getPropExpression(prop) {
|
|
|
|
|
|
|
+function getPropExpression(prop: any) {
|
|
|
return Array.isArray(prop) ? prop[0] : prop;
|
|
return Array.isArray(prop) ? prop[0] : prop;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -170,11 +172,12 @@ function findAttribute(attrs: string, propName: string): string {
|
|
|
const index = Object.keys(attrs).find(attr => {
|
|
const index = Object.keys(attrs).find(attr => {
|
|
|
return attr.toLowerCase() === propName.toLowerCase() || attr.toLowerCase() === kebabCase(propName);
|
|
return attr.toLowerCase() === propName.toLowerCase() || attr.toLowerCase() === kebabCase(propName);
|
|
|
});
|
|
});
|
|
|
|
|
+ // @ts-ignore
|
|
|
return attrs[index];
|
|
return attrs[index];
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// get watch depth of prop (string or array)
|
|
// get watch depth of prop (string or array)
|
|
|
-function getPropWatchDepth(defaultWatch, prop) {
|
|
|
|
|
|
|
+function getPropWatchDepth(defaultWatch: string, prop: string | any[]) {
|
|
|
const customWatchDepth = Array.isArray(prop) && angular.isObject(prop[1]) && prop[1].watchDepth;
|
|
const customWatchDepth = Array.isArray(prop) && angular.isObject(prop[1]) && prop[1].watchDepth;
|
|
|
return customWatchDepth || defaultWatch;
|
|
return customWatchDepth || defaultWatch;
|
|
|
}
|
|
}
|
|
@@ -197,11 +200,11 @@ function getPropWatchDepth(defaultWatch, prop) {
|
|
|
// }
|
|
// }
|
|
|
// }));
|
|
// }));
|
|
|
//
|
|
//
|
|
|
-const reactComponent = $injector => {
|
|
|
|
|
|
|
+const reactComponent = ($injector: any): any => {
|
|
|
return {
|
|
return {
|
|
|
restrict: 'E',
|
|
restrict: 'E',
|
|
|
replace: true,
|
|
replace: true,
|
|
|
- link: function(scope, elem, attrs) {
|
|
|
|
|
|
|
+ link: function(scope: any, elem: Element[], attrs: any) {
|
|
|
const reactComponent = getReactComponent(attrs.name, $injector);
|
|
const reactComponent = getReactComponent(attrs.name, $injector);
|
|
|
|
|
|
|
|
const renderMyComponent = () => {
|
|
const renderMyComponent = () => {
|
|
@@ -254,12 +257,12 @@ const reactComponent = $injector => {
|
|
|
//
|
|
//
|
|
|
// <hello name="name"/>
|
|
// <hello name="name"/>
|
|
|
//
|
|
//
|
|
|
-const reactDirective = $injector => {
|
|
|
|
|
- return (reactComponentName, props, conf, injectableProps) => {
|
|
|
|
|
|
|
+const reactDirective = ($injector: auto.IInjectorService) => {
|
|
|
|
|
+ return (reactComponentName: string, props: string[], conf: any, injectableProps: any) => {
|
|
|
const directive = {
|
|
const directive = {
|
|
|
restrict: 'E',
|
|
restrict: 'E',
|
|
|
replace: true,
|
|
replace: true,
|
|
|
- link: function(scope, elem, attrs) {
|
|
|
|
|
|
|
+ link: function(scope: any, elem: Element[], attrs: any) {
|
|
|
const reactComponent = getReactComponent(reactComponentName, $injector);
|
|
const reactComponent = getReactComponent(reactComponentName, $injector);
|
|
|
|
|
|
|
|
// if props is not defined, fall back to use the React component's propTypes if present
|
|
// if props is not defined, fall back to use the React component's propTypes if present
|
|
@@ -267,8 +270,8 @@ const reactDirective = $injector => {
|
|
|
|
|
|
|
|
// for each of the properties, get their scope value and set it to scope.props
|
|
// for each of the properties, get their scope value and set it to scope.props
|
|
|
const renderMyComponent = () => {
|
|
const renderMyComponent = () => {
|
|
|
- let scopeProps = {};
|
|
|
|
|
- const config = {};
|
|
|
|
|
|
|
+ let scopeProps: any = {};
|
|
|
|
|
+ const config: any = {};
|
|
|
|
|
|
|
|
props.forEach(prop => {
|
|
props.forEach(prop => {
|
|
|
const propName = getPropName(prop);
|
|
const propName = getPropName(prop);
|