UNPKG

@shopgate/engage

Version:
27 lines 6.91 kB
import _regeneratorRuntime from"@babel/runtime/regenerator";import _debounce from"lodash/debounce";function _defineProperty(obj,key,value){if(key in obj){Object.defineProperty(obj,key,{value:value,enumerable:true,configurable:true,writable:true});}else{obj[key]=value;}return obj;}function _extends(){_extends=Object.assign||function(target){for(var i=1;i<arguments.length;i++){var source=arguments[i];for(var key in source){if(Object.prototype.hasOwnProperty.call(source,key)){target[key]=source[key];}}}return target;};return _extends.apply(this,arguments);}function asyncGeneratorStep(gen,resolve,reject,_next,_throw,key,arg){try{var info=gen[key](arg);var value=info.value;}catch(error){reject(error);return;}if(info.done){resolve(value);}else{Promise.resolve(value).then(_next,_throw);}}function _asyncToGenerator(fn){return function(){var self=this,args=arguments;return new Promise(function(resolve,reject){var gen=fn.apply(self,args);function _next(value){asyncGeneratorStep(gen,resolve,reject,_next,_throw,"next",value);}function _throw(err){asyncGeneratorStep(gen,resolve,reject,_next,_throw,"throw",err);}_next(undefined);});};}function _slicedToArray(arr,i){return _arrayWithHoles(arr)||_iterableToArrayLimit(arr,i)||_nonIterableRest();}function _nonIterableRest(){throw new TypeError("Invalid attempt to destructure non-iterable instance");}function _iterableToArrayLimit(arr,i){var _arr=[];var _n=true;var _d=false;var _e=undefined;try{for(var _i=arr[Symbol.iterator](),_s;!(_n=(_s=_i.next()).done);_n=true){_arr.push(_s.value);if(i&&_arr.length===i)break;}}catch(err){_d=true;_e=err;}finally{try{if(!_n&&_i["return"]!=null)_i["return"]();}finally{if(_d)throw _e;}}return _arr;}function _arrayWithHoles(arr){if(Array.isArray(arr))return arr;}import{useRef,useState,useEffect,useCallback}from'react';import{useScrollTo}from"./useScrollTo";import{i18n}from"../helpers/i18n";import{useValidation}from"../validation";/** * Converts validation errors into errors for form builder. * @param {Object} validationErrors The validation errors. * @returns {Array} */export var convertValidationErrors=function convertValidationErrors(validationErrors){return Object.keys(validationErrors).map(function(key){return{path:key,message:i18n.text(validationErrors[key])};});};/** * @param {Object} initialState The initial form state. * @param {Function} complete The completion callback. * @param {Object} validationConstraints validationConstraints * @param {Object} [formContainerRef=null] A ref to a container with forms * @param {number} [validationErrorScrollOffset=10] When a form container ref is passed with the * parameters, whenever validation errors occur, the page will scroll to the first error. Depending * on the page, the scroll logic might not be accurate. So this offset parameter can be used * to influence scroll behavior. * @returns {{ handleChange, handleSubmit, values, valid, validationErrors: ?Object, isSubmitting }} */export function useFormState(initialState,complete){var validationConstraints=arguments.length>2&&arguments[2]!==undefined?arguments[2]:{};var formContainerRef=arguments.length>3&&arguments[3]!==undefined?arguments[3]:null;var validationErrorScrollOffset=arguments.length>4&&arguments[4]!==undefined?arguments[4]:10;var _useScrollTo=useScrollTo(formContainerRef,validationErrorScrollOffset),scrollTo=_useScrollTo.scrollTo;// Submit lock prevents the form from being submitted multiple times var submitLock=useRef(false);var _useState=useState(initialState),_useState2=_slicedToArray(_useState,2),values=_useState2[0],setValues=_useState2[1];var _useState3=useState(false),_useState4=_slicedToArray(_useState3,2),isSubmitting=_useState4[0],setSubmitting=_useState4[1];var _useState5=useState(false),_useState6=_slicedToArray(_useState5,2),changed=_useState6[0],setChanged=_useState6[1];var _useState7=useState(false),_useState8=_slicedToArray(_useState7,2),ignoreErrors=_useState8[0],setIgnoreErrors=_useState8[1];var _useValidation=useValidation(validationConstraints),valid=_useValidation.valid,validationErrors=_useValidation.validationErrors,validate=_useValidation.validate,reset=_useValidation.reset;var scrollToError=useCallback(function(){var errorElement=document.querySelector('.validationError');if(errorElement){scrollTo('.validationError');var inputElement=errorElement.querySelector('input, select, textarea');if(inputElement){inputElement.focus();}}},[scrollTo]);// -- CHANGED --------------- useEffect(function(){var isEqual=JSON.stringify(values)===JSON.stringify(initialState);if(!isEqual&&!changed){setChanged(true);}else if(isEqual&&changed){setChanged(false);}},[changed,initialState,values]);// -- IS_SUBMITTING --------- /* eslint-disable react-hooks/exhaustive-deps */useEffect(function(){if(!isSubmitting){return;}var mounted=true;if((valid===true||ignoreErrors)&&!submitLock.current){submitLock.current=true;_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee(){return _regeneratorRuntime.wrap(function _callee$(_context){while(1)switch(_context.prev=_context.next){case 0:_context.next=2;return complete(values);case 2:if(mounted){setSubmitting(false);setChanged(false);submitLock.current=false;}case 3:case"end":return _context.stop();}},_callee);}))();}// eslint-disable-next-line consistent-return return function(){mounted=false;};},[isSubmitting,valid,ignoreErrors]);/* eslint-enable react-hooks/exhaustive-deps */useEffect(function(){scrollToError();},[isSubmitting,scrollToError]);useEffect(function(){return function(){submitLock.current=false;};},[]);// -- VALIDATION ON SUBMIT --------- useEffect(function(){if(ignoreErrors){return;}// Yest no validation on submit if(changed&&valid!==null){validate(values);}if(isSubmitting&&valid===null){validate(values);}if(isSubmitting&&valid===false){setSubmitting(false);}},[changed,validate,values,isSubmitting,valid,ignoreErrors]);var handleSetIgnoreErrors=useCallback(function(value){setIgnoreErrors(value);if(ignoreErrors===true){reset();}},[ignoreErrors,reset]);/** * @param {string} sanitized The sanitized field value. * @param {Object} event The change event object. */var handleChange=useCallback(function(sanitized,event){if(!event){return;}setValues(_extends({},values,_defineProperty({},event.target.name,sanitized)));},[values]);/** * Debounced (dbl-click) submit handler * @param {Object} event The submit event object. */var handleSubmit=_debounce(function(event){if(event===null||event===void 0?void 0:event.preventDefault){event.preventDefault();}setSubmitting(true);},300,{leading:true,trailing:false});return{resetValidationErrors:reset,handleChange:handleChange,handleSubmit:handleSubmit,values:values,valid:!ignoreErrors?valid:true,validationErrors:!ignoreErrors?validationErrors:[],isSubmitting:isSubmitting,setValues:setValues,scrollToError:scrollToError,setIgnoreErrors:handleSetIgnoreErrors,validate:validate};}