UNPKG

fielder

Version:

A field-first form library for React and React Native

3 lines (2 loc) 7.49 kB
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("react")):"function"==typeof define&&define.amd?define(["exports","react"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).fielder={},e.react)}(this,(function(e,t){"use strict";const a=t.createContext(null),n=a.Provider,i="undefined"!=typeof window?t.useLayoutEffect:t.useEffect,r=e=>Object.entries(e).reduce(((e,[t,a])=>({...e,[t]:a.value})),{}),o=(e,t)=>Object.keys(e).reduce((({state:e,promises:a},n)=>{const i=e[n],r=u(t,i),o=s(r,i);if(!o||!r)return{state:e,promises:a};try{const t=o({trigger:r,value:i.value,form:e});return t instanceof Promise?{promises:{...a,[n]:t},state:{...e,[n]:{...i,isValidating:!0}}}:{promises:a,state:{...e,[n]:{...i,isValid:!0,isValidating:!1,error:void 0}}}}catch(t){return{promises:a,state:{...e,[n]:{...i,isValid:!1,isValidating:!1,error:t&&t.message?t.message:t}}}}}),{state:e,promises:{}}),s=(e,t)=>{if(e)return"function"==typeof t._validate?t._validate:"object"==typeof t._validate?t._validate[e]:void 0},u=(e,t)=>{if(t&&t._isActive&&t._validate){if("VALIDATE_SUBMISSION"===e.type)return"submit";if("SET_FIELD_VALUE"===e.type&&e.config.name!==t.name)return"update";if(e.config.name===t.name)return"MOUNT_FIELD"===e.type?"mount":"BLUR_FIELD"===e.type?"blur":"SET_FIELD_VALUE"===e.type?"change":"SET_FIELD_VALIDATION"===e.type&&t.hasBlurred?"blur":"SET_FIELD_VALIDATION"===e.type&&t.hasChanged?"change":"SET_FIELD_VALIDATION"===e.type?"mount":"VALIDATE_FIELD"===e.type?e.config.trigger||"change":void 0}},l=e=>Object.entries(e).reduce(((e,[t,a])=>a._isActive&&a.error?{...e,[t]:a.error}:e),{}),d=async e=>(await Promise.all(Object.entries(e).map((([e,t])=>t.then((()=>({key:e,error:void 0}))).catch((t=>({key:e,error:t.message}))))))).reduce(((e,t)=>({...e,[t.key]:t.error})),{}),c=e=>Object.entries(e).reduce(((e,[t,a])=>void 0===a?e:{...e,[t]:a}),{}),m=(e,t)=>{return"MOUNT_FIELD"===t.type?(a=e,({name:e,validate:t,initialValue:n})=>{const i=a[e]||{};return i&&i._isActive&&console.warn("Field is already mounted"),{...a,[e]:{...i,name:e,_isActive:!0,_validate:t,isValid:!0,isValidating:!1,value:void 0!==i.value?i.value:n,error:i.error,hasBlurred:!1,hasChanged:!1}}})(t.config):"UNMOUNT_FIELD"===t.type?(e=>({name:t,destroy:a=!1})=>{const n=e[t];if(void 0===n)throw Error("Cannot unmount non-mounted field");return a?Object.entries(e).reduce(((e,[a,n])=>a===t?e:{...e,[a]:n}),{}):{...e,[t]:{...n,_isActive:!1}}})(e)(t.config):"SET_FIELD_VALUE"===t.type?(e=>({name:t,value:a})=>{const n=e[t];if(void 0===n)throw Error("Cannot set value on non-mounted field");return n._isActive||console.warn("Setting field value for inactive field."),{...e,[t]:{...n,value:"function"==typeof a?a(n.value):a,hasChanged:!0}}})(e)(t.config):"BLUR_FIELD"===t.type?(e=>({name:t})=>{const a=e[t];if(void 0===a)throw Error("Cannot unmount non-mounted field");return a._isActive||console.warn("Setting field attribute on inactive field."),{...e,[t]:{...a,hasBlurred:!0}}})(e)(t.config):"SET_FIELD_STATE"===t.type?(e=>({name:t,state:a})=>{const n=e[t];if(void 0===n)throw Error("Cannot unmount non-mounted field");const i="function"==typeof a?a(n):a;return i===n?e:{...e,[t]:i}})(e)(t.config):"SET_FIELD_VALIDATION"===t.type?(e=>({name:t,validation:a})=>{const n=e[t];if(void 0===n)throw Error("Cannot set validation on non-mounted field");return n._isActive||console.warn("Setting field validation for inactive field."),{...e,[t]:{...n,_validate:a}}})(e)(t.config):e;var a},f=e=>{let t={};return(a,n)=>{t={...t,[a]:n};const i=i=>r=>{if(!e||!e.current)return void console.warn("Unable to update validation state. Dispatch not available.");if(t[a]!==n)return;const o=!i;e.current({type:"SET_FIELD_STATE",config:{name:a,state:e=>({...e,isValidating:!1,isValid:o,error:o?void 0:r.message})}})};n.then(i(!1)).catch(i(!0))}};e.FielderContext=a,e.FielderProvider=n,e.useField=({name:e,validate:n,initialValue:r,destroyOnUnmount:o=!1})=>{const s=t.useRef(o),u=t.useRef(!0),{fields:l,blurField:d,premountField:c,mountField:m,unmountField:f,setFieldValue:v,setFieldValidation:g}=t.useContext(a),p=t.useMemo((()=>({name:e,value:r,validate:n})),[]),_=t.useMemo((()=>u.current?c({name:p.name,initialValue:p.value,validate:p.validate}):l[p.name]),[p.name,p.value,p.validate,c,l]);i((()=>{m({name:p.name,initialValue:p.value,validate:p.validate})}),[p.name,p.validate,p.value,m]),i((()=>()=>{u.current=!1}),[]),t.useMemo((()=>s.current=o),[o]),i((()=>()=>{f({name:p.name,destroy:s.current})}),[f,p.name]),i((()=>{u.current?u.current=!1:g({name:p.name,validation:n})}),[n,p.name,g]);const y=t.useCallback((()=>d({name:p.name})),[p.name,d]),E=t.useCallback((e=>{if("boolean"==typeof p.value)return v({name:p.name,value:e=>!e});const t="object"==typeof e&&"currentTarget"in e?e.currentTarget.value:e;return v({name:p.name,value:e=>Array.isArray(e)?e.includes(t)?e.filter((e=>e!==t)):[...e,t]:t})}),[p.name,p.value,v]),{value:b,error:h,isValid:F,isValidating:V,hasChanged:I,hasBlurred:L}=_;return t.useMemo((()=>[{name:p.name,value:b,onBlur:y,onChange:E},{error:h,isValid:F,isValidating:V,hasBlurred:L,hasChanged:I}]),[p.name,b,y,E,h,F,V,I,L])},e.useForm=(e={})=>{const a=t.useRef(),n=t.useRef(),i=t.useMemo((()=>f(n)),[]),r=t.useMemo((()=>e.fromState?Object.entries(e.fromState).reduce(((e,[t,a])=>({...e,[t]:{_isActive:!1,name:t,value:a,isValid:!1,isValidating:!1,hasBlurred:!1,hasChanged:!1}})),{}):{}),[]),[s,u]=((e,a)=>{const n=t.useRef(a),[i,r]=t.useState(n.current);return[i,t.useCallback((t=>(n.current=e(n.current,t),r(n.current),n.current)),[])]})(((e,t)=>{const n=m(e,t),{state:r,promises:s}=o(n,t);return Object.keys(s).length>0&&Object.entries(s).map((([e,t])=>i(e,t))),a.current=s,r}),r);t.useMemo((()=>n.current=u),[u]);const v=t.useCallback((e=>{const t={type:"MOUNT_FIELD",config:e},a=m(s,t),{state:n}=o(a,t);return n[e.name]}),[s]),g=t.useCallback((e=>u({type:"MOUNT_FIELD",config:e})[e.name]),[u]),p=t.useCallback((e=>u({type:"UNMOUNT_FIELD",config:e})),[u]),_=t.useCallback((e=>u({type:"SET_FIELD_VALUE",config:e})),[u]),y=t.useCallback((e=>u({type:"SET_FIELD_STATE",config:e})),[u]),E=t.useCallback((e=>u({type:"BLUR_FIELD",config:e})),[u]),b=t.useCallback((e=>u({type:"SET_FIELD_VALIDATION",config:e})),[u]),h=t.useCallback((e=>u({type:"VALIDATE_FIELD",config:e})),[u]),F=t.useCallback((()=>{const e=u({type:"VALIDATE_SUBMISSION"}),t=(({state:e,promises:t})=>{const a=l(e);return t&&0!==Object.keys(t).length?d(t).then((e=>c({...a,...e}))):a})({state:e,promises:a.current});return t instanceof Promise?t.then((t=>({state:e,errors:t}))):{state:e,errors:t}}),[u]),V=t.useMemo((()=>Object.values(s).filter((e=>!(void 0===e||!e._isActive)))),[s]),I=t.useMemo((()=>V.every((e=>e.isValid))),[V]),L=t.useMemo((()=>V.some((e=>e.isValidating))),[V]);return t.useMemo((()=>({fields:s,isValid:I,isValidating:L,premountField:v,setFieldValue:_,blurField:E,validateField:h,validateSubmission:F,mountField:g,unmountField:p,setFieldState:y,setFieldValidation:b})),[s,I,L,v,_,E,h,F,g,p,y,b])},e.useFormContext=()=>t.useContext(a),e.useSubmit=e=>{const[n,i]=t.useState({isValidating:!1,hasSubmitted:!1}),{validateSubmission:o}=t.useContext(a),s=t.useCallback((async()=>{const t=o();i({isValidating:t instanceof Promise,hasSubmitted:!0});const{state:a,errors:n}=await t;i((e=>({...e,isValidating:!1}))),0===Object.keys(n).length&&e(r(a))}),[o,e]);return t.useMemo((()=>({...n,handleSubmit:s})),[n,s])},Object.defineProperty(e,"__esModule",{value:!0})})); //# sourceMappingURL=index.umd.js.map