UNPKG

vue-formify

Version:

Build powerful, type-safe forms in Vue.

1 lines 15.2 kB
(function(e,t){typeof exports==`object`&&typeof module<`u`?t(exports,require("vue")):typeof define==`function`&&define.amd?define([`exports`,`vue`],t):(e=typeof globalThis<`u`?globalThis:e||self,t(e.VueFormify={},e.Vue))})(this,function(e,t){Object.defineProperty(e,Symbol.toStringTag,{value:`Module`});var n=(0,t.reactive)({}),r=e=>typeof e==`object`&&!!e,i=/^\[(.+?)\]$/gm,a=/(^.*\[|\].*$)/g,o=/\[(\d*)\]/gm,s=/\[(\d+)\]/,c=/\[\d+\]/,l=(e,t,r)=>{if(e&&!(e in n[t].values)){let i=f(e,r);n[t].values=E(n[t].values,i)}},u=(e,t)=>{let n=e.as||``;return!e.as&&!t&&(n=`input`),n},d=(e,t,n)=>t.default?typeof e==`string`||!e?t.default(n()):{default:()=>t.default?.(n())}:t.default,f=(e,t)=>{let n=e.match(i);return n?{[n[0].replace(a,``)]:t}:e.split(`.`).reduceRight((e,t)=>{let n=t.match(o),r=t.replace(c,``),i=t.match(s)?.[1];return n?{[r]:{value:{[`[${i}]`]:e}}}:{[t]:e}},t)},p=(e,t=``)=>{let n={};for(let i in e){let a=t?`${t}.${i}`:i;if(r(e[i])&&!Array.isArray(e[i])){let t=p(e[i],a);n={...n,...t}}else n[a]=e[i]}return n},m=(e,t)=>{if(!t)return;let n=t.match(i);if(n)return e[n[0].replace(a,``)];let r=e,l=t.split(`.`),u=l.pop();for(let e of l){if(e.match(o)){let t=e.replace(c,``),n=e.match(s)?.[1];r=r?.[t]?.value?.[`[${n}]`]}else r=r[e];if(!r)return}if(u&&u.match(o)){let e=u.replace(c,``),t=u.match(s)?.[1];return u&&r?.[e]?.value?.[`[${t}]`]}return u&&r[u]},h=(e,t)=>{let n=t.match(i);if(n){let t=n[0].replace(a,``);delete e[t]}let r=e,l=t.split(`.`),u=l.pop();for(let e of l){if(e.match(o)){let t=e.replace(c,``),n=e.match(s)?.[1];r=r?.[t]?.value?.[`[${n}]`]}else r=r[e];if(!r)return}if(u){if(u.match(o)){let e=u.replace(c,``),t=u.match(s)?.[1];delete r?.[e]?.value?.[`[${t}]`],r?.[e]?.value&&!Object.keys(r?.[e]?.value).length&&(r[e].value=[])}else delete r[u];Object.keys(r).length===0&&h(e,l.join(`.`))}},g=e=>{if(!r(e))return e;try{return JSON.parse(JSON.stringify(e))}catch{return e}},_=(e,t)=>{if(e===t)return!0;if(typeof e!=typeof t)return!1;if(!r(e)||t===null)return e!==e&&t!==t;if(e instanceof Date||t instanceof Date)return e instanceof Date&&t instanceof Date&&e.getTime()===t.getTime();if(typeof File<`u`&&(e instanceof File||t instanceof File)||typeof Blob<`u`&&(e instanceof Blob||t instanceof Blob))return e===t;let n=Array.isArray(e);if(n!==Array.isArray(t))return!1;if(n)return e.length===t.length?e.every((e,n)=>_(e,t[n])):!1;let i=Object.keys(e).filter(t=>e[t]!==void 0),a=Object.keys(t).filter(e=>t[e]!==void 0);return i.length===a.length?i.every(n=>_(e[n],t[n])):!1},v=e=>!!e&&r(e)&&`value`in e&&!_(e.value,e.initialValue),y=e=>{if(!e||typeof e!=`object`)return!1;for(let t in e){let n=e[t];if(r(n)){if(`value`in n){if(n.ignore)continue;if(v(n))return!0}else if(y(n))return!0}}return!1},b=e=>{if(r(e))for(let t in e){let n=e[t];r(n)&&(`value`in n?(n.error=void 0,r(n.value)&&b(n.value)):b(n))}},x=e=>{if(!r(e))return!1;for(let t in e){let n=e[t];if(r(n)){if(`value`in n){if(n.ignore)continue;if(n.isTouched||n.value&&typeof n.value==`object`&&x(n.value))return!0}else if(x(n))return!0}}return!1};function S(e){return typeof e==`string`&&e?!0:Array.isArray(e)?e.some(e=>S(e)):r(e)?Object.values(e).some(e=>S(e)):!1}var C=(e,t)=>m(e,t)?.error,w=(e,t=`value`)=>{let n={};for(let a in e)if(r(e[a])&&`value`in e[a]){let{value:o,ignore:s}=e[a];if(r(o))if(Array.isArray(o)&&(n[a]=[]),Object.keys(o)[0]?.match?.(i))for(let e in o)!n[a]&&!s&&(n[a]=[]),t in o[e]?o[e][t]&&n[a].push(o[e][t]):!s&&n[a].push(w(o[e],t));else !s&&(n[a]=e[a][t]);else !s&&(n[a]=e[a][t])}else r(e[a])&&(n[a]=w(e[a],t));return n},T=e=>{let t=[];if(!Array.isArray(e.value)&&r(e.value)&&!(e.value instanceof Date)){if((Object.keys(e.value)?.[0])?.match?.(i)){for(let n in e.value)t.push(e.value[n].value);return t}return e.value}return e.value||typeof e.value==`boolean`?e.value:``},E=(...e)=>e.reduce((e,t)=>(Object.keys(t).forEach(n=>{let i=e[n],a=t[n];Array.isArray(i)&&Array.isArray(a)?e[n]=i.concat(...a):r(i)&&r(a)?e[n]=E(i,a):e[n]=a}),e),{}),D=(e,t=``)=>{let n=new FormData;return Object.keys(e).reduce((i,a)=>{let o=t?`${t}.${a}`:a;if(r(e[a])&&!Array.isArray(e[a])&&!(e[a]instanceof Date)&&!(e[a]instanceof File)&&!(e[a]instanceof Blob)){let t=D(e[a],o);i+=t}else Array.isArray(e[a])?e[a].forEach(e=>{n.append(`${o}[]`,e)}):n.append(`${o}`,e[a]);return i},``),n},O=e=>{if(e.path?.length){let t=``;for(let n of e.path){let e=typeof n==`object`?n.key:n;if(typeof e==`string`)t?t+=`.${e}`:t+=e;else if(typeof e==`number`)t+=`[${e}]`;else return null}return t}return null},k=async e=>{try{return await e}catch{return}},A=class{eventListeners={};on(e,t){this.eventListeners[e]||(this.eventListeners[e]=[]),this.eventListeners[e].push(t)}off(e,t){let n=this.eventListeners[e];n&&(this.eventListeners[e]=n.filter(e=>e!==t))}emit(e,t){let n=this.eventListeners[e];n&&n.forEach(e=>e(t))}},j=async(e,t,n,r)=>{let i=await e[`~standard`].validate(t);if(i.issues){for(let e of i.issues)n(r||O(e),e.message);return!1}return!0},M=(e,t,r,i,a,o,s)=>{let c=(t,r)=>{let i=m(n[e].values,t);i&&(i.error=r)};return{setError:c,resetError:()=>{i.value?.error&&(i.value.error=void 0);let r=t.replace(/\[\d+\]/,``),a=m(n[e].values,r);a?.error&&(a.error=void 0)},validateField:async()=>{if(r)return await j(r,a.value,c,t)},getError:()=>v(i.value)||o.value||s===`onSubmit`?i.value?.error:void 0}},N=(e,t,n)=>e?t||!0:n||!1,P=(e,t,n)=>e.value===`on`?N(e.checked,t,n):e.checked?e.value:void 0,F=(e,t,n)=>e.type===`checkbox`?P(e,t,n):e.type===`file`?e.multiple?e.files:e.files?.[0]:e.type===`select-multiple`?Array.from(e.options).filter(e=>e.selected).map(e=>e.value):e.value,I=(e,r={isArray:!1,isComponent:!1})=>{let{uid:i,preserveForm:a,mode:o,isSubmitted:s}=(0,t.inject)(`formData`,Object.create({})),c=(0,t.getCurrentInstance)(),u=e.name,d={value:m(n[i].values,u)?.value??void 0,initialValue:void 0,error:void 0,ignore:e.ignore,isTouched:!1},f=(0,t.computed)(()=>m(n[i].values,u)),p=(0,t.computed)(()=>v(f.value)),_=(0,t.computed)(()=>f.value?.isTouched),y=(0,t.computed)(()=>!f.value?.error),b=(e,t=u)=>{let r=m(n[i].values,t);r&&(r.value=E(r.value,e),r.error=void 0)},x=(0,t.computed)({get(){if(f.value)return f.value.value},set(e){if(f.value){if(r.isArray||Array.isArray(e)){f.value.value=[];for(let t=0;t<e.length;t++)b({[`[${t}]`]:{value:e[t]}},u);return f.value.value}f.value.value=e??``}}}),S=(0,t.computed)(()=>T(x)),{setError:C,resetError:w,validateField:D,getError:O}=M(i,u,e?.rule,f,x,s,o),k=e=>x.value=e,A=async t=>{r.isComponent||(typeof t==`object`&&t&&`target`in t?t.currentTarget!=null&&t.target!==t.currentTarget||k(F(t.target,e.trueValue,e.falseValue)):typeof t!=`object`||!t?k(t):`value`in t&&k(t.value)),f.value&&(f.value&&!f.value?.isTouched&&(f.value.isTouched=!0),w(),o===`onChange`&&D())},j=()=>{w()},N=async()=>{f.value&&!f.value?.isTouched&&(f.value.isTouched=!0),await D()},P=()=>{if(r.isArray||Array.isArray(m(n[i].initialValues,u))){if(m(n[i].initialValues,u)){let e=m(n[i].initialValues,u),t={};for(let n=0;n<e.length;n++)t={...t,[`[${n}]`]:{value:e[n],error:void 0}};return t}return[]}return m(n[i].values,u).value??e.modelValue??e.default??m(n[i].initialValues,u)??(r.isCheckbox?e.falseValue??!1:``)};if(l(u,i,JSON.parse(JSON.stringify(d))),!u)(0,t.warn)("`name` prop is required");else{let e=P();f.value.value=e,f.value.initialValue=g(e)}return(0,t.onBeforeUnmount)(()=>{e.preserve||a||h(n[i].values,u)}),(0,t.onMounted)(async()=>{await(0,t.nextTick)(),c?.subTree?.el&&`as`in e&&e.as===`select`&&Array.from(c.subTree.el.options).forEach(e=>{d.value?.includes?.(e.value)&&(e.selected=!0)})}),{value:x,isValid:y,isTouched:_,isDirty:p,inputProps:(0,t.computed)(()=>({modelValue:S.value,value:S.value,"onUpdate:modelValue":e=>{x.value=e,o===`onChange`&&D()},isTouched:_.value,onInput:A,onFocus:j,onBlur:N})),getError:O,setError:C,setArrayValue:b,setValue:k}},L=()=>(0,t.defineComponent)((e,{slots:r,emit:i,attrs:a})=>{let o=(0,t.ref)([]),{getError:s,setArrayValue:c}=I(e,{isArray:!0}),{uid:l}=(0,t.inject)(`formData`,Object.create({})),u=()=>{!e.ignore&&(m(n[l].values,e.name).error=void 0),o.value.push({id:o.value.length,name:e.name})},d=async r=>{m(n[l].values,e.name).error=void 0;let i=o.value.findIndex(e=>e.id===r);for(let t=i+1;t<o.value.length;t++){let r=`${e.name}[${t}]`,i=`${e.name}[${t-1}]`;m(n[l].values,r).error=void 0,m(n[l].values,i).error=void 0,m(n[l].values,i)&&c({[`[${t-1}]`]:JSON.parse(JSON.stringify(m(n[l].values,r)))})}await(0,t.nextTick)(),h(n[l].values,`${o.value[o.value.length-1].name}[${o.value.length-1}]`),o.value.splice(-1)};return(async()=>{o.value=[];let r=n[l].initialValues?.[e.name]||n[l].values[e.name].value;r&&(r.forEach?.(()=>{o.value.push({id:o.value.length,name:e.name})}),await(0,t.nextTick)(),r.forEach?.((e,t)=>{typeof e==`object`?Object.keys(e).forEach(n=>{c({[`[${t}]`]:{[n]:{value:e[n]}}})}):c({[`[${t}]`]:{value:e}})}))})(),()=>(0,t.h)(`div`,{...e,...a,...i},r.default?.({fields:(0,t.toValue)(o),add:u,remove:d,error:s}))},{name:`FieldArray`,props:{name:{type:String,default:``},default:{type:[String,Array,Boolean,Number,Object],default:void 0},preserve:{type:Boolean,default:!1},modelValue:{type:[String,Array,Boolean,Number,Object],default:void 0},as:{type:String,default:`input`},rule:{type:Object,default:void 0}},emits:[`update:modelValue`],slots:Object}),R=()=>(0,t.defineComponent)((e,{slots:r,emit:i,attrs:a})=>{let{uid:o,mode:s,isSubmitted:c}=(0,t.inject)(`formData`,Object.create({})),l=()=>{if(s===`onSubmit`||c.value||v(m(n[o].values,e.errorFor)))return C(n[o].values,e.errorFor)};return()=>(0,t.h)(`span`,{...e,...a,...i},r.default?r.default?.({error:l()}):Array.isArray(l())?l()?.[0]:l())},{name:`FieldError`,props:{errorFor:{type:String,default:void 0}},slots:Object}),z=0,B=e=>{let r=e?.name||`form-${++z}`,i=(0,t.ref)(!1),a=(0,t.ref)(!1),o=(0,t.ref)(!1),s=(0,t.ref)(0),c=new A,l=Object.create({}),u=(e=!1)=>{o.value=!1,s.value=0,e?(n[r].initialValues=Object.create({}),n[r].values=Object.create({}),l=JSON.stringify(Object.create({}))):n[r].values=JSON.parse(l),n[r].key++},d=e=>async()=>{await e?.(P.value)},h=(t,i)=>{if(m(n[r].values,t)){let e=m(n[r].values,t);e.value=i,e.error=void 0}else{let e=f(t,{value:i,error:void 0});n[r].values=E(n[r].values,e)}e?.schema&&j(e.schema,w(n[r].values),T)},g=t=>{let i=p(t);for(let e in i)if(m(n[r].values,e)&&`value`in m(n[r].values,e)){let t=m(n[r].values,e);t.value=i[e],t.error=void 0}e?.schema&&j(e.schema,w(n[r].values),T)},_=e=>{n[r].initialValues=e,n[r].key++},T=(e,t)=>{m(n[r].values,e)&&(m(n[r].values,e).error=t)},O=e=>{let t=m(n[r].values,e);return{value:t?.value,error:t?.error,isDirty:v(t),isTouched:!!t?.isTouched,isValid:!t?.error}},M=async()=>(o.value=!0,e?.schema?await j(e.schema,w(n[r].values),T):!0),N=e=>{if(e){let t=m(n[r].values,e);t&&(t.error=void 0);return}b(n[r].values)},P=(0,t.computed)(()=>w(n[r]?.values)),F=(0,t.computed)(()=>y(n[r]?.values)),I=(0,t.computed)(()=>x(n[r]?.values)),L=(0,t.computed)(()=>!S(w(n[r]?.values,`error`)));return n[r]||(n[r]={values:Object.create({}),initialValues:e?.initialValues||Object.create({}),key:0}),(0,t.getCurrentInstance)()&&!e?.preserve&&(0,t.onUnmounted)(()=>{delete n[r]}),{cmp:(0,t.defineComponent)((u,{slots:d,emit:h,attrs:g})=>{(0,t.provide)(`formData`,{uid:r,preserveForm:e?.preserve,mode:e?.mode,isSubmitted:o,emitter:c});let _=e=>C(n[r].values,e),v=async t=>{t.preventDefault(),o.value=!0,s.value++;let a=P.value;if(e?.schema&&!await j(e.schema,w(n[r].values),T))return t.preventDefault();u?.enctype===`multipart/form-data`&&(a=D(w(n[r].values))),!u.action&&(t.preventDefault(),i.value=!0,await k(u.onSubmit?.(a,t)),i.value=!1)},y=()=>{let e=p(n[r].initialValues);for(let t in e)if(!n[r].values[t]?.value){let i=m(n[r].values,t);i?i.value=e[t]:n[r].values=E(n[r].values,f(t,{value:e[t],error:void 0}))}};(0,t.watch)(P,(t,n)=>{a.value&&JSON.stringify(t)!==JSON.stringify(n)&&u.onValueChange&&c.emit(`value-change`,r),e?.mode===`onChange`&&F.value&&c.emit(`validate`)},{deep:!0}),Object.keys(u.initialValues).length&&(n[r].initialValues=E(n[r].initialValues,u.initialValues));let b,x;return(0,t.onMounted)(async()=>{y(),l=JSON.stringify(n[r].values),u?.onValueChange&&n[r]&&(b=e=>{e===r&&h(`value-change`,P.value)},c.on(`value-change`,b)),e?.mode===`onChange`&&(x=async()=>{if(e?.schema)return await j(e.schema,w(n[r].values),T)},c.on(`validate`,x)),await(0,t.nextTick)(),a.value=!0}),(0,t.onBeforeUnmount)(()=>{b&&c.off(`value-change`,b),x&&c.off(`validate`,x)}),()=>(0,t.h)(`form`,{...u,...g,...h,key:n[r].key,onSubmit:v},d.default?.({values:P.value,getError:_,getFieldState:O,isDirty:F.value,isValid:L.value,isTouched:I.value,isSubmitted:o.value,submitCount:s.value}))},{name:`FormComponent`,props:{enctype:{type:String,default:`application/x-www-form-urlencoded`},initialValues:{type:Object,default:Object.create({})},onValueChange:{type:Function,default:void 0},onSubmit:{type:Function,default:void 0}},emits:[`submit`,`value-change`],slots:Object}),values:P,isSubmitting:i,isSubmitted:o,isDirty:F,isValid:L,isTouched:I,submitCount:s,getFieldState:O,reset:u,setInitialValues:_,setValue:h,setValues:g,setError:T,validate:M,clearErrors:N,handleSubmit:d}},V=()=>(0,t.defineComponent)((e,{slots:n,attrs:r})=>{let{value:i,isValid:a,isTouched:o,isDirty:s,inputProps:c,getError:l}=I(e,{isComponent:!!e.custom,isCheckbox:r.type===`checkbox`}),f=(0,t.computed)(()=>{let t={...r,name:e.name,error:l(),onInput:e=>{c.value.onInput?.(e),typeof r.onInput==`function`&&r.onInput()},onChange:e=>{c.value.onInput?.(e),typeof r.onChange==`function`&&r.onChange()},onFocus:()=>{c.value.onFocus?.(),typeof r.onFocus==`function`&&r.onFocus()},onBlur:async()=>{c.value.onBlur?.(),typeof r.onBlur==`function`&&r.onBlur()}};return t.type===`checkbox`&&(t.checked=e.trueValue===void 0?!!i.value:i.value===e.trueValue),r.type!==`file`&&r.type!==`checkbox`&&e.as!==`select`&&!t.multiple&&(t.value=i.value),t}),p=()=>({field:{...c.value,error:l(),isValid:a.value,isTouched:o.value,isDirty:s.value,onFocus:c.value.onFocus,onBlur:c.value.onBlur}});return()=>{let i=(0,t.resolveDynamicComponent)(u(e,!!n.default)),l=d(i,n,p);if(i){let{value:n,modelValue:u,...d}=c.value,p=r.type===`checkbox`?d:c.value;return(0,t.h)(i,{...e,...f.value,...p,isValid:a.value,isTouched:o.value,isDirty:s.value},l)}else return l}},{name:`Field`,inheritAttrs:!1,props:{name:{type:String,default:``},default:{type:[String,Array,Boolean,Number,Object],default:void 0},preserve:{type:Boolean,default:!1},custom:{type:Boolean,default:!1},modelValue:{type:[String,Array,Boolean,Number,Object],default:void 0},as:{type:String,default:void 0},rule:{type:[Object,Function],default:void 0},ignore:{type:Boolean,default:void 0},trueValue:{type:[String,Boolean,Number,Object],default:void 0},falseValue:{type:[String,Boolean,Number,Object],default:void 0}},emits:[`update:modelValue`]});e.useForm=e=>{let t=B(e),n=V(),r=L(),i=R();return{Form:t.cmp,Field:n,FieldArray:r,Error:i,reset:t.reset,setInitialValues:t.setInitialValues,setValue:t.setValue,setValues:t.setValues,setError:t.setError,getFieldState:t.getFieldState,validate:t.validate,clearErrors:t.clearErrors,handleSubmit:t.handleSubmit,values:t.values,isSubmitting:t.isSubmitting,isSubmitted:t.isSubmitted,isDirty:t.isDirty,isValid:t.isValid,isTouched:t.isTouched,submitCount:t.submitCount}},e.useInput=I});