informed
Version:
A lightweight framework and utility for building powerful forms in React applications
208 lines (194 loc) • 8.64 kB
JavaScript
;
Object.defineProperty(exports, '__esModule', { value: true });
var _rollupPluginBabelHelpers = require('../_virtual/_rollupPluginBabelHelpers.js');
var React = require('react');
var Relevant = require('./Relevant.js');
var useArrayField = require('../hooks/useArrayField.js');
var Context = require('../Context.js');
var useFormController = require('../hooks/useFormController.js');
var useFieldState = require('../hooks/useFieldState.js');
var debug$1 = require('../debug.js');
var useScopedApi = require('../hooks/useScopedApi.js');
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
var _excluded = ["relevant", "relevanceWhen", "relevanceDeps", "name"],
_excluded2 = ["children"];
var debug = debug$1.Debug('informed:ArrayField' + '\t');
var ArrayField = function ArrayField(_ref) {
var relevant = _ref.relevant,
relevanceWhen = _ref.relevanceWhen,
relevanceDeps = _ref.relevanceDeps,
name = _ref.name,
props = _rollupPluginBabelHelpers.objectWithoutProperties(_ref, _excluded);
if (relevant) {
return /*#__PURE__*/React__default["default"].createElement(Relevant.Relevant, {
when: relevant,
relevanceWhen: relevanceWhen,
relevanceDeps: relevanceDeps
}, /*#__PURE__*/React__default["default"].createElement(ArrayFieldWrapper, _rollupPluginBabelHelpers["extends"]({
name: name
}, props)));
} else {
return /*#__PURE__*/React__default["default"].createElement(ArrayFieldWrapper, _rollupPluginBabelHelpers["extends"]({
name: name
}, props));
}
};
var ArrayFieldWrapper = function ArrayFieldWrapper(_ref2) {
var children = _ref2.children,
props = _rollupPluginBabelHelpers.objectWithoutProperties(_ref2, _excluded2);
var _useArrayField = useArrayField.useArrayField(props),
render = _useArrayField.render,
arrayFieldState = _useArrayField.arrayFieldState,
arrayFieldApi = _useArrayField.arrayFieldApi;
if (typeof children === 'function') {
return render(children(_rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({
arrayFieldApi: arrayFieldApi,
arrayFieldState: arrayFieldState
}, arrayFieldApi), arrayFieldState)));
}
return render(children);
};
var ArrayFieldItem = function ArrayFieldItem(_ref3) {
var arrayFieldItemState = _ref3.arrayFieldItemState,
arrayFieldItemApi = _ref3.arrayFieldItemApi,
children = _ref3.children;
var formController = useFormController.useFormController();
// Map will store all fields by name
// Key => name
// Val => fieldMetaRef
// Why? so the array knows about all its field meta
var _useState = React.useState(function () {
return new Map();
}),
_useState2 = _rollupPluginBabelHelpers.slicedToArray(_useState, 1),
fieldsMap = _useState2[0];
// Register for child field updates
var subState = useFieldState.useFieldState(arrayFieldItemState.name);
// Get scoped api for item api
var itemApi = useScopedApi.useScopedApi(arrayFieldItemState.name);
// Example evaluateWhen = ["name", "age"]
// TODO maybe add this
// useFieldSubscription(
// 'field-modified',
// [arrayFieldItemState.name],
// target => {
// debug(`updating hidden field ${hidden} for ${name} because of ${target}`);
// formController.setModifiedValue(
// `${arrayFieldItemState.name}.${hidden}`,
// formController.getValue(`${arrayFieldItemState.name}.${hidden}`)
// );
// console.log(
// `updating hidden field ${hidden} for ${name} because of ${target}`
// );
// },
// false
// );
// Need to memoize to prevent re renders
var wrappedController = React.useMemo(function () {
return _rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, formController), {}, {
register: function register(n, m) {
fieldsMap.set(n, m);
formController.register(n, m);
},
deregister: function deregister(n, m) {
fieldsMap["delete"](n);
formController.deregister(n, m);
// When the very last field from the array is removed unlock
var lockedUntil = formController.getRemovalLocked();
debug(
// fieldsMap,
'DEREGISTER', n, 'SIZE', fieldsMap.size, 'INDEX', arrayFieldItemState.index, 'LOCKEDUNTIL', lockedUntil);
if (lockedUntil != null && lockedUntil.index === arrayFieldItemState.index && lockedUntil.name === arrayFieldItemState.parent &&
// We are the last field in this item
// 1. Example fieldsMap.keys() ==> [ 'friends[0].name' ]
// 2. We are de registering friends[1].age
// 3. We look to see if friends[1] is in the field map
// 4. If its not, we are done and can unlock!!
!Array.from(fieldsMap.keys()).some(function (k) {
// debug(
// 'CHECKING',
// k,
// `${arrayFieldItemState.parent}[${lockedUntil.index}]`
// );
return k.includes("".concat(arrayFieldItemState.parent, "[").concat(lockedUntil.index, "]"));
})) {
debug('UNLOCKING');
formController.unlockRemoval();
}
}
});
},
// WHATEVER YOU DO... DONT REMOVE THIS... need updated controller when index changes
[arrayFieldItemState.index]);
var reset = React.useCallback(function () {
fieldsMap.forEach(function (fieldMeta) {
fieldMeta.current.fieldApi.reset();
});
}, [arrayFieldItemState.name, arrayFieldItemState.index]);
var arrayFieldStateValue = _rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, arrayFieldItemState), {}, {
values: subState.value,
errors: subState.error,
touched: subState.touched
});
var arrayFieldItemApiValue = React.useMemo(function () {
return _rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, arrayFieldItemApi), itemApi), {}, {
reset: reset
});
}, [arrayFieldItemState.name, arrayFieldItemState.index]);
// const memoizedChildren = useMemo(
// () => {
// debug('Rendering');
// return children({
// ...arrayFieldItemApiValue,
// name: arrayFieldItemState.name,
// index: arrayFieldItemState.index
// });
// },
// [arrayFieldItemState.name, arrayFieldItemState.index]
// );
if (typeof children === 'function') {
return /*#__PURE__*/React__default["default"].createElement(Context.FormControllerContext.Provider, {
value: wrappedController
}, /*#__PURE__*/React__default["default"].createElement(Context.ArrayFieldItemApiContext.Provider, {
value: arrayFieldItemApiValue
}, /*#__PURE__*/React__default["default"].createElement(Context.ArrayFieldItemStateContext.Provider, {
value: arrayFieldStateValue
}, /*#__PURE__*/React__default["default"].createElement(Context.ScopeContext.Provider, {
value: arrayFieldItemState.name
}, children(_rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, arrayFieldItemApiValue), {}, {
name: arrayFieldItemState.name,
index: arrayFieldItemState.index
}))))));
}
return /*#__PURE__*/React__default["default"].createElement(Context.FormControllerContext.Provider, {
value: wrappedController
}, /*#__PURE__*/React__default["default"].createElement(Context.ArrayFieldItemApiContext.Provider, {
value: arrayFieldItemApi
}, /*#__PURE__*/React__default["default"].createElement(Context.ArrayFieldItemStateContext.Provider, {
value: arrayFieldItemState
}, /*#__PURE__*/React__default["default"].createElement(Context.ScopeContext.Provider, {
value: arrayFieldItemState.name
}, children))));
};
ArrayField.Items = function (_ref4) {
var children = _ref4.children;
// TODO maybe add this { hidden, fields } =
var _useContext = React.useContext(Context.ArrayFieldStateContext),
fields = _useContext.fields;
// console.log("FIELDS", fields);
return fields.map(function (_ref5) {
var arrayFieldItemState = _ref5.arrayFieldItemState,
arrayFieldItemApi = _ref5.arrayFieldItemApi;
var key = arrayFieldItemState.key;
return /*#__PURE__*/React__default["default"].createElement(ArrayFieldItem, {
key: key
// hidden={hidden}
,
arrayFieldItemApi: arrayFieldItemApi,
arrayFieldItemState: arrayFieldItemState
}, children);
});
};
ArrayField.Items.displayName = 'ArrayField.Items';
exports.ArrayField = ArrayField;