@volverjs/form-vue 0.0.14-beta.1 → 0.0.14-beta.3
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/VvForm.d.ts +25 -15
- package/dist/VvFormField.d.ts +4 -4
- package/dist/VvFormTemplate.d.ts +115 -5
- package/dist/VvFormWrapper.d.ts +7 -13
- package/dist/index.d.ts +1008 -104
- package/dist/index.es.js +326 -310
- package/dist/index.umd.js +1 -1
- package/dist/types.d.ts +62 -128
- package/package.json +19 -18
- package/src/VvForm.ts +32 -14
- package/src/VvFormField.ts +1 -1
- package/src/VvFormTemplate.ts +14 -17
- package/src/VvFormWrapper.ts +1 -1
- package/src/index.ts +20 -13
- package/src/{types.d.ts → types.ts} +37 -14
- package/src/utils.ts +1 -1
package/dist/index.umd.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
(function(y,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):(y=typeof globalThis<"u"?globalThis:y||self,r(y["@volverjs/form-vue"]={},y.Vue,y.VueUseCore,y.zod))})(this,function(y,r,M,V){"use strict";function _(e){return Array.isArray(e)}function T(e){return typeof e<"u"}function N(e){return e===null}function G(e){return typeof e=="object"}function L(e){return typeof e=="string"}function C(e){return typeof e>"u"}const U=/^[0-9]+$/,J=["__proto__","prototype","constructor"];function k(e,s,f){const u=T(f)?f:void 0;if(!G(e)||!L(s))return u;const o=Z(s);if(o.length!==0){for(const t of o){if(t==="*")continue;const i=function(a){return a.map(l=>C(l)||N(l)?l:_(l)?i(l):l[t])};if(_(e)&&!U.test(t)?e=i(e):e=e[t],C(e)||N(e))break}return C(e)?u:e}}function W(e,s,f){if(!G(e)||!L(s))return;const u=Z(s);if(u.length===0)return;const o=u.length;for(let t=0;t<o;t++){const i=u[t];if(t===o-1){e[i]=f;return}if(i==="*"&&_(e)){const a=u.slice(t+1).join(".");for(const l of e)W(l,a,f);return}C(e[i])&&(e[i]={}),e=e[i]}}function Z(e){const s=e.split(/[.]|(?:\[(\d|\*)\])/).filter(f=>!!f);return s.some(f=>J.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="datetime-local",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||{}),S=(e=>(e.invalid="invalid",e.valid="valid",e))(S||{});const P=(e,s,f,u)=>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:i}){const a=r.computed({get(){if(n!=null&&n.formData)return k(Object(n.formData.value),String(o.name))},set(c){n!=null&&n.formData&&(W(Object(n.formData.value),String(o.name),c),i("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(()=>{O(),x()});const l=r.inject(s,void 0);l&&l.fields.value.add(o.name);const n=r.inject(e),{props:h,name:p}=r.toRefs(o),m=r.computed(()=>{if(n!=null&&n.errors.value)return k(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),O=r.watch(b,()=>{b.value?(i("invalid",v.value),l&&l.errors.value.set(o.name,{_errors:v.value})):(i("valid",a.value),l&&l.errors.value.delete(o.name))}),x=r.watch(()=>n==null?void 0:n.formData,()=>{i("update:formData",n==null?void 0:n.formData)},{deep:!0}),g=c=>{a.value=c},A=r.computed(()=>{let c=h.value;return typeof c=="function"&&(c=c(n==null?void 0:n.formData)),Object.keys(c).reduce((w,q)=>(w[q]=r.unref(c[q]),w),{})}),B=r.computed(()=>({...A.value,name:A.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":g}));return r.provide(f,{name:r.readonly(p),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:g,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(!((u==null?void 0:u.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(u!=null&&u.sideEffects&&await Promise.resolve(u.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.select:return import("@volverjs/ui-vue/vv-select");case d.combobox:return import("@volverjs/ui-vue/vv-combobox")}return import("@volverjs/ui-vue/vv-input-text")})}),hasProps:B,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=(e,s={})=>{const f=t=>{let i=t;for(;i instanceof V.ZodEffects;)i=i.innerType();return i instanceof V.ZodOptional&&(i=i._def.innerType),i},u=f(e);return{...(u instanceof V.ZodObject?u._def.unknownKeys==="passthrough":!1)?s:{},...Object.fromEntries(Object.entries(u.shape).map(([t,i])=>{const a=s[t];let l=f(i),n;if(l instanceof V.ZodDefault&&(n=l._def.defaultValue(),l=l._def.innerType),a===null&&l instanceof V.ZodNullable)return[t,a];if(l instanceof V.ZodSchema){const h=i.safeParse(a);if(h.success)return[t,h.data??n]}if(l instanceof V.ZodArray&&Array.isArray(a)&&a.length){const h=l._def.type;if(h instanceof V.ZodObject)return[t,a.map(p=>E(h,p&&typeof p=="object"?p:void 0))??n]}return l instanceof V.ZodObject?[t,E(l,a&&typeof a=="object"?a:n)]:[t,n]}))}},z=(e,s,f)=>{const u=r.ref(),o=r.ref(),t=r.ref(),i=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:l}){t.value=E(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}),M.watchThrottled(t,m=>{((u.value||(f==null?void 0:f.continuosValidation))??a.continuosValidation)&&n(),(!m||!a.modelValue||JSON.stringify(m)!==JSON.stringify(a.modelValue))&&l("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?(u.value=void 0,o.value=S.valid,t.value=v.data,l("update:modelValue",t.value),l("valid",v.data),!0):(u.value=v.error.format(),o.value=S.invalid,l("invalid",u.value),!1)},h=()=>n()?(l("submit",t.value),!0):!1,p=r.computed(()=>o.value===S.invalid);return r.provide(s,{formData:t,submit:h,validate:n,errors:r.readonly(u),status:r.readonly(o),invalid:p}),{formData:t,submit:h,validate:n,errors:r.readonly(u),status:r.readonly(o),invalid:p}},render(){return r.h("form",{onSubmit:r.withModifiers(this.submit,["prevent"])},{default:()=>{var a,l;return((l=(a=this.$slots)==null?void 0:a.default)==null?void 0:l.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:u,status:o,formData:t,VvForm:i}},R=(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(u,{emit:o}){const t=r.inject(e),i=r.inject(s,void 0),a=r.ref(new Set),l=r.ref(new Map),{name:n}=r.toRefs(u);r.provide(s,{name:r.readonly(n),errors:l,fields:a}),r.watch(a,p=>{i!=null&&i.fields&&p.forEach(m=>{i==null||i.fields.value.add(m)})},{deep:!0}),r.watch(()=>new Map(l.value),(p,m)=>{i!=null&&i.errors&&(Array.from(m.keys()).forEach(v=>{i.errors.value.delete(v)}),Array.from(p.keys()).forEach(v=>{const b=p.get(v);b&&i.errors.value.set(v,b)}))},{deep:!0});const h=r.computed(()=>t!=null&&t.invalid.value?l.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:l}},render(){var u,o;return this.tag?r.h(this.tag,null,{default:()=>{var t,i;return((i=(t=this.$slots).default)==null?void 0:i.call(t,{invalid:this.invalid,formData:this.formData,submit:this.submit,validate:this.validate,errors:this.errors,fieldsErrors:this.fieldsErrors}))??this.$slots.defalut}}):((o=(u=this.$slots).default)==null?void 0:o.call(u,{invalid:this.invalid,formData:this.formData,submit:this.submit,validate:this.validate,errors:this.errors,fieldsErrors:this.fieldsErrors}))??this.$slots.defalut}}),H=(e,s)=>{const f=r.defineComponent({props:{schema:{type:[Array,Function],required:!0}},setup(u,{slots:o}){const t=r.inject(e);if(!(t!=null&&t.formData))return;const i=typeof u.schema=="function"?u.schema(t):u.schema;let a;return()=>{var l;return i.reduce((n,h)=>{const p=typeof h=="function"?h(t):h,{vvIs:m,vvName:v,vvSlots:b,vvChildren:O,vvIf:x,vvElseIf:g,vvType:A,vvDefaultValue:B,vvShowValid:K,...c}=p;if(x!==void 0){if(typeof x=="string"?a=!!k(Object(t.formData.value),x):typeof x=="function"?a=r.unref(x(t)):a=r.unref(x),!a)return n}else if(g!==void 0&&a!==void 0){if(a||(typeof g=="string"?a=!!k(Object(t.formData.value),g):typeof g=="function"?a=r.unref(g(t)):a=r.unref(g),!a))return n}else a=void 0;const w=O?r.h(f,{schema:O}):void 0;return v?(n.push(r.h(s,{name:v,is:m,type:A,defaultValue:B,showValid:K,props:c},b??w)),n):m?(n.push(r.h(m,c,b??w)),n):(O&&n.push(w),n)},[(l=o==null?void 0:o.default)==null?void 0:l.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},I=(e,s={})=>{const f=Symbol(),u=Symbol(),o=Symbol(),{VvForm:t,errors:i,status:a,formData:l}=z(e,f,s),n=R(f,u),h=P(f,u,o,s),p=H(f,h);return{VvForm:t,VvFormWrapper:n,VvFormField:h,VvFormTemplate:p,formInjectionKey:f,formWrapperInjectionKey:u,formFieldInjectionKey:o,errors:i,status:a,formData:l}},$=Symbol(),Q=e=>{let s={};return e.schema&&(s=I(e.schema,e)),{...s,install(f,{global:u=!1}={}){f.provide($,e),u&&(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))}}},X=(e,s={})=>r.getCurrentInstance()?I(e,{...r.inject($,{}),...s}):I(e,s),Y=(e,s={})=>I(e,s);y.FormFieldType=d,y.createForm=Q,y.defaultObjectBySchema=E,y.formFactory=Y,y.pluginInjectionKey=$,y.useForm=X,Object.defineProperty(y,Symbol.toStringTag,{value:"Module"})});
|
|
1
|
+
(function(V,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):(V=typeof globalThis<"u"?globalThis:V||self,r(V["@volverjs/form-vue"]={},V.Vue,V.VueUseCore,V.zod))})(this,function(V,r,U,w){"use strict";function $(e){return Array.isArray(e)}function q(e){return typeof e<"u"}function G(e){return e===null}function L(e){return typeof e=="object"}function W(e){return typeof e=="string"}function k(e){return typeof e>"u"}const M=/^[0-9]+$/,J=["__proto__","prototype","constructor"];function S(e,u,a){const f=q(a)?a:void 0;if(!L(e)||!W(u))return f;const s=K(u);if(s.length!==0){for(const t of s){if(t==="*")continue;const l=function(o){return o.map(i=>k(i)||G(i)?i:$(i)?l(i):i[t])};if($(e)&&!M.test(t)?e=l(e):e=e[t],k(e)||G(e))break}return k(e)?f:e}}function Z(e,u,a){if(!L(e)||!W(u))return;const f=K(u);if(f.length===0)return;const s=f.length;for(let t=0;t<s;t++){const l=f[t];if(t===s-1){e[l]=a;return}if(l==="*"&&$(e)){const o=f.slice(t+1).join(".");for(const i of e)Z(i,o,a);return}k(e[l])&&(e[l]={}),e=e[l]}}function K(e){const u=e.split(/[.]|(?:\[(\d|\*)\])/).filter(a=>!!a);return u.some(a=>J.indexOf(a)!==-1)?[]:u}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="datetime-local",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||{}),I=(e=>(e.invalid="invalid",e.valid="valid",e))(I||{});const P=(e,u,a,f)=>r.defineComponent({name:"FieldComponent",props:{type:{type:String,validator:s=>Object.values(d).includes(s),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(s,{slots:t,emit:l}){const o=r.computed({get(){if(n!=null&&n.formData)return S(Object(n.formData.value),String(s.name))},set(c){n!=null&&n.formData&&(Z(Object(n.formData.value),String(s.name),c),l("update:modelValue",{newValue:o.value,formData:n==null?void 0:n.formData}))}});r.onMounted(()=>{o.value===void 0&&s.defaultValue!==void 0&&(o.value=s.defaultValue)}),r.onBeforeUnmount(()=>{x(),p()});const i=r.inject(u,void 0);i&&i.fields.value.add(s.name);const n=r.inject(e),{props:h,name:y}=r.toRefs(s),b=r.computed(()=>{if(n!=null&&n.errors.value)return S(n.errors.value,String(s.name))}),m=r.computed(()=>{var c;return(c=b.value)==null?void 0:c._errors}),v=r.computed(()=>b.value!==void 0),x=r.watch(v,()=>{v.value?(l("invalid",m.value),i&&i.errors.value.set(s.name,{_errors:m.value})):(l("valid",o.value),i&&i.errors.value.delete(s.name))}),p=r.watch(()=>n==null?void 0:n.formData,()=>{l("update:formData",n==null?void 0:n.formData)},{deep:!0}),g=c=>{o.value=c},_=r.computed(()=>{let c=h.value;return typeof c=="function"&&(c=c(n==null?void 0:n.formData)),Object.keys(c).reduce((C,O)=>(C[O]=r.unref(c[O]),C),{})}),N=r.computed(()=>({..._.value,name:_.value.name??s.name,invalid:v.value,valid:s.showValid?!!(!v.value&&o.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})(s.type),invalidLabel:m.value,modelValue:o.value,"onUpdate:modelValue":g}));return r.provide(a,{name:r.readonly(y),errors:r.readonly(b)}),{component:r.computed(()=>{if(s.type===d.custom)return{render(){var c;return((c=t.default)==null?void 0:c.call(t,{modelValue:o.value,onUpdate:g,submit:n==null?void 0:n.submit,validate:n==null?void 0:n.validate,invalid:v.value,invalidLabel:m.value,formData:n==null?void 0:n.formData.value,formErrors:n==null?void 0:n.errors.value,errors:b.value}))??t.defalut}};if(!((f==null?void 0:f.lazyLoad)??s.lazyLoad)){let c;switch(s.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(f!=null&&f.sideEffects&&await Promise.resolve(f.sideEffects(s.type)),s.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.select:return import("@volverjs/ui-vue/vv-select");case d.combobox:return import("@volverjs/ui-vue/vv-combobox")}return import("@volverjs/ui-vue/vv-input-text")})}),hasProps:N,invalid:v}},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=(e,u={})=>{const a=t=>{let l=t;for(;l instanceof w.ZodEffects;)l=l.innerType();return l instanceof w.ZodOptional&&(l=l._def.innerType),l},f=a(e);return{...(f instanceof w.ZodObject?f._def.unknownKeys==="passthrough":!1)?u:{},...Object.fromEntries(Object.entries(f.shape).map(([t,l])=>{const o=u[t];let i=a(l),n;if(i instanceof w.ZodDefault&&(n=i._def.defaultValue(),i=i._def.innerType),o===null&&i instanceof w.ZodNullable)return[t,o];if(i instanceof w.ZodSchema){const h=l.safeParse(o);if(h.success)return[t,h.data??n]}if(i instanceof w.ZodArray&&Array.isArray(o)&&o.length){const h=a(i._def.type);if(h instanceof w.ZodObject)return[t,o.map(y=>E(h,y&&typeof y=="object"?y:void 0))??n]}return i instanceof w.ZodObject?[t,E(i,o&&typeof o=="object"?o:n)]:[t,n]}))}},T=(e,u,a,f)=>{const s=r.ref(),t=r.ref(),l=r.ref(),o=r.defineComponent({name:"FormComponent",props:{modelValue:{type:Object,default:()=>({})},updateThrottle:{type:Number,default:500},continuosValidation:{type:Boolean,default:!1},template:{type:[Array,Function]}},emits:["invalid","valid","submit","update:modelValue"],expose:["submit","validate","errors","status","valid","invalid"],setup(i,{emit:n}){l.value=E(e,r.toRaw(i.modelValue)),r.watch(()=>i.modelValue,m=>{if(m){const v=r.isProxy(m)?r.toRaw(m):m;l.value=typeof(v==null?void 0:v.clone)=="function"?v.clone():JSON.parse(JSON.stringify(v))}},{deep:!0}),U.watchThrottled(l,m=>{var v;((s.value||(a==null?void 0:a.continuosValidation))??i.continuosValidation)&&h(),(!m||!i.modelValue||JSON.stringify(m)!==JSON.stringify(i.modelValue))&&(n("update:modelValue",m),(v=a==null?void 0:a.onUpdate)==null||v.call(a,r.toRaw(m)))},{deep:!0,throttle:(a==null?void 0:a.updateThrottle)??i.updateThrottle});const h=(m=l.value)=>{var x,p,g;const v=e.safeParse(m);return v.success?(s.value=void 0,t.value=I.valid,l.value=v.data,n("update:modelValue",l.value),(p=a==null?void 0:a.onUpdate)==null||p.call(a,r.toRaw(l.value)),n("valid",v.data),(g=a==null?void 0:a.onValid)==null||g.call(a,r.toRaw(l.value)),!0):(s.value=v.error.format(),t.value=I.invalid,n("invalid",s.value),(x=a==null?void 0:a.onInvalid)==null||x.call(a,r.toRaw(s.value)),!1)},y=()=>{var m;return h()?(n("submit",l.value),(m=a==null?void 0:a.onSubmit)==null||m.call(a,r.toRaw(l.value)),!0):!1},b=r.computed(()=>t.value===I.invalid);return r.provide(u,{formData:l,submit:y,validate:h,errors:r.readonly(s),status:r.readonly(t),invalid:b}),{formData:l,submit:y,validate:h,errors:r.readonly(s),status:r.readonly(t),invalid:b}},render(){return r.h("form",{onSubmit:r.withModifiers(this.submit,["prevent"])},(this.template??(a==null?void 0:a.template))&&f?[r.h(f,{schema:this.template??(a==null?void 0:a.template)})]:{default:()=>{var i,n;return((n=(i=this.$slots)==null?void 0:i.default)==null?void 0:n.call(i,{formData:this.formData,submit:this.submit,validate:this.validate,errors:this.errors,status:this.status,invalid:this.invalid}))??this.$slots.default}})}});return{errors:s,status:t,formData:l,VvForm:o}},z=(e,u)=>r.defineComponent({name:"WrapperComponent",props:{name:{type:String,required:!0},tag:{type:String,default:void 0}},emits:["invalid","valid"],expose:["fields","invalid"],setup(f,{emit:s}){const t=r.inject(e),l=r.inject(u,void 0),o=r.ref(new Set),i=r.ref(new Map),{name:n}=r.toRefs(f);r.provide(u,{name:r.readonly(n),errors:i,fields:o}),r.watch(o,y=>{l!=null&&l.fields&&y.forEach(b=>{l==null||l.fields.value.add(b)})},{deep:!0}),r.watch(()=>new Map(i.value),(y,b)=>{l!=null&&l.errors&&(Array.from(b.keys()).forEach(m=>{l.errors.value.delete(m)}),Array.from(y.keys()).forEach(m=>{const v=y.get(m);v&&l.errors.value.set(m,v)}))},{deep:!0});const h=r.computed(()=>t!=null&&t.invalid.value?i.value.size>0:!1);return r.watch(h,()=>{h.value?s("invalid"):s("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:o,fieldsErrors:i}},render(){var f,s;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}}):((s=(f=this.$slots).default)==null?void 0:s.call(f,{invalid:this.invalid,formData:this.formData,submit:this.submit,validate:this.validate,errors:this.errors,fieldsErrors:this.fieldsErrors}))??this.$slots.defalut}}),H=(e,u)=>{const a=r.defineComponent({props:{schema:{type:[Array,Function],required:!0}},setup(f,{slots:s}){const t=r.inject(e);if(t!=null&&t.formData)return()=>{var i;const l=typeof f.schema=="function"?f.schema(t):f.schema;let o;return l.reduce((n,h)=>{const y=typeof h=="function"?h(t):h,{vvIs:b,vvName:m,vvSlots:v,vvChildren:x,vvIf:p,vvElseIf:g,vvType:_,vvDefaultValue:N,vvShowValid:R,vvContent:c,...C}=y;if(p!==void 0){if(typeof p=="string"?o=!!S(Object(t.formData.value),p):typeof p=="function"?o=r.unref(p(t)):o=r.unref(p),!o)return n}else if(g!==void 0&&o!==void 0){if(o||(typeof g=="string"?o=!!S(Object(t.formData.value),g):typeof g=="function"?o=r.unref(g(t)):o=r.unref(g),!o))return n}else o=void 0;const O=x?r.h(a,{schema:x}):void 0;return m?(n.push(r.h(u,{name:m,is:b,type:_,defaultValue:N,showValid:R,props:C},v??O??c)),n):b?(n.push(r.h(b,C,v??O??c)),n):(x&&n.push(O),n)},[(i=s==null?void 0:s.default)==null?void 0:i.call(s,{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 a},A=(e,u={})=>{const a=Symbol(),f=Symbol(),s=Symbol(),t=z(a,f),l=P(a,f,s,u),o=H(a,l),{VvForm:i,errors:n,status:h,formData:y}=T(e,a,u,o);return{VvForm:i,VvFormWrapper:t,VvFormField:l,VvFormTemplate:o,formInjectionKey:a,formWrapperInjectionKey:f,formFieldInjectionKey:s,errors:n,status:h,formData:y}},B=Symbol(),Q=e=>{let u={};return e.schema&&(u=A(e.schema,e)),{...u,install(a,{global:f=!1}={}){a.provide(B,e),f&&(a.config.globalProperties.$vvForm=e,u!=null&&u.VvForm&&a.component("VvForm",u.VvForm),u!=null&&u.VvFormWrapper&&a.component("VvFormWrapper",u.VvFormWrapper),u!=null&&u.VvFormField&&a.component("VvFormField",u.VvFormField),u!=null&&u.VvFormTemplate&&a.component("VvFormTemplate",u.VvFormTemplate))}}},X=(e,u={})=>r.getCurrentInstance()?A(e,{...r.inject(B,{}),...u}):A(e,u),Y=(e,u={})=>A(e,u);V.FormFieldType=d,V.createForm=Q,V.defaultObjectBySchema=E,V.formFactory=Y,V.pluginInjectionKey=B,V.useForm=X,Object.defineProperty(V,Symbol.toStringTag,{value:"Module"})});
|
package/dist/types.d.ts
CHANGED
|
@@ -1,132 +1,66 @@
|
|
|
1
|
-
import type
|
|
2
|
-
import type { z, AnyZodObject, ZodEffects } from 'zod'
|
|
3
|
-
import type { FormFieldType, FormStatus } from './enums'
|
|
4
|
-
|
|
5
|
-
export type FormSchema =
|
|
6
|
-
| AnyZodObject
|
|
7
|
-
| ZodEffects<AnyZodObject>
|
|
8
|
-
| ZodEffects<ZodEffects<AnyZodObject>>
|
|
9
|
-
|
|
1
|
+
import { type Component, type DeepReadonly, type Ref } from 'vue';
|
|
2
|
+
import type { z, AnyZodObject, ZodEffects, inferFormattedError } from 'zod';
|
|
3
|
+
import type { FormFieldType, FormStatus } from './enums';
|
|
4
|
+
export type FormSchema = AnyZodObject | ZodEffects<AnyZodObject> | ZodEffects<ZodEffects<AnyZodObject>>;
|
|
10
5
|
export type FormFieldComponentOptions = {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
export type
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
6
|
+
lazyLoad?: boolean;
|
|
7
|
+
sideEffects?: (type: `${FormFieldType}`) => Promise<void> | void;
|
|
8
|
+
};
|
|
9
|
+
export type FormComponentOptions<Schema> = {
|
|
10
|
+
updateThrottle?: number;
|
|
11
|
+
continuosValidation?: boolean;
|
|
12
|
+
template?: Schema extends FormSchema ? FormTemplate<Schema> : never;
|
|
13
|
+
onUpdate?: Schema extends FormSchema ? (data: Partial<z.infer<Schema> | undefined>) => void : never;
|
|
14
|
+
onSubmit?: Schema extends FormSchema ? (data: z.infer<Schema>) => void : never;
|
|
15
|
+
onInvalid?: Schema extends FormSchema ? (error: inferFormattedError<Schema, string>) => void : never;
|
|
16
|
+
onValid?: Schema extends FormSchema ? (data: z.infer<Schema>) => void : never;
|
|
17
|
+
};
|
|
18
|
+
export type FormComposableOptions<Schema> = FormFieldComponentOptions & FormComponentOptions<Schema>;
|
|
19
|
+
type FormPluginOptionsSchema = {
|
|
20
|
+
schema?: FormSchema;
|
|
21
|
+
};
|
|
22
|
+
export type FormPluginOptions = FormPluginOptionsSchema & FormComposableOptions<FormPluginOptionsSchema['schema']>;
|
|
27
23
|
export type InjectedFormData<Schema extends FormSchema> = {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
}
|
|
35
|
-
|
|
24
|
+
formData: Ref<Partial<z.infer<Schema>> | undefined>;
|
|
25
|
+
errors: Readonly<Ref<DeepReadonly<z.inferFormattedError<Schema>> | undefined>>;
|
|
26
|
+
submit: () => boolean;
|
|
27
|
+
validate: () => boolean;
|
|
28
|
+
status: Readonly<Ref<FormStatus | undefined>>;
|
|
29
|
+
invalid: Readonly<Ref<boolean>>;
|
|
30
|
+
};
|
|
36
31
|
export type InjectedFormWrapperData<Schema extends FormSchema> = {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
}
|
|
41
|
-
|
|
32
|
+
name: Ref<string>;
|
|
33
|
+
fields: Ref<Set<string>>;
|
|
34
|
+
errors: Ref<Map<string, z.inferFormattedError<Schema, string>>>;
|
|
35
|
+
};
|
|
42
36
|
export type InjectedFormFieldData<Schema extends FormSchema> = {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
type
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
export type
|
|
72
|
-
|
|
73
|
-
? {
|
|
74
|
-
[K in TupleKeys<T>]-?: PathConcat<K & string, T[K]>
|
|
75
|
-
}[TupleKeys<T>]
|
|
76
|
-
: PathConcat<ArrayKey, V>
|
|
77
|
-
: {
|
|
78
|
-
[K in keyof T]-?: PathConcat<K & string, T[K]>
|
|
79
|
-
}[keyof T]
|
|
80
|
-
|
|
81
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
82
|
-
export type PathValue<T, TPath extends Path<T> | ArrayPath<T>> = T extends any
|
|
83
|
-
? TPath extends `${infer K}.${infer R}`
|
|
84
|
-
? K extends keyof T
|
|
85
|
-
? R extends Path<T[K]>
|
|
86
|
-
? undefined extends T[K]
|
|
87
|
-
? PathValue<T[K], R> | undefined
|
|
88
|
-
: PathValue<T[K], R>
|
|
89
|
-
: never
|
|
90
|
-
: K extends `${ArrayKey}`
|
|
91
|
-
? T extends readonly (infer V)[]
|
|
92
|
-
? PathValue<V, R & Path<V>>
|
|
93
|
-
: never
|
|
94
|
-
: never
|
|
95
|
-
: TPath extends keyof T
|
|
96
|
-
? T[TPath]
|
|
97
|
-
: TPath extends `${ArrayKey}`
|
|
98
|
-
? T extends readonly (infer V)[]
|
|
99
|
-
? V
|
|
100
|
-
: never
|
|
101
|
-
: never
|
|
102
|
-
: never
|
|
103
|
-
|
|
104
|
-
export type AnyBoolean<Schema> =
|
|
105
|
-
| boolean
|
|
106
|
-
| Ref<boolean>
|
|
107
|
-
| ((data?: InjectedFormData<Schema>) => boolean | Ref<boolean>)
|
|
108
|
-
|
|
109
|
-
export type SimpleFormTemplateItem<Schema extends FormSchema> = Record<
|
|
110
|
-
string,
|
|
111
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
112
|
-
any
|
|
113
|
-
> & {
|
|
114
|
-
vvIs?: string | Component
|
|
115
|
-
vvName?: Path<z.infer<Schema>>
|
|
116
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
117
|
-
vvSlots?: Record<string, any>
|
|
118
|
-
vvChildren?: Array<
|
|
119
|
-
| SimpleFormTemplateItem<Schema>
|
|
120
|
-
| ((data?: InjectedFormData<Schema>) => SimpleFormTemplateItem<Schema>)
|
|
121
|
-
>
|
|
122
|
-
vvIf?: AnyBoolean<Schema> | Path<z.infer<Schema>>
|
|
123
|
-
vvElseIf?: AnyBoolean<Schema> | Path<z.infer<Schema>>
|
|
124
|
-
vvType?: `${FormFieldType}`
|
|
125
|
-
vvShowValid?: boolean
|
|
126
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
127
|
-
vvDefaultValue?: any
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
export type FormTemplateItem<Schema extends FormSchema> =
|
|
131
|
-
| SimpleFormTemplateItem<Schema>
|
|
132
|
-
| ((data?: InjectedFormData<Schema>) => SimpleFormTemplateItem<Schema>)
|
|
37
|
+
name: Ref<string>;
|
|
38
|
+
errors: Readonly<Ref<DeepReadonly<z.inferFormattedError<Schema>>>>;
|
|
39
|
+
};
|
|
40
|
+
export type Primitive = null | undefined | string | number | boolean | symbol | bigint;
|
|
41
|
+
type ArrayKey = number;
|
|
42
|
+
type IsTuple<T extends readonly any[]> = number extends T['length'] ? false : true;
|
|
43
|
+
type TupleKeys<T extends readonly any[]> = Exclude<keyof T, keyof any[]>;
|
|
44
|
+
export type PathConcat<TKey extends string | number, TValue> = TValue extends Primitive ? `${TKey}` : `${TKey}` | `${TKey}.${Path<TValue>}`;
|
|
45
|
+
export type Path<T> = T extends readonly (infer V)[] ? IsTuple<T> extends true ? {
|
|
46
|
+
[K in TupleKeys<T>]-?: PathConcat<K & string, T[K]>;
|
|
47
|
+
}[TupleKeys<T>] : PathConcat<ArrayKey, V> : {
|
|
48
|
+
[K in keyof T]-?: PathConcat<K & string, T[K]>;
|
|
49
|
+
}[keyof T];
|
|
50
|
+
export type PathValue<T, TPath extends Path<T> | Path<T>[]> = T extends any ? TPath extends `${infer K}.${infer R}` ? K extends keyof T ? R extends Path<T[K]> ? undefined extends T[K] ? PathValue<T[K], R> | undefined : PathValue<T[K], R> : never : K extends `${ArrayKey}` ? T extends readonly (infer V)[] ? PathValue<V, R & Path<V>> : never : never : TPath extends keyof T ? T[TPath] : TPath extends `${ArrayKey}` ? T extends readonly (infer V)[] ? V : never : never : never;
|
|
51
|
+
export type AnyBoolean<Schema extends FormSchema> = boolean | Ref<boolean> | ((data?: InjectedFormData<Schema>) => boolean | Ref<boolean>);
|
|
52
|
+
export type SimpleFormTemplateItem<Schema extends FormSchema> = Record<string, any> & {
|
|
53
|
+
vvIs?: string | Component;
|
|
54
|
+
vvName?: Path<z.infer<Schema>>;
|
|
55
|
+
vvSlots?: Record<string, any>;
|
|
56
|
+
vvChildren?: Array<SimpleFormTemplateItem<Schema> | ((data?: InjectedFormData<Schema>) => SimpleFormTemplateItem<Schema>)>;
|
|
57
|
+
vvIf?: AnyBoolean<Schema> | Path<z.infer<Schema>>;
|
|
58
|
+
vvElseIf?: AnyBoolean<Schema> | Path<z.infer<Schema>>;
|
|
59
|
+
vvType?: `${FormFieldType}`;
|
|
60
|
+
vvShowValid?: boolean;
|
|
61
|
+
vvContent?: string;
|
|
62
|
+
vvDefaultValue?: any;
|
|
63
|
+
};
|
|
64
|
+
export type FormTemplateItem<Schema extends FormSchema> = SimpleFormTemplateItem<Schema> | ((data?: InjectedFormData<Schema>) => SimpleFormTemplateItem<Schema>);
|
|
65
|
+
export type FormTemplate<Schema extends FormSchema> = FormTemplateItem<Schema>[] | ((data?: InjectedFormData<Schema>) => FormTemplateItem<Schema>[]);
|
|
66
|
+
export {};
|
package/package.json
CHANGED
|
@@ -19,11 +19,11 @@
|
|
|
19
19
|
"bugs": {
|
|
20
20
|
"url": "https://github.com/volverjs/form-vue/issues"
|
|
21
21
|
},
|
|
22
|
-
"version": "0.0.14-beta.
|
|
22
|
+
"version": "0.0.14-beta.3",
|
|
23
23
|
"engines": {
|
|
24
24
|
"node": ">= 16.x"
|
|
25
25
|
},
|
|
26
|
-
"packageManager": "pnpm@
|
|
26
|
+
"packageManager": "pnpm@8.6.12",
|
|
27
27
|
"type": "module",
|
|
28
28
|
"main": "./dist/index.js",
|
|
29
29
|
"module": "./dist/index.js",
|
|
@@ -35,34 +35,34 @@
|
|
|
35
35
|
"*.d.ts"
|
|
36
36
|
],
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@volverjs/ui-vue": "^0.0.
|
|
39
|
-
"@vueuse/core": "^10.
|
|
38
|
+
"@volverjs/ui-vue": "^0.0.9",
|
|
39
|
+
"@vueuse/core": "^10.4.1",
|
|
40
40
|
"ts-dot-prop": "^2.1.3",
|
|
41
41
|
"vue": "^3.3.4",
|
|
42
|
-
"zod": "^3.
|
|
42
|
+
"zod": "^3.22.2"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
|
-
"@playwright/experimental-ct-vue": "1.
|
|
45
|
+
"@playwright/experimental-ct-vue": "1.37.1",
|
|
46
46
|
"@testing-library/vue": "^7.0.0",
|
|
47
|
-
"@typescript-eslint/eslint-plugin": "^6.
|
|
48
|
-
"@typescript-eslint/parser": "^6.
|
|
49
|
-
"@vitejs/plugin-vue": "^4.
|
|
47
|
+
"@typescript-eslint/eslint-plugin": "^6.5.0",
|
|
48
|
+
"@typescript-eslint/parser": "^6.5.0",
|
|
49
|
+
"@vitejs/plugin-vue": "^4.3.4",
|
|
50
50
|
"@volverjs/style": "^0.1.11",
|
|
51
51
|
"@vue/compiler-sfc": "^3.3.4",
|
|
52
52
|
"@vue/runtime-core": "^3.3.4",
|
|
53
53
|
"@vue/test-utils": "^2.4.1",
|
|
54
54
|
"copy": "^0.3.2",
|
|
55
|
-
"eslint": "^8.
|
|
56
|
-
"eslint-config-prettier": "^
|
|
55
|
+
"eslint": "^8.48.0",
|
|
56
|
+
"eslint-config-prettier": "^9.0.0",
|
|
57
57
|
"eslint-plugin-prettier": "^5.0.0",
|
|
58
|
-
"happy-dom": "^10.
|
|
59
|
-
"prettier": "^3.0.
|
|
60
|
-
"typescript": "^5.
|
|
61
|
-
"vite": "^4.4.
|
|
58
|
+
"happy-dom": "^10.11.2",
|
|
59
|
+
"prettier": "^3.0.3",
|
|
60
|
+
"typescript": "^5.2.2",
|
|
61
|
+
"vite": "^4.4.9",
|
|
62
|
+
"vite-plugin-dts": "^3.5.3",
|
|
62
63
|
"vite-plugin-eslint": "^1.8.1",
|
|
63
64
|
"vite-plugin-externalize-deps": "^0.7.0",
|
|
64
|
-
"vitest": "^0.34.
|
|
65
|
-
"vue-tsc": "^1.8.8"
|
|
65
|
+
"vitest": "^0.34.3"
|
|
66
66
|
},
|
|
67
67
|
"typesVersions": {
|
|
68
68
|
"*": {
|
|
@@ -83,7 +83,8 @@
|
|
|
83
83
|
"scripts": {
|
|
84
84
|
"lint": "eslint . --ext .js,.jsx,.ts,.tsx",
|
|
85
85
|
"type-check": "tsc --noEmit",
|
|
86
|
-
"build": "vite build
|
|
86
|
+
"build": "vite build",
|
|
87
|
+
"dev": "vite build --watch",
|
|
87
88
|
"test": "pnpm run test-vitest && pnpm run test-playwright",
|
|
88
89
|
"test-vitest": "vitest run",
|
|
89
90
|
"test-vitest-watch": "vitest",
|
package/src/VvForm.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
|
+
type Component,
|
|
2
3
|
type InjectionKey,
|
|
3
4
|
type DeepReadonly,
|
|
4
5
|
type Ref,
|
|
6
|
+
type PropType,
|
|
5
7
|
withModifiers,
|
|
6
8
|
defineComponent,
|
|
7
9
|
ref,
|
|
@@ -18,6 +20,7 @@ import type { z, ZodFormattedError, TypeOf } from 'zod'
|
|
|
18
20
|
import type {
|
|
19
21
|
FormComponentOptions,
|
|
20
22
|
FormSchema,
|
|
23
|
+
FormTemplate,
|
|
21
24
|
InjectedFormData,
|
|
22
25
|
} from './types'
|
|
23
26
|
import { FormStatus } from './enums'
|
|
@@ -26,9 +29,10 @@ import { defaultObjectBySchema } from './utils'
|
|
|
26
29
|
export const defineForm = <Schema extends FormSchema>(
|
|
27
30
|
schema: Schema,
|
|
28
31
|
provideKey: InjectionKey<InjectedFormData<Schema>>,
|
|
29
|
-
options?: FormComponentOptions
|
|
32
|
+
options?: FormComponentOptions<Schema>,
|
|
33
|
+
VvFormTemplate?: Component,
|
|
30
34
|
) => {
|
|
31
|
-
const errors = ref<
|
|
35
|
+
const errors = ref<z.inferFormattedError<Schema> | undefined>()
|
|
32
36
|
const status = ref<FormStatus | undefined>()
|
|
33
37
|
const formData = ref<Partial<z.infer<Schema> | undefined>>()
|
|
34
38
|
const component = defineComponent({
|
|
@@ -46,6 +50,9 @@ export const defineForm = <Schema extends FormSchema>(
|
|
|
46
50
|
type: Boolean,
|
|
47
51
|
default: false,
|
|
48
52
|
},
|
|
53
|
+
template: {
|
|
54
|
+
type: [Array, Function] as PropType<FormTemplate<Schema>>,
|
|
55
|
+
},
|
|
49
56
|
},
|
|
50
57
|
emits: ['invalid', 'valid', 'submit', 'update:modelValue'],
|
|
51
58
|
expose: ['submit', 'validate', 'errors', 'status', 'valid', 'invalid'],
|
|
@@ -89,6 +96,7 @@ export const defineForm = <Schema extends FormSchema>(
|
|
|
89
96
|
JSON.stringify(props.modelValue)
|
|
90
97
|
) {
|
|
91
98
|
emit('update:modelValue', newValue)
|
|
99
|
+
options?.onUpdate?.(toRaw(newValue))
|
|
92
100
|
}
|
|
93
101
|
},
|
|
94
102
|
{
|
|
@@ -107,13 +115,16 @@ export const defineForm = <Schema extends FormSchema>(
|
|
|
107
115
|
>
|
|
108
116
|
status.value = FormStatus.invalid
|
|
109
117
|
emit('invalid', errors.value)
|
|
118
|
+
options?.onInvalid?.(toRaw(errors.value))
|
|
110
119
|
return false
|
|
111
120
|
}
|
|
112
121
|
errors.value = undefined
|
|
113
122
|
status.value = FormStatus.valid
|
|
114
123
|
formData.value = parseResult.data
|
|
115
124
|
emit('update:modelValue', formData.value)
|
|
125
|
+
options?.onUpdate?.(toRaw(formData.value))
|
|
116
126
|
emit('valid', parseResult.data)
|
|
127
|
+
options?.onValid?.(toRaw(formData.value))
|
|
117
128
|
return true
|
|
118
129
|
}
|
|
119
130
|
|
|
@@ -122,7 +133,8 @@ export const defineForm = <Schema extends FormSchema>(
|
|
|
122
133
|
if (!validate()) {
|
|
123
134
|
return false
|
|
124
135
|
}
|
|
125
|
-
emit('submit', formData.value)
|
|
136
|
+
emit('submit', formData.value as z.infer<Schema>)
|
|
137
|
+
options?.onSubmit?.(toRaw(formData.value) as z.infer<Schema>)
|
|
126
138
|
return true
|
|
127
139
|
}
|
|
128
140
|
|
|
@@ -153,17 +165,23 @@ export const defineForm = <Schema extends FormSchema>(
|
|
|
153
165
|
{
|
|
154
166
|
onSubmit: withModifiers(this.submit, ['prevent']),
|
|
155
167
|
},
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
168
|
+
(this.template ?? options?.template) && VvFormTemplate
|
|
169
|
+
? [
|
|
170
|
+
h(VvFormTemplate, {
|
|
171
|
+
schema: this.template ?? options?.template,
|
|
172
|
+
}),
|
|
173
|
+
]
|
|
174
|
+
: {
|
|
175
|
+
default: () =>
|
|
176
|
+
this.$slots?.default?.({
|
|
177
|
+
formData: this.formData,
|
|
178
|
+
submit: this.submit,
|
|
179
|
+
validate: this.validate,
|
|
180
|
+
errors: this.errors,
|
|
181
|
+
status: this.status,
|
|
182
|
+
invalid: this.invalid,
|
|
183
|
+
}) ?? this.$slots.default,
|
|
184
|
+
},
|
|
167
185
|
)
|
|
168
186
|
},
|
|
169
187
|
})
|
package/src/VvFormField.ts
CHANGED
package/src/VvFormTemplate.ts
CHANGED
|
@@ -12,35 +12,30 @@ import {
|
|
|
12
12
|
unref,
|
|
13
13
|
} from 'vue'
|
|
14
14
|
import type { TypeOf, z } from 'zod'
|
|
15
|
-
import type { FormSchema, InjectedFormData,
|
|
15
|
+
import type { FormSchema, InjectedFormData, FormTemplate } from './types'
|
|
16
16
|
import type { FormStatus } from './enums'
|
|
17
17
|
|
|
18
18
|
export const defineFormTemplate = <Schema extends FormSchema>(
|
|
19
19
|
formProvideKey: InjectionKey<InjectedFormData<Schema>>,
|
|
20
20
|
VvFormField: Component,
|
|
21
21
|
) => {
|
|
22
|
-
const VvFormTemplate
|
|
22
|
+
const VvFormTemplate = defineComponent({
|
|
23
23
|
props: {
|
|
24
24
|
schema: {
|
|
25
|
-
type: [Array, Function] as PropType<
|
|
26
|
-
| FormTemplateItem<Schema>[]
|
|
27
|
-
| ((
|
|
28
|
-
data?: InjectedFormData<Schema>,
|
|
29
|
-
) => FormTemplateItem<Schema>[])
|
|
30
|
-
>,
|
|
25
|
+
type: [Array, Function] as PropType<FormTemplate<Schema>>,
|
|
31
26
|
required: true,
|
|
32
27
|
},
|
|
33
28
|
},
|
|
34
29
|
setup(templateProps, { slots: templateSlots }) {
|
|
35
30
|
const injectedFormData = inject(formProvideKey)
|
|
36
31
|
if (!injectedFormData?.formData) return
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
normalizedSchema.reduce<(VNode | VNode[] | undefined)[]>(
|
|
32
|
+
return () => {
|
|
33
|
+
const normalizedSchema =
|
|
34
|
+
typeof templateProps.schema === 'function'
|
|
35
|
+
? templateProps.schema(injectedFormData)
|
|
36
|
+
: templateProps.schema
|
|
37
|
+
let lastIf: boolean | undefined = undefined
|
|
38
|
+
return normalizedSchema.reduce<(VNode | VNode[] | undefined)[]>(
|
|
44
39
|
(acc, field) => {
|
|
45
40
|
const normalizedField =
|
|
46
41
|
typeof field === 'function'
|
|
@@ -56,6 +51,7 @@ export const defineFormTemplate = <Schema extends FormSchema>(
|
|
|
56
51
|
vvType,
|
|
57
52
|
vvDefaultValue,
|
|
58
53
|
vvShowValid,
|
|
54
|
+
vvContent,
|
|
59
55
|
...props
|
|
60
56
|
} = normalizedField
|
|
61
57
|
|
|
@@ -120,7 +116,7 @@ export const defineFormTemplate = <Schema extends FormSchema>(
|
|
|
120
116
|
showValid: vvShowValid,
|
|
121
117
|
props,
|
|
122
118
|
},
|
|
123
|
-
vvSlots ?? hChildren,
|
|
119
|
+
vvSlots ?? hChildren ?? vvContent,
|
|
124
120
|
),
|
|
125
121
|
)
|
|
126
122
|
return acc
|
|
@@ -130,7 +126,7 @@ export const defineFormTemplate = <Schema extends FormSchema>(
|
|
|
130
126
|
h(
|
|
131
127
|
vvIs as Component,
|
|
132
128
|
props,
|
|
133
|
-
vvSlots ?? hChildren,
|
|
129
|
+
vvSlots ?? hChildren ?? vvContent,
|
|
134
130
|
),
|
|
135
131
|
)
|
|
136
132
|
return acc
|
|
@@ -152,6 +148,7 @@ export const defineFormTemplate = <Schema extends FormSchema>(
|
|
|
152
148
|
}),
|
|
153
149
|
],
|
|
154
150
|
)
|
|
151
|
+
}
|
|
155
152
|
},
|
|
156
153
|
})
|
|
157
154
|
|
package/src/VvFormWrapper.ts
CHANGED
|
@@ -42,7 +42,7 @@ export const defineFormWrapper = <Schema extends FormSchema>(
|
|
|
42
42
|
const wrapperProvided = inject(wrapperProvideKey, undefined)
|
|
43
43
|
const fields = ref(new Set<string>())
|
|
44
44
|
const fieldsErrors: Ref<
|
|
45
|
-
Map<string,
|
|
45
|
+
Map<string, z.inferFormattedError<Schema>>
|
|
46
46
|
> = ref(new Map())
|
|
47
47
|
const { name } = toRefs(props)
|
|
48
48
|
|
package/src/index.ts
CHANGED
|
@@ -19,11 +19,13 @@ import type {
|
|
|
19
19
|
Path,
|
|
20
20
|
PathValue,
|
|
21
21
|
FormSchema,
|
|
22
|
+
FormTemplate,
|
|
22
23
|
} from './types'
|
|
24
|
+
import type { AnyZodObject } from 'zod'
|
|
23
25
|
|
|
24
26
|
const _formFactory = <Schema extends FormSchema>(
|
|
25
27
|
schema: Schema,
|
|
26
|
-
options: FormComposableOptions = {},
|
|
28
|
+
options: FormComposableOptions<Schema> = {},
|
|
27
29
|
) => {
|
|
28
30
|
// create injection keys
|
|
29
31
|
const formInjectionKey = Symbol() as InjectionKey<InjectedFormData<Schema>>
|
|
@@ -35,11 +37,6 @@ const _formFactory = <Schema extends FormSchema>(
|
|
|
35
37
|
>
|
|
36
38
|
|
|
37
39
|
// create components
|
|
38
|
-
const { VvForm, errors, status, formData } = defineForm(
|
|
39
|
-
schema,
|
|
40
|
-
formInjectionKey,
|
|
41
|
-
options,
|
|
42
|
-
)
|
|
43
40
|
const VvFormWrapper = defineFormWrapper(
|
|
44
41
|
formInjectionKey,
|
|
45
42
|
formWrapperInjectionKey,
|
|
@@ -51,6 +48,12 @@ const _formFactory = <Schema extends FormSchema>(
|
|
|
51
48
|
options,
|
|
52
49
|
)
|
|
53
50
|
const VvFormTemplate = defineFormTemplate(formInjectionKey, VvFormField)
|
|
51
|
+
const { VvForm, errors, status, formData } = defineForm(
|
|
52
|
+
schema,
|
|
53
|
+
formInjectionKey,
|
|
54
|
+
options,
|
|
55
|
+
VvFormTemplate,
|
|
56
|
+
)
|
|
54
57
|
|
|
55
58
|
return {
|
|
56
59
|
VvForm,
|
|
@@ -73,7 +76,7 @@ export const createForm = (
|
|
|
73
76
|
): Plugin & Partial<ReturnType<typeof useForm>> => {
|
|
74
77
|
let toReturn: Partial<ReturnType<typeof useForm>> = {}
|
|
75
78
|
if (options.schema) {
|
|
76
|
-
toReturn = _formFactory(options.schema, options)
|
|
79
|
+
toReturn = _formFactory(options.schema as AnyZodObject, options)
|
|
77
80
|
}
|
|
78
81
|
return {
|
|
79
82
|
...toReturn,
|
|
@@ -102,15 +105,18 @@ export const createForm = (
|
|
|
102
105
|
|
|
103
106
|
export const useForm = <Schema extends FormSchema>(
|
|
104
107
|
schema: Schema,
|
|
105
|
-
options: FormComposableOptions = {},
|
|
108
|
+
options: FormComposableOptions<Schema> = {},
|
|
106
109
|
) => {
|
|
107
110
|
if (!getCurrentInstance()) {
|
|
108
111
|
return _formFactory(schema, options)
|
|
109
112
|
}
|
|
110
|
-
return _formFactory(
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
113
|
+
return _formFactory(
|
|
114
|
+
schema as AnyZodObject,
|
|
115
|
+
{
|
|
116
|
+
...inject(pluginInjectionKey, {}),
|
|
117
|
+
...options,
|
|
118
|
+
} as FormComposableOptions<AnyZodObject>,
|
|
119
|
+
)
|
|
114
120
|
}
|
|
115
121
|
|
|
116
122
|
export { FormFieldType } from './enums'
|
|
@@ -130,6 +136,7 @@ export type {
|
|
|
130
136
|
FormComponent,
|
|
131
137
|
FormWrapperComponent,
|
|
132
138
|
FormFieldComponent,
|
|
139
|
+
FormTemplate,
|
|
133
140
|
FormTemplateComponent,
|
|
134
141
|
FormTemplateItem,
|
|
135
142
|
Path,
|
|
@@ -141,7 +148,7 @@ export type {
|
|
|
141
148
|
*/
|
|
142
149
|
export const formFactory = <Schema extends FormSchema>(
|
|
143
150
|
schema: Schema,
|
|
144
|
-
options: FormComposableOptions = {},
|
|
151
|
+
options: FormComposableOptions<Schema> = {},
|
|
145
152
|
) => {
|
|
146
153
|
return _formFactory(schema, options)
|
|
147
154
|
}
|