UNPKG

informed

Version:

A lightweight framework and utility for building powerful forms in React applications

121 lines (112 loc) 4.75 kB
import { slicedToArray as _slicedToArray, toConsumableArray as _toConsumableArray } from '../_virtual/_rollupPluginBabelHelpers.js'; import { useContext, useRef, useMemo, useEffect } from 'react'; import { ScopeContext } from '../Context.js'; import { useFormController } from './useFormController.js'; import { useStateWithGetter } from './useStateWithGetter.js'; import { useFieldSubscription } from './useFieldSubscription.js'; import { Debug } from '../debug.js'; var logger = 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(); // Get scope var scope = useContext(ScopeContext); // Need ref to scope because subscriptions will keep ref to it var scopeRef = useRef(scope); scopeRef.current = scope; var depsRef = useRef(); depsRef.current = relevanceDeps; // Relevant state var _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 = _slicedToArray(_useStateWithGetter, 3), isRelevant = _useStateWithGetter2[0], setIsRelevant = _useStateWithGetter2[1], getIsRelevant = _useStateWithGetter2[2]; var check = typeof relevanceWhen === 'function' ? [] : relevanceWhen; var fields = 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(_toConsumableArray(check), [scope])); // Example relevanceWhen = ["name", "age"] 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 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); }; } }, []); 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(_toConsumableArray(relevanceDeps))); return isRelevant; }; export { useRelevance };