UNPKG

envoc-form

Version:

Envoc form components

96 lines (95 loc) 4.64 kB
"use strict"; var __assign = (this && this.__assign) || function () { __assign = Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; Object.defineProperty(exports, "__esModule", { value: true }); var react_1 = require("react"); var formik_1 = require("formik"); var FieldNameContext_1 = require("./FieldNameContext"); var ServerErrorContext_1 = require("../Form/ServerErrorContext"); /** Provides a consistent way to deal with all form fields (non array). */ function useStandardField(_a) { var providedId = _a.id, providedName = _a.name, disabled = _a.disabled, validate = _a.validate, normalize = _a.normalize; // because the formik errors are evaluated all at the same time we need to keep server errors separate var _b = (0, react_1.useContext)(ServerErrorContext_1.ServerErrorContext), getServerError = _b.getError, setServerError = _b.setError; // ensure that form section values are obeyed, e.g. homeAddress.zipCode var fieldNameContextValue = (0, react_1.useContext)(FieldNameContext_1.FieldNameContext); var name = fieldNameContextValue ? "".concat(fieldNameContextValue, ".").concat(providedName) : providedName; // ensure that nested contexts don't have duplicate id issues when an id is specified var id = providedId ? fieldNameContextValue ? "".concat(fieldNameContextValue, ".").concat(providedId) : providedId : name; // ensure that our custom validation rules are handled // e.g. we allow arrays of validators var _c = (0, formik_1.useField)({ name: name, id: id ? id : name, disabled: disabled, validate: callAllValidators, }), formikInput = _c[0], formikMeta = _c[1]; var _d = (0, formik_1.useFormikContext)(), setFieldTouched = _d.setFieldTouched, setFieldValue = _d.setFieldValue, isSubmitting = _d.isSubmitting; var touched = formikMeta.touched !== false && formikMeta.touched !== undefined; (0, react_1.useEffect)(function () { if (!touched && isSubmitting) { // because we do not always register all fields up front. // e.g. formik expects even a 'create' form to have all fields given, at least, blank values // It looks like this was going to be a thing: https://github.com/jaredpalmer/formik/issues/691 // Formik appears to not have an active maintainer: https://github.com/jaredpalmer/formik/discussions/3526 // We previously had a different fix in place using handleBlur, but it was causing an infinite update cycle. // This was noted as existing, but there was a note about it not working for FieldArray (this does appear to work in my testing with FieldArray) setFieldTouched(name); } }, [isSubmitting, name, setFieldTouched, touched]); // these are the props we expect consumers of this hook to pass directly to the input (or other control) var resultInput = { name: formikInput.name, // pass any direct from server props through normalize without making the form dirty (e.g. phone number) value: normalize ? normalize(formikInput.value) : formikInput.value, onChange: handleChange, onBlur: handleBlur, // extensions to formik id: id, }; var resultMeta = __assign(__assign({}, formikMeta), { error: getServerError(name) || (touched ? formikMeta.error : undefined), // extensions to formik warning: undefined, touched: touched }); return [resultInput, resultMeta]; function handleBlur() { formikInput.onBlur({ target: { name: name } }); } function handleChange(value) { if (disabled) { return; } var normalized = normalize ? normalize(value) : value; setFieldValue(name, normalized); setServerError(name, undefined); } function callAllValidators(value) { if (disabled || !validate) { return; } if (!Array.isArray(validate)) { return validate(value); } for (var i = 0; i < validate.length; i++) { var result = validate[i](value); if (result) { return result; } } } } exports.default = useStandardField;