@bigbinary/neetoui
Version:
neetoUI drives the experience at all neeto products
200 lines (193 loc) • 8.86 kB
JavaScript
;
var _extends = require('@babel/runtime/helpers/extends');
var React = require('react');
var formik = require('formik');
var _defineProperty = require('@babel/runtime/helpers/defineProperty');
var _asyncToGenerator = require('@babel/runtime/helpers/asyncToGenerator');
var _objectWithoutProperties = require('@babel/runtime/helpers/objectWithoutProperties');
var _regeneratorRuntime = require('@babel/runtime/regenerator');
var ramda = require('ramda');
var _toConsumableArray = require('@babel/runtime/helpers/toConsumableArray');
var _slicedToArray = require('@babel/runtime/helpers/slicedToArray');
var neetoCist = require('@bigbinary/neeto-cist');
var transformObjectToDotNotation = function transformObjectToDotNotation(object) {
var prefix = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "";
var result = [];
Object.entries(object).forEach(function (_ref) {
var _ref2 = _slicedToArray(_ref, 2),
key = _ref2[0],
value = _ref2[1];
if (!value) return;
var nextKey = prefix ? "".concat(prefix, ".").concat(key) : key;
if (ramda.is(Object, value)) {
result.push.apply(result, _toConsumableArray(transformObjectToDotNotation(value, nextKey)));
} else {
result.push(nextKey);
}
});
return result;
};
var getErrorFieldName = function getErrorFieldName(formikErrors) {
var _transformObjectToDot;
return (_transformObjectToDot = transformObjectToDotNotation(formikErrors)) === null || _transformObjectToDot === void 0 ? void 0 : _transformObjectToDot[0];
};
var getFieldsWithServerError = function getFieldsWithServerError() {
var status = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
return Object.keys(status).filter(function (fieldName) {
return neetoCist.isPresent(status[fieldName]);
});
};
var scrollToError = function scrollToError(formRef, errors, status) {
var fieldErrorName = getErrorFieldName(errors);
var _getFieldsWithServerE = getFieldsWithServerError(status),
_getFieldsWithServerE2 = _slicedToArray(_getFieldsWithServerE, 1),
fieldWithServerError = _getFieldsWithServerE2[0];
if (!fieldErrorName && !fieldWithServerError) return;
var errorFieldName = fieldErrorName || fieldWithServerError;
var errorFormElement = formRef.current.querySelector("[name=\"".concat(errorFieldName, "\"]"));
errorFormElement === null || errorFormElement === void 0 || errorFormElement.scrollIntoView({
behavior: "smooth",
block: "center"
});
};
var ScrollToErrorField = function ScrollToErrorField(_ref) {
var formRef = _ref.formRef;
var _useFormikContext = formik.useFormikContext(),
submitCount = _useFormikContext.submitCount,
isValid = _useFormikContext.isValid,
errors = _useFormikContext.errors,
status = _useFormikContext.status;
React.useEffect(function () {
var fieldsWithServerError = getFieldsWithServerError(status);
if (!formRef.current || isValid && ramda.isEmpty(fieldsWithServerError)) {
return;
}
scrollToError(formRef, errors, status);
}, [submitCount]);
return null;
};
var _excluded = ["validateForm", "setErrors", "setTouched", "submitForm"];
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
var FormWrapper = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
var className = _ref.className,
formProps = _ref.formProps,
children = _ref.children,
scrollToErrorField = _ref.scrollToErrorField;
var _useFormikContext = formik.useFormikContext(),
validateForm = _useFormikContext.validateForm,
setErrors = _useFormikContext.setErrors,
setTouched = _useFormikContext.setTouched,
submitForm = _useFormikContext.submitForm,
formikBag = _objectWithoutProperties(_useFormikContext, _excluded);
var isFormDirty = formikBag.dirty,
isSubmitting = formikBag.isSubmitting,
status = formikBag.status;
var formRefForScrollToErrorField = React.useRef();
var formRef = ref || formRefForScrollToErrorField;
var handleKeyDown = React.useCallback( /*#__PURE__*/function () {
var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(event) {
var isEventFromEditorOrTextarea, errors, fieldStatuses;
return _regeneratorRuntime.wrap(function _callee$(_context) {
while (1) switch (_context.prev = _context.next) {
case 0:
isEventFromEditorOrTextarea = event.target.tagName === "TEXTAREA" || event.target.editor;
if (!(event.key !== "Enter")) {
_context.next = 3;
break;
}
return _context.abrupt("return");
case 3:
if (!(isEventFromEditorOrTextarea && !event.metaKey)) {
_context.next = 5;
break;
}
return _context.abrupt("return");
case 5:
event.preventDefault();
if (!event.shiftKey) {
_context.next = 8;
break;
}
return _context.abrupt("return");
case 8:
if (!(!isFormDirty || isSubmitting)) {
_context.next = 10;
break;
}
return _context.abrupt("return");
case 10:
_context.prev = 10;
_context.next = 13;
return validateForm();
case 13:
errors = _context.sent;
fieldStatuses = getFieldsWithServerError(status);
if (Object.keys(errors).length > 0 || Object.keys(fieldStatuses).length > 0) {
setErrors(errors);
setTouched(_objectSpread(_objectSpread({}, errors), status));
scrollToErrorField && scrollToError(formRef, errors, status);
} else {
submitForm();
}
_context.next = 21;
break;
case 18:
_context.prev = 18;
_context.t0 = _context["catch"](10);
// eslint-disable-next-line no-console
console.error("An unhandled error was caught from validateForm()", _context.t0);
case 21:
case "end":
return _context.stop();
}
}, _callee, null, [[10, 18]]);
}));
return function (_x) {
return _ref2.apply(this, arguments);
};
}(), [validateForm, setErrors, setTouched, isFormDirty, isSubmitting, submitForm, status]);
return /*#__PURE__*/React.createElement(formik.Form, _extends({
className: className,
noValidate: true,
"data-testid": "neeto-ui-form-wrapper",
ref: formRef,
onKeyDown: handleKeyDown
}, formProps), scrollToErrorField && /*#__PURE__*/React.createElement(ScrollToErrorField, {
formRef: formRef
}), children);
});
FormWrapper.displayName = "FormWrapper";
var Form = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
var className = _ref.className,
children = _ref.children,
formikProps = _ref.formikProps,
formProps = _ref.formProps,
_ref$scrollToErrorFie = _ref.scrollToErrorField,
scrollToErrorField = _ref$scrollToErrorFie === void 0 ? false : _ref$scrollToErrorFie;
var formikRef = React.useRef();
var handleSubmit = function handleSubmit(values, actions) {
var _formikRef$current;
var fieldsWithServerError = getFieldsWithServerError((_formikRef$current = formikRef.current) === null || _formikRef$current === void 0 ? void 0 : _formikRef$current.status);
if (fieldsWithServerError.length > 0) {
actions.setSubmitting(false);
return undefined;
}
return formikProps.onSubmit(values, actions);
};
return /*#__PURE__*/React.createElement(formik.Formik, _extends({
innerRef: formikRef
}, formikProps, {
onSubmit: handleSubmit
}), function (props) {
return /*#__PURE__*/React.createElement(FormWrapper, {
className: className,
formProps: formProps,
ref: ref,
scrollToErrorField: scrollToErrorField
}, typeof children === "function" ? children(props) : children);
});
});
Form.displayName = "Form";
module.exports = Form;
//# sourceMappingURL=Form.js.map