@volverjs/form-vue 0.0.10-beta.8 → 0.0.10

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(y,t){typeof exports=="object"&&typeof module<"u"?t(exports,require("vue"),require("@vueuse/core"),require("zod")):typeof define=="function"&&define.amd?define(["exports","vue","@vueuse/core","zod"],t):(y=typeof globalThis<"u"?globalThis:y||self,t(y["@volverjs/form-vue"]={},y.Vue,y.VueUseCore,y.zod))})(this,function(y,t,M,x){"use strict";function I(e){return Array.isArray(e)}function Z(e){return typeof e<"u"}function W(e){return e===null}function A(e){return typeof e=="object"}function L(e){return typeof e=="string"}function k(e){return typeof e>"u"}const z=/^[0-9]+$/,U=["__proto__","prototype","constructor"];function C(e,o,f){const i=Z(f)?f:void 0;if(!A(e)||!L(o))return i;const a=K(o);if(a.length!==0){for(const r of a){if(r==="*")continue;const u=function(s){return s.map(l=>k(l)||W(l)?l:I(l)?u(l):l[r])};if(I(e)&&!z.test(r)?e=u(e):e=e[r],k(e)||W(e))break}return k(e)?i:e}}function _(e,o,f){if(!A(e)||!L(o))return;const i=K(o);if(i.length===0)return;const a=i.length;for(let r=0;r<a;r++){const u=i[r];if(r===a-1){e[u]=f;return}if(u==="*"&&I(e)){const s=i.slice(r+1).join(".");for(const l of e)_(l,s,f);return}k(e[u])&&(e[u]={}),e=e[u]}}function K(e){const o=e.split(/[.]|(?:\[(\d|\*)\])/).filter(f=>!!f);return o.some(f=>U.indexOf(f)!==-1)?[]:o}var c=(e=>(e.text="text",e.number="number",e.email="email",e.password="password",e.tel="tel",e.url="url",e.search="search",e.date="date",e.time="time",e.datetimeLocal="datetimeLocal",e.month="month",e.week="week",e.color="color",e.select="select",e.checkbox="checkbox",e.radio="radio",e.textarea="textarea",e.radioGroup="radioGroup",e.checkboxGroup="checkboxGroup",e.combobox="combobox",e.custom="custom",e))(c||{}),O=(e=>(e.invalid="invalid",e.valid="valid",e))(O||{});const J=(e,o,f,i)=>t.defineComponent({name:"FieldComponent",props:{type:{type:String,validator:a=>Object.values(c).includes(a),default:c.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}},emits:["invalid","valid","update:formData","update:modelValue"],expose:["invalid","invalidLabel","errors"],setup(a,{slots:r,emit:u}){const s=t.computed({get(){if(n!=null&&n.formData)return C(Object(n.formData.value),String(a.name))},set(d){n!=null&&n.formData&&(_(Object(n.formData.value),String(a.name),d),u("update:modelValue",{newValue:s.value,formData:n==null?void 0:n.formData}))}});t.onMounted(()=>{s.value===void 0&&a.defaultValue!==void 0&&(s.value=a.defaultValue)}),t.onBeforeUnmount(()=>{w(),g()});const l=t.inject(o,void 0);l&&l.fields.value.add(a.name);const n=t.inject(e),{props:h,name:b}=t.toRefs(a),p=t.computed(()=>{if(n!=null&&n.errors.value)return C(n.errors.value,String(a.name))}),m=t.computed(()=>{var d;return(d=p.value)==null?void 0:d._errors}),v=t.computed(()=>p.value!==void 0),w=t.watch(v,()=>{v.value?(u("invalid",m.value),l&&l.errors.value.set(a.name,{_errors:m.value})):(u("valid",s.value),l&&l.errors.value.delete(a.name))}),g=t.watch(()=>n==null?void 0:n.formData,()=>{u("update:formData",n==null?void 0:n.formData)},{deep:!0}),V=d=>{s.value=d},E=t.computed(()=>typeof h.value=="function"?h.value(n==null?void 0:n.formData):h.value),N=t.computed(()=>({...E.value,name:E.value.name??a.name,invalid:v.value,valid:a.showValid?!!(!v.value&&s.value):void 0,type:(d=>{if([c.text,c.number,c.email,c.password,c.tel,c.url,c.search,c.date,c.time,c.datetimeLocal,c.month,c.week,c.color].includes(d))return d})(a.type),invalidLabel:m.value,modelValue:s.value,"onUpdate:modelValue":V}));return t.provide(f,{name:t.readonly(b),errors:t.readonly(p)}),{component:t.computed(()=>{if(a.type===c.custom)return{render(){var d;return((d=r.default)==null?void 0:d.call(r,{modelValue:s.value,onUpdate:V,invalid:v.value,invalidLabel:m.value,formData:n==null?void 0:n.formData.value,formErrors:n==null?void 0:n.errors.value,errors:p.value}))??r.defalut}};if(!((i==null?void 0:i.lazyLoad)??a.lazyload)){let d;switch(a.type){case c.select:d=t.resolveComponent("VvSelect");break;case c.checkbox:d=t.resolveComponent("VvCheckbox");break;case c.radio:d=t.resolveComponent("VvRadio");break;case c.textarea:d=t.resolveComponent("VvTextarea");break;case c.radioGroup:d=t.resolveComponent("VvRadioGroup");break;case c.checkboxGroup:d=t.resolveComponent("VvCheckboxGroup");break;case c.combobox:d=t.resolveComponent("VvCombobox");break;default:d=t.resolveComponent("VvInputText")}if(typeof d!="string")return d;console.warn(`[form-vue warn]: ${d} not found, the component will be loaded asynchronously. To avoid this warning, please set "lazyLoad" option.`)}return t.defineAsyncComponent(async()=>{switch(i!=null&&i.sideEffects&&await Promise.resolve(i.sideEffects(a.type)),a.type){case c.textarea:return import("@volverjs/ui-vue/vv-textarea");case c.radio:return import("@volverjs/ui-vue/vv-radio");case c.radioGroup:return import("@volverjs/ui-vue/vv-radio-group");case c.checkbox:return import("@volverjs/ui-vue/vv-checkbox");case c.checkboxGroup:return import("@volverjs/ui-vue/vv-checkbox-group");case c.combobox:return import("@volverjs/ui-vue/vv-combobox")}return import("@volverjs/ui-vue/vv-input-text")})}),hasProps:N,invalid:v}},render(){return this.is?t.h(this.is,this.hasProps,this.$slots):this.type===c.custom?t.h(this.component,null,this.$slots):t.h(this.component,this.hasProps,this.$slots)}}),$=(e,o={})=>{const f=r=>{let u=r;for(;u instanceof x.ZodEffects;)u=u.innerType();return u},i=f(e);return{...(i instanceof x.ZodObject?i._def.unknownKeys==="passthrough":!1)?o:{},...Object.fromEntries(Object.entries(i.shape).map(([r,u])=>{const s=o[r],l=f(u);let n;if(l instanceof x.ZodDefault&&(n=l._def.defaultValue()),s===null&&l instanceof x.ZodNullable)return[r,s];if(l instanceof x.ZodSchema){const h=l.safeParse(o[r]);if(h.success)return[r,h.data??n]}return l instanceof x.ZodObject?[r,$(l,s&&typeof s=="object"?s:{})]:[r,n]}))}},P=(e,o,f)=>{const i=t.ref(),a=t.ref(),r=t.ref(),u=t.defineComponent({name:"FormComponent",props:{modelValue:{type:Object,default:()=>({})},updateThrottle:{type:Number,default:500},continuosValidation:{type:Boolean,default:!1}},emits:["invalid","valid","submit","update:modelValue"],expose:["submit","errors","status"],setup(s,{emit:l}){r.value=$(e,s.modelValue);const n=(f==null?void 0:f.continuosValidation)??s.continuosValidation;t.watch(()=>s.modelValue,m=>{if(m){const v=t.isProxy(m)?t.toRaw(m):m;r.value=typeof(v==null?void 0:v.clone)=="function"?v.clone():JSON.parse(JSON.stringify(v))}},{deep:!0}),M.watchThrottled(r,m=>{(i.value||n)&&h(),(!m||!s.modelValue||JSON.stringify(m)!==JSON.stringify(s.modelValue))&&l("update:modelValue",m)},{deep:!0,throttle:(f==null?void 0:f.updateThrottle)??s.updateThrottle});const h=(m=r.value)=>{const v=e.safeParse(m);return v.success?(i.value=void 0,a.value=O.valid,r.value=v.data,l("update:modelValue",r.value),l("valid",v.data),!0):(i.value=v.error.format(),a.value=O.invalid,l("invalid",i.value),!1)},b=()=>h()?(l("submit",r.value),!0):!1,p=t.computed(()=>a.value===O.invalid);return t.provide(o,{formData:r,submit:b,errors:t.readonly(i),status:t.readonly(a),invalid:p}),{formData:r,submit:b,errors:t.readonly(i),status:t.readonly(a),invalid:p}},render(){return t.h("form",{onSubmit:t.withModifiers(this.submit,["prevent"])},{default:()=>{var s,l;return((l=(s=this.$slots)==null?void 0:s.default)==null?void 0:l.call(s,{formData:this.formData,submit:this.submit,errors:this.errors,status:this.status,invalid:this.invalid}))??this.$slots.default}})}});return{errors:i,status:a,formData:r,VvForm:u}},T=(e,o)=>t.defineComponent({name:"WrapperComponent",props:{name:{type:String,required:!0},tag:{type:String,default:void 0}},emits:["invalid","valid"],expose:["fields","invalid"],setup(i,{emit:a}){const r=t.inject(e),u=t.inject(o,void 0),s=t.ref(new Set),l=t.ref(new Map),{name:n}=t.toRefs(i);t.provide(o,{name:t.readonly(n),errors:l,fields:s}),t.watch(s,b=>{u!=null&&u.fields&&b.forEach(p=>{u==null||u.fields.value.add(p)})},{deep:!0}),t.watch(()=>new Map(l.value),(b,p)=>{u!=null&&u.errors&&(Array.from(p.keys()).forEach(m=>{u.errors.value.delete(m)}),Array.from(b.keys()).forEach(m=>{const v=b.get(m);v&&u.errors.value.set(m,v)}))},{deep:!0});const h=t.computed(()=>r!=null&&r.invalid.value?l.value.size>0:!1);return t.watch(h,()=>{h.value?a("invalid"):a("valid")}),{formData:r==null?void 0:r.formData,errors:r==null?void 0:r.errors,invalid:h,fields:s,fieldsErrors:l}},render(){var i,a;return this.tag?t.h(this.tag,null,{default:()=>{var r,u;return((u=(r=this.$slots).default)==null?void 0:u.call(r,{invalid:this.invalid,formData:this.formData,errors:this.errors,fieldsErrors:this.fieldsErrors}))??this.$slots.defalut}}):((a=(i=this.$slots).default)==null?void 0:a.call(i,{invalid:this.invalid,formData:this.formData,errors:this.errors,fieldsErrors:this.fieldsErrors}))??this.$slots.defalut}}),D=(e,o)=>{const f=t.defineComponent({props:{schema:{type:[Array,Function],required:!0}},setup(i,{slots:a}){const r=t.inject(e);if(!(r!=null&&r.formData))return;const u=typeof i.schema=="function"?i.schema(r):i.schema;let s;return()=>{var l;return u.reduce((n,h)=>{const b=typeof h=="function"?h(r):h,{vvIs:p,vvName:m,vvSlots:v,vvChildren:w,vvIf:g,vvElseIf:V,vvType:E,vvDefaultValue:N,vvShowValid:q,...d}=b;if(g!==void 0){if(typeof g=="string"?s=!!C(Object(r.formData.value),g):typeof g=="function"?s=t.unref(g(r)):s=t.unref(g),!s)return n}else if(V!==void 0&&s!==void 0){if(s||(typeof V=="string"?s=!!C(Object(r.formData.value),V):typeof V=="function"?s=t.unref(V(r)):s=t.unref(V),!s))return n}else s=void 0;const G=w?t.h(f,{schema:w}):void 0;return m?(n.push(t.h(o,{name:m,is:p,type:E,defaultValue:N,showValid:q,props:d},v??G)),n):p?(n.push(t.h(p,d,v??G)),n):(w&&n.push(G),n)},[(l=a==null?void 0:a.default)==null?void 0:l.call(a,{formData:r==null?void 0:r.formData.value,submit:r==null?void 0:r.submit,errors:r==null?void 0:r.errors.value,status:r==null?void 0:r.status.value,invalid:r==null?void 0:r.invalid.value})])}}});return f},S=(e,o={})=>{const f=Symbol(),i=Symbol(),a=Symbol(),{VvForm:r,errors:u,status:s,formData:l}=P(e,f,o),n=T(f,i),h=J(f,i,a,o),b=D(f,h);return{VvForm:r,VvFormWrapper:n,VvFormField:h,VvFormTemplate:b,formInjectionKey:f,formWrapperInjectionKey:i,formFieldInjectionKey:a,errors:u,status:s,formData:l}},B=Symbol(),H=e=>{let o={};return e.schema&&(o=S(e.schema,e)),{...o,install(f,{global:i=!1}={}){f.provide(B,e),i&&(f.config.globalProperties.$vvForm=e,o!=null&&o.VvForm&&f.component("VvForm",o.VvForm),o!=null&&o.VvFormWrapper&&f.component("VvFormWrapper",o.VvFormWrapper),o!=null&&o.VvFormField&&f.component("VvFormField",o.VvFormField),o!=null&&o.VvFormTemplate&&f.component("VvFormTemplate",o.VvFormTemplate))}}},Q=(e,o={})=>t.getCurrentInstance()?S(e,{...t.inject(B,{}),...o}):S(e,o),R=(e,o={})=>S(e,o);y.FormFieldType=c,y.createForm=H,y.defaultObjectBySchema=$,y.formFactory=R,y.pluginInjectionKey=B,y.useForm=Q,Object.defineProperty(y,Symbol.toStringTag,{value:"Module"})});
1
+ (function(p,r){typeof exports=="object"&&typeof module<"u"?r(exports,require("vue"),require("@vueuse/core"),require("zod")):typeof define=="function"&&define.amd?define(["exports","vue","@vueuse/core","zod"],r):(p=typeof globalThis<"u"?globalThis:p||self,r(p["@volverjs/form-vue"]={},p.Vue,p.VueUseCore,p.zod))})(this,function(p,r,Z,x){"use strict";function I(e){return Array.isArray(e)}function z(e){return typeof e<"u"}function G(e){return e===null}function W(e){return typeof e=="object"}function A(e){return typeof e=="string"}function k(e){return typeof e>"u"}const M=/^[0-9]+$/,U=["__proto__","prototype","constructor"];function C(e,s,f){const i=z(f)?f:void 0;if(!W(e)||!A(s))return i;const o=K(s);if(o.length!==0){for(const t of o){if(t==="*")continue;const l=function(a){return a.map(u=>k(u)||G(u)?u:I(u)?l(u):u[t])};if(I(e)&&!M.test(t)?e=l(e):e=e[t],k(e)||G(e))break}return k(e)?i:e}}function _(e,s,f){if(!W(e)||!A(s))return;const i=K(s);if(i.length===0)return;const o=i.length;for(let t=0;t<o;t++){const l=i[t];if(t===o-1){e[l]=f;return}if(l==="*"&&I(e)){const a=i.slice(t+1).join(".");for(const u of e)_(u,a,f);return}k(e[l])&&(e[l]={}),e=e[l]}}function K(e){const s=e.split(/[.]|(?:\[(\d|\*)\])/).filter(f=>!!f);return s.some(f=>U.indexOf(f)!==-1)?[]:s}var d=(e=>(e.text="text",e.number="number",e.email="email",e.password="password",e.tel="tel",e.url="url",e.search="search",e.date="date",e.time="time",e.datetimeLocal="datetimeLocal",e.month="month",e.week="week",e.color="color",e.select="select",e.checkbox="checkbox",e.radio="radio",e.textarea="textarea",e.radioGroup="radioGroup",e.checkboxGroup="checkboxGroup",e.combobox="combobox",e.custom="custom",e))(d||{}),O=(e=>(e.invalid="invalid",e.valid="valid",e))(O||{});const J=(e,s,f,i)=>r.defineComponent({name:"FieldComponent",props:{type:{type:String,validator:o=>Object.values(d).includes(o),default:d.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}},emits:["invalid","valid","update:formData","update:modelValue"],expose:["invalid","invalidLabel","errors"],setup(o,{slots:t,emit:l}){const a=r.computed({get(){if(n!=null&&n.formData)return C(Object(n.formData.value),String(o.name))},set(c){n!=null&&n.formData&&(_(Object(n.formData.value),String(o.name),c),l("update:modelValue",{newValue:a.value,formData:n==null?void 0:n.formData}))}});r.onMounted(()=>{a.value===void 0&&o.defaultValue!==void 0&&(a.value=o.defaultValue)}),r.onBeforeUnmount(()=>{w(),g()});const u=r.inject(s,void 0);u&&u.fields.value.add(o.name);const n=r.inject(e),{props:h,name:y}=r.toRefs(o),m=r.computed(()=>{if(n!=null&&n.errors.value)return C(n.errors.value,String(o.name))}),v=r.computed(()=>{var c;return(c=m.value)==null?void 0:c._errors}),b=r.computed(()=>m.value!==void 0),w=r.watch(b,()=>{b.value?(l("invalid",v.value),u&&u.errors.value.set(o.name,{_errors:v.value})):(l("valid",a.value),u&&u.errors.value.delete(o.name))}),g=r.watch(()=>n==null?void 0:n.formData,()=>{l("update:formData",n==null?void 0:n.formData)},{deep:!0}),V=c=>{a.value=c},E=r.computed(()=>typeof h.value=="function"?h.value(n==null?void 0:n.formData):h.value),L=r.computed(()=>({...E.value,name:E.value.name??o.name,invalid:b.value,valid:o.showValid?!!(!b.value&&a.value):void 0,type:(c=>{if([d.text,d.number,d.email,d.password,d.tel,d.url,d.search,d.date,d.time,d.datetimeLocal,d.month,d.week,d.color].includes(c))return c})(o.type),invalidLabel:v.value,modelValue:a.value,"onUpdate:modelValue":V}));return r.provide(f,{name:r.readonly(y),errors:r.readonly(m)}),{component:r.computed(()=>{if(o.type===d.custom)return{render(){var c;return((c=t.default)==null?void 0:c.call(t,{modelValue:a.value,onUpdate:V,submit:n==null?void 0:n.submit,validate:n==null?void 0:n.validate,invalid:b.value,invalidLabel:v.value,formData:n==null?void 0:n.formData.value,formErrors:n==null?void 0:n.errors.value,errors:m.value}))??t.defalut}};if(!((i==null?void 0:i.lazyLoad)??o.lazyLoad)){let c;switch(o.type){case d.select:c=r.resolveComponent("VvSelect");break;case d.checkbox:c=r.resolveComponent("VvCheckbox");break;case d.radio:c=r.resolveComponent("VvRadio");break;case d.textarea:c=r.resolveComponent("VvTextarea");break;case d.radioGroup:c=r.resolveComponent("VvRadioGroup");break;case d.checkboxGroup:c=r.resolveComponent("VvCheckboxGroup");break;case d.combobox:c=r.resolveComponent("VvCombobox");break;default:c=r.resolveComponent("VvInputText")}if(typeof c!="string")return c;console.warn(`[form-vue warn]: ${c} not found, the component will be loaded asynchronously. To avoid this warning, please set "lazyLoad" option.`)}return r.defineAsyncComponent(async()=>{switch(i!=null&&i.sideEffects&&await Promise.resolve(i.sideEffects(o.type)),o.type){case d.textarea:return import("@volverjs/ui-vue/vv-textarea");case d.radio:return import("@volverjs/ui-vue/vv-radio");case d.radioGroup:return import("@volverjs/ui-vue/vv-radio-group");case d.checkbox:return import("@volverjs/ui-vue/vv-checkbox");case d.checkboxGroup:return import("@volverjs/ui-vue/vv-checkbox-group");case d.combobox:return import("@volverjs/ui-vue/vv-combobox")}return import("@volverjs/ui-vue/vv-input-text")})}),hasProps:L,invalid:b}},render(){return this.is?r.h(this.is,this.hasProps,this.$slots):this.type===d.custom?r.h(this.component,null,this.$slots):r.h(this.component,this.hasProps,this.$slots)}}),$=(e,s={})=>{const f=t=>{let l=t;for(;l instanceof x.ZodEffects;)l=l.innerType();return l},i=f(e);return{...(i instanceof x.ZodObject?i._def.unknownKeys==="passthrough":!1)?s:{},...Object.fromEntries(Object.entries(i.shape).map(([t,l])=>{const a=s[t],u=f(l);let n;if(u instanceof x.ZodDefault&&(n=u._def.defaultValue()),a===null&&u instanceof x.ZodNullable)return[t,a];if(u instanceof x.ZodSchema){const h=l.safeParse(a);if(h.success)return[t,h.data??n]}return u instanceof x.ZodObject?[t,$(u,a&&typeof a=="object"?a:{})]:[t,n]}))}},P=(e,s,f)=>{const i=r.ref(),o=r.ref(),t=r.ref(),l=r.defineComponent({name:"FormComponent",props:{modelValue:{type:Object,default:()=>({})},updateThrottle:{type:Number,default:500},continuosValidation:{type:Boolean,default:!1}},emits:["invalid","valid","submit","update:modelValue"],expose:["submit","validate","errors","status","valid","invalid"],setup(a,{emit:u}){t.value=$(e,r.toRaw(a.modelValue)),r.watch(()=>a.modelValue,m=>{if(m){const v=r.isProxy(m)?r.toRaw(m):m;t.value=typeof(v==null?void 0:v.clone)=="function"?v.clone():JSON.parse(JSON.stringify(v))}},{deep:!0}),Z.watchThrottled(t,m=>{((i.value||(f==null?void 0:f.continuosValidation))??a.continuosValidation)&&n(),(!m||!a.modelValue||JSON.stringify(m)!==JSON.stringify(a.modelValue))&&u("update:modelValue",m)},{deep:!0,throttle:(f==null?void 0:f.updateThrottle)??a.updateThrottle});const n=(m=t.value)=>{const v=e.safeParse(m);return v.success?(i.value=void 0,o.value=O.valid,t.value=v.data,u("update:modelValue",t.value),u("valid",v.data),!0):(i.value=v.error.format(),o.value=O.invalid,u("invalid",i.value),!1)},h=()=>n()?(u("submit",t.value),!0):!1,y=r.computed(()=>o.value===O.invalid);return r.provide(s,{formData:t,submit:h,validate:n,errors:r.readonly(i),status:r.readonly(o),invalid:y}),{formData:t,submit:h,validate:n,errors:r.readonly(i),status:r.readonly(o),invalid:y}},render(){return r.h("form",{onSubmit:r.withModifiers(this.submit,["prevent"])},{default:()=>{var a,u;return((u=(a=this.$slots)==null?void 0:a.default)==null?void 0:u.call(a,{formData:this.formData,submit:this.submit,validate:this.validate,errors:this.errors,status:this.status,invalid:this.invalid}))??this.$slots.default}})}});return{errors:i,status:o,formData:t,VvForm:l}},T=(e,s)=>r.defineComponent({name:"WrapperComponent",props:{name:{type:String,required:!0},tag:{type:String,default:void 0}},emits:["invalid","valid"],expose:["fields","invalid"],setup(i,{emit:o}){const t=r.inject(e),l=r.inject(s,void 0),a=r.ref(new Set),u=r.ref(new Map),{name:n}=r.toRefs(i);r.provide(s,{name:r.readonly(n),errors:u,fields:a}),r.watch(a,y=>{l!=null&&l.fields&&y.forEach(m=>{l==null||l.fields.value.add(m)})},{deep:!0}),r.watch(()=>new Map(u.value),(y,m)=>{l!=null&&l.errors&&(Array.from(m.keys()).forEach(v=>{l.errors.value.delete(v)}),Array.from(y.keys()).forEach(v=>{const b=y.get(v);b&&l.errors.value.set(v,b)}))},{deep:!0});const h=r.computed(()=>t!=null&&t.invalid.value?u.value.size>0:!1);return r.watch(h,()=>{h.value?o("invalid"):o("valid")}),{formData:t==null?void 0:t.formData,errors:t==null?void 0:t.errors,submit:t==null?void 0:t.submit,validate:t==null?void 0:t.validate,invalid:h,fields:a,fieldsErrors:u}},render(){var i,o;return this.tag?r.h(this.tag,null,{default:()=>{var t,l;return((l=(t=this.$slots).default)==null?void 0:l.call(t,{invalid:this.invalid,formData:this.formData,submit:this.submit,validate:this.validate,errors:this.errors,fieldsErrors:this.fieldsErrors}))??this.$slots.defalut}}):((o=(i=this.$slots).default)==null?void 0:o.call(i,{invalid:this.invalid,formData:this.formData,submit:this.submit,validate:this.validate,errors:this.errors,fieldsErrors:this.fieldsErrors}))??this.$slots.defalut}}),R=(e,s)=>{const f=r.defineComponent({props:{schema:{type:[Array,Function],required:!0}},setup(i,{slots:o}){const t=r.inject(e);if(!(t!=null&&t.formData))return;const l=typeof i.schema=="function"?i.schema(t):i.schema;let a;return()=>{var u;return l.reduce((n,h)=>{const y=typeof h=="function"?h(t):h,{vvIs:m,vvName:v,vvSlots:b,vvChildren:w,vvIf:g,vvElseIf:V,vvType:E,vvDefaultValue:L,vvShowValid:q,...c}=y;if(g!==void 0){if(typeof g=="string"?a=!!C(Object(t.formData.value),g):typeof g=="function"?a=r.unref(g(t)):a=r.unref(g),!a)return n}else if(V!==void 0&&a!==void 0){if(a||(typeof V=="string"?a=!!C(Object(t.formData.value),V):typeof V=="function"?a=r.unref(V(t)):a=r.unref(V),!a))return n}else a=void 0;const N=w?r.h(f,{schema:w}):void 0;return v?(n.push(r.h(s,{name:v,is:m,type:E,defaultValue:L,showValid:q,props:c},b??N)),n):m?(n.push(r.h(m,c,b??N)),n):(w&&n.push(N),n)},[(u=o==null?void 0:o.default)==null?void 0:u.call(o,{formData:t==null?void 0:t.formData.value,submit:t==null?void 0:t.submit,validate:t==null?void 0:t.validate,errors:t==null?void 0:t.errors.value,status:t==null?void 0:t.status.value,invalid:t==null?void 0:t.invalid.value})])}}});return f},S=(e,s={})=>{const f=Symbol(),i=Symbol(),o=Symbol(),{VvForm:t,errors:l,status:a,formData:u}=P(e,f,s),n=T(f,i),h=J(f,i,o,s),y=R(f,h);return{VvForm:t,VvFormWrapper:n,VvFormField:h,VvFormTemplate:y,formInjectionKey:f,formWrapperInjectionKey:i,formFieldInjectionKey:o,errors:l,status:a,formData:u}},B=Symbol(),H=e=>{let s={};return e.schema&&(s=S(e.schema,e)),{...s,install(f,{global:i=!1}={}){f.provide(B,e),i&&(f.config.globalProperties.$vvForm=e,s!=null&&s.VvForm&&f.component("VvForm",s.VvForm),s!=null&&s.VvFormWrapper&&f.component("VvFormWrapper",s.VvFormWrapper),s!=null&&s.VvFormField&&f.component("VvFormField",s.VvFormField),s!=null&&s.VvFormTemplate&&f.component("VvFormTemplate",s.VvFormTemplate))}}},Q=(e,s={})=>r.getCurrentInstance()?S(e,{...r.inject(B,{}),...s}):S(e,s),X=(e,s={})=>S(e,s);p.FormFieldType=d,p.createForm=H,p.defaultObjectBySchema=$,p.formFactory=X,p.pluginInjectionKey=B,p.useForm=Q,Object.defineProperty(p,Symbol.toStringTag,{value:"Module"})});
package/dist/types.d.ts CHANGED
@@ -28,6 +28,7 @@ export type InjectedFormData<Schema extends FormSchema> = {
28
28
  formData: Ref<Partial<z.infer<Schema>> | undefined>
29
29
  errors: Readonly<Ref<DeepReadonly<z.inferFormattedError<Schema>>>>
30
30
  submit: () => boolean
31
+ validate: () => boolean
31
32
  status: Readonly<Ref<FormStatus | undefined>>
32
33
  invalid: Readonly<Ref<boolean>>
33
34
  }
package/package.json CHANGED
@@ -19,7 +19,7 @@
19
19
  "bugs": {
20
20
  "url": "https://github.com/volverjs/form-vue/issues"
21
21
  },
22
- "version": "0.0.10-beta.8",
22
+ "version": "0.0.10",
23
23
  "engines": {
24
24
  "node": ">= 16.x"
25
25
  },
package/src/VvForm.ts CHANGED
@@ -48,13 +48,14 @@ export const defineForm = <Schema extends FormSchema>(
48
48
  },
49
49
  },
50
50
  emits: ['invalid', 'valid', 'submit', 'update:modelValue'],
51
- expose: ['submit', 'errors', 'status'],
51
+ expose: ['submit', 'validate', 'errors', 'status', 'valid', 'invalid'],
52
52
  setup(props, { emit }) {
53
- formData.value = defaultObjectBySchema(schema, props.modelValue)
54
-
55
- const keepValidation =
56
- options?.continuosValidation ?? props.continuosValidation
53
+ formData.value = defaultObjectBySchema(
54
+ schema,
55
+ toRaw(props.modelValue),
56
+ )
57
57
 
58
+ // clone modelValue and update formData
58
59
  watch(
59
60
  () => props.modelValue,
60
61
  (newValue) => {
@@ -70,12 +71,16 @@ export const defineForm = <Schema extends FormSchema>(
70
71
  },
71
72
  { deep: true },
72
73
  )
73
- // v-model
74
+
75
+ // emit update:modelValue on formData change
74
76
  watchThrottled(
75
77
  formData,
76
78
  (newValue) => {
77
- if (errors.value || keepValidation) {
78
- parseModelValue()
79
+ if (
80
+ (errors.value || options?.continuosValidation) ??
81
+ props.continuosValidation
82
+ ) {
83
+ validate()
79
84
  }
80
85
  if (
81
86
  !newValue ||
@@ -92,7 +97,8 @@ export const defineForm = <Schema extends FormSchema>(
92
97
  },
93
98
  )
94
99
 
95
- const parseModelValue = (value = formData.value) => {
100
+ // validate formData with safeParse
101
+ const validate = (value = formData.value) => {
96
102
  const parseResult = schema.safeParse(value)
97
103
  if (!parseResult.success) {
98
104
  errors.value =
@@ -111,9 +117,9 @@ export const defineForm = <Schema extends FormSchema>(
111
117
  return true
112
118
  }
113
119
 
114
- // submit
120
+ // emit submit event if form is valid
115
121
  const submit = () => {
116
- if (!parseModelValue()) {
122
+ if (!validate()) {
117
123
  return false
118
124
  }
119
125
  emit('submit', formData.value)
@@ -122,10 +128,11 @@ export const defineForm = <Schema extends FormSchema>(
122
128
 
123
129
  const invalid = computed(() => status.value === FormStatus.invalid)
124
130
 
125
- // provide
131
+ // provide data to children
126
132
  provide(provideKey, {
127
133
  formData,
128
134
  submit,
135
+ validate,
129
136
  errors: readonly(errors),
130
137
  status: readonly(status),
131
138
  invalid,
@@ -134,6 +141,7 @@ export const defineForm = <Schema extends FormSchema>(
134
141
  return {
135
142
  formData,
136
143
  submit,
144
+ validate,
137
145
  errors: readonly(errors),
138
146
  status: readonly(status),
139
147
  invalid,
@@ -150,6 +158,7 @@ export const defineForm = <Schema extends FormSchema>(
150
158
  this.$slots?.default?.({
151
159
  formData: this.formData,
152
160
  submit: this.submit,
161
+ validate: this.validate,
153
162
  errors: this.errors,
154
163
  status: this.status,
155
164
  invalid: this.invalid,
@@ -175,6 +184,7 @@ export const defineForm = <Schema extends FormSchema>(
175
184
  ? undefined
176
185
  : Partial<TypeOf<Schema>> | undefined
177
186
  submit: () => boolean
187
+ validate: () => boolean
178
188
  errors: Readonly<
179
189
  Ref<DeepReadonly<z.inferFormattedError<Schema>>>
180
190
  >
@@ -76,7 +76,7 @@ export const defineFormField = <Schema extends FormSchema>(
76
76
  type: [String, Number, Boolean, Array, Object],
77
77
  default: undefined,
78
78
  },
79
- lazyload: {
79
+ lazyLoad: {
80
80
  type: Boolean,
81
81
  default: false,
82
82
  },
@@ -225,6 +225,8 @@ export const defineFormField = <Schema extends FormSchema>(
225
225
  slots.default?.({
226
226
  modelValue: modelValue.value,
227
227
  onUpdate,
228
+ submit: injectedFormData?.submit,
229
+ validate: injectedFormData?.validate,
228
230
  invalid: invalid.value,
229
231
  invalidLabel: invalidLabel.value,
230
232
  formData: injectedFormData?.formData.value,
@@ -235,7 +237,7 @@ export const defineFormField = <Schema extends FormSchema>(
235
237
  },
236
238
  }
237
239
  }
238
- if (!(options?.lazyLoad ?? props.lazyload)) {
240
+ if (!(options?.lazyLoad ?? props.lazyLoad)) {
239
241
  let component: string | ConcreteComponent
240
242
  switch (props.type) {
241
243
  case FormFieldType.select:
@@ -144,6 +144,7 @@ export const defineFormTemplate = <Schema extends FormSchema>(
144
144
  templateSlots?.default?.({
145
145
  formData: injectedFormData?.formData.value,
146
146
  submit: injectedFormData?.submit,
147
+ validate: injectedFormData?.validate,
147
148
  errors: injectedFormData?.errors.value,
148
149
  status: injectedFormData?.status.value,
149
150
  invalid: injectedFormData?.invalid.value,
@@ -166,6 +167,7 @@ export const defineFormTemplate = <Schema extends FormSchema>(
166
167
  ? undefined
167
168
  : Partial<TypeOf<Schema>> | undefined
168
169
  submit: () => boolean
170
+ validate: () => boolean
169
171
  errors: Readonly<
170
172
  Ref<DeepReadonly<z.inferFormattedError<Schema>>>
171
173
  >
@@ -103,6 +103,8 @@ export const defineFormWrapper = <Schema extends FormSchema>(
103
103
  return {
104
104
  formData: injectedFormData?.formData,
105
105
  errors: injectedFormData?.errors,
106
+ submit: injectedFormData?.submit,
107
+ validate: injectedFormData?.validate,
106
108
  invalid,
107
109
  fields,
108
110
  fieldsErrors,
@@ -115,6 +117,8 @@ export const defineFormWrapper = <Schema extends FormSchema>(
115
117
  this.$slots.default?.({
116
118
  invalid: this.invalid,
117
119
  formData: this.formData,
120
+ submit: this.submit,
121
+ validate: this.validate,
118
122
  errors: this.errors,
119
123
  fieldsErrors: this.fieldsErrors,
120
124
  }) ?? this.$slots.defalut,
@@ -124,6 +128,8 @@ export const defineFormWrapper = <Schema extends FormSchema>(
124
128
  this.$slots.default?.({
125
129
  invalid: this.invalid,
126
130
  formData: this.formData,
131
+ submit: this.submit,
132
+ validate: this.validate,
127
133
  errors: this.errors,
128
134
  fieldsErrors: this.fieldsErrors,
129
135
  }) ?? this.$slots.defalut
@@ -143,6 +149,8 @@ export const defineFormWrapper = <Schema extends FormSchema>(
143
149
  | undefined
144
150
  ? undefined
145
151
  : Partial<TypeOf<Schema>> | undefined
152
+ submit: () => boolean
153
+ validate: () => boolean
146
154
  errors: Readonly<
147
155
  Ref<DeepReadonly<z.inferFormattedError<Schema>>>
148
156
  >
package/src/types.d.ts CHANGED
@@ -28,6 +28,7 @@ export type InjectedFormData<Schema extends FormSchema> = {
28
28
  formData: Ref<Partial<z.infer<Schema>> | undefined>
29
29
  errors: Readonly<Ref<DeepReadonly<z.inferFormattedError<Schema>>>>
30
30
  submit: () => boolean
31
+ validate: () => boolean
31
32
  status: Readonly<Ref<FormStatus | undefined>>
32
33
  invalid: Readonly<Ref<boolean>>
33
34
  }
package/src/utils.ts CHANGED
@@ -31,38 +31,41 @@ export const defaultObjectBySchema = <Schema extends FormSchema>(
31
31
  return {
32
32
  ...(unknownKeys ? original : {}),
33
33
  ...Object.fromEntries(
34
- Object.entries(innerType.shape).map(([key, subSchema]) => {
35
- const originalValue = original[key]
36
- const innerType = getInnerType(subSchema as ZodTypeAny)
37
- let defaultValue = undefined
38
- if (innerType instanceof ZodDefault) {
39
- defaultValue = innerType._def.defaultValue()
40
- }
41
- if (
42
- originalValue === null &&
43
- innerType instanceof ZodNullable
44
- ) {
45
- return [key, originalValue]
46
- }
47
- if (innerType instanceof ZodSchema) {
48
- const parse = innerType.safeParse(original[key])
49
- if (parse.success) {
50
- return [key, parse.data ?? defaultValue]
34
+ (Object.entries(innerType.shape) as [string, ZodTypeAny][]).map(
35
+ ([key, subSchema]) => {
36
+ const originalValue = original[key]
37
+ const innerType = getInnerType(subSchema)
38
+ let defaultValue = undefined
39
+ if (innerType instanceof ZodDefault) {
40
+ defaultValue = innerType._def.defaultValue()
51
41
  }
52
- }
53
- if (innerType instanceof ZodObject) {
54
- return [
55
- key,
56
- defaultObjectBySchema(
57
- innerType,
58
- originalValue && typeof originalValue === 'object'
59
- ? originalValue
60
- : {},
61
- ),
62
- ]
63
- }
64
- return [key, defaultValue]
65
- }),
42
+ if (
43
+ originalValue === null &&
44
+ innerType instanceof ZodNullable
45
+ ) {
46
+ return [key, originalValue]
47
+ }
48
+ if (innerType instanceof ZodSchema) {
49
+ const parse = subSchema.safeParse(originalValue)
50
+ if (parse.success) {
51
+ return [key, parse.data ?? defaultValue]
52
+ }
53
+ }
54
+ if (innerType instanceof ZodObject) {
55
+ return [
56
+ key,
57
+ defaultObjectBySchema(
58
+ innerType,
59
+ originalValue &&
60
+ typeof originalValue === 'object'
61
+ ? originalValue
62
+ : {},
63
+ ),
64
+ ]
65
+ }
66
+ return [key, defaultValue]
67
+ },
68
+ ),
66
69
  ),
67
70
  } as Partial<z.infer<Schema>>
68
71
  }