UNPKG

informed

Version:

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

93 lines (81 loc) 3.59 kB
import { toConsumableArray as _toConsumableArray } from '../_virtual/_rollupPluginBabelHelpers.js'; import { useContext, useMemo, useEffect } from 'react'; import { useFormController } from './useFormController.js'; import { isChild } from '../utils.js'; import { Debug } from '../debug.js'; import { useScoper } from './useScoper.js'; import { ScopeContext } from '../Context.js'; var debug = Debug('informed:useFieldSubscription' + '\t'); /* ----------------------- useFieldSubscription ----------------------- */ var useFieldSubscription = function useFieldSubscription(event) { var fields = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : []; var cb = arguments.length > 2 ? arguments[2] : undefined; var scoped = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true; var flipped = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false; // Create scoper function var scope = useScoper(); var scopedContext = useContext(ScopeContext); // Determine what fields is ( might be function ) var check = typeof fields === 'function' ? [] : fields; var builtFields = useMemo(function () { if (typeof fields === 'function') { // Generate fields array with scope // Example: fields = scope => [`${scope}.foo`, `${scope}.bar`] return fields(scopedContext); } // Example relevanceWhen = ["name", "age"] return fields; }, [].concat(_toConsumableArray(check), [scope])); // Generate scoped fields var scopedFields = useMemo(function () { if (scoped && typeof fields != 'function') { return builtFields.map(function (field) { return scope(field); }); } return builtFields; }, [builtFields]); // Grab the form controller var formController = useFormController(); // Magic trick // const forceUpdate = useForceUpdate(); // Register for events on our field useEffect(function () { var listener = function listener(target, triggers) { // Who triggered this event // Example trigger = "UnitedStates.Price" debug("target: ".concat(target, ", triggers: ").concat(triggers)); // console.log('TARGET', target, 'FIELDS', scopedFields); // either // 1. All fields are supposed to update // 2. This is a specific registration "foo" === "foo" // 3. This field is a child of registration "friends[0].name" is a child of name="friends[0]" if (target === '_ALL_' || scopedFields.includes(target) || target && scopedFields.some(function (field) { if (flipped) { // isChild( parent, child ) return isChild(target, field); } else { // isChild( parent, child ) return isChild(field, target); } })) { debug("subscription ".concat(event, " triggered with target ").concat(target, " from trigger ").concat(triggers, " for"), scopedFields); // forceUpdate(); cb(target, triggers); } }; formController.emitter.on(event, listener); if (scopedFields.length) { debug("Adding subscription on event ".concat(event, ", subscribing to events from ").concat(scopedFields)); } // When name changes we always force an update! // forceUpdate(); return function () { if (scopedFields.length) { debug("Removing subscription on event ".concat(event, ", un-subscribing to events from ").concat(scopedFields)); } formController.emitter.removeListener(event, listener); }; }, _toConsumableArray(check)); }; export { useFieldSubscription };