informed
Version:
A lightweight framework and utility for building powerful forms in React applications
108 lines (99 loc) • 3.85 kB
JavaScript
import { slicedToArray as _slicedToArray, toConsumableArray as _toConsumableArray } from '../_virtual/_rollupPluginBabelHelpers.js';
import { useContext, useRef, useState, useMemo, useEffect } from 'react';
import { ScopeContext } from '../Context.js';
import { useFormController } from './useFormController.js';
import { useFieldSubscription } from './useFieldSubscription.js';
import { Debug } from '../debug.js';
var logger = Debug('informed:useConditional' + '\t');
/* ----------------------- useDepends ----------------------- */
var useConditional = function useConditional(_ref) {
var name = _ref.name,
evaluate = _ref.evaluate,
_ref$evaluateWhen = _ref.evaluateWhen,
evaluateWhen = _ref$evaluateWhen === void 0 ? [] : _ref$evaluateWhen,
_ref$dependsOn = _ref.dependsOn,
dependsOn = _ref$dependsOn === void 0 ? [] : _ref$dependsOn,
_ref$native = _ref["native"],
_native = _ref$native === void 0 ? false : _ref$native,
_ref$evaluateOnMount = _ref.evaluateOnMount,
evaluateOnMount = _ref$evaluateOnMount === void 0 ? true : _ref$evaluateOnMount;
// 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;
// Conditional state
var _useState = useState(function () {
if (evaluate && evaluateOnMount) {
return evaluate({
formState: formController.getFormState(),
formApi: formController.getFormApi(),
scope: scope,
dependsOn: dependsOn
});
}
return {};
}),
_useState2 = _slicedToArray(_useState, 2),
props = _useState2[0],
setProps = _useState2[1];
var check = typeof evaluateWhen === 'function' ? [] : evaluateWhen;
var fields = useMemo(function () {
if (typeof evaluateWhen === 'function') {
// Generate fields array with scope
// Example: evaluateWhen = scope => [`${scope}.foo`, `${scope}.bar`]
return evaluateWhen(scope);
}
// Example evaluateWhen = ["name", "age"]
return evaluateWhen;
}, [].concat(_toConsumableArray(check), [scope]));
var event = _native ? 'field-native' : 'field-value';
// Example evaluateWhen = ["name", "age"]
useFieldSubscription(event, fields, function (target, triggers) {
logger("re-evaluating ".concat(name, " because ").concat(target, " changed, triggerd by ").concat(JSON.stringify(triggers, null, 2)));
var res = evaluate({
formState: formController.getFormState(),
formApi: formController.getFormApi(),
scope: scopeRef.current,
dependsOn: dependsOn,
target: target,
triggers: triggers
});
setProps(res);
},
// Note: we pass false because we don't want this to be scoped!
// When the user explicitly uses a function!
!(typeof evaluateWhen === 'function'));
useEffect(function () {
if (evaluate && evaluateOnMount) {
// When name changes we always re evaluate
setProps(evaluate({
formState: formController.getFormState(),
formApi: formController.getFormApi(),
scope: scope,
dependsOn: dependsOn
}));
}
}, [name].concat(_toConsumableArray(dependsOn)));
// Trigger evaluate on a reset of form
useEffect(function () {
var listener = function listener() {
if (evaluate && evaluateOnMount) {
setProps(evaluate({
formState: formController.getFormState(),
formApi: formController.getFormApi(),
scope: scope,
dependsOn: dependsOn
}));
}
};
formController.emitter.on('reset', listener);
return function () {
formController.emitter.removeListener('reset', listener);
};
}, []);
return props;
};
export { useConditional };