@volverjs/form-vue 1.0.0-beta.32 → 1.0.0-beta.34

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.umd.js CHANGED
@@ -1 +1 @@
1
- (function(C,e){typeof exports=="object"&&typeof module<"u"?e(exports,require("vue"),require("@vueuse/core"),require("zod")):typeof define=="function"&&define.amd?define(["exports","vue","@vueuse/core","zod"],e):(C=typeof globalThis<"u"?globalThis:C||self,e(C["@volverjs/form-vue"]={},C.Vue,C.VueUseCore,C.zod))})(this,function(C,e,Q,A){"use strict";var p=(t=>(t.text="text",t.number="number",t.email="email",t.password="password",t.tel="tel",t.url="url",t.search="search",t.date="date",t.time="time",t.datetimeLocal="datetime-local",t.month="month",t.week="week",t.color="color",t.select="select",t.checkbox="checkbox",t.radio="radio",t.textarea="textarea",t.radioGroup="radioGroup",t.checkboxGroup="checkboxGroup",t.combobox="combobox",t.custom="custom",t))(p||{}),B=(t=>(t.invalid="invalid",t.valid="valid",t.submitting="submitting",t.reset="reset",t.updated="updated",t.unknown="unknown",t))(B||{});function W(t,i={}){const r=v=>{let d=v;for(;d instanceof A.ZodEffects;)d=d.innerType();return d instanceof A.ZodOptional&&(d=d._def.innerType),d},m=v=>{let d=v;for(;d instanceof A.ZodEffects;)d=d.innerType();return d instanceof A.ZodOptional},n=r(t);return{...(n instanceof A.ZodObject?n._def.unknownKeys==="passthrough":!1)?i:{},...Object.fromEntries(Object.entries(n.shape).map(([v,d])=>{const f=i[v],g=m(d);let c=r(d),o;if(c instanceof A.ZodDefault&&(o=c._def.defaultValue(),c=c._def.innerType),f===null&&c instanceof A.ZodNullable)return[v,f];if(f==null&&g)return[v,o];if(c instanceof A.ZodSchema){const y=d.safeParse(f);if(y.success)return[v,y.data??o]}if(c instanceof A.ZodArray&&Array.isArray(f)&&f.length){const y=r(c._def.type);if(y instanceof A.ZodObject)return[v,f.map(b=>W(y,b&&typeof b=="object"?b:void 0))]}if(c instanceof A.ZodRecord&&f){const y=r(c._def.valueType);if(y instanceof A.ZodObject)return[v,Object.keys(f).reduce((b,V)=>(b[V]=W(y,f[V]),b),{})]}return c instanceof A.ZodObject?[v,W(c,f&&typeof f=="object"?f:o)]:[v,o]}))}}function D(t,i,r,m,n){const a=e.ref(),v=e.ref(),d=e.computed(()=>v.value===B.invalid),f=e.ref(),g=e.ref(!1);let c;const o=x=>{const O=W(t,x);if(r!=null&&r.class){const s=r.class;return new s(O)}return O},y=async(x=f.value,O)=>{if(c=O,g.value)return!0;const s=await t.safeParseAsync(x);if(!s.success){if(v.value=B.invalid,!O)return a.value=s.error.format(),!1;const I=s.error.issues.filter(U=>O.has(U.path.join(".")));return I.length?(a.value=new A.ZodError(I).format(),!1):(a.value=void 0,!0)}return a.value=void 0,v.value=B.valid,f.value=o(s.data),!0},b=()=>{a.value=void 0,v.value=void 0,c=void 0},V=()=>{f.value=o(),b(),v.value=B.reset},u=async()=>g.value||!await y()?!1:(v.value=B.submitting,!0),{ignoreUpdates:S,stop:w}=Q.watchIgnorable(f,()=>{v.value=B.updated},{deep:!0,eventFilter:Q.throttleFilter((r==null?void 0:r.updateThrottle)??500)}),E=e.readonly(a),R=e.readonly(v),G=e.defineComponent({name:"VvForm",props:{continuousValidation:{type:Boolean,default:!1},modelValue:{type:Object,default:()=>({})},readonly:{type:Boolean,default:(r==null?void 0:r.readonly)??!1},tag:{type:String,default:"form"},template:{type:[Array,Function],default:void 0}},emits:["invalid","submit","update:modelValue","update:readonly","valid","reset"],expose:["errors","invalid","readonly","status","submit","tag","template","valid","validate","clear","reset"],slots:Object,setup(x,{emit:O}){return f.value=o(e.toRaw(x.modelValue)),e.watch(()=>x.modelValue,s=>{if(s){const I=e.isProxy(s)?e.toRaw(s):s;if(JSON.stringify(I)===JSON.stringify(e.toRaw(f.value)))return;f.value=typeof(I==null?void 0:I.clone)=="function"?I.clone():JSON.parse(JSON.stringify(I))}},{deep:!0}),e.watch(v,async s=>{var I,U,L,K,T,H;if(s===B.invalid){const l=e.toRaw(a.value);O("invalid",l),(I=r==null?void 0:r.onInvalid)==null||I.call(r,l);return}if(s===B.valid){const l=e.toRaw(f.value);O("valid",l),(U=r==null?void 0:r.onValid)==null||U.call(r,l),O("update:modelValue",l),(L=r==null?void 0:r.onUpdate)==null||L.call(r,l);return}if(s===B.submitting){const l=e.toRaw(f.value);O("submit",l),(K=r==null?void 0:r.onSubmit)==null||K.call(r,l);return}if(s===B.reset){const l=e.toRaw(f.value);O("reset",l),(T=r==null?void 0:r.onReset)==null||T.call(r,l);return}if(s===B.updated){if((a.value||r!=null&&r.continuousValidation||x.continuousValidation)&&await y(void 0,c),!f.value||!x.modelValue||JSON.stringify(f.value)!==JSON.stringify(x.modelValue)){const l=e.toRaw(f.value);O("update:modelValue",l),(H=r==null?void 0:r.onUpdate)==null||H.call(r,l)}v.value===B.updated&&(v.value=B.unknown)}}),e.onMounted(()=>{g.value=x.readonly}),e.watch(()=>x.readonly,s=>{g.value=s}),e.watch(g,s=>{s!==x.readonly&&O("update:readonly",g.value)}),e.provide(i,{clear:b,errors:E,formData:f,ignoreUpdates:S,invalid:d,readonly:g,reset:V,status:R,stopUpdatesWatch:w,submit:u,validate:y,wrappers:n}),{clear:b,errors:E,formData:f,ignoreUpdates:S,invalid:d,isReadonly:g,reset:V,status:R,stopUpdatesWatch:w,submit:u,validate:y,wrappers:n}},render(){const x=()=>{var O,s;return((s=(O=this.$slots)==null?void 0:O.default)==null?void 0:s.call(O,{errors:E.value,formData:f.value,invalid:d.value,readonly:g.value,status:R.value,wrappers:n,clear:b,ignoreUpdates:S,reset:V,stopUpdatesWatch:w,submit:u,validate:y}))??this.$slots.default};return e.h(this.tag,{onSubmit:e.withModifiers(this.submit,["prevent"]),onReset:e.withModifiers(this.reset,["prevent"])},(this.template??(r==null?void 0:r.template))&&m?[e.h(m,{schema:this.template??(r==null?void 0:r.template)},{default:x})]:{default:x})}});return{clear:b,errors:a,formData:f,ignoreUpdates:S,invalid:d,readonly:g,reset:V,status:v,wrappers:n,stopUpdatesWatch:w,submit:u,validate:y,VvForm:G}}function q(t){return Array.isArray(t)}function F(t){return typeof t<"u"}function X(t){return t===null}function Y(t){return typeof t=="object"}function z(t){return typeof t=="string"}function _(t){return typeof t>"u"}const ee=/^[0-9]+$/,re=["__proto__","prototype","constructor"];function $(t,i,r){const m=F(r)?r:void 0;if(!Y(t)||!z(i))return m;const n=j(i);if(n.length!==0){for(const a of n){if(a==="*")continue;const v=function(d){return d.map(f=>_(f)||X(f)?f:q(f)?v(f):f[a])};if(q(t)&&!ee.test(a)?t=v(t):t=t[a],_(t)||X(t))break}return _(t)?m:t}}function J(t,i,r){if(!Y(t)||!z(i))return;const m=j(i);if(m.length===0)return;const n=m.length;for(let a=0;a<n;a++){const v=m[a];if(a===n-1){t[v]=r;return}if(v==="*"&&q(t)){const d=m.slice(a+1).join(".");for(const f of t)J(f,d,r);return}_(t[v])&&(t[v]={}),t=t[v]}}function j(t){const i=t.split(/[.]|(?:\[(\d|\*)\])/).filter(r=>!!r);return i.some(r=>re.indexOf(r)!==-1)?[]:i}function te(t,i,r,m){return e.defineComponent({name:"VvFormField",props:{type:{type:String,validator:n=>Object.values(p).includes(n),default:p.custom},is:{type:[Object,String],default:void 0},name:{type:[String,Number,Boolean,Symbol],required:!0},props:{type:[Object,Function],default:()=>({})},showValid:{type:Boolean,default:!1},defaultValue:{type:[String,Number,Boolean,Array,Object],default:void 0},lazyLoad:{type:Boolean,default:!1},readonly:{type:Boolean,default:void 0}},emits:["invalid","update:formData","update:modelValue","valid"],expose:["component","errors","hasProps","invalid","invalidLabel","is","type"],slots:Object,setup(n,{slots:a,emit:v}){const{props:d,name:f}=e.toRefs(n),g=e.useId(),c=e.inject(i,void 0);c&&c.fields.value.set(g,n.name);const o=e.inject(t),y=e.computed({get(){if(o!=null&&o.formData)return $(new Object(o.formData.value),String(n.name))},set(s){o!=null&&o.formData&&(J(new Object(o.formData.value),String(n.name),s),v("update:modelValue",{newValue:y.value,formData:o==null?void 0:o.formData}))}});e.onMounted(()=>{y.value===void 0&&n.defaultValue!==void 0&&(y.value=n.defaultValue)}),e.onBeforeUnmount(()=>{c&&c.fields.value.delete(g)});const b=e.computed(()=>{if(o!=null&&o.errors.value)return $(o.errors.value,String(n.name))}),V=e.computed(()=>{var s;return(s=b.value)==null?void 0:s._errors}),u=e.computed(()=>b.value!==void 0),S=e.watch(u,()=>{if(u.value){v("invalid",b.value),c&&c.errors.value.set(String(n.name),b.value);return}v("valid",y.value),c&&c.errors.value.delete(n.name)}),w=e.watch(()=>o==null?void 0:o.formData,()=>{v("update:formData",o==null?void 0:o.formData)},{deep:!0});e.onBeforeUnmount(()=>{S(),w()});const E=s=>{s instanceof InputEvent&&(s=s.target.value),y.value=s},R=e.computed(()=>{let s=d.value;return typeof s=="function"&&(s=s(o==null?void 0:o.formData)),Object.keys(s).reduce((I,U)=>(I[U]=e.unref(s[U]),I),{})}),G=e.computed(()=>o!=null&&o.readonly.value?!0:R.value.readonly??n.readonly),x=e.computed(()=>({...R.value,name:R.value.name??n.name,invalid:u.value,valid:n.showValid?!!(!u.value&&y.value):void 0,type:(s=>{if([p.color,p.date,p.datetimeLocal,p.email,p.month,p.number,p.password,p.search,p.tel,p.text,p.time,p.url,p.week].includes(s))return s})(n.type),invalidLabel:V.value,modelValue:y.value,readonly:G.value,"onUpdate:modelValue":E}));return e.provide(r,{name:e.readonly(f),errors:e.readonly(b)}),{component:e.computed(()=>{if(n.type===p.custom)return{render(){var s;return((s=a.default)==null?void 0:s.call(a,{errors:b.value,formData:o==null?void 0:o.formData.value,formErrors:o==null?void 0:o.errors.value,invalid:u.value,invalidLabel:V.value,modelValue:y.value,readonly:G.value,onUpdate:E,submit:o==null?void 0:o.submit,validate:o==null?void 0:o.validate}))??a.default}};if(!((m==null?void 0:m.lazyLoad)??n.lazyLoad)){let s;switch(n.type){case p.select:s=e.resolveComponent("VvSelect");break;case p.checkbox:s=e.resolveComponent("VvCheckbox");break;case p.radio:s=e.resolveComponent("VvRadio");break;case p.textarea:s=e.resolveComponent("VvTextarea");break;case p.radioGroup:s=e.resolveComponent("VvRadioGroup");break;case p.checkboxGroup:s=e.resolveComponent("VvCheckboxGroup");break;case p.combobox:s=e.resolveComponent("VvCombobox");break;default:s=e.resolveComponent("VvInputText")}if(typeof s!="string")return s;console.warn(`[@volverjs/form-vue]: ${s} not found, the component will be loaded asynchronously. To avoid this warning, please set "lazyLoad" option.`)}return e.defineAsyncComponent(async()=>{switch(m!=null&&m.sideEffects&&await Promise.resolve(m.sideEffects(n.type)),n.type){case p.textarea:return import("@volverjs/ui-vue/vv-textarea");case p.radio:return import("@volverjs/ui-vue/vv-radio");case p.radioGroup:return import("@volverjs/ui-vue/vv-radio-group");case p.checkbox:return import("@volverjs/ui-vue/vv-checkbox");case p.checkboxGroup:return import("@volverjs/ui-vue/vv-checkbox-group");case p.select:return import("@volverjs/ui-vue/vv-select");case p.combobox:return import("@volverjs/ui-vue/vv-combobox")}return import("@volverjs/ui-vue/vv-input-text")})}),hasProps:x,invalid:u}},render(){return this.is?e.h(this.is,this.hasProps,this.$slots):this.type===p.custom?e.h(this.component,null,this.$slots):e.h(this.component,this.hasProps,this.$slots)}})}function ae(t,i,r){return e.defineComponent({name:"VvFormFieldsGroup",props:{is:{type:[Object,String],default:void 0},names:{type:[Array,Object],required:!0},props:{type:[Object,Function],default:()=>({})},showValid:{type:Boolean,default:!1},defaultValues:{type:[Object],default:void 0},readonly:{type:Boolean,default:void 0}},emits:["invalid","update:formData","update:modelValue","valid"],expose:["component","errors","hasProps","invalid","invalidLabels","is"],slots:Object,setup(m,{slots:n,emit:a}){const{props:v,names:d,defaultValues:f}=e.toRefs(m),g=e.useId(),c=e.computed(()=>Array.isArray(d.value)?d.value:Object.values(d.value)),o=e.computed(()=>Array.isArray(d.value)?d.value:Object.keys(d.value)),y=e.computed(()=>Array.isArray(d.value)?d.value.reduce((l,h)=>(l[String(h)]=h,l),{}):d.value),b=e.computed(()=>Object.keys(y.value).reduce((l,h)=>(l[String(y.value[h])]=h,l),{})),V=e.inject(i,void 0);V&&c.value.forEach(l=>{V.fields.value.set(`${g}-${l}`,l)});const u=e.inject(t),S=e.computed({get(){return u!=null&&u.formData?o.value.reduce((l,h)=>(l[h]=$(new Object(u.formData.value),y.value[h]),l),{}):{}},set(l){u!=null&&u.formData&&(o.value.forEach(h=>{J(new Object(u.formData.value),y.value[h],l==null?void 0:l[h])}),a("update:modelValue",{newValue:S.value,formData:u==null?void 0:u.formData}))}});e.onMounted(()=>{f.value&&c.value.forEach(l=>{var h,k;((h=f.value)==null?void 0:h[l])!==void 0&&S.value[l]===void 0&&(S.value={...S.value,[l]:(k=f.value)==null?void 0:k[l]})})}),e.onBeforeUnmount(()=>{V&&c.value.forEach(l=>{V.fields.value.delete(`${g}-${l}`)})});const w=e.computed(()=>{if(!(u!=null&&u.errors.value))return;const l=c.value.reduce((h,k)=>{if(!u.errors.value)return h;const Z=$(u.errors.value,String(k));return Z===void 0||(h[String(k)]=Z),h},{});if(Object.keys(l).length!==0)return l}),E=e.computed(()=>{if(!w.value)return;const l=Object.keys(w.value).reduce((h,k)=>{var Z;return(Z=w.value)!=null&&Z[k]&&(h[b.value[k]]=w.value[k]._errors),h},{});if(Object.keys(l).length!==0)return l}),R=e.computed(()=>w.value!==void 0),G=e.computed(()=>o.value.reduce((l,h)=>{var k;return l[h]=!!((k=w.value)!=null&&k[b.value[h]]),l},{})),x=e.watch(R,()=>{if(R.value){a("invalid",w.value),V&&c.value.forEach(l=>{var h,k;if(!((h=w.value)!=null&&h[l])){V.errors.value.delete(l);return}V.errors.value.set(l,(k=w.value)==null?void 0:k[l])});return}a("valid",S.value),V&&c.value.forEach(l=>{V.errors.value.delete(l)})}),O=e.watch(()=>u==null?void 0:u.formData,()=>{a("update:formData",u==null?void 0:u.formData)},{deep:!0});e.onBeforeUnmount(()=>{x(),O()});const s=l=>{S.value=l},I=(l,h)=>{h instanceof InputEvent&&(h=h.target.value),o.value.includes(l)&&(S.value={...S.value,[l]:h})},U=e.computed(()=>{let l=v.value;return typeof l=="function"&&(l=l(u==null?void 0:u.formData)),Object.keys(l).reduce((h,k)=>(h[k]=e.unref(l[k]),h),{})}),L=e.computed(()=>u!=null&&u.readonly.value?!0:U.value.readonly??m.readonly),K=e.computed(()=>o.value.reduce((l,h)=>(l[`onUpdate:${h}`]=k=>{I(h,k)},l),{"onUpdate:modelValue":s})),T=e.computed(()=>({...K.value,...U.value,names:U.value.name??c.value,invalid:R.value,invalids:G.value,valid:m.showValid?!!(!R.value&&S.value):void 0,invalidLabels:E.value,modelValue:S.value,readonly:L.value}));return e.provide(r,{names:e.readonly(d),errors:e.readonly(w)}),{component:e.computed(()=>({render(){var l;return((l=n.default)==null?void 0:l.call(n,{errors:w.value,formData:u==null?void 0:u.formData.value,formErrors:u==null?void 0:u.errors.value,invalid:R.value,invalids:G.value,invalidLabels:E.value,modelValue:S.value,onUpdate:s,onUpdateField:I,readonly:L.value,submit:u==null?void 0:u.submit,validate:u==null?void 0:u.validate}))??n.default}})),hasProps:T,invalid:R}},render(){return this.is?e.h(this.is,this.hasProps,this.$slots):e.h(this.component,null,this.$slots)}})}function ne(t,i){return e.defineComponent({name:"VvFormWrapper",props:{name:{type:String,required:!0},tag:{type:String,default:void 0}},emits:["invalid","valid"],expose:["clear","errors","fields","fieldsErrors","formData","invalid","reset","submit","tag","validate","validateWrapper"],slots:Object,setup(r,{emit:m}){const n=e.inject(t),a=e.inject(i,void 0),v=e.ref(new Map),d=e.ref(new Map),{name:f}=e.toRefs(r),g=e.computed(()=>n!=null&&n.invalid.value?d.value.size>0:!1);e.watch(g,()=>{g.value?m("invalid"):m("valid")});const c={name:e.readonly(f),errors:d,invalid:e.readonly(g),fields:v};e.provide(i,c),e.watch(v,(y,b)=>{a!=null&&a.fields&&b.forEach((V,u)=>{y.has(u)||a==null||a.fields.value.delete(u)}),a!=null&&a.fields&&y.forEach((V,u)=>{a!=null&&a.fields.value.has(u)||a==null||a.fields.value.set(u,V)})},{deep:!0}),e.watch(d,(y,b)=>{a!=null&&a.errors&&(Array.from(b.keys()).forEach(V=>{a.errors.value.delete(V)}),Array.from(y.keys()).forEach(V=>{const u=y.get(V);u&&a.errors.value.set(V,u)}))},{deep:!0}),e.onMounted(()=>{if(!(n!=null&&n.wrappers)||!f.value){console.warn("[@volverjs/form-vue]: Invalid wrapper registration state");return}if(n.wrappers.has(f.value)){console.warn(`[@volverjs/form-vue]: wrapper name "${f.value}" is already used`);return}n.wrappers.set(f.value,c)}),e.onBeforeUnmount(()=>{n!=null&&n.wrappers&&f.value&&n.wrappers.delete(f.value)});const o=()=>(n==null?void 0:n.validate(void 0,new Set(v.value.values())))??Promise.resolve(!0);return{errors:n==null?void 0:n.errors,fields:v,fieldsErrors:d,formData:n==null?void 0:n.formData,invalid:g,clear:n==null?void 0:n.clear,reset:n==null?void 0:n.reset,submit:n==null?void 0:n.submit,validate:n==null?void 0:n.validate,validateWrapper:o}},render(){const r=()=>{var m,n;return(n=(m=this.$slots).default)==null?void 0:n.call(m,{errors:this.errors,fieldsErrors:this.fieldsErrors,formData:this.formData,invalid:this.invalid,clear:this.clear,reset:this.reset,submit:this.submit,validate:this.validate,validateWrapper:this.validateWrapper})};return this.tag?e.h(this.tag,null,{default:r}):r()}})}function le(t,i){const r=e.defineComponent({name:"VvFormTemplate",props:{schema:{type:[Array,Function],required:!0},scope:{type:Object,default:()=>({})}},slots:Object,setup(m,{slots:n}){const a=e.inject(t);if(a!=null&&a.formData)return()=>{var g;const v=typeof m.schema=="function"?m.schema(a,m.scope):m.schema;let d;const f=v.reduce((c,o)=>{const y=typeof o=="function"?o(a,m.scope):o,{vvIs:b,vvName:V,vvSlots:u,vvChildren:S,vvIf:w,vvElseIf:E,vvType:R,vvDefaultValue:G,vvShowValid:x,vvContent:O,...s}=y;if(w!==void 0){if(typeof w=="string"?d=!!$(new Object(a.formData.value),w):typeof w=="function"?d=e.unref(w(a)):d=e.unref(w),!d)return c}else if(E!==void 0&&d!==void 0){if(d||(typeof E=="string"?d=!!$(new Object(a.formData.value),E):typeof E=="function"?d=e.unref(E(a)):d=e.unref(E),!d))return c}else d=void 0;let I;return S&&(typeof b=="string"?I=e.h(r,{schema:S}):I={default:U=>e.h(r,{schema:S,scope:U})}),V?(c.push(e.h(i,{name:V,is:b,type:R,defaultValue:G,showValid:x,props:s},u??I??O)),c):b?(c.push(e.h(b,s,u??I??O)),c):(I&&("default"in I?c.push(I.default(m.scope)):c.push(I)),c)},[]);return f.push((g=n==null?void 0:n.default)==null?void 0:g.call(n,{errors:a==null?void 0:a.errors.value,formData:a==null?void 0:a.formData.value,invalid:a==null?void 0:a.invalid.value,status:a==null?void 0:a.status.value,submit:a==null?void 0:a.submit,validate:a==null?void 0:a.validate,clear:a==null?void 0:a.clear,reset:a==null?void 0:a.reset})),f}}});return r}function M(t,i={}){const r=Symbol("formInjectionKey"),m=Symbol("formWrapperInjectionKey"),n=Symbol("formFieldInjectionKey"),a=Symbol("formFieldsGroupInjectionKey"),v=ne(r,m),d=te(r,m,n,i),f=ae(r,m,a),g=le(r,d),c=new Map,{clear:o,errors:y,formData:b,ignoreUpdates:V,invalid:u,readonly:S,reset:w,status:E,stopUpdatesWatch:R,submit:G,validate:x,VvForm:O}=D(t,r,i,g,c);return{clear:o,errors:y,formData:b,formFieldInjectionKey:n,formInjectionKey:r,formWrapperInjectionKey:m,ignoreUpdates:V,invalid:u,readonly:S,reset:w,status:E,stopUpdatesWatch:R,submit:G,validate:x,wrappers:c,VvForm:O,VvFormField:d,VvFormFieldsGroup:f,VvFormTemplate:g,VvFormWrapper:v}}const P=Symbol("pluginInjectionKey");function ue(t){let i={};return t.schema&&(i=M(t.schema,t)),{...i,install(r,{global:m=!1}={}){r.provide(P,t),m&&(r.config.globalProperties.$vvForm=t,i!=null&&i.VvForm&&r.component("VvForm",i.VvForm),i!=null&&i.VvFormWrapper&&r.component("VvFormWrapper",i.VvFormWrapper),i!=null&&i.VvFormField&&r.component("VvFormField",i.VvFormField),i!=null&&i.VvFormFieldsGroup&&r.component("VvFormFieldsGroup",i.VvFormFieldsGroup),i!=null&&i.VvFormTemplate&&r.component("VvFormTemplate",i.VvFormTemplate))}}}const N=new Map;function se(t,i={}){if(i.scope&&N.has(i.scope))return N.get(i.scope);if(!e.getCurrentInstance()){const m=M(t,i);return i.scope&&N.set(i.scope,m),m}const r=M(t,{...e.inject(P,{}),...i});return i.scope&&N.set(i.scope,r),r}function oe(t,i={}){return M(t,i)}C.FormFieldType=p,C.createForm=ue,C.defaultObjectBySchema=W,C.formType=oe,C.pluginInjectionKey=P,C.useForm=se,Object.defineProperty(C,Symbol.toStringTag,{value:"Module"})});
1
+ (function(C,e){typeof exports=="object"&&typeof module<"u"?e(exports,require("vue"),require("@vueuse/core"),require("zod")):typeof define=="function"&&define.amd?define(["exports","vue","@vueuse/core","zod"],e):(C=typeof globalThis<"u"?globalThis:C||self,e(C["@volverjs/form-vue"]={},C.Vue,C.VueUseCore,C.zod))})(this,function(C,e,Q,B){"use strict";var b=(t=>(t.text="text",t.number="number",t.email="email",t.password="password",t.tel="tel",t.url="url",t.search="search",t.date="date",t.time="time",t.datetimeLocal="datetime-local",t.month="month",t.week="week",t.color="color",t.select="select",t.checkbox="checkbox",t.radio="radio",t.textarea="textarea",t.radioGroup="radioGroup",t.checkboxGroup="checkboxGroup",t.combobox="combobox",t.custom="custom",t))(b||{}),A=(t=>(t.invalid="invalid",t.valid="valid",t.submitting="submitting",t.reset="reset",t.updated="updated",t.unknown="unknown",t))(A||{});function L(t,i={}){const r=v=>{let d=v;for(;d instanceof B.ZodEffects;)d=d.innerType();return d instanceof B.ZodOptional&&(d=d._def.innerType),d},m=v=>{let d=v;for(;d instanceof B.ZodEffects;)d=d.innerType();return d instanceof B.ZodOptional},n=r(t);return{...(n instanceof B.ZodObject?n._def.unknownKeys==="passthrough":!1)?i:{},...Object.fromEntries(Object.entries(n.shape).map(([v,d])=>{const f=i[v],O=m(d);let c=r(d),o;if(c instanceof B.ZodDefault&&(o=c._def.defaultValue(),c=c._def.innerType),f===null&&c instanceof B.ZodNullable)return[v,f];if(f==null&&O)return[v,o];if(c instanceof B.ZodSchema){const y=d.safeParse(f);if(y.success)return[v,y.data??o]}if(c instanceof B.ZodArray&&Array.isArray(f)&&f.length){const y=r(c._def.type);if(y instanceof B.ZodObject)return[v,f.map(w=>L(y,w&&typeof w=="object"?w:void 0))]}if(c instanceof B.ZodRecord&&f){const y=r(c._def.valueType);if(y instanceof B.ZodObject)return[v,Object.keys(f).reduce((w,p)=>(w[p]=L(y,f[p]),w),{})]}return c instanceof B.ZodObject?[v,L(c,f&&typeof f=="object"?f:o)]:[v,o]}))}}function D(t,i,r,m,n){const a=e.ref(),v=e.ref(),d=e.computed(()=>v.value===A.invalid),f=e.ref(),O=e.ref(!1);let c;const o=x=>{const I=L(t,x);if(r!=null&&r.class){const u=r.class;return new u(I)}return I},y=async(x=f.value,I)=>{if(c=I,O.value)return!0;const u=await t.safeParseAsync(x);if(!u.success){if(v.value=A.invalid,!I)return a.value=u.error.format(),!1;const S=u.error.issues.filter(U=>I.has(U.path.join(".")));return S.length?(a.value=new B.ZodError(S).format(),!1):(a.value=void 0,!0)}return a.value=void 0,v.value=A.valid,f.value=o(u.data),!0},w=()=>{a.value=void 0,v.value=void 0,c=void 0},p=()=>{f.value=o(),w(),v.value=A.reset},s=async()=>O.value||!await y()?!1:(v.value=A.submitting,!0),{ignoreUpdates:g,stop:V}=Q.watchIgnorable(f,()=>{v.value=A.updated},{deep:!0,eventFilter:Q.throttleFilter((r==null?void 0:r.updateThrottle)??500)}),E=e.readonly(a),k=e.readonly(v),G=e.defineComponent({name:"VvForm",props:{continuousValidation:{type:Boolean,default:!1},modelValue:{type:Object,default:()=>({})},readonly:{type:Boolean,default:(r==null?void 0:r.readonly)??!1},tag:{type:String,default:"form"},template:{type:[Array,Function],default:void 0}},emits:["invalid","submit","update:modelValue","update:readonly","valid","reset"],expose:["errors","invalid","readonly","status","submit","tag","template","valid","validate","clear","reset"],slots:Object,setup(x,{emit:I}){return f.value=o(e.toRaw(x.modelValue)),e.watch(()=>x.modelValue,u=>{if(u){const S=e.isProxy(u)?e.toRaw(u):u;if(JSON.stringify(S)===JSON.stringify(e.toRaw(f.value)))return;f.value=typeof(S==null?void 0:S.clone)=="function"?S.clone():JSON.parse(JSON.stringify(S))}},{deep:!0}),e.watch(v,async u=>{var S,U,M,K,T,H;if(u===A.invalid){const l=e.toRaw(a.value);I("invalid",l),(S=r==null?void 0:r.onInvalid)==null||S.call(r,l);return}if(u===A.valid){const l=e.toRaw(f.value);I("valid",l),(U=r==null?void 0:r.onValid)==null||U.call(r,l),I("update:modelValue",l),(M=r==null?void 0:r.onUpdate)==null||M.call(r,l);return}if(u===A.submitting){const l=e.toRaw(f.value);I("submit",l),(K=r==null?void 0:r.onSubmit)==null||K.call(r,l);return}if(u===A.reset){const l=e.toRaw(f.value);I("reset",l),(T=r==null?void 0:r.onReset)==null||T.call(r,l);return}if(u===A.updated){if((a.value||r!=null&&r.continuousValidation||x.continuousValidation)&&await y(void 0,c),!f.value||!x.modelValue||JSON.stringify(f.value)!==JSON.stringify(x.modelValue)){const l=e.toRaw(f.value);I("update:modelValue",l),(H=r==null?void 0:r.onUpdate)==null||H.call(r,l)}v.value===A.updated&&(v.value=A.unknown)}}),e.onMounted(()=>{O.value=x.readonly}),e.watch(()=>x.readonly,u=>{O.value=u}),e.watch(O,u=>{u!==x.readonly&&I("update:readonly",O.value)}),e.provide(i,{clear:w,errors:E,formData:f,ignoreUpdates:g,invalid:d,readonly:O,reset:p,status:k,stopUpdatesWatch:V,submit:s,validate:y,wrappers:n}),{clear:w,errors:E,formData:f,ignoreUpdates:g,invalid:d,isReadonly:O,reset:p,status:k,stopUpdatesWatch:V,submit:s,validate:y,wrappers:n}},render(){const x=()=>{var I,u;return((u=(I=this.$slots)==null?void 0:I.default)==null?void 0:u.call(I,{errors:E.value,formData:f.value,invalid:d.value,readonly:O.value,status:k.value,wrappers:n,clear:w,ignoreUpdates:g,reset:p,stopUpdatesWatch:V,submit:s,validate:y}))??this.$slots.default};return e.h(this.tag,{onSubmit:e.withModifiers(this.submit,["prevent"]),onReset:e.withModifiers(this.reset,["prevent"])},(this.template??(r==null?void 0:r.template))&&m?[e.h(m,{schema:this.template??(r==null?void 0:r.template)},{default:x})]:{default:x})}});return{clear:w,errors:a,formData:f,ignoreUpdates:g,invalid:d,readonly:O,reset:p,status:v,wrappers:n,stopUpdatesWatch:V,submit:s,validate:y,VvForm:G}}function q(t){return Array.isArray(t)}function F(t){return!1}function X(t){return t===null}function Y(t){return typeof t=="object"}function z(t){return typeof t=="string"}function _(t){return typeof t>"u"}const ee=/^[0-9]+$/,re=["__proto__","prototype","constructor"];function $(t,i,r){const m=F()?r:void 0;if(!Y(t)||!z(i))return m;const n=j(i);if(n.length!==0){for(const a of n){if(a==="*")continue;const v=function(d){return d.map(f=>_(f)||X(f)?f:q(f)?v(f):f[a])};if(q(t)&&!ee.test(a)?t=v(t):t=t[a],_(t)||X(t))break}return _(t)?m:t}}function J(t,i,r){if(!Y(t)||!z(i))return;const m=j(i);if(m.length===0)return;const n=m.length;for(let a=0;a<n;a++){const v=m[a];if(a===n-1){t[v]=r;return}if(v==="*"&&q(t)){const d=m.slice(a+1).join(".");for(const f of t)J(f,d,r);return}_(t[v])&&(t[v]={}),t=t[v]}}function j(t){const i=t.split(/[.]|(?:\[(\d|\*)\])/).filter(r=>!!r);return i.some(r=>re.indexOf(r)!==-1)?[]:i}function te(t,i,r,m){return e.defineComponent({name:"VvFormField",props:{type:{type:String,validator:n=>Object.values(b).includes(n),default:b.custom},is:{type:[Object,String],default:void 0},name:{type:[String,Number,Boolean,Symbol],required:!0},props:{type:[Object,Function],default:()=>({})},showValid:{type:Boolean,default:!1},defaultValue:{type:[String,Number,Boolean,Array,Object],default:void 0},lazyLoad:{type:Boolean,default:!1},readonly:{type:Boolean,default:void 0}},emits:["invalid","update:formData","update:modelValue","valid"],expose:["component","errors","hasProps","invalid","invalidLabel","is","type"],slots:Object,setup(n,{slots:a,emit:v}){const{props:d,name:f}=e.toRefs(n),O=e.useId(),c=e.inject(i,void 0);c&&c.fields.value.set(O,n.name);const o=e.inject(t),y=e.computed({get(){if(o!=null&&o.formData)return $(new Object(o.formData.value),String(n.name))},set(u){o!=null&&o.formData&&(J(new Object(o.formData.value),String(n.name),u),v("update:modelValue",{newValue:y.value,formData:o==null?void 0:o.formData}))}});e.onMounted(()=>{y.value===void 0&&n.defaultValue!==void 0&&(y.value=n.defaultValue)}),e.onBeforeUnmount(()=>{c&&c.fields.value.delete(O)});const w=e.computed(()=>{if(o!=null&&o.errors.value)return $(o.errors.value,String(n.name))}),p=e.computed(()=>{var u;return(u=w.value)==null?void 0:u._errors}),s=e.computed(()=>w.value!==void 0),g=e.watch(s,u=>{if(u){v("invalid",w.value),c&&c.errors.value.set(String(n.name),w.value);return}v("valid",y.value),c&&c.errors.value.delete(n.name)}),V=e.watch(()=>o==null?void 0:o.formData,()=>{v("update:formData",o==null?void 0:o.formData)},{deep:!0});e.onBeforeUnmount(()=>{g(),V()});const E=u=>{u instanceof InputEvent&&(u=u.target.value),y.value=u},k=e.computed(()=>{let u=d.value;return typeof u=="function"&&(u=u(o==null?void 0:o.formData)),Object.keys(u).reduce((S,U)=>(S[U]=e.unref(u[U]),S),{})}),G=e.computed(()=>o!=null&&o.readonly.value||c!=null&&c.readonly.value?!0:k.value.readonly??n.readonly),x=e.computed(()=>({...k.value,name:k.value.name??n.name,invalid:s.value,valid:n.showValid?!!(!s.value&&y.value):void 0,type:(u=>{if([b.color,b.date,b.datetimeLocal,b.email,b.month,b.number,b.password,b.search,b.tel,b.text,b.time,b.url,b.week].includes(u))return u})(n.type),invalidLabel:p.value,modelValue:y.value,readonly:G.value,"onUpdate:modelValue":E}));return e.provide(r,{name:e.readonly(f),errors:e.readonly(w)}),{component:e.computed(()=>{if(n.type===b.custom)return{render(){var u;return((u=a.default)==null?void 0:u.call(a,{errors:w.value,formData:o==null?void 0:o.formData.value,formErrors:o==null?void 0:o.errors.value,invalid:s.value,invalidLabel:p.value,modelValue:y.value,readonly:G.value,onUpdate:E,submit:o==null?void 0:o.submit,validate:o==null?void 0:o.validate}))??a.default}};if(!((m==null?void 0:m.lazyLoad)??n.lazyLoad)){let u;switch(n.type){case b.select:u=e.resolveComponent("VvSelect");break;case b.checkbox:u=e.resolveComponent("VvCheckbox");break;case b.radio:u=e.resolveComponent("VvRadio");break;case b.textarea:u=e.resolveComponent("VvTextarea");break;case b.radioGroup:u=e.resolveComponent("VvRadioGroup");break;case b.checkboxGroup:u=e.resolveComponent("VvCheckboxGroup");break;case b.combobox:u=e.resolveComponent("VvCombobox");break;default:u=e.resolveComponent("VvInputText")}if(typeof u!="string")return u;console.warn(`[@volverjs/form-vue]: ${u} not found, the component will be loaded asynchronously. To avoid this warning, please set "lazyLoad" option.`)}return e.defineAsyncComponent(async()=>{switch(m!=null&&m.sideEffects&&await Promise.resolve(m.sideEffects(n.type)),n.type){case b.textarea:return import("@volverjs/ui-vue/vv-textarea");case b.radio:return import("@volverjs/ui-vue/vv-radio");case b.radioGroup:return import("@volverjs/ui-vue/vv-radio-group");case b.checkbox:return import("@volverjs/ui-vue/vv-checkbox");case b.checkboxGroup:return import("@volverjs/ui-vue/vv-checkbox-group");case b.select:return import("@volverjs/ui-vue/vv-select");case b.combobox:return import("@volverjs/ui-vue/vv-combobox")}return import("@volverjs/ui-vue/vv-input-text")})}),hasProps:x,invalid:s}},render(){return this.is?e.h(this.is,this.hasProps,this.$slots):this.type===b.custom?e.h(this.component,null,this.$slots):e.h(this.component,this.hasProps,this.$slots)}})}function ne(t,i,r){return e.defineComponent({name:"VvFormFieldsGroup",props:{is:{type:[Object,String],default:void 0},names:{type:[Array,Object],required:!0},props:{type:[Object,Function],default:()=>({})},showValid:{type:Boolean,default:!1},defaultValues:{type:[Object],default:void 0},readonly:{type:Boolean,default:void 0}},emits:["invalid","update:formData","update:modelValue","valid"],expose:["component","errors","hasProps","invalid","invalidLabels","is"],slots:Object,setup(m,{slots:n,emit:a}){const{props:v,names:d,defaultValues:f}=e.toRefs(m),O=e.useId(),c=e.computed(()=>Array.isArray(d.value)?d.value:Object.values(d.value)),o=e.computed(()=>Array.isArray(d.value)?d.value:Object.keys(d.value)),y=e.computed(()=>Array.isArray(d.value)?d.value.reduce((l,h)=>(l[String(h)]=h,l),{}):d.value),w=e.computed(()=>Object.keys(y.value).reduce((l,h)=>(l[String(y.value[h])]=h,l),{})),p=e.inject(i,void 0);p&&c.value.forEach(l=>{p.fields.value.set(`${O}-${l}`,l)});const s=e.inject(t),g=e.computed({get(){return s!=null&&s.formData?o.value.reduce((l,h)=>(l[h]=$(new Object(s.formData.value),y.value[h]),l),{}):{}},set(l){s!=null&&s.formData&&(o.value.forEach(h=>{J(new Object(s.formData.value),y.value[h],l==null?void 0:l[h])}),a("update:modelValue",{newValue:g.value,formData:s==null?void 0:s.formData}))}});e.onMounted(()=>{f.value&&c.value.forEach(l=>{var h,R;((h=f.value)==null?void 0:h[l])!==void 0&&g.value[l]===void 0&&(g.value={...g.value,[l]:(R=f.value)==null?void 0:R[l]})})}),e.onBeforeUnmount(()=>{p&&c.value.forEach(l=>{p.fields.value.delete(`${O}-${l}`)})});const V=e.computed(()=>{if(!(s!=null&&s.errors.value))return;const l=c.value.reduce((h,R)=>{if(!s.errors.value)return h;const Z=$(s.errors.value,String(R));return Z===void 0||(h[String(R)]=Z),h},{});if(Object.keys(l).length!==0)return l}),E=e.computed(()=>{if(!V.value)return;const l=Object.keys(V.value).reduce((h,R)=>{var Z;return(Z=V.value)!=null&&Z[R]&&(h[w.value[R]]=V.value[R]._errors),h},{});if(Object.keys(l).length!==0)return l}),k=e.computed(()=>V.value!==void 0),G=e.computed(()=>o.value.reduce((l,h)=>{var R;return l[h]=!!((R=V.value)!=null&&R[w.value[h]]),l},{})),x=e.watch(k,()=>{if(k.value){a("invalid",V.value),p&&c.value.forEach(l=>{var h,R;if(!((h=V.value)!=null&&h[l])){p.errors.value.delete(l);return}p.errors.value.set(l,(R=V.value)==null?void 0:R[l])});return}a("valid",g.value),p&&c.value.forEach(l=>{p.errors.value.delete(l)})}),I=e.watch(()=>s==null?void 0:s.formData,()=>{a("update:formData",s==null?void 0:s.formData)},{deep:!0});e.onBeforeUnmount(()=>{x(),I()});const u=l=>{g.value=l},S=(l,h)=>{h instanceof InputEvent&&(h=h.target.value),o.value.includes(l)&&(g.value={...g.value,[l]:h})},U=e.computed(()=>{let l=v.value;return typeof l=="function"&&(l=l(s==null?void 0:s.formData)),Object.keys(l).reduce((h,R)=>(h[R]=e.unref(l[R]),h),{})}),M=e.computed(()=>s!=null&&s.readonly.value?!0:U.value.readonly??m.readonly),K=e.computed(()=>o.value.reduce((l,h)=>(l[`onUpdate:${h}`]=R=>{S(h,R)},l),{"onUpdate:modelValue":u})),T=e.computed(()=>({...K.value,...U.value,names:U.value.name??c.value,invalid:k.value,invalids:G.value,valid:m.showValid?!!(!k.value&&g.value):void 0,invalidLabels:E.value,modelValue:g.value,readonly:M.value}));return e.provide(r,{names:e.readonly(d),errors:e.readonly(V)}),{component:e.computed(()=>({render(){var l;return((l=n.default)==null?void 0:l.call(n,{errors:V.value,formData:s==null?void 0:s.formData.value,formErrors:s==null?void 0:s.errors.value,invalid:k.value,invalids:G.value,invalidLabels:E.value,modelValue:g.value,onUpdate:u,onUpdateField:S,readonly:M.value,submit:s==null?void 0:s.submit,validate:s==null?void 0:s.validate}))??n.default}})),hasProps:T,invalid:k}},render(){return this.is?e.h(this.is,this.hasProps,this.$slots):e.h(this.component,null,this.$slots)}})}function ae(t,i){return e.defineComponent({name:"VvFormWrapper",props:{name:{type:String,required:!0},tag:{type:String,default:void 0},readonly:{type:Boolean,default:!1}},emits:["invalid","valid"],expose:["clear","errors","fields","fieldsErrors","formData","invalid","readonly","reset","submit","tag","validate","validateWrapper"],slots:Object,setup(r,{emit:m}){const n=e.inject(t),a=e.inject(i,void 0),v=e.ref(new Map),d=e.ref(new Map),{name:f}=e.toRefs(r),O=e.computed(()=>n!=null&&n.invalid.value?d.value.size>0:!1);e.watch(O,p=>{if(p){m("invalid");return}m("valid")});const c=e.computed(()=>(n==null?void 0:n.readonly.value)||r.readonly),o={name:e.readonly(f),errors:d,invalid:e.readonly(O),readonly:e.readonly(c),fields:v};e.provide(i,o);const y=e.computed(()=>new Map(v.value));e.watch(y,(p,s)=>{a!=null&&a.fields&&(s.forEach((g,V)=>{p.has(V)||a==null||a.fields.value.delete(V)}),p.forEach((g,V)=>{a!=null&&a.fields.value.has(V)||a==null||a.fields.value.set(V,g)}))},{deep:!0}),e.watch(d,p=>{a!=null&&a.errors&&v.value.forEach(s=>{if(p.has(s)||a.errors.value.delete(s),p.has(s)){const g=p.get(s);g&&a.errors.value.set(s,g)}})},{deep:!0}),e.onMounted(()=>{if(!(n!=null&&n.wrappers)||!f.value){console.warn("[@volverjs/form-vue]: Invalid wrapper registration state");return}if(n.wrappers.has(f.value)){console.warn(`[@volverjs/form-vue]: wrapper name "${f.value}" is already used`);return}n.wrappers.set(f.value,o)}),e.onBeforeUnmount(()=>{n!=null&&n.wrappers&&f.value&&n.wrappers.delete(f.value)});const w=()=>(n==null?void 0:n.validate(void 0,new Set(v.value.values())))??Promise.resolve(!0);return{errors:n==null?void 0:n.errors,fields:v,fieldsErrors:d,formData:n==null?void 0:n.formData,invalid:O,readonly:c,clear:n==null?void 0:n.clear,reset:n==null?void 0:n.reset,submit:n==null?void 0:n.submit,validate:n==null?void 0:n.validate,validateWrapper:w}},render(){const r=()=>{var m,n;return(n=(m=this.$slots).default)==null?void 0:n.call(m,{errors:this.errors,fieldsErrors:this.fieldsErrors,formData:this.formData,invalid:this.invalid,readonly:this.readonly,clear:this.clear,reset:this.reset,submit:this.submit,validate:this.validate,validateWrapper:this.validateWrapper})};return this.tag?e.h(this.tag,null,{default:r}):r()}})}function le(t,i){const r=e.defineComponent({name:"VvFormTemplate",props:{schema:{type:[Array,Function],required:!0},scope:{type:Object,default:()=>({})}},slots:Object,setup(m,{slots:n}){const a=e.inject(t);if(a!=null&&a.formData)return()=>{var O;const v=typeof m.schema=="function"?m.schema(a,m.scope):m.schema;let d;const f=v.reduce((c,o)=>{const y=typeof o=="function"?o(a,m.scope):o,{vvIs:w,vvName:p,vvSlots:s,vvChildren:g,vvIf:V,vvElseIf:E,vvType:k,vvDefaultValue:G,vvShowValid:x,vvContent:I,...u}=y;if(V!==void 0){if(typeof V=="string"?d=!!$(new Object(a.formData.value),V):typeof V=="function"?d=e.unref(V(a)):d=e.unref(V),!d)return c}else if(E!==void 0&&d!==void 0){if(d||(typeof E=="string"?d=!!$(new Object(a.formData.value),E):typeof E=="function"?d=e.unref(E(a)):d=e.unref(E),!d))return c}else d=void 0;let S;return g&&(typeof w=="string"?S=e.h(r,{schema:g}):S={default:U=>e.h(r,{schema:g,scope:U})}),p?(c.push(e.h(i,{name:p,is:w,type:k,defaultValue:G,showValid:x,props:u},s??S??I)),c):w?(c.push(e.h(w,u,s??S??I)),c):(S&&("default"in S?c.push(S.default(m.scope)):c.push(S)),c)},[]);return f.push((O=n==null?void 0:n.default)==null?void 0:O.call(n,{errors:a==null?void 0:a.errors.value,formData:a==null?void 0:a.formData.value,invalid:a==null?void 0:a.invalid.value,status:a==null?void 0:a.status.value,submit:a==null?void 0:a.submit,validate:a==null?void 0:a.validate,clear:a==null?void 0:a.clear,reset:a==null?void 0:a.reset})),f}}});return r}function N(t,i={}){const r=Symbol("formInjectionKey"),m=Symbol("formWrapperInjectionKey"),n=Symbol("formFieldInjectionKey"),a=Symbol("formFieldsGroupInjectionKey"),v=ae(r,m),d=te(r,m,n,i),f=ne(r,m,a),O=le(r,d),c=new Map,{clear:o,errors:y,formData:w,ignoreUpdates:p,invalid:s,readonly:g,reset:V,status:E,stopUpdatesWatch:k,submit:G,validate:x,VvForm:I}=D(t,r,i,O,c);return{clear:o,errors:y,formData:w,formFieldInjectionKey:n,formInjectionKey:r,formWrapperInjectionKey:m,ignoreUpdates:p,invalid:s,readonly:g,reset:V,status:E,stopUpdatesWatch:k,submit:G,validate:x,wrappers:c,VvForm:I,VvFormField:d,VvFormFieldsGroup:f,VvFormTemplate:O,VvFormWrapper:v}}const W=Symbol("pluginInjectionKey");function ue(t){let i={};return t.schema&&(i=N(t.schema,t)),{...i,install(r,{global:m=!1}={}){r.provide(W,t),m&&(r.config.globalProperties.$vvForm=t,i!=null&&i.VvForm&&r.component("VvForm",i.VvForm),i!=null&&i.VvFormWrapper&&r.component("VvFormWrapper",i.VvFormWrapper),i!=null&&i.VvFormField&&r.component("VvFormField",i.VvFormField),i!=null&&i.VvFormFieldsGroup&&r.component("VvFormFieldsGroup",i.VvFormFieldsGroup),i!=null&&i.VvFormTemplate&&r.component("VvFormTemplate",i.VvFormTemplate))}}}const P=new Map;function oe(t,i={}){if(i.scope&&P.has(i.scope))return P.get(i.scope);if(!e.getCurrentInstance()){const m=N(t,i);return i.scope&&P.set(i.scope,m),m}const r=N(t,{...e.inject(W,{}),...i});return i.scope&&P.set(i.scope,r),r}function se(t,i={}){return N(t,i)}C.FormFieldType=b,C.createForm=ue,C.defaultObjectBySchema=L,C.formType=se,C.pluginInjectionKey=W,C.useForm=oe,Object.defineProperty(C,Symbol.toStringTag,{value:"Module"})});
package/dist/types.d.ts CHANGED
@@ -48,6 +48,7 @@ export type InjectedFormWrapperData<Schema extends FormSchema> = {
48
48
  name: Readonly<Ref<string>>;
49
49
  errors: Ref<Map<string, z.inferFormattedError<Schema>>>;
50
50
  invalid: Readonly<Ref<boolean>>;
51
+ readonly: Readonly<Ref<boolean>>;
51
52
  fields: Ref<Map<string, string>>;
52
53
  };
53
54
  export type InjectedFormFieldData<Schema extends FormSchema> = {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@volverjs/form-vue",
3
3
  "type": "module",
4
- "version": "1.0.0-beta.32",
4
+ "version": "1.0.0-beta.34",
5
5
  "description": "Vue 3 Forms with @volverjs/ui-vue",
6
6
  "author": "8 Wave S.r.l.",
7
7
  "license": "MIT",
@@ -57,23 +57,23 @@
57
57
  "zod": "^3.*"
58
58
  },
59
59
  "devDependencies": {
60
- "@antfu/eslint-config": "^3.11.2",
60
+ "@antfu/eslint-config": "^4.4.0",
61
61
  "@nabla/vite-plugin-eslint": "^2.0.5",
62
- "@playwright/experimental-ct-vue": "1.49.0",
62
+ "@playwright/experimental-ct-vue": "1.50.1",
63
63
  "@testing-library/vue": "^8.1.0",
64
64
  "@vitejs/plugin-vue": "^5.2.1",
65
- "@volverjs/style": "0.1.15",
65
+ "@volverjs/style": "0.1.17",
66
66
  "@vue/compiler-sfc": "^3.5.13",
67
67
  "@vue/runtime-core": "^3.5.13",
68
68
  "@vue/test-utils": "^2.4.6",
69
69
  "copy": "^0.3.2",
70
- "eslint": "^9.16.0",
71
- "happy-dom": "^15.11.7",
72
- "typescript": "5.4.2",
73
- "vite": "^6.0.2",
74
- "vite-plugin-dts": "^4.3.0",
75
- "vite-plugin-externalize-deps": "^0.8.0",
76
- "vitest": "2.1.6"
70
+ "eslint": "^9.21.0",
71
+ "happy-dom": "^17.1.8",
72
+ "typescript": "5.8.2",
73
+ "vite": "^6.2.0",
74
+ "vite-plugin-dts": "^4.5.3",
75
+ "vite-plugin-externalize-deps": "^0.9.0",
76
+ "vitest": "3.0.7"
77
77
  },
78
78
  "scripts": {
79
79
  "lint": "eslint .",
package/src/VvForm.ts CHANGED
@@ -1,9 +1,13 @@
1
+ import type { Component, InjectionKey, PropType, SlotsType, UnwrapRef } from 'vue'
2
+ import type { z } from 'zod'
3
+ import type {
4
+ FormComponentOptions,
5
+ FormSchema,
6
+ FormTemplate,
7
+ InjectedFormData,
8
+ InjectedFormWrapperData,
9
+ } from './types'
1
10
  import {
2
- type Component,
3
- type InjectionKey,
4
- type PropType,
5
- type SlotsType,
6
- type UnwrapRef,
7
11
  computed,
8
12
  defineComponent,
9
13
  h,
@@ -20,14 +24,7 @@ import {
20
24
  throttleFilter,
21
25
  watchIgnorable,
22
26
  } from '@vueuse/core'
23
- import { type z, ZodError } from 'zod'
24
- import type {
25
- FormComponentOptions,
26
- FormSchema,
27
- FormTemplate,
28
- InjectedFormData,
29
- InjectedFormWrapperData,
30
- } from './types'
27
+ import { ZodError } from 'zod'
31
28
  import { FormStatus } from './enums'
32
29
  import { defaultObjectBySchema } from './utils'
33
30
 
@@ -1,12 +1,15 @@
1
+ import type { Component, ConcreteComponent, DeepReadonly, InjectionKey, PropType, Ref, SlotsType } from 'vue'
2
+ import type { z } from 'zod'
3
+ import type {
4
+ FormFieldComponentOptions,
5
+ FormSchema,
6
+ InjectedFormData,
7
+ InjectedFormFieldData,
8
+ InjectedFormWrapperData,
9
+ Path,
10
+ } from './types'
1
11
  import { get, set } from 'ts-dot-prop'
2
12
  import {
3
- type Component,
4
- type ConcreteComponent,
5
- type DeepReadonly,
6
- type InjectionKey,
7
- type PropType,
8
- type Ref,
9
- type SlotsType,
10
13
  computed,
11
14
  defineAsyncComponent,
12
15
  defineComponent,
@@ -22,16 +25,7 @@ import {
22
25
  watch,
23
26
  useId,
24
27
  } from 'vue'
25
- import type { z } from 'zod'
26
28
  import { FormFieldType } from './enums'
27
- import type {
28
- FormFieldComponentOptions,
29
- FormSchema,
30
- InjectedFormData,
31
- InjectedFormFieldData,
32
- InjectedFormWrapperData,
33
- Path,
34
- } from './types'
35
29
 
36
30
  export function defineFormField<Schema extends FormSchema, Type = undefined>(formProvideKey: InjectionKey<InjectedFormData<Schema, Type>>, wrapperProvideKey: InjectionKey<InjectedFormWrapperData<Schema>>, formFieldInjectionKey: InjectionKey<InjectedFormFieldData<Schema>>, options?: FormFieldComponentOptions) {
37
31
  return defineComponent({
@@ -175,11 +169,11 @@ export function defineFormField<Schema extends FormSchema, Type = undefined>(for
175
169
  const invalidLabel = computed(() => {
176
170
  return errors.value?._errors
177
171
  })
178
- const invalid = computed(() => {
172
+ const isInvalid = computed(() => {
179
173
  return errors.value !== undefined
180
174
  })
181
- const unwatchInvalid = watch(invalid, () => {
182
- if (invalid.value) {
175
+ const unwatchInvalid = watch(isInvalid, (newValue) => {
176
+ if (newValue) {
183
177
  emit('invalid', errors.value)
184
178
  if (injectedWrapperData) {
185
179
  injectedWrapperData.errors.value.set(
@@ -230,14 +224,17 @@ export function defineFormField<Schema extends FormSchema, Type = undefined>(for
230
224
  if (injectedFormData?.readonly.value) {
231
225
  return true
232
226
  }
227
+ if (injectedWrapperData?.readonly.value) {
228
+ return true
229
+ }
233
230
  return (hasFieldProps.value.readonly ?? props.readonly) as boolean
234
231
  })
235
232
  const hasProps = computed(() => ({
236
233
  ...hasFieldProps.value,
237
234
  'name': hasFieldProps.value.name ?? props.name,
238
- 'invalid': invalid.value,
235
+ 'invalid': isInvalid.value,
239
236
  'valid': props.showValid
240
- ? Boolean(!invalid.value && modelValue.value)
237
+ ? Boolean(!isInvalid.value && modelValue.value)
241
238
  : undefined,
242
239
  'type': ((type: FormFieldType) => {
243
240
  if (
@@ -283,7 +280,7 @@ export function defineFormField<Schema extends FormSchema, Type = undefined>(for
283
280
  errors: errors.value,
284
281
  formData: injectedFormData?.formData.value,
285
282
  formErrors: injectedFormData?.errors.value,
286
- invalid: invalid.value,
283
+ invalid: isInvalid.value,
287
284
  invalidLabel: invalidLabel.value,
288
285
  modelValue: modelValue.value,
289
286
  readonly: isReadonly.value,
@@ -367,7 +364,7 @@ export function defineFormField<Schema extends FormSchema, Type = undefined>(for
367
364
  })
368
365
  })
369
366
 
370
- return { component, hasProps, invalid }
367
+ return { component, hasProps, invalid: isInvalid }
371
368
  },
372
369
  render() {
373
370
  if (this.is) {
@@ -1,11 +1,14 @@
1
+ import type { Component, DeepReadonly, InjectionKey, PropType, Ref, SlotsType } from 'vue'
2
+ import type { z } from 'zod'
3
+ import type {
4
+ FormSchema,
5
+ InjectedFormData,
6
+ InjectedFormFieldsGroupData,
7
+ InjectedFormWrapperData,
8
+ Path,
9
+ } from './types'
1
10
  import { get, set } from 'ts-dot-prop'
2
11
  import {
3
- type Component,
4
- type DeepReadonly,
5
- type InjectionKey,
6
- type PropType,
7
- type Ref,
8
- type SlotsType,
9
12
  computed,
10
13
  defineComponent,
11
14
  h,
@@ -19,14 +22,6 @@ import {
19
22
  useId,
20
23
  watch,
21
24
  } from 'vue'
22
- import type { z } from 'zod'
23
- import type {
24
- FormSchema,
25
- InjectedFormData,
26
- InjectedFormFieldsGroupData,
27
- InjectedFormWrapperData,
28
- Path,
29
- } from './types'
30
25
 
31
26
  export function defineFormFieldsGroup<Schema extends FormSchema, Type = undefined>(formProvideKey: InjectionKey<InjectedFormData<Schema, Type>>, wrapperProvideKey: InjectionKey<InjectedFormWrapperData<Schema>>, formFieldsGroupInjectionKey: InjectionKey<InjectedFormFieldsGroupData<Schema>>) {
32
27
  return defineComponent({
@@ -1,19 +1,14 @@
1
+ import type { Component, DeepReadonly, InjectionKey, PropType, SlotsType, VNode } from 'vue'
2
+ import type { FormSchema, InjectedFormData, FormTemplate, RenderFunctionOutput } from './types'
3
+ import type { z } from 'zod'
4
+ import type { FormStatus } from './enums'
1
5
  import { get } from 'ts-dot-prop'
2
6
  import {
3
- type Component,
4
- type DeepReadonly,
5
- type InjectionKey,
6
- type PropType,
7
- type SlotsType,
8
- type VNode,
9
7
  defineComponent,
10
8
  h,
11
9
  inject,
12
10
  unref,
13
11
  } from 'vue'
14
- import type { FormSchema, InjectedFormData, FormTemplate, RenderFunctionOutput } from './types'
15
- import type { z } from 'zod'
16
- import type { FormStatus } from './enums'
17
12
 
18
13
  export function defineFormTemplate<Schema extends FormSchema, Type = undefined>(formProvideKey: InjectionKey<InjectedFormData<Schema, Type>>, VvFormField: Component) {
19
14
  const VvFormTemplate = defineComponent({
@@ -47,9 +42,9 @@ export function defineFormTemplate<Schema extends FormSchema, Type = undefined>(
47
42
  return () => {
48
43
  const normalizedSchema = typeof templateProps.schema === 'function'
49
44
  ? templateProps.schema(
50
- injectedFormData,
51
- templateProps.scope,
52
- )
45
+ injectedFormData,
46
+ templateProps.scope,
47
+ )
53
48
  : templateProps.schema
54
49
  let lastIf: boolean | undefined
55
50
  const toReturn = normalizedSchema.reduce<
@@ -1,8 +1,11 @@
1
+ import type { DeepReadonly, InjectionKey, Ref, SlotsType } from 'vue'
2
+ import type { z } from 'zod'
3
+ import type {
4
+ FormSchema,
5
+ InjectedFormData,
6
+ InjectedFormWrapperData,
7
+ } from './types'
1
8
  import {
2
- type DeepReadonly,
3
- type InjectionKey,
4
- type Ref,
5
- type SlotsType,
6
9
  computed,
7
10
  defineComponent,
8
11
  h,
@@ -15,12 +18,6 @@ import {
15
18
  toRefs,
16
19
  watch,
17
20
  } from 'vue'
18
- import type { z } from 'zod'
19
- import type {
20
- FormSchema,
21
- InjectedFormData,
22
- InjectedFormWrapperData,
23
- } from './types'
24
21
 
25
22
  export function defineFormWrapper<Schema extends FormSchema, Type = undefined>(formProvideKey: InjectionKey<InjectedFormData<Schema, Type>>, wrapperProvideKey: InjectionKey<InjectedFormWrapperData<Schema>>) {
26
23
  return defineComponent({
@@ -34,6 +31,10 @@ export function defineFormWrapper<Schema extends FormSchema, Type = undefined>(f
34
31
  type: String,
35
32
  default: undefined,
36
33
  },
34
+ readonly: {
35
+ type: Boolean,
36
+ default: false,
37
+ },
37
38
  },
38
39
  emits: ['invalid', 'valid'],
39
40
  expose: [
@@ -43,6 +44,7 @@ export function defineFormWrapper<Schema extends FormSchema, Type = undefined>(f
43
44
  'fieldsErrors',
44
45
  'formData',
45
46
  'invalid',
47
+ 'readonly',
46
48
  'reset',
47
49
  'submit',
48
50
  'tag',
@@ -56,6 +58,7 @@ export function defineFormWrapper<Schema extends FormSchema, Type = undefined>(f
56
58
  formData?: undefined extends Type ? Partial<z.infer<Schema>> : Type
57
59
  formErrors?: DeepReadonly<z.inferFormattedError<Schema>>
58
60
  invalid: boolean
61
+ readonly: boolean
59
62
  clear?: InjectedFormData<Schema, Type>['clear']
60
63
  reset?: InjectedFormData<Schema, Type>['reset']
61
64
  submit?: InjectedFormData<Schema, Type>['submit']
@@ -64,54 +67,58 @@ export function defineFormWrapper<Schema extends FormSchema, Type = undefined>(f
64
67
  }
65
68
  }>,
66
69
  setup(props, { emit }) {
70
+ // inject data from parent form
67
71
  const injectedFormData = inject(formProvideKey)
68
- const wrapperProvided = inject(wrapperProvideKey, undefined)
69
- const fields = ref(new Map<string, string>())
72
+ // inject data from parent form wrapper
73
+ const injectedWrapperData = inject(wrapperProvideKey, undefined)
74
+ const fields: Ref<Map<string, string>> = ref(new Map())
70
75
  const fieldsErrors: Ref<
71
76
  Map<string, z.inferFormattedError<Schema>>
72
77
  > = ref(new Map())
73
78
  const { name } = toRefs(props)
74
79
 
75
80
  // invalid
76
- const invalid = computed(() => {
81
+ const isInvalid = computed(() => {
77
82
  if (!injectedFormData?.invalid.value) {
78
83
  return false
79
84
  }
80
85
  return fieldsErrors.value.size > 0
81
86
  })
82
- watch(invalid, () => {
83
- if (invalid.value) {
87
+ watch(isInvalid, (newValue) => {
88
+ if (newValue) {
84
89
  emit('invalid')
90
+ return
85
91
  }
86
- else {
87
- emit('valid')
88
- }
92
+ emit('valid')
89
93
  })
90
94
 
95
+ // readonly
96
+ const isReadonly = computed(() => injectedFormData?.readonly.value || props.readonly)
97
+
91
98
  // provide data to child fields
92
99
  const providedData = {
93
100
  name: readonly(name),
94
101
  errors: fieldsErrors,
95
- invalid: readonly(invalid),
102
+ invalid: readonly(isInvalid),
103
+ readonly: readonly(isReadonly),
96
104
  fields,
97
105
  }
98
106
  provide(wrapperProvideKey, providedData)
99
107
 
100
108
  // add fields to parent wrapper
109
+ const computedFields = computed(() => new Map(fields.value))
101
110
  watch(
102
- fields,
111
+ computedFields,
103
112
  (newValue, oldValue) => {
104
- if (wrapperProvided?.fields) {
105
- oldValue.forEach((_field, id) => {
106
- if (!newValue.has(id)) {
107
- wrapperProvided?.fields.value.delete(id)
113
+ if (injectedWrapperData?.fields) {
114
+ oldValue.forEach((_field, key) => {
115
+ if (!newValue.has(key)) {
116
+ injectedWrapperData?.fields.value.delete(key)
108
117
  }
109
118
  })
110
- }
111
- if (wrapperProvided?.fields) {
112
- newValue.forEach((field, id) => {
113
- if (!wrapperProvided?.fields.value.has(id)) {
114
- wrapperProvided?.fields.value.set(id, field)
119
+ newValue.forEach((field, key) => {
120
+ if (!injectedWrapperData?.fields.value.has(key)) {
121
+ injectedWrapperData?.fields.value.set(key, field)
115
122
  }
116
123
  })
117
124
  }
@@ -122,15 +129,17 @@ export function defineFormWrapper<Schema extends FormSchema, Type = undefined>(f
122
129
  // add fields errors to parent wrapper
123
130
  watch(
124
131
  fieldsErrors,
125
- (newValue, oldValue) => {
126
- if (wrapperProvided?.errors) {
127
- Array.from(oldValue.keys()).forEach((key) => {
128
- wrapperProvided.errors.value.delete(key)
129
- })
130
- Array.from(newValue.keys()).forEach((key) => {
131
- const value = newValue.get(key)
132
- if (value) {
133
- wrapperProvided.errors.value.set(key, value)
132
+ (newValue) => {
133
+ if (injectedWrapperData?.errors) {
134
+ fields.value.forEach((field) => {
135
+ if (!newValue.has(field)) {
136
+ injectedWrapperData.errors.value.delete(field)
137
+ }
138
+ if (newValue.has(field)) {
139
+ const value = newValue.get(field)
140
+ if (value) {
141
+ injectedWrapperData.errors.value.set(field, value)
142
+ }
134
143
  }
135
144
  })
136
145
  }
@@ -164,7 +173,8 @@ export function defineFormWrapper<Schema extends FormSchema, Type = undefined>(f
164
173
  fields,
165
174
  fieldsErrors,
166
175
  formData: injectedFormData?.formData,
167
- invalid,
176
+ invalid: isInvalid,
177
+ readonly: isReadonly,
168
178
  clear: injectedFormData?.clear,
169
179
  reset: injectedFormData?.reset,
170
180
  submit: injectedFormData?.submit,
@@ -179,6 +189,7 @@ export function defineFormWrapper<Schema extends FormSchema, Type = undefined>(f
179
189
  fieldsErrors: this.fieldsErrors,
180
190
  formData: this.formData,
181
191
  invalid: this.invalid,
192
+ readonly: this.readonly,
182
193
  clear: this.clear,
183
194
  reset: this.reset,
184
195
  submit: this.submit,
package/src/index.ts CHANGED
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  getCurrentInstance,
3
- type App,
3
+
4
4
  inject,
5
- type InjectionKey,
6
- type Plugin,
5
+
7
6
  } from 'vue'
7
+ import type { App, InjectionKey, Plugin } from 'vue'
8
8
  import type { AnyZodObject } from 'zod'
9
9
  import { defineForm } from './VvForm'
10
10
  import { defineFormField } from './VvFormField'
package/src/types.ts CHANGED
@@ -74,6 +74,7 @@ export type InjectedFormWrapperData<Schema extends FormSchema> = {
74
74
  name: Readonly<Ref<string>>
75
75
  errors: Ref<Map<string, z.inferFormattedError<Schema>>>
76
76
  invalid: Readonly<Ref<boolean>>
77
+ readonly: Readonly<Ref<boolean>>
77
78
  fields: Ref<Map<string, string>>
78
79
  }
79
80
 
package/src/utils.ts CHANGED
@@ -1,7 +1,5 @@
1
1
  import {
2
- type z,
3
- type AnyZodObject,
4
- type ZodTypeAny,
2
+
5
3
  ZodDefault,
6
4
  ZodObject,
7
5
  ZodEffects,
@@ -11,6 +9,7 @@ import {
11
9
  ZodRecord,
12
10
  ZodArray,
13
11
  } from 'zod'
12
+ import type { z, AnyZodObject, ZodTypeAny } from 'zod'
14
13
  import type { EffectType, FormSchema } from './types'
15
14
 
16
15
  export function defaultObjectBySchema<Schema extends FormSchema>(schema: Schema, original: Partial<z.infer<Schema>> & Record<string, unknown> = {}): Partial<z.infer<Schema>> {