UNPKG

react-magnetic-di

Version:
67 lines (58 loc) 2.84 kB
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } import React, { useContext, useMemo, forwardRef } from 'react'; import PropTypes from 'prop-types'; import { KEY } from './constants'; import { Context } from './context'; import { getDisplayName } from './utils'; export var DiProvider = function DiProvider(_ref) { var children = _ref.children, use = _ref.use, target = _ref.target; var _useContext = useContext(Context), _getDependencies = _useContext.getDependencies; // memo provider value so gets computed only once var value = useMemo(function () { // create a map of dependency real -> replacement for fast lookup var replacementMap = use.reduce(function (m, d) { return m.set(d[KEY], d); }, new Map()); // support single or multiple targets var targets = target && (Array.isArray(target) ? target : [target]); return { getDependencies: function getDependencies(realDeps, targetChild) { // First we collect dependencies from parent provider(s) (if any) var dependencies = _getDependencies(realDeps, targetChild); // If no target or target is in the array of targets, map use if (!targetChild || !targets || targets.includes(targetChild)) { return dependencies.map(function (dep) { // dep can be either the original or a replacement // if another provider at the top has already swapped it // so we check if here we need to inject a different one // or return the original / parent replacement var real = dep[KEY] || dep; return replacementMap.get(real) || dep; }); } return dependencies; } }; }, [_getDependencies]); // ignore use & target props return /*#__PURE__*/React.createElement(Context.Provider, { value: value }, children); }; DiProvider.propTypes = { children: PropTypes.oneOfType([PropTypes.func, PropTypes.node]), target: PropTypes.oneOfType([PropTypes.func, PropTypes.arrayOf(PropTypes.func)]), use: PropTypes.arrayOf(PropTypes.func).isRequired }; export function withDi(Comp, deps) { var target = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null; var WrappedComponent = /*#__PURE__*/forwardRef(function (props, ref) { return /*#__PURE__*/React.createElement(DiProvider, { use: deps, target: target }, /*#__PURE__*/React.createElement(Comp, _extends({ ref: ref }, props))); }); WrappedComponent.displayName = getDisplayName(Comp, 'withDi'); return WrappedComponent; }