@volverjs/form-vue 1.0.0-beta.25 → 1.0.0-beta.26
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 +13 -10
- package/dist/VvFormField.d.ts +5 -5
- package/dist/VvFormFieldsGroup.d.ts +5 -5
- package/dist/VvFormTemplate.d.ts +9 -9
- package/dist/VvFormWrapper.d.ts +10 -10
- package/dist/index.d.ts +683 -177
- package/dist/index.es.js +627 -587
- package/dist/index.umd.js +1 -1
- package/dist/types.d.ts +25 -20
- package/package.json +10 -10
- package/src/VvForm.ts +26 -15
- package/src/VvFormField.ts +14 -7
- package/src/VvFormFieldsGroup.ts +17 -6
- package/src/VvFormTemplate.ts +17 -19
- package/src/VvFormWrapper.ts +45 -14
- package/src/index.ts +24 -10
- package/src/types.ts +39 -34
package/dist/index.umd.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
(function(A,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):(A=typeof globalThis<"u"?globalThis:A||self,e(A["@volverjs/form-vue"]={},A.Vue,A.VueUseCore,A.zod))})(this,function(A,e,T,B){"use strict";var p=(r=>(r.text="text",r.number="number",r.email="email",r.password="password",r.tel="tel",r.url="url",r.search="search",r.date="date",r.time="time",r.datetimeLocal="datetime-local",r.month="month",r.week="week",r.color="color",r.select="select",r.checkbox="checkbox",r.radio="radio",r.textarea="textarea",r.radioGroup="radioGroup",r.checkboxGroup="checkboxGroup",r.combobox="combobox",r.custom="custom",r))(p||{}),G=(r=>(r.invalid="invalid",r.valid="valid",r.submitting="submitting",r.reset="reset",r.updated="updated",r.unknown="unknown",r))(G||{});function L(r,s={}){const t=v=>{let u=v;for(;u instanceof B.ZodEffects;)u=u.innerType();return u instanceof B.ZodOptional&&(u=u._def.innerType),u},c=v=>{let u=v;for(;u instanceof B.ZodEffects;)u=u.innerType();return u instanceof B.ZodOptional},a=t(r);return{...(a instanceof B.ZodObject?a._def.unknownKeys==="passthrough":!1)?s:{},...Object.fromEntries(Object.entries(a.shape).map(([v,u])=>{const d=s[v],V=c(u);let l=t(u),h;if(l instanceof B.ZodDefault&&(h=l._def.defaultValue(),l=l._def.innerType),d===null&&l instanceof B.ZodNullable)return[v,d];if(d==null&&V)return[v,h];if(l instanceof B.ZodSchema){const b=u.safeParse(d);if(b.success)return[v,b.data??h]}if(l instanceof B.ZodArray&&Array.isArray(d)&&d.length){const b=t(l._def.type);if(b instanceof B.ZodObject)return[v,d.map(y=>L(b,y&&typeof y=="object"?y:void 0))]}if(l instanceof B.ZodRecord&&d){const b=t(l._def.valueType);if(b instanceof B.ZodObject)return[v,Object.keys(d).reduce((y,o)=>(y[o]=L(b,d[o]),y),{})]}return l instanceof B.ZodObject?[v,L(l,d&&typeof d=="object"?d:h)]:[v,h]}))}}function z(r,s,t,c){const a=e.ref(),n=e.ref(),v=e.computed(()=>n.value===G.invalid),u=e.ref(),d=e.ref(!1);let V;const l=async(x=u.value,w)=>{if(V=w,d.value)return!0;const g=await r.safeParseAsync(x);if(!g.success){if(n.value=G.invalid,!w)return a.value=g.error.format(),!1;const i=g.error.issues.filter(U=>w.has(U.path.join(".")));return i.length?(a.value=new B.ZodError(i).format(),!1):(a.value=void 0,!0)}return a.value=void 0,n.value=G.valid,u.value=g.data,!0},h=()=>{a.value=void 0,n.value=void 0,V=void 0},b=()=>{u.value=L(r),h(),n.value=G.reset},y=async()=>d.value||!await l()?!1:(n.value=G.submitting,!0),{ignoreUpdates:o,stop:O}=T.watchIgnorable(u,()=>{n.value=G.updated},{deep:!0,eventFilter:T.throttleFilter((t==null?void 0:t.updateThrottle)??500)}),S=e.readonly(a),E=e.readonly(n),k=e.defineComponent({name:"VvForm",props:{continuousValidation:{type:Boolean,default:!1},modelValue:{type:Object,default:()=>({})},readonly:{type:Boolean,default:(t==null?void 0:t.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:w}){return u.value=L(r,e.toRaw(x.modelValue)),e.watch(()=>x.modelValue,g=>{if(g){const i=e.isProxy(g)?e.toRaw(g):g;if(JSON.stringify(i)===JSON.stringify(e.toRaw(u.value)))return;u.value=typeof(i==null?void 0:i.clone)=="function"?i.clone():JSON.parse(JSON.stringify(i))}},{deep:!0}),e.watch(n,async g=>{var i,U,R,W,$,M;if(g===G.invalid){const C=e.toRaw(a.value);w("invalid",C),(i=t==null?void 0:t.onInvalid)==null||i.call(t,C);return}if(g===G.valid){const C=e.toRaw(u.value);w("valid",C),(U=t==null?void 0:t.onValid)==null||U.call(t,C),w("update:modelValue",C),(R=t==null?void 0:t.onUpdate)==null||R.call(t,C);return}if(g===G.submitting){const C=e.toRaw(u.value);w("submit",C),(W=t==null?void 0:t.onSubmit)==null||W.call(t,C);return}if(g===G.reset){const C=e.toRaw(u.value);w("reset",C),($=t==null?void 0:t.onReset)==null||$.call(t,C);return}if(g===G.updated){if((a.value||t!=null&&t.continuousValidation||x.continuousValidation)&&await l(void 0,V),!u.value||!x.modelValue||JSON.stringify(u.value)!==JSON.stringify(x.modelValue)){const C=e.toRaw(u.value);w("update:modelValue",C),(M=t==null?void 0:t.onUpdate)==null||M.call(t,C)}n.value===G.updated&&(n.value=G.unknown)}}),e.onMounted(()=>{d.value=x.readonly}),e.watch(()=>x.readonly,g=>{d.value=g}),e.watch(d,g=>{g!==x.readonly&&w("update:readonly",d.value)}),e.provide(s,{clear:h,errors:S,formData:u,ignoreUpdates:o,invalid:v,readonly:d,reset:b,status:E,stopUpdatesWatch:O,submit:y,validate:l}),{clear:h,errors:S,formData:u,ignoreUpdates:o,invalid:v,isReadonly:d,reset:b,status:E,stopUpdatesWatch:O,submit:y,validate:l}},render(){const x=()=>{var w,g;return((g=(w=this.$slots)==null?void 0:w.default)==null?void 0:g.call(w,{clear:h,errors:S,formData:u,ignoreUpdates:o,invalid:v,readonly:d,reset:b,status:E,stopUpdatesWatch:O,submit:y,validate:l}))??this.$slots.default};return e.h(this.tag,{onSubmit:e.withModifiers(this.submit,["prevent"]),onReset:e.withModifiers(this.reset,["prevent"])},(this.template??(t==null?void 0:t.template))&&c?[e.h(c,{schema:this.template??(t==null?void 0:t.template)},{default:x})]:{default:x})}});return{clear:h,errors:a,formData:u,ignoreUpdates:o,invalid:v,readonly:d,reset:b,status:n,stopUpdatesWatch:O,submit:y,validate:l,VvForm:k}}function P(r){return Array.isArray(r)}function j(r){return typeof r<"u"}function H(r){return r===null}function Q(r){return typeof r=="object"}function X(r){return typeof r=="string"}function _(r){return typeof r>"u"}const D=/^[0-9]+$/,F=["__proto__","prototype","constructor"];function Z(r,s,t){const c=j(t)?t:void 0;if(!Q(r)||!X(s))return c;const a=Y(s);if(a.length!==0){for(const n of a){if(n==="*")continue;const v=function(u){return u.map(d=>_(d)||H(d)?d:P(d)?v(d):d[n])};if(P(r)&&!D.test(n)?r=v(r):r=r[n],_(r)||H(r))break}return _(r)?c:r}}function q(r,s,t){if(!Q(r)||!X(s))return;const c=Y(s);if(c.length===0)return;const a=c.length;for(let n=0;n<a;n++){const v=c[n];if(n===a-1){r[v]=t;return}if(v==="*"&&P(r)){const u=c.slice(n+1).join(".");for(const d of r)q(d,u,t);return}_(r[v])&&(r[v]={}),r=r[v]}}function Y(r){const s=r.split(/[.]|(?:\[(\d|\*)\])/).filter(t=>!!t);return s.some(t=>F.indexOf(t)!==-1)?[]:s}function ee(r,s,t,c){return e.defineComponent({name:"VvFormField",props:{type:{type:String,validator:a=>Object.values(p).includes(a),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(a,{slots:n,emit:v}){const{props:u,name:d}=e.toRefs(a),V=e.inject(s,void 0);V&&V.fields.value.add(a.name);const l=e.inject(r),h=e.computed({get(){if(l!=null&&l.formData)return Z(new Object(l.formData.value),String(a.name))},set(i){l!=null&&l.formData&&(q(new Object(l.formData.value),String(a.name),i),v("update:modelValue",{newValue:h.value,formData:l==null?void 0:l.formData}))}});e.onMounted(()=>{h.value===void 0&&a.defaultValue!==void 0&&(h.value=a.defaultValue)});const b=e.computed(()=>{if(l!=null&&l.errors.value)return Z(l.errors.value,String(a.name))}),y=e.computed(()=>{var i;return(i=b.value)==null?void 0:i._errors}),o=e.computed(()=>b.value!==void 0),O=e.watch(o,()=>{if(o.value){v("invalid",b.value),V&&V.errors.value.set(String(a.name),b.value);return}v("valid",h.value),V&&V.errors.value.delete(a.name)}),S=e.watch(()=>l==null?void 0:l.formData,()=>{v("update:formData",l==null?void 0:l.formData)},{deep:!0});e.onBeforeUnmount(()=>{O(),S()});const E=i=>{i instanceof InputEvent&&(i=i.target.value),h.value=i},k=e.computed(()=>{let i=u.value;return typeof i=="function"&&(i=i(l==null?void 0:l.formData)),Object.keys(i).reduce((U,R)=>(U[R]=e.unref(i[R]),U),{})}),x=e.computed(()=>l!=null&&l.readonly.value?!0:k.value.readonly??a.readonly),w=e.computed(()=>({...k.value,name:k.value.name??a.name,invalid:o.value,valid:a.showValid?!!(!o.value&&h.value):void 0,type:(i=>{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(i))return i})(a.type),invalidLabel:y.value,modelValue:h.value,readonly:x.value,"onUpdate:modelValue":E}));return e.provide(t,{name:e.readonly(d),errors:e.readonly(b)}),{component:e.computed(()=>{if(a.type===p.custom)return{render(){var i;return((i=n.default)==null?void 0:i.call(n,{errors:b.value,formData:l==null?void 0:l.formData.value,formErrors:l==null?void 0:l.errors.value,invalid:o.value,invalidLabel:y.value,modelValue:h.value,onUpdate:E,readonly:x.value,submit:l==null?void 0:l.submit,validate:l==null?void 0:l.validate}))??n.default}};if(!((c==null?void 0:c.lazyLoad)??a.lazyLoad)){let i;switch(a.type){case p.select:i=e.resolveComponent("VvSelect");break;case p.checkbox:i=e.resolveComponent("VvCheckbox");break;case p.radio:i=e.resolveComponent("VvRadio");break;case p.textarea:i=e.resolveComponent("VvTextarea");break;case p.radioGroup:i=e.resolveComponent("VvRadioGroup");break;case p.checkboxGroup:i=e.resolveComponent("VvCheckboxGroup");break;case p.combobox:i=e.resolveComponent("VvCombobox");break;default:i=e.resolveComponent("VvInputText")}if(typeof i!="string")return i;console.warn(`[form-vue warn]: ${i} not found, the component will be loaded asynchronously. To avoid this warning, please set "lazyLoad" option.`)}return e.defineAsyncComponent(async()=>{switch(c!=null&&c.sideEffects&&await Promise.resolve(c.sideEffects(a.type)),a.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:w,invalid:o}},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 re(r,s,t){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(c,{slots:a,emit:n}){const{props:v,names:u,defaultValues:d}=e.toRefs(c),V=e.computed(()=>Array.isArray(u.value)?u.value:Object.values(u.value)),l=e.computed(()=>Array.isArray(u.value)?u.value:Object.keys(u.value)),h=e.computed(()=>Array.isArray(u.value)?u.value.reduce((f,m)=>(f[String(m)]=m,f),{}):u.value),b=e.computed(()=>Object.keys(h.value).reduce((f,m)=>(f[String(h.value[m])]=m,f),{})),y=e.inject(s,void 0);y&&V.value.forEach(f=>{y.fields.value.add(f)});const o=e.inject(r),O=e.computed({get(){return o!=null&&o.formData?l.value.reduce((f,m)=>(f[m]=Z(new Object(o.formData.value),h.value[m]),f),{}):{}},set(f){o!=null&&o.formData&&(l.value.forEach(m=>{q(new Object(o.formData.value),h.value[m],f==null?void 0:f[m])}),n("update:modelValue",{newValue:O.value,formData:o==null?void 0:o.formData}))}});e.onMounted(()=>{d.value&&V.value.forEach(f=>{var m,I;((m=d.value)==null?void 0:m[f])!==void 0&&O.value[f]===void 0&&(O.value={...O.value,[f]:(I=d.value)==null?void 0:I[f]})})});const S=e.computed(()=>{if(!(o!=null&&o.errors.value))return;const f=V.value.reduce((m,I)=>{if(!o.errors.value)return m;const N=Z(o.errors.value,String(I));return N===void 0||(m[String(I)]=N),m},{});if(Object.keys(f).length!==0)return f}),E=e.computed(()=>{if(!S.value)return;const f=Object.keys(S.value).reduce((m,I)=>{var N;return(N=S.value)!=null&&N[I]&&(m[b.value[I]]=S.value[I]._errors),m},{});if(Object.keys(f).length!==0)return f}),k=e.computed(()=>S.value!==void 0),x=e.computed(()=>l.value.reduce((f,m)=>{var I;return f[m]=!!((I=S.value)!=null&&I[b.value[m]]),f},{})),w=e.watch(k,()=>{if(k.value){n("invalid",S.value),y&&V.value.forEach(f=>{var m,I;if(!((m=S.value)!=null&&m[f])){y.errors.value.delete(f);return}y.errors.value.set(f,(I=S.value)==null?void 0:I[f])});return}n("valid",O.value),y&&V.value.forEach(f=>{y.errors.value.delete(f)})}),g=e.watch(()=>o==null?void 0:o.formData,()=>{n("update:formData",o==null?void 0:o.formData)},{deep:!0});e.onBeforeUnmount(()=>{w(),g()});const i=f=>{O.value=f},U=(f,m)=>{m instanceof InputEvent&&(m=m.target.value),l.value.includes(f)&&(O.value={...O.value,[f]:m})},R=e.computed(()=>{let f=v.value;return typeof f=="function"&&(f=f(o==null?void 0:o.formData)),Object.keys(f).reduce((m,I)=>(m[I]=e.unref(f[I]),m),{})}),W=e.computed(()=>o!=null&&o.readonly.value?!0:R.value.readonly??c.readonly),$=e.computed(()=>l.value.reduce((f,m)=>(f[`onUpdate:${m}`]=I=>{U(m,I)},f),{"onUpdate:modelValue":i})),M=e.computed(()=>({...$.value,...R.value,names:R.value.name??V.value,invalid:k.value,invalids:x.value,valid:c.showValid?!!(!k.value&&O.value):void 0,invalidLabels:E.value,modelValue:O.value,readonly:W.value}));return e.provide(t,{names:e.readonly(u),errors:e.readonly(S)}),{component:e.computed(()=>({render(){var f;return((f=a.default)==null?void 0:f.call(a,{errors:S.value,formData:o==null?void 0:o.formData.value,formErrors:o==null?void 0:o.errors.value,invalid:k.value,invalids:x.value,invalidLabels:E.value,modelValue:O.value,onUpdate:i,onUpdateField:U,readonly:W.value,submit:o==null?void 0:o.submit,validate:o==null?void 0:o.validate}))??a.default}})),hasProps:M,invalid:k}},render(){return this.is?e.h(this.is,this.hasProps,this.$slots):e.h(this.component,null,this.$slots)}})}function te(r,s){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(t,{emit:c}){const a=e.inject(r),n=e.inject(s,void 0),v=e.ref(new Set),u=e.ref(new Map),{name:d}=e.toRefs(t);e.provide(s,{name:e.readonly(d),errors:u,fields:v}),e.watch(v,h=>{n!=null&&n.fields&&h.forEach(b=>{n==null||n.fields.value.add(b)})},{deep:!0}),e.watch(()=>new Map(u.value),(h,b)=>{n!=null&&n.errors&&(Array.from(b.keys()).forEach(y=>{n.errors.value.delete(y)}),Array.from(h.keys()).forEach(y=>{const o=h.get(y);o&&n.errors.value.set(y,o)}))},{deep:!0});const V=e.computed(()=>a!=null&&a.invalid.value?u.value.size>0:!1);e.watch(V,()=>{V.value?c("invalid"):c("valid")});const l=()=>(a==null?void 0:a.validate(void 0,v.value))??Promise.resolve(!0);return{clear:a==null?void 0:a.clear,errors:a==null?void 0:a.errors,fields:v,fieldsErrors:u,formData:a==null?void 0:a.formData,invalid:V,reset:a==null?void 0:a.reset,submit:a==null?void 0:a.submit,validate:a==null?void 0:a.validate,validateWrapper:l}},render(){const t=()=>{var c,a;return(a=(c=this.$slots).default)==null?void 0:a.call(c,{clear:this.clear,errors:this.errors,fieldsErrors:this.fieldsErrors,formData:this.formData,invalid:this.invalid,reset:this.reset,submit:this.submit,validate:this.validate,validateWrapper:this.validateWrapper})};return this.tag?e.h(this.tag,null,{default:t}):t()}})}function ae(r,s){const t=e.defineComponent({name:"VvFormTemplate",props:{schema:{type:[Array,Function],required:!0},scope:{type:Object,default:()=>({})}},slots:Object,setup(c,{slots:a}){const n=e.inject(r);if(n!=null&&n.formData)return()=>{var V;const v=typeof c.schema=="function"?c.schema(n,c.scope):c.schema;let u;const d=v.reduce((l,h)=>{const b=typeof h=="function"?h(n,c.scope):h,{vvIs:y,vvName:o,vvSlots:O,vvChildren:S,vvIf:E,vvElseIf:k,vvType:x,vvDefaultValue:w,vvShowValid:g,vvContent:i,...U}=b;if(E!==void 0){if(typeof E=="string"?u=!!Z(new Object(n.formData.value),E):typeof E=="function"?u=e.unref(E(n)):u=e.unref(E),!u)return l}else if(k!==void 0&&u!==void 0){if(u||(typeof k=="string"?u=!!Z(new Object(n.formData.value),k):typeof k=="function"?u=e.unref(k(n)):u=e.unref(k),!u))return l}else u=void 0;let R;return S&&(typeof y=="string"?R=e.h(t,{schema:S}):R={default:W=>e.h(t,{schema:S,scope:W})}),o?(l.push(e.h(s,{name:o,is:y,type:x,defaultValue:w,showValid:g,props:U},O??R??i)),l):y?(l.push(e.h(y,U,O??R??i)),l):(R&&("default"in R?l.push(R.default(c.scope)):l.push(R)),l)},[]);return d.push((V=a==null?void 0:a.default)==null?void 0:V.call(a,{errors:n==null?void 0:n.errors.value,formData:n==null?void 0:n.formData.value,invalid:n==null?void 0:n.invalid.value,status:n==null?void 0:n.status.value,submit:n==null?void 0:n.submit,validate:n==null?void 0:n.validate,clear:n==null?void 0:n.clear,reset:n==null?void 0:n.reset})),d}}});return t}function K(r,s={}){const t=Symbol("formInjectionKey"),c=Symbol("formWrapperInjectionKey"),a=Symbol("formFieldInjectionKey"),n=Symbol("formFieldsGroupInjectionKey"),v=te(t,c),u=ee(t,c,a,s),d=re(t,c,n),V=ae(t,u),{clear:l,errors:h,formData:b,ignoreUpdates:y,invalid:o,readonly:O,reset:S,status:E,stopUpdatesWatch:k,submit:x,validate:w,VvForm:g}=z(r,t,s,V);return{clear:l,errors:h,formData:b,formFieldInjectionKey:a,formInjectionKey:t,formWrapperInjectionKey:c,ignoreUpdates:y,invalid:o,readonly:O,reset:S,status:E,stopUpdatesWatch:k,submit:x,validate:w,VvForm:g,VvFormField:u,VvFormFieldsGroup:d,VvFormTemplate:V,VvFormWrapper:v}}const J=Symbol("pluginInjectionKey");function ne(r){let s={};return r.schema&&(s=K(r.schema,r)),{...s,install(t,{global:c=!1}={}){t.provide(J,r),c&&(t.config.globalProperties.$vvForm=r,s!=null&&s.VvForm&&t.component("VvForm",s.VvForm),s!=null&&s.VvFormWrapper&&t.component("VvFormWrapper",s.VvFormWrapper),s!=null&&s.VvFormField&&t.component("VvFormField",s.VvFormField),s!=null&&s.VvFormFieldsGroup&&t.component("VvFormFieldsGroup",s.VvFormFieldsGroup),s!=null&&s.VvFormTemplate&&t.component("VvFormTemplate",s.VvFormTemplate))}}}function le(r,s={}){return e.getCurrentInstance()?K(r,{...e.inject(J,{}),...s}):K(r,s)}function ue(r,s={}){return K(r,s)}A.FormFieldType=p,A.createForm=ne,A.defaultObjectBySchema=L,A.formFactory=ue,A.pluginInjectionKey=J,A.useForm=le,Object.defineProperty(A,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,A){"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||{}),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,o={}){const r=c=>{let f=c;for(;f instanceof A.ZodEffects;)f=f.innerType();return f instanceof A.ZodOptional&&(f=f._def.innerType),f},m=c=>{let f=c;for(;f instanceof A.ZodEffects;)f=f.innerType();return f instanceof A.ZodOptional},a=r(t);return{...(a instanceof A.ZodObject?a._def.unknownKeys==="passthrough":!1)?o:{},...Object.fromEntries(Object.entries(a.shape).map(([c,f])=>{const i=o[c],g=m(f);let v=r(f),u;if(v instanceof A.ZodDefault&&(u=v._def.defaultValue(),v=v._def.innerType),i===null&&v instanceof A.ZodNullable)return[c,i];if(i==null&&g)return[c,u];if(v instanceof A.ZodSchema){const p=f.safeParse(i);if(p.success)return[c,p.data??u]}if(v instanceof A.ZodArray&&Array.isArray(i)&&i.length){const p=r(v._def.type);if(p instanceof A.ZodObject)return[c,i.map(h=>W(p,h&&typeof h=="object"?h:void 0))]}if(v instanceof A.ZodRecord&&i){const p=r(v._def.valueType);if(p instanceof A.ZodObject)return[c,Object.keys(i).reduce((h,V)=>(h[V]=W(p,i[V]),h),{})]}return v instanceof A.ZodObject?[c,W(v,i&&typeof i=="object"?i:u)]:[c,u]}))}}function D(t,o,r,m,a){const n=e.ref(),c=e.ref(),f=e.computed(()=>c.value===B.invalid),i=e.ref(),g=e.ref(!1);let v;const u=x=>{const O=W(t,x);if(r!=null&&r.class){const s=r.class;return new s(O)}return O},p=async(x=i.value,O)=>{if(v=O,g.value)return!0;const s=await t.safeParseAsync(x);if(!s.success){if(c.value=B.invalid,!O)return n.value=s.error.format(),!1;const I=s.error.issues.filter(U=>O.has(U.path.join(".")));return I.length?(n.value=new A.ZodError(I).format(),!1):(n.value=void 0,!0)}return n.value=void 0,c.value=B.valid,i.value=u(s.data),!0},h=()=>{n.value=void 0,c.value=void 0,v=void 0},V=()=>{i.value=u(),h(),c.value=B.reset},d=async()=>g.value||!await p()?!1:(c.value=B.submitting,!0),{ignoreUpdates:S,stop:w}=Q.watchIgnorable(i,()=>{c.value=B.updated},{deep:!0,eventFilter:Q.throttleFilter((r==null?void 0:r.updateThrottle)??500)}),E=e.readonly(n),R=e.readonly(c),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 i.value=u(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(i.value)))return;i.value=typeof(I==null?void 0:I.clone)=="function"?I.clone():JSON.parse(JSON.stringify(I))}},{deep:!0}),e.watch(c,async s=>{var I,U,L,K,T,H;if(s===B.invalid){const l=e.toRaw(n.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(i.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(i.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(i.value);O("reset",l),(T=r==null?void 0:r.onReset)==null||T.call(r,l);return}if(s===B.updated){if((n.value||r!=null&&r.continuousValidation||x.continuousValidation)&&await p(void 0,v),!i.value||!x.modelValue||JSON.stringify(i.value)!==JSON.stringify(x.modelValue)){const l=e.toRaw(i.value);O("update:modelValue",l),(H=r==null?void 0:r.onUpdate)==null||H.call(r,l)}c.value===B.updated&&(c.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(o,{clear:h,errors:E,formData:i,ignoreUpdates:S,invalid:f,readonly:g,reset:V,status:R,stopUpdatesWatch:w,submit:d,validate:p,wrappers:a}),{clear:h,errors:E,formData:i,ignoreUpdates:S,invalid:f,isReadonly:g,reset:V,status:R,stopUpdatesWatch:w,submit:d,validate:p,wrappers:a}},render(){const x=()=>{var O,s;return((s=(O=this.$slots)==null?void 0:O.default)==null?void 0:s.call(O,{clear:h,errors:E,formData:i,ignoreUpdates:S,invalid:f,readonly:g,reset:V,status:R,stopUpdatesWatch:w,submit:d,validate:p,wrappers:a}))??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:h,errors:n,formData:i,ignoreUpdates:S,invalid:f,readonly:g,reset:V,status:c,wrappers:a,stopUpdatesWatch:w,submit:d,validate:p,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 M(t){return typeof t>"u"}const ee=/^[0-9]+$/,re=["__proto__","prototype","constructor"];function $(t,o,r){const m=F(r)?r:void 0;if(!Y(t)||!z(o))return m;const a=j(o);if(a.length!==0){for(const n of a){if(n==="*")continue;const c=function(f){return f.map(i=>M(i)||X(i)?i:q(i)?c(i):i[n])};if(q(t)&&!ee.test(n)?t=c(t):t=t[n],M(t)||X(t))break}return M(t)?m:t}}function J(t,o,r){if(!Y(t)||!z(o))return;const m=j(o);if(m.length===0)return;const a=m.length;for(let n=0;n<a;n++){const c=m[n];if(n===a-1){t[c]=r;return}if(c==="*"&&q(t)){const f=m.slice(n+1).join(".");for(const i of t)J(i,f,r);return}M(t[c])&&(t[c]={}),t=t[c]}}function j(t){const o=t.split(/[.]|(?:\[(\d|\*)\])/).filter(r=>!!r);return o.some(r=>re.indexOf(r)!==-1)?[]:o}function te(t,o,r,m){return e.defineComponent({name:"VvFormField",props:{type:{type:String,validator:a=>Object.values(b).includes(a),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(a,{slots:n,emit:c}){const{props:f,name:i}=e.toRefs(a),g=e.useId(),v=e.inject(o,void 0);v&&v.fields.value.set(g,a.name);const u=e.inject(t),p=e.computed({get(){if(u!=null&&u.formData)return $(new Object(u.formData.value),String(a.name))},set(s){u!=null&&u.formData&&(J(new Object(u.formData.value),String(a.name),s),c("update:modelValue",{newValue:p.value,formData:u==null?void 0:u.formData}))}});e.onMounted(()=>{p.value===void 0&&a.defaultValue!==void 0&&(p.value=a.defaultValue)}),e.onBeforeUnmount(()=>{v&&v.fields.value.delete(g)});const h=e.computed(()=>{if(u!=null&&u.errors.value)return $(u.errors.value,String(a.name))}),V=e.computed(()=>{var s;return(s=h.value)==null?void 0:s._errors}),d=e.computed(()=>h.value!==void 0),S=e.watch(d,()=>{if(d.value){c("invalid",h.value),v&&v.errors.value.set(String(a.name),h.value);return}c("valid",p.value),v&&v.errors.value.delete(a.name)}),w=e.watch(()=>u==null?void 0:u.formData,()=>{c("update:formData",u==null?void 0:u.formData)},{deep:!0});e.onBeforeUnmount(()=>{S(),w()});const E=s=>{s instanceof InputEvent&&(s=s.target.value),p.value=s},R=e.computed(()=>{let s=f.value;return typeof s=="function"&&(s=s(u==null?void 0:u.formData)),Object.keys(s).reduce((I,U)=>(I[U]=e.unref(s[U]),I),{})}),G=e.computed(()=>u!=null&&u.readonly.value?!0:R.value.readonly??a.readonly),x=e.computed(()=>({...R.value,name:R.value.name??a.name,invalid:d.value,valid:a.showValid?!!(!d.value&&p.value):void 0,type:(s=>{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(s))return s})(a.type),invalidLabel:V.value,modelValue:p.value,readonly:G.value,"onUpdate:modelValue":E}));return e.provide(r,{name:e.readonly(i),errors:e.readonly(h)}),{component:e.computed(()=>{if(a.type===b.custom)return{render(){var s;return((s=n.default)==null?void 0:s.call(n,{errors:h.value,formData:u==null?void 0:u.formData.value,formErrors:u==null?void 0:u.errors.value,invalid:d.value,invalidLabel:V.value,modelValue:p.value,onUpdate:E,readonly:G.value,submit:u==null?void 0:u.submit,validate:u==null?void 0:u.validate}))??n.default}};if(!((m==null?void 0:m.lazyLoad)??a.lazyLoad)){let s;switch(a.type){case b.select:s=e.resolveComponent("VvSelect");break;case b.checkbox:s=e.resolveComponent("VvCheckbox");break;case b.radio:s=e.resolveComponent("VvRadio");break;case b.textarea:s=e.resolveComponent("VvTextarea");break;case b.radioGroup:s=e.resolveComponent("VvRadioGroup");break;case b.checkboxGroup:s=e.resolveComponent("VvCheckboxGroup");break;case b.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(a.type)),a.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:d}},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,o,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:a,emit:n}){const{props:c,names:f,defaultValues:i}=e.toRefs(m),g=e.useId(),v=e.computed(()=>Array.isArray(f.value)?f.value:Object.values(f.value)),u=e.computed(()=>Array.isArray(f.value)?f.value:Object.keys(f.value)),p=e.computed(()=>Array.isArray(f.value)?f.value.reduce((l,y)=>(l[String(y)]=y,l),{}):f.value),h=e.computed(()=>Object.keys(p.value).reduce((l,y)=>(l[String(p.value[y])]=y,l),{})),V=e.inject(o,void 0);V&&v.value.forEach(l=>{V.fields.value.set(`${g}-${l}`,l)});const d=e.inject(t),S=e.computed({get(){return d!=null&&d.formData?u.value.reduce((l,y)=>(l[y]=$(new Object(d.formData.value),p.value[y]),l),{}):{}},set(l){d!=null&&d.formData&&(u.value.forEach(y=>{J(new Object(d.formData.value),p.value[y],l==null?void 0:l[y])}),n("update:modelValue",{newValue:S.value,formData:d==null?void 0:d.formData}))}});e.onMounted(()=>{i.value&&v.value.forEach(l=>{var y,k;((y=i.value)==null?void 0:y[l])!==void 0&&S.value[l]===void 0&&(S.value={...S.value,[l]:(k=i.value)==null?void 0:k[l]})})}),e.onBeforeUnmount(()=>{V&&v.value.forEach(l=>{V.fields.value.delete(`${g}-${l}`)})});const w=e.computed(()=>{if(!(d!=null&&d.errors.value))return;const l=v.value.reduce((y,k)=>{if(!d.errors.value)return y;const Z=$(d.errors.value,String(k));return Z===void 0||(y[String(k)]=Z),y},{});if(Object.keys(l).length!==0)return l}),E=e.computed(()=>{if(!w.value)return;const l=Object.keys(w.value).reduce((y,k)=>{var Z;return(Z=w.value)!=null&&Z[k]&&(y[h.value[k]]=w.value[k]._errors),y},{});if(Object.keys(l).length!==0)return l}),R=e.computed(()=>w.value!==void 0),G=e.computed(()=>u.value.reduce((l,y)=>{var k;return l[y]=!!((k=w.value)!=null&&k[h.value[y]]),l},{})),x=e.watch(R,()=>{if(R.value){n("invalid",w.value),V&&v.value.forEach(l=>{var y,k;if(!((y=w.value)!=null&&y[l])){V.errors.value.delete(l);return}V.errors.value.set(l,(k=w.value)==null?void 0:k[l])});return}n("valid",S.value),V&&v.value.forEach(l=>{V.errors.value.delete(l)})}),O=e.watch(()=>d==null?void 0:d.formData,()=>{n("update:formData",d==null?void 0:d.formData)},{deep:!0});e.onBeforeUnmount(()=>{x(),O()});const s=l=>{S.value=l},I=(l,y)=>{y instanceof InputEvent&&(y=y.target.value),u.value.includes(l)&&(S.value={...S.value,[l]:y})},U=e.computed(()=>{let l=c.value;return typeof l=="function"&&(l=l(d==null?void 0:d.formData)),Object.keys(l).reduce((y,k)=>(y[k]=e.unref(l[k]),y),{})}),L=e.computed(()=>d!=null&&d.readonly.value?!0:U.value.readonly??m.readonly),K=e.computed(()=>u.value.reduce((l,y)=>(l[`onUpdate:${y}`]=k=>{I(y,k)},l),{"onUpdate:modelValue":s})),T=e.computed(()=>({...K.value,...U.value,names:U.value.name??v.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(f),errors:e.readonly(w)}),{component:e.computed(()=>({render(){var l;return((l=a.default)==null?void 0:l.call(a,{errors:w.value,formData:d==null?void 0:d.formData.value,formErrors:d==null?void 0:d.errors.value,invalid:R.value,invalids:G.value,invalidLabels:E.value,modelValue:S.value,onUpdate:s,onUpdateField:I,readonly:L.value,submit:d==null?void 0:d.submit,validate:d==null?void 0:d.validate}))??a.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 ae(t,o){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 a=e.inject(t),n=e.inject(o,void 0),c=e.ref(new Map),f=e.ref(new Map),{name:i}=e.toRefs(r);e.provide(o,{name:e.readonly(i),errors:f,fields:c}),e.watch(c,(u,p)=>{n!=null&&n.fields&&p.entries().forEach(([h])=>{u.has(h)||n==null||n.fields.value.delete(h)}),n!=null&&n.fields&&u.entries().forEach(([h,V])=>{n!=null&&n.fields.value.has(h)||n==null||n.fields.value.set(h,V)})},{deep:!0}),e.watch(f,(u,p)=>{n!=null&&n.errors&&(Array.from(p.keys()).forEach(h=>{n.errors.value.delete(h)}),Array.from(u.keys()).forEach(h=>{const V=u.get(h);V&&n.errors.value.set(h,V)}))},{deep:!0});const g=e.computed(()=>a!=null&&a.invalid.value?f.value.size>0:!1);e.watch(g,()=>{g.value?m("invalid"):m("valid")}),e.onMounted(()=>{const u=e.getCurrentInstance();if(!u||!(a!=null&&a.wrappers)||!i.value){console.warn("[@volverjs/form-vue]: Invalid wrapper registration state");return}if(a.wrappers.has(i.value)){console.warn(`[@volverjs/form-vue]: wrapper name "${i.value}" is already used`);return}a.wrappers.set(i.value,u)}),e.onBeforeUnmount(()=>{a!=null&&a.wrappers&&i.value&&a.wrappers.delete(i.value)});const v=()=>(a==null?void 0:a.validate(void 0,new Set(c.value.values())))??Promise.resolve(!0);return{clear:a==null?void 0:a.clear,errors:a==null?void 0:a.errors,fields:c,fieldsErrors:f,formData:a==null?void 0:a.formData,invalid:g,reset:a==null?void 0:a.reset,submit:a==null?void 0:a.submit,validate:a==null?void 0:a.validate,validateWrapper:v}},render(){const r=()=>{var m,a;return(a=(m=this.$slots).default)==null?void 0:a.call(m,{clear:this.clear,errors:this.errors,fieldsErrors:this.fieldsErrors,formData:this.formData,invalid:this.invalid,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,o){const r=e.defineComponent({name:"VvFormTemplate",props:{schema:{type:[Array,Function],required:!0},scope:{type:Object,default:()=>({})}},slots:Object,setup(m,{slots:a}){const n=e.inject(t);if(n!=null&&n.formData)return()=>{var g;const c=typeof m.schema=="function"?m.schema(n,m.scope):m.schema;let f;const i=c.reduce((v,u)=>{const p=typeof u=="function"?u(n,m.scope):u,{vvIs:h,vvName:V,vvSlots:d,vvChildren:S,vvIf:w,vvElseIf:E,vvType:R,vvDefaultValue:G,vvShowValid:x,vvContent:O,...s}=p;if(w!==void 0){if(typeof w=="string"?f=!!$(new Object(n.formData.value),w):typeof w=="function"?f=e.unref(w(n)):f=e.unref(w),!f)return v}else if(E!==void 0&&f!==void 0){if(f||(typeof E=="string"?f=!!$(new Object(n.formData.value),E):typeof E=="function"?f=e.unref(E(n)):f=e.unref(E),!f))return v}else f=void 0;let I;return S&&(typeof h=="string"?I=e.h(r,{schema:S}):I={default:U=>e.h(r,{schema:S,scope:U})}),V?(v.push(e.h(o,{name:V,is:h,type:R,defaultValue:G,showValid:x,props:s},d??I??O)),v):h?(v.push(e.h(h,s,d??I??O)),v):(I&&("default"in I?v.push(I.default(m.scope)):v.push(I)),v)},[]);return i.push((g=a==null?void 0:a.default)==null?void 0:g.call(a,{errors:n==null?void 0:n.errors.value,formData:n==null?void 0:n.formData.value,invalid:n==null?void 0:n.invalid.value,status:n==null?void 0:n.status.value,submit:n==null?void 0:n.submit,validate:n==null?void 0:n.validate,clear:n==null?void 0:n.clear,reset:n==null?void 0:n.reset})),i}}});return r}function N(t,o={}){const r=Symbol("formInjectionKey"),m=Symbol("formWrapperInjectionKey"),a=Symbol("formFieldInjectionKey"),n=Symbol("formFieldsGroupInjectionKey"),c=ae(r,m),f=te(r,m,a,o),i=ne(r,m,n),g=le(r,f),v=new Map,{clear:u,errors:p,formData:h,ignoreUpdates:V,invalid:d,readonly:S,reset:w,status:E,stopUpdatesWatch:R,submit:G,validate:x,VvForm:O}=D(t,r,o,g,v);return{clear:u,errors:p,formData:h,formFieldInjectionKey:a,formInjectionKey:r,formWrapperInjectionKey:m,ignoreUpdates:V,invalid:d,readonly:S,reset:w,status:E,stopUpdatesWatch:R,submit:G,validate:x,wrappers:v,VvForm:O,VvFormField:f,VvFormFieldsGroup:i,VvFormTemplate:g,VvFormWrapper:c}}const P=Symbol("pluginInjectionKey");function ue(t){let o={};return t.schema&&(o=N(t.schema,t)),{...o,install(r,{global:m=!1}={}){r.provide(P,t),m&&(r.config.globalProperties.$vvForm=t,o!=null&&o.VvForm&&r.component("VvForm",o.VvForm),o!=null&&o.VvFormWrapper&&r.component("VvFormWrapper",o.VvFormWrapper),o!=null&&o.VvFormField&&r.component("VvFormField",o.VvFormField),o!=null&&o.VvFormFieldsGroup&&r.component("VvFormFieldsGroup",o.VvFormFieldsGroup),o!=null&&o.VvFormTemplate&&r.component("VvFormTemplate",o.VvFormTemplate))}}}const _=new Map;function se(t,o={}){if(o.scope&&_.has(o.scope))return _.get(o.scope);if(!e.getCurrentInstance()){const m=N(t,o);return o.scope&&_.set(o.scope,m),m}const r=N(t,{...e.inject(P,{}),...o});return o.scope&&_.set(o.scope,r),r}function oe(t,o={}){return N(t,o)}C.FormFieldType=b,C.createForm=ue,C.defaultObjectBySchema=W,C.formType=oe,C.pluginInjectionKey=P,C.useForm=se,Object.defineProperty(C,Symbol.toStringTag,{value:"Module"})});
|
package/dist/types.d.ts
CHANGED
|
@@ -10,27 +10,31 @@ export type FormFieldComponentOptions = {
|
|
|
10
10
|
lazyLoad?: boolean;
|
|
11
11
|
sideEffects?: (type: `${FormFieldType}`) => Promise<void> | void;
|
|
12
12
|
};
|
|
13
|
-
export type FormComponentOptions<Schema> = {
|
|
13
|
+
export type FormComponentOptions<Schema, Type> = {
|
|
14
14
|
updateThrottle?: number;
|
|
15
15
|
continuousValidation?: boolean;
|
|
16
16
|
readonly?: boolean;
|
|
17
|
-
template?: Schema extends FormSchema ? FormTemplate<Schema> : never;
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
17
|
+
template?: Schema extends FormSchema ? FormTemplate<Schema, Type> : never;
|
|
18
|
+
class?: Schema extends FormSchema ? new (data?: Partial<z.infer<Schema>>) => Type : never;
|
|
19
|
+
onUpdate?: Schema extends FormSchema ? (data?: undefined extends Type ? Partial<z.infer<Schema>> : Type) => void : never;
|
|
20
|
+
onSubmit?: Schema extends FormSchema ? (data?: undefined extends Type ? Partial<z.infer<Schema>> : Type) => void : never;
|
|
21
|
+
onReset?: Schema extends FormSchema ? (data?: undefined extends Type ? Partial<z.infer<Schema>> : Type) => void : never;
|
|
21
22
|
onInvalid?: Schema extends FormSchema ? (error?: z.inferFormattedError<Schema>) => void : never;
|
|
22
|
-
onValid?: Schema extends FormSchema ? (data?: z.infer<Schema
|
|
23
|
+
onValid?: Schema extends FormSchema ? (data?: undefined extends Type ? Partial<z.infer<Schema>> : Type) => void : never;
|
|
23
24
|
};
|
|
24
|
-
export type FormComposableOptions<Schema> = FormFieldComponentOptions & FormComponentOptions<Schema
|
|
25
|
-
|
|
25
|
+
export type FormComposableOptions<Schema, Type> = FormFieldComponentOptions & FormComponentOptions<Schema, Type> & {
|
|
26
|
+
scope?: string;
|
|
27
|
+
};
|
|
28
|
+
type FormPluginOptionsSchema<T = Partial<z.infer<FormSchema>>> = {
|
|
26
29
|
schema?: FormSchema;
|
|
30
|
+
factory?: (data?: Partial<z.infer<FormSchema>>) => T;
|
|
27
31
|
};
|
|
28
|
-
export type FormPluginOptions = FormPluginOptionsSchema & FormComposableOptions<FormPluginOptionsSchema['schema']>;
|
|
29
|
-
export type InjectedFormData<Schema extends FormSchema> = {
|
|
30
|
-
formData: Ref<Partial<z.infer<Schema>> | undefined>;
|
|
32
|
+
export type FormPluginOptions = FormPluginOptionsSchema & FormComposableOptions<FormPluginOptionsSchema['schema'], FormPluginOptionsSchema['factory']>;
|
|
33
|
+
export type InjectedFormData<Schema extends FormSchema, Type> = {
|
|
34
|
+
formData: Ref<(undefined extends Type ? Partial<z.infer<Schema>> : Type) | undefined>;
|
|
31
35
|
errors: Readonly<Ref<DeepReadonly<z.inferFormattedError<Schema>> | undefined>>;
|
|
32
36
|
submit: () => Promise<boolean>;
|
|
33
|
-
validate: (formData?: Partial<z.infer<Schema
|
|
37
|
+
validate: (formData?: undefined extends Type ? Partial<z.infer<Schema>> : Type, fields?: Set<string>) => Promise<boolean>;
|
|
34
38
|
clear: () => void;
|
|
35
39
|
reset: () => void;
|
|
36
40
|
ignoreUpdates: IgnoredUpdater;
|
|
@@ -38,10 +42,11 @@ export type InjectedFormData<Schema extends FormSchema> = {
|
|
|
38
42
|
status: Readonly<Ref<FormStatus | undefined>>;
|
|
39
43
|
invalid: Readonly<Ref<boolean>>;
|
|
40
44
|
readonly: Ref<boolean>;
|
|
45
|
+
wrappers: Map<string, Component>;
|
|
41
46
|
};
|
|
42
47
|
export type InjectedFormWrapperData<Schema extends FormSchema> = {
|
|
43
48
|
name: Ref<string>;
|
|
44
|
-
fields: Ref<
|
|
49
|
+
fields: Ref<Map<string, string>>;
|
|
45
50
|
errors: Ref<Map<string, z.inferFormattedError<Schema>>>;
|
|
46
51
|
};
|
|
47
52
|
export type InjectedFormFieldData<Schema extends FormSchema> = {
|
|
@@ -62,21 +67,21 @@ export type Path<T> = T extends readonly (infer V)[] ? IsTuple<T> extends true ?
|
|
|
62
67
|
[K in keyof T]-?: PathConcat<K & string, T[K]>;
|
|
63
68
|
}[keyof T];
|
|
64
69
|
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 `${number}` ? T extends readonly (infer V)[] ? PathValue<V, R & Path<V>> : never : never : TPath extends keyof T ? T[TPath] : TPath extends `${number}` ? T extends readonly (infer V)[] ? V : never : never : never;
|
|
65
|
-
export type AnyBoolean<Schema extends FormSchema> = boolean | Ref<boolean> | ((data?: InjectedFormData<Schema>) => boolean | Ref<boolean>);
|
|
66
|
-
export type SimpleFormTemplateItem<Schema extends FormSchema> = Record<string, any> & {
|
|
70
|
+
export type AnyBoolean<Schema extends FormSchema, Type> = boolean | Ref<boolean> | ((data?: InjectedFormData<Schema, Type>) => boolean | Ref<boolean>);
|
|
71
|
+
export type SimpleFormTemplateItem<Schema extends FormSchema, Type> = Record<string, any> & {
|
|
67
72
|
vvIs?: string | Component;
|
|
68
73
|
vvName?: Path<z.infer<Schema>>;
|
|
69
74
|
vvSlots?: Record<string, any>;
|
|
70
|
-
vvChildren?: Array<SimpleFormTemplateItem<Schema> | ((data?: InjectedFormData<Schema>, scope?: Record<string, unknown>) => SimpleFormTemplateItem<Schema>)> | ((data?: InjectedFormData<Schema>, scope?: Record<string, unknown>) => Array<SimpleFormTemplateItem<Schema> | ((data?: InjectedFormData<Schema>, scope?: Record<string, unknown>) => SimpleFormTemplateItem<Schema>)>);
|
|
71
|
-
vvIf?: AnyBoolean<Schema> | Path<z.infer<Schema>>;
|
|
72
|
-
vvElseIf?: AnyBoolean<Schema> | Path<z.infer<Schema>>;
|
|
75
|
+
vvChildren?: Array<SimpleFormTemplateItem<Schema, Type> | ((data?: InjectedFormData<Schema, Type>, scope?: Record<string, unknown>) => SimpleFormTemplateItem<Schema, Type>)> | ((data?: InjectedFormData<Schema, Type>, scope?: Record<string, unknown>) => Array<SimpleFormTemplateItem<Schema, Type> | ((data?: InjectedFormData<Schema, Type>, scope?: Record<string, unknown>) => SimpleFormTemplateItem<Schema, Type>)>);
|
|
76
|
+
vvIf?: AnyBoolean<Schema, Type> | Path<z.infer<Schema>>;
|
|
77
|
+
vvElseIf?: AnyBoolean<Schema, Type> | Path<z.infer<Schema>>;
|
|
73
78
|
vvType?: `${FormFieldType}`;
|
|
74
79
|
vvShowValid?: boolean;
|
|
75
80
|
vvContent?: string;
|
|
76
81
|
vvDefaultValue?: any;
|
|
77
82
|
};
|
|
78
|
-
export type FormTemplateItem<Schema extends FormSchema> = SimpleFormTemplateItem<Schema> | ((data?: InjectedFormData<Schema>, scope?: Record<string, unknown>) => SimpleFormTemplateItem<Schema>);
|
|
79
|
-
export type FormTemplate<Schema extends FormSchema> = FormTemplateItem<Schema>[] | ((data?: InjectedFormData<Schema>, scope?: Record<string, unknown>) => FormTemplateItem<Schema>[]);
|
|
83
|
+
export type FormTemplateItem<Schema extends FormSchema, Type> = SimpleFormTemplateItem<Schema, Type> | ((data?: InjectedFormData<Schema, Type>, scope?: Record<string, unknown>) => SimpleFormTemplateItem<Schema, Type>);
|
|
84
|
+
export type FormTemplate<Schema extends FormSchema, Type> = FormTemplateItem<Schema, Type>[] | ((data?: InjectedFormData<Schema, Type>, scope?: Record<string, unknown>) => FormTemplateItem<Schema, Type>[]);
|
|
80
85
|
export type RenderFunctionOutput = VNode<RendererNode, RendererElement, {
|
|
81
86
|
[key: string]: any;
|
|
82
87
|
}>;
|
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.
|
|
4
|
+
"version": "1.0.0-beta.26",
|
|
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.
|
|
60
|
+
"@antfu/eslint-config": "^3.9.2",
|
|
61
61
|
"@nabla/vite-plugin-eslint": "^2.0.4",
|
|
62
|
-
"@playwright/experimental-ct-vue": "1.
|
|
62
|
+
"@playwright/experimental-ct-vue": "1.49.0",
|
|
63
63
|
"@testing-library/vue": "^8.1.0",
|
|
64
|
-
"@vitejs/plugin-vue": "^5.
|
|
64
|
+
"@vitejs/plugin-vue": "^5.2.0",
|
|
65
65
|
"@volverjs/style": "0.1.15",
|
|
66
|
-
"@vue/compiler-sfc": "^3.5.
|
|
67
|
-
"@vue/runtime-core": "^3.5.
|
|
66
|
+
"@vue/compiler-sfc": "^3.5.13",
|
|
67
|
+
"@vue/runtime-core": "^3.5.13",
|
|
68
68
|
"@vue/test-utils": "^2.4.6",
|
|
69
69
|
"copy": "^0.3.2",
|
|
70
|
-
"eslint": "^9.
|
|
71
|
-
"happy-dom": "^15.11.
|
|
72
|
-
"typescript": "^5.
|
|
70
|
+
"eslint": "^9.15.0",
|
|
71
|
+
"happy-dom": "^15.11.6",
|
|
72
|
+
"typescript": "^5.7.2",
|
|
73
73
|
"vite": "^5.4.11",
|
|
74
74
|
"vite-plugin-dts": "^4.3.0",
|
|
75
75
|
"vite-plugin-externalize-deps": "^0.8.0",
|
|
76
|
-
"vitest": "^2.1.
|
|
76
|
+
"vitest": "^2.1.5"
|
|
77
77
|
},
|
|
78
78
|
"scripts": {
|
|
79
79
|
"lint": "eslint .",
|
package/src/VvForm.ts
CHANGED
|
@@ -29,14 +29,25 @@ import type {
|
|
|
29
29
|
import { FormStatus } from './enums'
|
|
30
30
|
import { defaultObjectBySchema } from './utils'
|
|
31
31
|
|
|
32
|
-
export function defineForm<Schema extends FormSchema>(schema: Schema, provideKey: InjectionKey<InjectedFormData<Schema>>, options
|
|
32
|
+
export function defineForm<Schema extends FormSchema, Type, FormTemplateComponent extends Component, FormWrapperComponent extends Component>(schema: Schema, provideKey: InjectionKey<InjectedFormData<Schema, Type>>, options: FormComponentOptions<Schema, Type>, VvFormTemplate: FormTemplateComponent, wrappers: Map<string, FormWrapperComponent>) {
|
|
33
33
|
const errors = ref<z.inferFormattedError<Schema> | undefined>()
|
|
34
34
|
const status = ref<FormStatus | undefined>()
|
|
35
35
|
const invalid = computed(() => status.value === FormStatus.invalid)
|
|
36
|
-
const formData = ref<Partial<z.infer<Schema
|
|
36
|
+
const formData = ref<undefined extends Type ? Partial<z.infer<Schema>> : Type>()
|
|
37
37
|
const readonly = ref<boolean>(false)
|
|
38
38
|
let validationFields: Set<string> | undefined
|
|
39
39
|
|
|
40
|
+
const formDataAdapter = (data?: z.infer<Schema>): undefined extends Type ? Partial<z.infer<Schema>> : Type => {
|
|
41
|
+
const toReturn = defaultObjectBySchema(schema, data)
|
|
42
|
+
if (options?.class) {
|
|
43
|
+
const ClassObject = options.class
|
|
44
|
+
// @ts-expect-error - this is a class
|
|
45
|
+
return new ClassObject(toReturn)
|
|
46
|
+
}
|
|
47
|
+
// @ts-expect-error - this is a plain object
|
|
48
|
+
return toReturn
|
|
49
|
+
}
|
|
50
|
+
|
|
40
51
|
const validate = async (value = formData.value, fields?: Set<string>) => {
|
|
41
52
|
validationFields = fields
|
|
42
53
|
if (readonly.value) {
|
|
@@ -46,8 +57,7 @@ export function defineForm<Schema extends FormSchema>(schema: Schema, provideKey
|
|
|
46
57
|
if (!parseResult.success) {
|
|
47
58
|
status.value = FormStatus.invalid
|
|
48
59
|
if (!fields) {
|
|
49
|
-
errors.value
|
|
50
|
-
= parseResult.error.format() as z.inferFormattedError<Schema>
|
|
60
|
+
errors.value = parseResult.error.format() as z.inferFormattedError<Schema>
|
|
51
61
|
return false
|
|
52
62
|
}
|
|
53
63
|
const fieldsIssues = parseResult.error.issues.filter(item => fields.has(item.path.join('.')))
|
|
@@ -60,7 +70,7 @@ export function defineForm<Schema extends FormSchema>(schema: Schema, provideKey
|
|
|
60
70
|
}
|
|
61
71
|
errors.value = undefined
|
|
62
72
|
status.value = FormStatus.valid
|
|
63
|
-
formData.value = parseResult.data
|
|
73
|
+
formData.value = formDataAdapter(parseResult.data)
|
|
64
74
|
return true
|
|
65
75
|
}
|
|
66
76
|
|
|
@@ -71,7 +81,7 @@ export function defineForm<Schema extends FormSchema>(schema: Schema, provideKey
|
|
|
71
81
|
}
|
|
72
82
|
|
|
73
83
|
const reset = () => {
|
|
74
|
-
formData.value =
|
|
84
|
+
formData.value = formDataAdapter()
|
|
75
85
|
clear()
|
|
76
86
|
status.value = FormStatus.reset
|
|
77
87
|
}
|
|
@@ -121,7 +131,7 @@ export function defineForm<Schema extends FormSchema>(schema: Schema, provideKey
|
|
|
121
131
|
default: 'form',
|
|
122
132
|
},
|
|
123
133
|
template: {
|
|
124
|
-
type: [Array, Function] as PropType<FormTemplate<Schema>>,
|
|
134
|
+
type: [Array, Function] as PropType<FormTemplate<Schema, Type>>,
|
|
125
135
|
default: undefined,
|
|
126
136
|
},
|
|
127
137
|
},
|
|
@@ -159,13 +169,11 @@ export function defineForm<Schema extends FormSchema>(schema: Schema, provideKey
|
|
|
159
169
|
validate: typeof validate
|
|
160
170
|
clear: typeof clear
|
|
161
171
|
reset: typeof reset
|
|
172
|
+
wrappers: typeof wrappers
|
|
162
173
|
}
|
|
163
174
|
}>,
|
|
164
175
|
setup(props, { emit }) {
|
|
165
|
-
formData.value =
|
|
166
|
-
schema,
|
|
167
|
-
toRaw(props.modelValue),
|
|
168
|
-
)
|
|
176
|
+
formData.value = formDataAdapter(toRaw(props.modelValue))
|
|
169
177
|
|
|
170
178
|
watch(
|
|
171
179
|
() => props.modelValue,
|
|
@@ -182,10 +190,9 @@ export function defineForm<Schema extends FormSchema>(schema: Schema, provideKey
|
|
|
182
190
|
return
|
|
183
191
|
}
|
|
184
192
|
|
|
185
|
-
formData.value
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
: JSON.parse(JSON.stringify(original))
|
|
193
|
+
formData.value = typeof original?.clone === 'function'
|
|
194
|
+
? original.clone()
|
|
195
|
+
: JSON.parse(JSON.stringify(original))
|
|
189
196
|
}
|
|
190
197
|
},
|
|
191
198
|
{ deep: true },
|
|
@@ -272,6 +279,7 @@ export function defineForm<Schema extends FormSchema>(schema: Schema, provideKey
|
|
|
272
279
|
stopUpdatesWatch,
|
|
273
280
|
submit,
|
|
274
281
|
validate,
|
|
282
|
+
wrappers,
|
|
275
283
|
})
|
|
276
284
|
|
|
277
285
|
return {
|
|
@@ -286,6 +294,7 @@ export function defineForm<Schema extends FormSchema>(schema: Schema, provideKey
|
|
|
286
294
|
stopUpdatesWatch,
|
|
287
295
|
submit,
|
|
288
296
|
validate,
|
|
297
|
+
wrappers,
|
|
289
298
|
}
|
|
290
299
|
},
|
|
291
300
|
render() {
|
|
@@ -302,6 +311,7 @@ export function defineForm<Schema extends FormSchema>(schema: Schema, provideKey
|
|
|
302
311
|
stopUpdatesWatch,
|
|
303
312
|
submit,
|
|
304
313
|
validate,
|
|
314
|
+
wrappers,
|
|
305
315
|
}) ?? this.$slots.default
|
|
306
316
|
return h(
|
|
307
317
|
this.tag,
|
|
@@ -336,6 +346,7 @@ export function defineForm<Schema extends FormSchema>(schema: Schema, provideKey
|
|
|
336
346
|
readonly,
|
|
337
347
|
reset,
|
|
338
348
|
status,
|
|
349
|
+
wrappers,
|
|
339
350
|
stopUpdatesWatch,
|
|
340
351
|
submit,
|
|
341
352
|
validate,
|
package/src/VvFormField.ts
CHANGED
|
@@ -20,8 +20,9 @@ import {
|
|
|
20
20
|
toRefs,
|
|
21
21
|
unref,
|
|
22
22
|
watch,
|
|
23
|
+
useId,
|
|
23
24
|
} from 'vue'
|
|
24
|
-
import type { inferFormattedError,
|
|
25
|
+
import type { inferFormattedError, z } from 'zod'
|
|
25
26
|
import { FormFieldType } from './enums'
|
|
26
27
|
import type {
|
|
27
28
|
FormFieldComponentOptions,
|
|
@@ -32,7 +33,7 @@ import type {
|
|
|
32
33
|
Path,
|
|
33
34
|
} from './types'
|
|
34
35
|
|
|
35
|
-
export function defineFormField<Schema extends FormSchema>(formProvideKey: InjectionKey<InjectedFormData<Schema>>, wrapperProvideKey: InjectionKey<InjectedFormWrapperData<Schema>>, formFieldInjectionKey: InjectionKey<InjectedFormFieldData<Schema>>, options?: FormFieldComponentOptions) {
|
|
36
|
+
export function defineFormField<Schema extends FormSchema, Type>(formProvideKey: InjectionKey<InjectedFormData<Schema, Type>>, wrapperProvideKey: InjectionKey<InjectedFormWrapperData<Schema>>, formFieldInjectionKey: InjectionKey<InjectedFormFieldData<Schema>>, options?: FormFieldComponentOptions) {
|
|
36
37
|
return defineComponent({
|
|
37
38
|
name: 'VvFormField',
|
|
38
39
|
props: {
|
|
@@ -101,24 +102,25 @@ export function defineFormField<Schema extends FormSchema>(formProvideKey: Injec
|
|
|
101
102
|
[key: string]: any
|
|
102
103
|
default: {
|
|
103
104
|
errors: z.inferFormattedError<Schema>
|
|
104
|
-
formData?: Partial<
|
|
105
|
+
formData?: undefined extends Type ? Partial<z.infer<Schema>> : Type
|
|
105
106
|
formErrors?: DeepReadonly<inferFormattedError<Schema, string>>
|
|
106
107
|
invalid: boolean
|
|
107
108
|
invalidLabel?: string[]
|
|
108
109
|
modelValue: any
|
|
109
110
|
onUpdate: (value: unknown) => void
|
|
110
111
|
readonly: boolean
|
|
111
|
-
submit?: InjectedFormData<Schema>['submit']
|
|
112
|
-
validate?: InjectedFormData<Schema>['validate']
|
|
112
|
+
submit?: InjectedFormData<Schema, Type>['submit']
|
|
113
|
+
validate?: InjectedFormData<Schema, Type>['validate']
|
|
113
114
|
}
|
|
114
115
|
}>,
|
|
115
116
|
setup(props, { slots, emit }) {
|
|
116
117
|
const { props: fieldProps, name: fieldName } = toRefs(props)
|
|
118
|
+
const fieldId = useId()
|
|
117
119
|
|
|
118
120
|
// inject data from parent form wrapper
|
|
119
121
|
const injectedWrapperData = inject(wrapperProvideKey, undefined)
|
|
120
122
|
if (injectedWrapperData) {
|
|
121
|
-
injectedWrapperData.fields.value.
|
|
123
|
+
injectedWrapperData.fields.value.set(fieldId, props.name as string)
|
|
122
124
|
}
|
|
123
125
|
|
|
124
126
|
// inject data from parent form
|
|
@@ -158,6 +160,11 @@ export function defineFormField<Schema extends FormSchema>(formProvideKey: Injec
|
|
|
158
160
|
modelValue.value = props.defaultValue
|
|
159
161
|
}
|
|
160
162
|
})
|
|
163
|
+
onBeforeUnmount(() => {
|
|
164
|
+
if (injectedWrapperData) {
|
|
165
|
+
injectedWrapperData.fields.value.delete(fieldId)
|
|
166
|
+
}
|
|
167
|
+
})
|
|
161
168
|
|
|
162
169
|
const errors = computed(() => {
|
|
163
170
|
if (!injectedFormData?.errors.value) {
|
|
@@ -319,7 +326,7 @@ export function defineFormField<Schema extends FormSchema>(formProvideKey: Injec
|
|
|
319
326
|
return component
|
|
320
327
|
}
|
|
321
328
|
console.warn(
|
|
322
|
-
`[form-vue
|
|
329
|
+
`[@volverjs/form-vue]: ${component} not found, the component will be loaded asynchronously. To avoid this warning, please set "lazyLoad" option.`,
|
|
323
330
|
)
|
|
324
331
|
}
|
|
325
332
|
return defineAsyncComponent(async () => {
|
package/src/VvFormFieldsGroup.ts
CHANGED
|
@@ -16,9 +16,10 @@ import {
|
|
|
16
16
|
readonly,
|
|
17
17
|
toRefs,
|
|
18
18
|
unref,
|
|
19
|
+
useId,
|
|
19
20
|
watch,
|
|
20
21
|
} from 'vue'
|
|
21
|
-
import type { inferFormattedError,
|
|
22
|
+
import type { inferFormattedError, z } from 'zod'
|
|
22
23
|
import type {
|
|
23
24
|
FormSchema,
|
|
24
25
|
InjectedFormData,
|
|
@@ -27,7 +28,7 @@ import type {
|
|
|
27
28
|
Path,
|
|
28
29
|
} from './types'
|
|
29
30
|
|
|
30
|
-
export function defineFormFieldsGroup<Schema extends FormSchema>(formProvideKey: InjectionKey<InjectedFormData<Schema>>, wrapperProvideKey: InjectionKey<InjectedFormWrapperData<Schema>>, formFieldsGroupInjectionKey: InjectionKey<InjectedFormFieldsGroupData<Schema>>) {
|
|
31
|
+
export function defineFormFieldsGroup<Schema extends FormSchema, Type>(formProvideKey: InjectionKey<InjectedFormData<Schema, Type>>, wrapperProvideKey: InjectionKey<InjectedFormWrapperData<Schema>>, formFieldsGroupInjectionKey: InjectionKey<InjectedFormFieldsGroupData<Schema>>) {
|
|
31
32
|
return defineComponent({
|
|
32
33
|
name: 'VvFormFieldsGroup',
|
|
33
34
|
props: {
|
|
@@ -86,7 +87,7 @@ export function defineFormFieldsGroup<Schema extends FormSchema>(formProvideKey:
|
|
|
86
87
|
[key: string]: any
|
|
87
88
|
default: {
|
|
88
89
|
errors?: Record<Path<z.infer<Schema>>, z.inferFormattedError<Schema>>
|
|
89
|
-
formData?: Partial<
|
|
90
|
+
formData?: undefined extends Type ? Partial<z.infer<Schema>> : Type
|
|
90
91
|
formErrors?: DeepReadonly<inferFormattedError<Schema, string>>
|
|
91
92
|
invalid: boolean
|
|
92
93
|
invalids: Record<string, boolean>
|
|
@@ -95,12 +96,13 @@ export function defineFormFieldsGroup<Schema extends FormSchema>(formProvideKey:
|
|
|
95
96
|
onUpdate: (value: Record<string, any>) => void
|
|
96
97
|
onUpdateField: (name: string, value: any) => void
|
|
97
98
|
readonly: boolean
|
|
98
|
-
submit?: InjectedFormData<Schema>['submit']
|
|
99
|
-
validate?: InjectedFormData<Schema>['validate']
|
|
99
|
+
submit?: InjectedFormData<Schema, Type>['submit']
|
|
100
|
+
validate?: InjectedFormData<Schema, Type>['validate']
|
|
100
101
|
}
|
|
101
102
|
}>,
|
|
102
103
|
setup(props, { slots, emit }) {
|
|
103
104
|
const { props: fieldProps, names: fieldsNames, defaultValues } = toRefs(props)
|
|
105
|
+
const fieldGroupId = useId()
|
|
104
106
|
const names = computed<Path<z.infer<Schema>>[]>(() => {
|
|
105
107
|
if (Array.isArray(fieldsNames.value)) {
|
|
106
108
|
return fieldsNames.value
|
|
@@ -136,7 +138,7 @@ export function defineFormFieldsGroup<Schema extends FormSchema>(formProvideKey:
|
|
|
136
138
|
const injectedWrapperData = inject(wrapperProvideKey, undefined)
|
|
137
139
|
if (injectedWrapperData) {
|
|
138
140
|
names.value.forEach((name) => {
|
|
139
|
-
injectedWrapperData.fields.value.
|
|
141
|
+
injectedWrapperData.fields.value.set(`${fieldGroupId}-${name}`, name as string)
|
|
140
142
|
})
|
|
141
143
|
}
|
|
142
144
|
|
|
@@ -192,6 +194,15 @@ export function defineFormFieldsGroup<Schema extends FormSchema>(formProvideKey:
|
|
|
192
194
|
})
|
|
193
195
|
}
|
|
194
196
|
})
|
|
197
|
+
onBeforeUnmount(() => {
|
|
198
|
+
if (injectedWrapperData) {
|
|
199
|
+
names.value.forEach((name) => {
|
|
200
|
+
injectedWrapperData.fields.value.delete(
|
|
201
|
+
`${fieldGroupId}-${name}`,
|
|
202
|
+
)
|
|
203
|
+
})
|
|
204
|
+
}
|
|
205
|
+
})
|
|
195
206
|
|
|
196
207
|
const errors = computed(() => {
|
|
197
208
|
if (!injectedFormData?.errors.value) {
|
package/src/VvFormTemplate.ts
CHANGED
|
@@ -12,15 +12,15 @@ import {
|
|
|
12
12
|
unref,
|
|
13
13
|
} from 'vue'
|
|
14
14
|
import type { FormSchema, InjectedFormData, FormTemplate, RenderFunctionOutput } from './types'
|
|
15
|
-
import type {
|
|
15
|
+
import type { z, inferFormattedError } from 'zod'
|
|
16
16
|
import type { FormStatus } from './enums'
|
|
17
17
|
|
|
18
|
-
export function defineFormTemplate<Schema extends FormSchema>(formProvideKey: InjectionKey<InjectedFormData<Schema>>, VvFormField: Component) {
|
|
18
|
+
export function defineFormTemplate<Schema extends FormSchema, Type>(formProvideKey: InjectionKey<InjectedFormData<Schema, Type>>, VvFormField: Component) {
|
|
19
19
|
const VvFormTemplate = defineComponent({
|
|
20
20
|
name: 'VvFormTemplate',
|
|
21
21
|
props: {
|
|
22
22
|
schema: {
|
|
23
|
-
type: [Array, Function] as PropType<FormTemplate<Schema>>,
|
|
23
|
+
type: [Array, Function] as PropType<FormTemplate<Schema, Type>>,
|
|
24
24
|
required: true,
|
|
25
25
|
},
|
|
26
26
|
scope: {
|
|
@@ -31,13 +31,13 @@ export function defineFormTemplate<Schema extends FormSchema>(formProvideKey: In
|
|
|
31
31
|
slots: Object as SlotsType<{
|
|
32
32
|
default: {
|
|
33
33
|
errors?: DeepReadonly<inferFormattedError<Schema, string>>
|
|
34
|
-
formData?: Partial<
|
|
34
|
+
formData?: undefined extends Type ? Partial<z.infer<Schema>> : Type
|
|
35
35
|
invalid: boolean
|
|
36
36
|
status?: FormStatus
|
|
37
|
-
submit?: InjectedFormData<Schema>['submit']
|
|
38
|
-
validate?: InjectedFormData<Schema>['validate']
|
|
39
|
-
clear?: InjectedFormData<Schema>['clear']
|
|
40
|
-
reset?: InjectedFormData<Schema>['reset']
|
|
37
|
+
submit?: InjectedFormData<Schema, Type>['submit']
|
|
38
|
+
validate?: InjectedFormData<Schema, Type>['validate']
|
|
39
|
+
clear?: InjectedFormData<Schema, Type>['clear']
|
|
40
|
+
reset?: InjectedFormData<Schema, Type>['reset']
|
|
41
41
|
}
|
|
42
42
|
}>,
|
|
43
43
|
setup(templateProps, { slots: templateSlots }) {
|
|
@@ -45,21 +45,19 @@ export function defineFormTemplate<Schema extends FormSchema>(formProvideKey: In
|
|
|
45
45
|
if (!injectedFormData?.formData)
|
|
46
46
|
return
|
|
47
47
|
return () => {
|
|
48
|
-
const normalizedSchema
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
: templateProps.schema
|
|
48
|
+
const normalizedSchema = typeof templateProps.schema === 'function'
|
|
49
|
+
? templateProps.schema(
|
|
50
|
+
injectedFormData,
|
|
51
|
+
templateProps.scope,
|
|
52
|
+
)
|
|
53
|
+
: templateProps.schema
|
|
55
54
|
let lastIf: boolean | undefined
|
|
56
55
|
const toReturn = normalizedSchema.reduce<
|
|
57
56
|
(VNode | VNode[] | undefined)[]
|
|
58
57
|
>((acc, field) => {
|
|
59
|
-
const normalizedField
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
: field
|
|
58
|
+
const normalizedField = typeof field === 'function'
|
|
59
|
+
? field(injectedFormData, templateProps.scope)
|
|
60
|
+
: field
|
|
63
61
|
const {
|
|
64
62
|
vvIs,
|
|
65
63
|
vvName,
|