informed
Version:
A lightweight framework and utility for building powerful forms in React applications
93 lines (81 loc) • 3.59 kB
JavaScript
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 };