frmx
Version:
Simple, Performant, Lightweight React Forms
19 lines (16 loc) • 11.2 kB
JavaScript
import e,{useRef as t,useState as n,useEffect as r}from"react";
/*! *****************************************************************************
Copyright (c) Microsoft Corporation.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */function o(e,t){var n={};for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&t.indexOf(r)<0&&(n[r]=e[r]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var o=0;for(r=Object.getOwnPropertySymbols(e);o<r.length;o++)t.indexOf(r[o])<0&&Object.prototype.propertyIsEnumerable.call(e,r[o])&&(n[r[o]]=e[r[o]])}return n}const i=e.createContext(null),s=()=>e.useContext(i),c=e.createContext(null);function a(e,t,n){for(var r=[],o=Math.max(e.length,t.length),i=0,s=0;s<o||i;){var c=i+(s<e.length?e[s]:0)+(s<t.length?t[s]:0);r.push(c%n),i=Math.floor(c/n),s++}return r}function u(e,t,n){if(e<0)return null;if(0==e)return[];for(var r=[],o=t;1&e&&(r=a(r,o,n)),0!=(e>>=1);)o=a(o,o,n);return r}function l(e,t,n){var r=function(e,t){for(var n=e.split(""),r=[],o=n.length-1;o>=0;o--){var i=parseInt(n[o],t);if(isNaN(i))return null;r.push(i)}return r}(e,t);if(null===r)return null;for(var o=[],i=[1],s=0;s<r.length;s++)r[s]&&(o=a(o,u(r[s],i,n),n)),i=u(t,i,n);var c="";for(s=o.length-1;s>=0;s--)c+=o[s].toString(n);return c}function d(e,t){const n=new CustomEvent(e,{detail:t});document.dispatchEvent(n)}function f(t,n){!function(t,n,r){e.useEffect((()=>{const e=t&&"current"in t?t.current:t;return e&&function(e,t,n){e.addEventListener(t,n)}(e,n,r),()=>e&&function(e,t,n){e.removeEventListener(t,n)}(e,n,r)}),[n,t,r])}("undefined"==typeof window?void 0:document,t,n)}const h=(e,t)=>`frmx-${e}-set-${t}`,p=e=>`form-${e}-reset`,g=e=>`form-${e}-submit`;function m(e,t){return function n(r,o,i){if(("string"==typeof o||o instanceof Array)&&o.length||((!process.env.NODE_ENV||"development"===process.env.NODE_ENV)&&console.warn("The provided path should be a string or an array, you provided "+o+" (This message won't pop up in production mode."),o=String(o)),"object"!=typeof r)return t;"string"==typeof o&&(o=o.split("."));var s=o[0];return 1===o.length?e(r,s,i):n(r[s],o.slice(1),i)}}function v(e,t,n){return e[t]=n,!0}var b=function(e,t,n){return Object.defineProperty(e,t,n),!0};function O(e,t){return delete e[t]}function y(e,t){return t in e}function w(e,t){return e[t]}function C(e){return void 0===e&&(e={}),new Proxy(e,{get:m(w),set:m(v,!0),has:m(y),defineProperty:m(b),deleteProperty:m(O),getPrototypeOf:function(e){return e}})}function E(e){const t=e=>{var n,r,o=function(n){for(var r in e)n[r]=t(e[r]);return n};switch(null===(r=e)?"Null":void 0===r?"Undefined":Object.prototype.toString.call(r).slice(8,-1)){case"Object":return o({});case"Array":return o([]);case"Date":return new Date(e.valueOf());case"RegExp":return n=e,new RegExp(n.source,(n.global?"g":"")+(n.ignoreCase?"i":"")+(n.multiline?"m":"")+(n.sticky?"y":"")+(n.unicode?"u":""));default:return e}};return null!=e&&"function"==typeof e.clone?e.clone():t(e)}const j=new class{constructor(e){e=e||{},this.seq=0,this.mid=(e.mid||1)%1023,this.offset=e.offset||0,this.lastTime=0}generate(){const e=Date.now(),t=(e-this.offset).toString(2);this.lastTime==e?(this.seq++,this.seq>4095&&(this.seq=0)):this.seq=0,this.lastTime=e;let n=this.seq.toString(2),r=this.mid.toString(2);for(;n.length<12;)n="0"+n;for(;r.length<10;)r="0"+r;const o=t+r+n;let i="";for(let e=o.length;e>0;e-=4)i=parseInt(o.substring(e-4,e),2).toString(16)+i;return"0x"===(s=i).substring(0,2)&&(s=s.substring(2)),l(s=s.toLowerCase(),16,10);var s}};function S(t){var{afterChange:n,autoCompleteOff:r,children:s,clearAfterSubmit:c,disabled:a,disableIf:u,disableIfNoUpdates:l,disableIfInvalid:f,initialValues:m={},refresh:v,onInvalidSubmit:b,onReset:O,onSubmit:y,schemaValidation:w={},render:S="div"}=t,F=o(t,["afterChange","autoCompleteOff","children","clearAfterSubmit","disabled","disableIf","disableIfNoUpdates","disableIfInvalid","initialValues","refresh","onInvalidSubmit","onReset","onSubmit","schemaValidation","render"]);const P=e.useRef(C(E(m))),x=e.useRef(C(w)),I=e.useRef(new Set),k=e.useRef(new Set),V=e.useRef(new Set),R=e.useRef(!1),N=e.useRef(j.generate());e.useEffect((()=>{v&&(P.current=C(E(m)),x.current=C(E(w)))}),[m]);const T=()=>k.current.size>0,A=()=>V.current.size>0,D=()=>new Set(V.current),X=e=>{k.current.has(e)||k.current.add(e)},$=()=>{O&&T()&&O(P.current),k.current=new Set,P.current=C(E(m)),d(p(N.current)),n&&n(E(Object.getPrototypeOf(P.current)),null,A(),D())},U=e=>{null==e||e.preventDefault(),d(g(N.current)),!0!==R.current&&(l&&!T()||((f||b)&&A()||u&&u(E(Object.getPrototypeOf(P.current)))?b&&b():(R.current=!0,y(E(Object.getPrototypeOf(P.current)),Array.from(k.current)),V.current=new Set,k.current=new Set,c&&$()),R.current=!1))},q=Object.assign(Object.assign(Object.assign({},"form"===S?{noValidate:!0,autoComplete:r?"off":"on",onSubmit:U}:{}),{children:s}),F);return e.createElement(i.Provider,{value:{disabled:!!a,formId:N.current,handleSubmit:U,getErrors:D,getFields:()=>Object.getPrototypeOf(P.current),getOneField:e=>P.current[e],getOneUpdated:e=>k.current.has(e),getOneError:e=>V.current.has(e),getUpdatesList:()=>[...k.current],hasUpdates:T,hasErrors:A,registerFieldObserver:e=>!I.current.has(e)&&I.current.add(e),render:S,resetForm:$,setOneError:(e,t)=>{t&&!V.current.has(e)?V.current.add(e):!t&&V.current.has(e)&&V.current.delete(e)},setOneField:(e,t)=>{try{P.current[e]=t,X(e),I.current.has(e)&&d(h(N.current,e),t),n&&n(E(Object.getPrototypeOf(P.current)),e,A(),D())}catch(e){console.log(e)}},setOneUpdated:X,unsetOneField:e=>{delete P.current[e],k.current.delete(e),V.current.delete(e),I.current.delete(e)},schemaValidation:x.current}},e.createElement(S,q))}const F=e=>{return t=()=>console.warn(e+" (This message won't pop up in production mode. See the docs here: https://www.frmx.dev/docs)."),(!process.env.NODE_ENV||"development"===process.env.NODE_ENV)&&t();var t},P=e=>F(`You must be inside a <FrmX/> provider in order to use ${e}.`);function x(e){f(g(s().formId),e)}function I(e){f(p(s().formId),e)}function k(o,i={}){const a=s();if(!a)return void((null==i?void 0:i.native)||P(`the useFldX() hook at the input controlling the ${o} field`));const{disabled:u,getFields:l,getOneField:d,schemaValidation:f,setOneError:h,setOneField:p}=a,g=e.useContext(c),m=t(((e,t,n)=>n[Boolean(e)?t.replace(new RegExp(`${e.validationPath}.[0-9]+`,"g"),e.validationPath):t])(g,o,f)),[v,b]=n(d(o)),[O,y]=n(!m.current),[w,C]=n(!1),[E,j]=n(!1),[S,F]=n(!1),k=e=>{if(m.current&&"function"==typeof m.current){const t=!m.current(e,l());O||t||y(!0),F(t),h(o,t)}};r((()=>(k(v),()=>h(o,!1))),[]);I((()=>{const e=d(o);b(e),j(!1),y(!1),C(!1),k(e)}));x((()=>{j(!0),k(d(o))}));return{value:v,setValue:e=>{e="function"==typeof e?e(v):e,e=(null==i?void 0:i.trim)&&"string"==typeof e?e.trim():e,b(e),k(e),p(o,e),i.afterChange&&i.afterChange(e,o,S)},error:S&&(O||w||E),disabled:u||(null==i?void 0:i.disabled),onBlur:()=>C(!0)}}function V(t){var n,{afterChange:r,autoCapitalizeOn:i,autoCompleteOff:s,autoCorrectOn:c,children:a,disabled:u,path:l,getValueFromArgs:d,isErrorProp:f,onChangeProp:h="onChange",spellCheckOn:p,trim:g,type:m="text",valueProp:v="value"}=t,b=o(t,["afterChange","autoCapitalizeOn","autoCompleteOff","autoCorrectOn","children","disabled","path","getValueFromArgs","isErrorProp","onChangeProp","spellCheckOn","trim","type","valueProp"]);const O=k(l,{afterChange:r,trim:g,disabled:u,native:!0});if(!O)return P("the <FldX/> component"),a||null;const{value:y,setValue:w,error:C,disabled:E,onBlur:j}=O,S="input"===a.type?null===(n=a.props)||void 0===n?void 0:n.type:void 0;S&&(m=S);const x=e.useRef(((...e)=>{let t=d?d(e):"checkbox"===m?e[0].target.checked:e[0].target.value;w(t)})),I=Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({type:m,onBlur:j,onChange:x.current,disabled:E,["checkbox"===m?"checked":"value"]:y},f?{[f]:C}:{}),!c&&{autoCorrect:"off"}),!i&&{autoCapitalize:"none"}),!p&&{spellCheck:"false"}),s&&{autoComplete:"off"}),b);try{if(e.isValidElement(a)&&e.Children.only(a))return e.cloneElement(a,I);throw new Error}catch(e){return F(`The Field component can have only one child component. Check out the field ${l} to fix the problem, otherwise this field won't work.`),a}}function R(t){var{disabled:n,children:r}=t,i=o(t,["disabled","children"]);const{disabled:c,render:a,handleSubmit:u}=s(),l=n||c,d=Object.assign(Object.assign(Object.assign({},l?{disabled:l}:{}),"div"===a?{onClick:u,type:"button"}:{type:"submit"}),i);try{if(e.isValidElement(r)&&e.Children.only(r))return e.cloneElement(r,d);throw new Error}catch(e){return F("The FldX component can have only one child component, otherwise submitting won't work."),r}}function N(t){var{children:n,onClick:r}=t,i=o(t,["children","onClick"]);const{disabled:c,resetForm:a}=s(),u=Object.assign(Object.assign(Object.assign({type:"button"},c?{disabled:c}:{}),{onClick:()=>[a(),r&&r()]}),i);try{if(e.isValidElement(n)&&e.Children.only(n))return e.cloneElement(n,u);throw new Error}catch(e){return F("The FldX component can have only one child component, otherwise resetting won't work."),n}}function T({children:t,path:n,model:r="",startWithOneMore:o}){const i=s();if(!i)return P("<ArrX/>"),t||null;const{disabled:a,formId:u,getOneField:l,setOneField:d}=i;if("function"!=typeof t)throw new Error("The <ArrX/> component only accepts a function as a child (render props). See the documentation here: https://www.frmx.dev/docs/api/arrx#render-props");const[h,g]=e.useState(l(n)),m=e.useRef((()=>g(l(n))));f(p(u),m.current);const v=e.useRef((e=>{
//! Events might be implicitely and accidentally passed to the function depending how the onClick event handler is passed, hence the check
const t=[...l(n),E(!e||(null==e?void 0:e.nativeEvent)||(null==e?void 0:e._reactName)?r:e)];g(t),d(n,t)})),b=e.useRef((e=>{const t=l(n).filter(((t,n)=>n!==e));d(n,t),g(t)}));return e.useEffect((()=>{o&&v.current()}),[]),e.createElement(c.Provider,{value:{validationPath:n}},t({path:n,items:h,removeItem:b.current,addItem:v.current,disabled:a}))}function A(e,o){const i=s();if(!i)return void P("the useFldXObserver() hook");r((()=>{i.registerFieldObserver(e)}),[]);const[c,a]=n(i.getOneField(e)),u=t((e=>{const t=e.detail;a(t),o&&"function"==typeof o&&o(t)})),l=t((t=>{a(i.getOneField(e))}));return f(h(i.formId,e),u.current),f(p(i.formId),l.current),c}export{V as Field,T as FieldArray,S as Form,N as Reset,R as Submit,k as useField,A as useFieldObserver,s as useForm,I as useResetListener,x as useSubmitListener};
//# sourceMappingURL=index.js.map