informed
Version:
A lightweight framework and utility for building powerful forms in React applications
125 lines (114 loc) • 4.93 kB
JavaScript
;
Object.defineProperty(exports, '__esModule', { value: true });
var _rollupPluginBabelHelpers = require('../_virtual/_rollupPluginBabelHelpers.js');
var React = require('react');
var Context = require('../Context.js');
var useFormController = require('./useFormController.js');
var useStateWithGetter = require('./useStateWithGetter.js');
var useFieldSubscription = require('./useFieldSubscription.js');
var debug = require('../debug.js');
var logger = debug.Debug('informed:useRelevance' + '\t');
/* ----------------------- useRelevance ----------------------- */
var useRelevance = function useRelevance(_ref) {
var name = _ref.name,
relevant = _ref.relevant,
_ref$relevanceWhen = _ref.relevanceWhen,
relevanceWhen = _ref$relevanceWhen === void 0 ? [] : _ref$relevanceWhen,
_ref$relevanceDeps = _ref.relevanceDeps,
relevanceDeps = _ref$relevanceDeps === void 0 ? [] : _ref$relevanceDeps;
// Grab the form controller
var formController = useFormController.useFormController();
// Get scope
var scope = React.useContext(Context.ScopeContext);
// Need ref to scope because subscriptions will keep ref to it
var scopeRef = React.useRef(scope);
scopeRef.current = scope;
var depsRef = React.useRef();
depsRef.current = relevanceDeps;
// Relevant state
var _useStateWithGetter = useStateWithGetter.useStateWithGetter(function () {
if (relevant) {
logger("re-evaluated relevance for ".concat(name, " for the first inital load"));
return relevant({
formState: formController.getFormState(),
formApi: formController.getFormApi(),
scope: scope,
relevanceDeps: relevanceDeps
});
}
return true;
}),
_useStateWithGetter2 = _rollupPluginBabelHelpers.slicedToArray(_useStateWithGetter, 3),
isRelevant = _useStateWithGetter2[0],
setIsRelevant = _useStateWithGetter2[1],
getIsRelevant = _useStateWithGetter2[2];
var check = typeof relevanceWhen === 'function' ? [] : relevanceWhen;
var fields = React.useMemo(function () {
if (typeof relevanceWhen === 'function') {
// Generate fields array with scope
// Example: relevanceWhen = scope => [`${scope}.foo`, `${scope}.bar`]
return relevanceWhen(scope);
}
// Example relevanceWhen = ["name", "age"]
return relevanceWhen;
}, [].concat(_rollupPluginBabelHelpers.toConsumableArray(check), [scope]));
// Example relevanceWhen = ["name", "age"]
useFieldSubscription.useFieldSubscription('field-value', fields, function (target) {
logger("re-evaluating relevance for ".concat(name, " because of ").concat(target));
var rel = relevant({
formState: formController.getFormState(),
formApi: formController.getFormApi(),
scope: scopeRef.current,
relevanceDeps: depsRef.current
});
// Only update if we changed
if (getIsRelevant() != rel) {
// console.log("UPDATING", name, rel);
setIsRelevant(rel);
}
},
// Note: we pass false because we don't want this to be scoped!
// When the user explicitly uses a function!
!(typeof relevanceWhen === 'function'));
// Register for ALL events if we have no relevanceWhen
React.useEffect(function () {
if (relevant && typeof relevanceWhen !== 'function' && relevanceWhen.length === 0) {
// When we have a field update we always check
var listener = function listener(target) {
logger("re-evaluating relevance for ".concat(name, " because of ").concat(target));
var rel = relevant({
formState: formController.getFormState(),
formApi: formController.getFormApi(),
scope: scopeRef.current,
relevanceDeps: depsRef.current
});
logger("re-evaluated relevance for ".concat(name, " because of ").concat(target, " and got ").concat(rel));
// Only update if we changed
if (getIsRelevant() != rel) {
// console.log("UPDATING", name, rel);
logger("updating relevance for ".concat(name, " because of ").concat(target, " and got ").concat(rel));
setIsRelevant(rel);
}
};
formController.emitter.on('field', listener);
return function () {
// console.log("REMOVED LISTENER", name);
formController.emitter.removeListener('field', listener);
};
}
}, []);
React.useEffect(function () {
if (relevant) {
logger("re-evaluated relevance for ".concat(name, " because name change or relevanceDeps"));
// When name changes we always check if relevant
setIsRelevant(relevant({
formState: formController.getFormState(),
formApi: formController.getFormApi(),
scope: scopeRef.current,
relevanceDeps: depsRef.current
}));
}
}, [name].concat(_rollupPluginBabelHelpers.toConsumableArray(relevanceDeps)));
return isRelevant;
};
exports.useRelevance = useRelevance;