@progress/kendo-vue-form 8.2.0-develop.1 → 8.3.0-develop.1

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/Field.js CHANGED
@@ -5,4 +5,4 @@
5
5
  * Licensed under commercial license. See LICENSE.md in the package root for more information
6
6
  *-------------------------------------------------------------------------------------------
7
7
  */
8
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("vue"),o=require("@progress/kendo-vue-common"),l=r.defineComponent({name:"KendoField",props:{component:[String,Number,Boolean,Object],validator:[Function,Array],name:String},created(){return this.kendoForm?this.kendoForm.registerField(this.$props.name,this.$props.validator):void 0},inject:{kendoForm:{default:null}},emits:["change"],methods:{handleOnChange(e){const t=e&&(e.value!==void 0?e.value:e.target?e.target.value:e.target);this.kendoForm.onChange(this.$props.name,{value:t}),this.$emit("change",e)},onNativeComponentChange(e){this.kendoForm.onChange(this.$props.name,{value:e.target.value})},handleOnBlur(){this.kendoForm.onBlur(this.$props.name)},handleOnFocus(){this.kendoForm.onFocus(this.$props.name)}},render(){const e=o.getDefaultSlots(this),{name:t,component:n,id:s}=this.$props;if(!this.kendoForm)return null;const i=this.kendoForm.values[t];if(typeof n=="string"&&(n==="input"||n==="textarea"))return r.h(n,{onBlur:this.handleOnBlur,onFocus:this.handleOnFocus,name:t,value:i||""});if(n){const a=o.templateRendering.call(this,n,o.getListeners.call(this));return o.getTemplate.call(this,{h:r.h,template:a,additionalProps:{value:i,validationMessage:this.kendoForm.errors[t],touched:this.kendoForm.touchedByField[t],modified:this.kendoForm.modifiedByField[t],visited:this.kendoForm.visitedByField[t],valid:!(this.kendoForm.errors[t]&&this.kendoForm.touchedByField[t]),name:t,id:s,...this.$attrs},additionalListeners:{change:this.handleOnChange,blur:this.handleOnBlur,focus:this.handleOnFocus},defaultSlots:e})}}});exports.Field=l;
8
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("vue"),o=require("@progress/kendo-vue-common"),d=r.defineComponent({name:"KendoField",props:{component:[String,Number,Boolean,Object],validator:[Function,Array],name:String,colSpan:[Number,Array]},created(){return this.kendoForm?this.kendoForm.registerField(this.$props.name,this.$props.validator):void 0},inject:{kendoForm:{default:null}},emits:["change"],methods:{handleOnChange(e){const n=e&&(e.value!==void 0?e.value:e.target?e.target.value:e.target);this.kendoForm.onChange(this.$props.name,{value:n}),this.$emit("change",e)},onNativeComponentChange(e){this.kendoForm.onChange(this.$props.name,{value:e.target.value})},handleOnBlur(){this.kendoForm.onBlur(this.$props.name)},handleOnFocus(){this.kendoForm.onFocus(this.$props.name)}},render(){const e=o.getDefaultSlots(this),{name:n,component:t,id:a,colSpan:s}=this.$props;if(!this.kendoForm)return null;const i=this.kendoForm.values[n];if(typeof t=="string"&&(t==="input"||t==="textarea"))return r.h(t,{onBlur:this.handleOnBlur,onFocus:this.handleOnFocus,name:n,value:i||""});if(t){const l=o.templateRendering.call(this,t,o.getListeners.call(this));return o.getTemplate.call(this,{h:r.h,template:l,additionalProps:{value:i,validationMessage:this.kendoForm.errors[n],touched:this.kendoForm.touchedByField[n],modified:this.kendoForm.modifiedByField[n],visited:this.kendoForm.visitedByField[n],valid:!(this.kendoForm.errors[n]&&this.kendoForm.touchedByField[n]),name:n,id:a,...s!==void 0?{colSpan:s}:{},...this.$attrs},additionalListeners:{change:this.handleOnChange,blur:this.handleOnBlur,focus:this.handleOnFocus},defaultSlots:e})}}});exports.Field=d;
package/Field.mjs CHANGED
@@ -5,14 +5,15 @@
5
5
  * Licensed under commercial license. See LICENSE.md in the package root for more information
6
6
  *-------------------------------------------------------------------------------------------
7
7
  */
8
- import { defineComponent as a, h as i } from "vue";
9
- import { getDefaultSlots as l, templateRendering as d, getListeners as h, getTemplate as u } from "@progress/kendo-vue-common";
10
- const F = /* @__PURE__ */ a({
8
+ import { defineComponent as l, h as r } from "vue";
9
+ import { getDefaultSlots as d, templateRendering as h, getListeners as u, getTemplate as m } from "@progress/kendo-vue-common";
10
+ const F = /* @__PURE__ */ l({
11
11
  name: "KendoField",
12
12
  props: {
13
13
  component: [String, Number, Boolean, Object],
14
14
  validator: [Function, Array],
15
- name: String
15
+ name: String,
16
+ colSpan: [Number, Array]
16
17
  },
17
18
  created() {
18
19
  return this.kendoForm ? this.kendoForm.registerField(this.$props.name, this.$props.validator) : void 0;
@@ -43,25 +44,26 @@ const F = /* @__PURE__ */ a({
43
44
  }
44
45
  },
45
46
  render() {
46
- const e = l(this), {
47
+ const e = d(this), {
47
48
  name: t,
48
49
  component: n,
49
- id: r
50
+ id: a,
51
+ colSpan: i
50
52
  } = this.$props;
51
53
  if (!this.kendoForm)
52
54
  return null;
53
55
  const o = this.kendoForm.values[t];
54
56
  if (typeof n == "string" && (n === "input" || n === "textarea"))
55
- return i(n, {
57
+ return r(n, {
56
58
  onBlur: this.handleOnBlur,
57
59
  onFocus: this.handleOnFocus,
58
60
  name: t,
59
61
  value: o || ""
60
62
  });
61
63
  if (n) {
62
- const s = d.call(this, n, h.call(this));
63
- return u.call(this, {
64
- h: i,
64
+ const s = h.call(this, n, u.call(this));
65
+ return m.call(this, {
66
+ h: r,
65
67
  template: s,
66
68
  additionalProps: {
67
69
  value: o,
@@ -78,7 +80,10 @@ const F = /* @__PURE__ */ a({
78
80
  // displayed in another language (not localizable)
79
81
  valid: !(this.kendoForm.errors[t] && this.kendoForm.touchedByField[t]),
80
82
  name: t,
81
- id: r,
83
+ id: a,
84
+ ...i !== void 0 ? {
85
+ colSpan: i
86
+ } : {},
82
87
  ...this.$attrs
83
88
  },
84
89
  additionalListeners: {
package/FieldWrapper.d.ts CHANGED
@@ -6,6 +6,7 @@
6
6
  *-------------------------------------------------------------------------------------------
7
7
  */
8
8
  import { PropType } from 'vue';
9
+ import { ResponsiveFormBreakPoint } from './interfaces/ResponsiveFormBreakPoint';
9
10
  /**
10
11
  * Represents the props of the Kendo U for Vue FieldWrapper component.
11
12
  */
@@ -14,6 +15,10 @@ export interface FieldWrapperProps {
14
15
  * If set to `true` enable the horizontal layout of the form editors.
15
16
  */
16
17
  horizontal?: boolean;
18
+ /**
19
+ * Defines the colspan for the form field element related to the parent Form component columns. Can be a number or an array of responsive breakpoints.
20
+ */
21
+ colSpan?: number | ResponsiveFormBreakPoint[];
17
22
  /**
18
23
  * @hidden
19
24
  */
@@ -25,13 +30,20 @@ export interface FieldWrapperProps {
25
30
  declare const FieldWrapper: import('vue').DefineComponent<import('vue').ExtractPropTypes<{
26
31
  dir: PropType<any>;
27
32
  horizontal: PropType<boolean>;
28
- }>, {}, {}, {
33
+ colSpan: PropType<number | ResponsiveFormBreakPoint[]>;
34
+ }>, {}, {
35
+ colSpanClass: string;
36
+ }, {
29
37
  fieldClassName(): {
30
38
  'k-form-field': boolean;
31
39
  'k-rtl': boolean;
32
40
  };
33
- }, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<import('vue').ExtractPropTypes<{
41
+ }, {
42
+ _updateColSpanClass(): void;
43
+ _setupColSpanObserver(): void;
44
+ }, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<import('vue').ExtractPropTypes<{
34
45
  dir: PropType<any>;
35
46
  horizontal: PropType<boolean>;
47
+ colSpan: PropType<number | ResponsiveFormBreakPoint[]>;
36
48
  }>> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, true, {}, any>;
37
49
  export { FieldWrapper };
package/FieldWrapper.js CHANGED
@@ -5,4 +5,4 @@
5
5
  * Licensed under commercial license. See LICENSE.md in the package root for more information
6
6
  *-------------------------------------------------------------------------------------------
7
7
  */
8
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("vue"),a=require("./package-metadata.js"),t=require("@progress/kendo-vue-common"),o=e.defineComponent({name:"KendoFieldWrapper",props:{dir:String,horizontal:Boolean},created(){t.validatePackage(a.packageMetadata)},computed:{fieldClassName(){return{"k-form-field":!0,"k-rtl":this.$props.dir==="rtl"}}},render(){const r=t.getDefaultSlots(this);return e.createVNode("div",{class:this.fieldClassName},[r])}});exports.FieldWrapper=o;
8
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("vue"),l=require("./package-metadata.js"),i=require("@progress/kendo-vue-common"),r=require("./utils.js"),o=t.defineComponent({name:"KendoFieldWrapper",props:{dir:String,horizontal:Boolean,colSpan:[Number,Array]},data(){return{colSpanClass:""}},created(){i.validatePackage(l.packageMetadata),this._resizeObserver=null,this._formElement=null},mounted(){var e;this.$props.colSpan!==void 0&&(this._formElement=((e=this.$el)==null?void 0:e.closest("form"))||null,this._setupColSpanObserver())},beforeUnmount(){this._resizeObserver&&this._formElement&&(this._resizeObserver.unobserve(this._formElement),this._resizeObserver.disconnect(),this._resizeObserver=null)},watch:{colSpan(e){var s;e!==void 0?(this._formElement=((s=this.$el)==null?void 0:s.closest("form"))||null,this._setupColSpanObserver()):(this._resizeObserver&&this._formElement&&(this._resizeObserver.unobserve(this._formElement),this._resizeObserver.disconnect(),this._resizeObserver=null),this.colSpanClass="")}},computed:{fieldClassName(){return{"k-form-field":!0,"k-rtl":this.$props.dir==="rtl",...this.colSpanClass?{[this.colSpanClass]:!0}:{}}}},methods:{_updateColSpanClass(){const e=typeof window!="undefined"?window.innerWidth:0,s=this._formElement?r.getElementInnerWidth(this._formElement):e,n=r.calculateColSpan(this.$props.colSpan,s);this.colSpanClass=r.generateColSpanClass(n)},_setupColSpanObserver(){this._resizeObserver&&(this._resizeObserver.disconnect(),this._resizeObserver=null),this._updateColSpanClass(),this._formElement&&typeof window!="undefined"&&"ResizeObserver"in window&&(this._resizeObserver=new ResizeObserver(()=>this._updateColSpanClass()),this._resizeObserver.observe(this._formElement))}},render(){const e=i.getDefaultSlots(this);return t.createVNode("div",{class:this.fieldClassName},[e])}});exports.FieldWrapper=o;
package/FieldWrapper.mjs CHANGED
@@ -5,33 +5,65 @@
5
5
  * Licensed under commercial license. See LICENSE.md in the package root for more information
6
6
  *-------------------------------------------------------------------------------------------
7
7
  */
8
- import { defineComponent as r, createVNode as t } from "vue";
9
- import { packageMetadata as a } from "./package-metadata.mjs";
10
- import { getDefaultSlots as o, validatePackage as i } from "@progress/kendo-vue-common";
11
- const s = /* @__PURE__ */ r({
8
+ import { defineComponent as t, createVNode as i } from "vue";
9
+ import { packageMetadata as n } from "./package-metadata.mjs";
10
+ import { getDefaultSlots as l, validatePackage as o } from "@progress/kendo-vue-common";
11
+ import { getElementInnerWidth as a, calculateColSpan as h, generateColSpanClass as p } from "./utils.mjs";
12
+ const u = /* @__PURE__ */ t({
12
13
  name: "KendoFieldWrapper",
13
14
  props: {
14
15
  dir: String,
15
- horizontal: Boolean
16
+ horizontal: Boolean,
17
+ colSpan: [Number, Array]
18
+ },
19
+ data() {
20
+ return {
21
+ colSpanClass: ""
22
+ };
16
23
  },
17
24
  created() {
18
- i(a);
25
+ o(n), this._resizeObserver = null, this._formElement = null;
26
+ },
27
+ mounted() {
28
+ var e;
29
+ this.$props.colSpan !== void 0 && (this._formElement = ((e = this.$el) == null ? void 0 : e.closest("form")) || null, this._setupColSpanObserver());
30
+ },
31
+ beforeUnmount() {
32
+ this._resizeObserver && this._formElement && (this._resizeObserver.unobserve(this._formElement), this._resizeObserver.disconnect(), this._resizeObserver = null);
33
+ },
34
+ watch: {
35
+ colSpan(e) {
36
+ var s;
37
+ e !== void 0 ? (this._formElement = ((s = this.$el) == null ? void 0 : s.closest("form")) || null, this._setupColSpanObserver()) : (this._resizeObserver && this._formElement && (this._resizeObserver.unobserve(this._formElement), this._resizeObserver.disconnect(), this._resizeObserver = null), this.colSpanClass = "");
38
+ }
19
39
  },
20
40
  computed: {
21
41
  fieldClassName() {
22
42
  return {
23
43
  "k-form-field": !0,
24
- "k-rtl": this.$props.dir === "rtl"
44
+ "k-rtl": this.$props.dir === "rtl",
45
+ ...this.colSpanClass ? {
46
+ [this.colSpanClass]: !0
47
+ } : {}
25
48
  };
26
49
  }
27
50
  },
51
+ methods: {
52
+ _updateColSpanClass() {
53
+ const e = typeof window != "undefined" ? window.innerWidth : 0, s = this._formElement ? a(this._formElement) : e, r = h(this.$props.colSpan, s);
54
+ this.colSpanClass = p(r);
55
+ },
56
+ _setupColSpanObserver() {
57
+ this._resizeObserver && (this._resizeObserver.disconnect(), this._resizeObserver = null), this._updateColSpanClass(), this._formElement && typeof window != "undefined" && "ResizeObserver" in window && (this._resizeObserver = new ResizeObserver(() => this._updateColSpanClass()), this._resizeObserver.observe(this._formElement));
58
+ }
59
+ },
28
60
  render() {
29
- const e = o(this);
30
- return t("div", {
61
+ const e = l(this);
62
+ return i("div", {
31
63
  class: this.fieldClassName
32
64
  }, [e]);
33
65
  }
34
66
  });
35
67
  export {
36
- s as FieldWrapper
68
+ u as FieldWrapper
37
69
  };
package/Form.d.ts CHANGED
@@ -6,18 +6,23 @@
6
6
  *-------------------------------------------------------------------------------------------
7
7
  */
8
8
  import { FieldValidatorType } from './interfaces/FieldValidator';
9
+ import { FormRenderProps } from './interfaces/FormRenderProps';
9
10
  import { KeyValue } from './interfaces/KeyValue';
10
11
  import { PropType } from 'vue';
11
12
  /**
12
13
  * @hidden
13
14
  */
14
15
  declare const Form: import('vue').DefineComponent<import('vue').ExtractPropTypes<{
15
- renderForm: PropType<(props: import('./index').FormRenderProps) => any>;
16
+ renderForm: PropType<(props: FormRenderProps) => any>;
16
17
  initialValues: PropType<{
17
18
  [name: string]: any;
18
19
  }>;
19
20
  validator: PropType<import('./index').FormValidatorType>;
20
21
  ignoreModified: PropType<boolean>;
22
+ errors: PropType<{
23
+ [name: string]: string;
24
+ }>;
25
+ onChange: PropType<(fieldName: string, value: any, valueGetter: (name: string) => any) => void>;
21
26
  }>, {}, {
22
27
  validatorsByField: {};
23
28
  fields: any[];
@@ -79,7 +84,7 @@ declare const Form: import('vue').DefineComponent<import('vue').ExtractPropTypes
79
84
  * > Use `onChange` only if you cannot achieve the desired behavior
80
85
  * through the Field component by FormRenderProps.
81
86
  */
82
- onChange(name: string, options: {
87
+ handleFieldChange(name: string, options: {
83
88
  value: any;
84
89
  }): void;
85
90
  onFocus(name: string): void;
@@ -122,12 +127,16 @@ declare const Form: import('vue').DefineComponent<import('vue').ExtractPropTypes
122
127
  submitclick: any;
123
128
  submit: any;
124
129
  }, string, import('vue').PublicProps, Readonly<import('vue').ExtractPropTypes<{
125
- renderForm: PropType<(props: import('./index').FormRenderProps) => any>;
130
+ renderForm: PropType<(props: FormRenderProps) => any>;
126
131
  initialValues: PropType<{
127
132
  [name: string]: any;
128
133
  }>;
129
134
  validator: PropType<import('./index').FormValidatorType>;
130
135
  ignoreModified: PropType<boolean>;
136
+ errors: PropType<{
137
+ [name: string]: string;
138
+ }>;
139
+ onChange: PropType<(fieldName: string, value: any, valueGetter: (name: string) => any) => void>;
131
140
  }>> & Readonly<{
132
141
  onSubmit?: (...args: any[] | unknown[]) => any;
133
142
  onSubmitclick?: (...args: any[] | unknown[]) => any;
package/Form.js CHANGED
@@ -5,4 +5,4 @@
5
5
  * Licensed under commercial license. See LICENSE.md in the package root for more information
6
6
  *-------------------------------------------------------------------------------------------
7
7
  */
8
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const d=require("@progress/kendo-vue-common"),u=require("./package-metadata.js"),h=require("vue"),a=0,n=h.defineComponent({name:"KendoForm",inheritAttrs:!1,props:{renderForm:[Object,Function],initialValues:Object,validator:Function,ignoreModified:Boolean},emits:{submitclick:null,submit:null},created(){this._accumulatorTimeout=void 0,d.validatePackage(u.packageMetadata),this.form.values=d.clone(this.$props.initialValues)},mounted(){this.form.errors=this.getErrors(),this.form.allowSubmit=this.allowSubmit(),this.form.valid=this.isValid()},unmounted(){this.onDestroy()},data(){return{validatorsByField:{},fields:[],unmounted:!1,form:{id:this.id,errors:{},values:{},modifiedByField:{},touchedByField:{},visitedByField:{},valid:!1,modified:!1,touched:!1,visited:!1,submitted:!1,valueGetter:this.valueGetter,allowSubmit:!1,validate:this.validate,onChange:this.onChange,onSubmit:this.onSubmit,onFormReset:this.resetForm,registerField:this.onFieldRegister,onFocus:this.onFocus,onBlur:this.onBlur,onUnshift:this.onUnshift,onPush:this.onPush,onInsert:this.onInsert,onPop:this.onPop,onRemove:this.onRemove,onReplace:this.onReplace,onMove:this.onMove}}},provide(){return{kendoForm:this.$data.form}},watch:{"form.values"(){this.form.errors=this.getErrors(),this.form.allowSubmit=this.allowSubmit(),this.form.valid=this.isValid()},"form.touchedByField"(i){this.form.touched=this.isFormTouched(i,this.fields),this.form.allowSubmit=this.allowSubmit()},"form.modifiedByField"(i){this.form.modified=this.isFormModified(i,this.fields),this.form.allowSubmit=this.allowSubmit()},"form.visitedByField"(i){this.form.visited=this.isFormVisited(i,this.fields)}},methods:{isValid(){return this.isFormValid(this.form.errors)},formErrors(){if(this.$props.validator)return this.$props.validator(this.form.values,this.valueGetter)},getErrors(){const i={},t=this.validatorsByField;return Object.keys(this.fields).forEach(s=>{if(i[s]="",t[s]){const r=[];t[s].forEach(o=>{Array.isArray(o)?r.push(...o):r.push(o)}),r.find(o=>{if(o){const l=o(this.valueGetter(s),this.valueGetter,{name:s});if(l)return i[s]=l,!0}return!1})}}),this.formErrors()&&d.cloneObject(this.formErrors(),i),i},accumulatedForceUpdate(){this._accumulatorTimeout&&clearTimeout(this._accumulatorTimeout),d.canUseDOM&&(this._accumulatorTimeout=window.setTimeout(()=>{this._accumulatorTimeout=void 0},a))},resetForm(){this.form.values=d.clone(this.$props.initialValues),this.id=d.guid(),this.form.touchedByField={},this.form.visitedByField={},this.form.modifiedByField={},this.form.submitted=!1},onReset(){this.resetForm()},addField(i){this.fields[i]=!0},validate(i){const t={},e=i||this.fields;Object.keys(e).forEach(s=>{t[s]=!0}),this.form.touchedByField={...t}},onSubmit(i){const t={},e=this.fields;i&&(typeof i.preventDefault=="function"&&i.preventDefault(),typeof i.stopPropagation=="function"&&i.stopPropagation()),Object.keys(e).forEach(l=>{t[l]=!0}),this.form.visitedByField={...t},this.form.touchedByField={...t};const s=this.form.values,r=this.isValid(),o=this.isFormModified(this.form.modifiedByField,e);this.$emit("submitclick",{values:s,isValid:r,isModified:o,event:i}),r&&(this.$props.ignoreModified||o)&&(this.form.submitted=!0,this.$emit("submit",s,i))},onChange(i,t){const{value:e}=t;this.addField(i),this.form.modifiedByField[i]||(this.form.modifiedByField={...this.form.modifiedByField,[i]:!0}),this.valueSetter(i,e)},onFocus(i){this.form.visitedByField[i]||(this.form.visitedByField={...this.form.visitedByField,[i]:!0})},onBlur(i){this.form.touchedByField[i]||(this.onFocus(i),this.form.touchedByField={...this.form.touchedByField,[i]:!0})},onFieldRegister(i,t){this.addField(i);const e=this.validatorsByField[i]||[],s=e.length;return this.validatorsByField={...this.validatorsByField,[i]:[...e,t]},this.accumulatedForceUpdate(),()=>{if(this._unmounted)return;const r=[...this.validatorsByField[i]||[]],o=!!r[s];r[s]=void 0,this.validatorsByField={...this.validatorsByField,[i]:r},o&&this.accumulatedForceUpdate()}},isFormValid(i){return!Object.keys(i).some(t=>!!i[t])},isFormModified(i,t){return Object.keys(t).some(e=>i[e])},isFormHasNotTouched(i,t){return Object.keys(t).some(e=>!i[e])},isFormTouched(i,t){return Object.keys(t).some(e=>i[e])},isFormVisited(i,t){return Object.keys(t).some(e=>i[e])},formHasNotTouched(){return this.isFormHasNotTouched(this.form.touchedByField,this.fields)},allowSubmit(){return this.formHasNotTouched()&&!this.isValid()||this.isValid()&&(this.$props.ignoreModified||this.isFormModified(this.form.modifiedByField,this.fields))},valueGetter(i){return this.form.values[i]},valueSetter(i,t){this.form.values={...this.form.values,[i]:t}},onArrayAction(i){this.addField(i),this.form.modifiedByField[i]||(this.form.modifiedByField={...this.form.modifiedByField,[i]:!0}),this.onBlur(i,!0)},onInsert(i,t){this.onArrayAction(i);const e=[...this.valueGetter(i)||[]];e.splice(t.index,0,t.value),this.valueSetter(i,e)},onUnshift(i,t){this.onInsert(i,{value:t.value,index:0})},onPush(i,t){this.onArrayAction(i);const e=[...this.valueGetter(i)||[],t.value];this.valueSetter(i,e)},onPop(i){this.onArrayAction(i);const t=[...this.valueGetter(i)||[]],e=t.pop();return this.valueSetter(i,t),e},onRemove(i,t){this.onArrayAction(i);const e=[...this.valueGetter(i)||[]],s=e.splice(t.index,1);return this.valueSetter(i,e),s},onReplace(i,t){this.onArrayAction(i);const e=[...this.valueGetter(i)||[]];e.splice(t.index,1,t.value),this.valueSetter(i,e)},onMove(i,t){this.onArrayAction(i);const e=[...this.valueGetter(i)||[]],s=e[t.prevIndex];e.splice(t.prevIndex,1),e.splice(t.nextIndex,0,s),this.valueSetter(i,e)},onDestroy(){this.unmounted=!0,this._accumulatorTimeout&&clearTimeout(this._accumulatorTimeout)}},render(){return d.getDefaultSlots(this)}});exports.Form=n;
8
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const d=require("@progress/kendo-vue-common"),h=require("./package-metadata.js"),u=require("vue"),a=0,n=u.defineComponent({name:"KendoForm",inheritAttrs:!1,props:{renderForm:[Object,Function],initialValues:Object,validator:Function,ignoreModified:Boolean,errors:Object,onChange:Function},emits:{submitclick:null,submit:null},created(){this._accumulatorTimeout=void 0,d.validatePackage(h.packageMetadata),this.form.values=d.clone(this.$props.initialValues)},mounted(){this.form.errors=this.getErrors(),this.form.allowSubmit=this.allowSubmit(),this.form.valid=this.isValid()},unmounted(){this.onDestroy()},data(){return{validatorsByField:{},fields:[],unmounted:!1,form:{id:this.id,errors:{},values:{},modifiedByField:{},touchedByField:{},visitedByField:{},valid:!1,modified:!1,touched:!1,visited:!1,submitted:!1,valueGetter:this.valueGetter,allowSubmit:!1,validate:this.validate,onChange:this.handleFieldChange,onSubmit:this.onSubmit,onFormReset:this.resetForm,registerField:this.onFieldRegister,onFocus:this.onFocus,onBlur:this.onBlur,onUnshift:this.onUnshift,onPush:this.onPush,onInsert:this.onInsert,onPop:this.onPop,onRemove:this.onRemove,onReplace:this.onReplace,onMove:this.onMove}}},provide(){return{kendoForm:this.$data.form}},watch:{"form.values"(){this.form.errors=this.getErrors(),this.form.allowSubmit=this.allowSubmit(),this.form.valid=this.isValid()},"form.touchedByField"(i){this.form.touched=this.isFormTouched(i,this.fields),this.form.allowSubmit=this.allowSubmit()},"form.modifiedByField"(i){this.form.modified=this.isFormModified(i,this.fields),this.form.allowSubmit=this.allowSubmit()},"form.visitedByField"(i){this.form.visited=this.isFormVisited(i,this.fields)},errors(i){this.form.errors=this.getErrors(),this.form.allowSubmit=this.allowSubmit(),this.form.valid=this.isValid()}},methods:{isValid(){return this.isFormValid(this.form.errors)},formErrors(){if(this.$props.validator)return this.$props.validator(this.form.values,this.valueGetter)},getErrors(){const i={},t=this.validatorsByField;return Object.keys(this.fields).forEach(s=>{if(i[s]="",t[s]){const r=[];t[s].forEach(o=>{Array.isArray(o)?r.push(...o):r.push(o)}),r.find(o=>{if(o){const l=o(this.valueGetter(s),this.valueGetter,{name:s});if(l)return i[s]=l,!0}return!1})}}),this.formErrors()&&d.cloneObject(this.formErrors(),i),this.$props.errors&&d.cloneObject(this.$props.errors,i),i},accumulatedForceUpdate(){this._accumulatorTimeout&&clearTimeout(this._accumulatorTimeout),d.canUseDOM&&(this._accumulatorTimeout=window.setTimeout(()=>{this._accumulatorTimeout=void 0},a))},resetForm(){this.form.values=d.clone(this.$props.initialValues),this.id=d.guid(),this.form.touchedByField={},this.form.visitedByField={},this.form.modifiedByField={},this.form.submitted=!1},onReset(){this.resetForm()},addField(i){this.fields[i]=!0},validate(i){const t={},e=i||this.fields;Object.keys(e).forEach(s=>{t[s]=!0}),this.form.touchedByField={...t}},onSubmit(i){const t={},e=this.fields;i&&(typeof i.preventDefault=="function"&&i.preventDefault(),typeof i.stopPropagation=="function"&&i.stopPropagation()),Object.keys(e).forEach(l=>{t[l]=!0}),this.form.visitedByField={...t},this.form.touchedByField={...t};const s=this.form.values,r=this.isValid(),o=this.isFormModified(this.form.modifiedByField,e);this.$emit("submitclick",{values:s,isValid:r,isModified:o,event:i}),r&&(this.$props.ignoreModified||o)&&(this.form.submitted=!0,this.$emit("submit",s,i))},handleFieldChange(i,t){const{value:e}=t;this.addField(i),this.form.modifiedByField[i]||(this.form.modifiedByField={...this.form.modifiedByField,[i]:!0}),this.valueSetter(i,e),this.$props.onChange&&this.$props.onChange(i,e,this.valueGetter)},onFocus(i){this.form.visitedByField[i]||(this.form.visitedByField={...this.form.visitedByField,[i]:!0})},onBlur(i){this.form.touchedByField[i]||(this.onFocus(i),this.form.touchedByField={...this.form.touchedByField,[i]:!0})},onFieldRegister(i,t){this.addField(i);const e=this.validatorsByField[i]||[],s=e.length;return this.validatorsByField={...this.validatorsByField,[i]:[...e,t]},this.accumulatedForceUpdate(),()=>{if(this._unmounted)return;const r=[...this.validatorsByField[i]||[]],o=!!r[s];r[s]=void 0,this.validatorsByField={...this.validatorsByField,[i]:r},o&&this.accumulatedForceUpdate()}},isFormValid(i){return!Object.keys(i).some(t=>!!i[t])},isFormModified(i,t){return Object.keys(t).some(e=>i[e])},isFormHasNotTouched(i,t){return Object.keys(t).some(e=>!i[e])},isFormTouched(i,t){return Object.keys(t).some(e=>i[e])},isFormVisited(i,t){return Object.keys(t).some(e=>i[e])},formHasNotTouched(){return this.isFormHasNotTouched(this.form.touchedByField,this.fields)},allowSubmit(){return this.formHasNotTouched()&&!this.isValid()||this.isValid()&&(this.$props.ignoreModified||this.isFormModified(this.form.modifiedByField,this.fields))},valueGetter(i){return this.form.values[i]},valueSetter(i,t){this.form.values={...this.form.values,[i]:t}},onArrayAction(i){this.addField(i),this.form.modifiedByField[i]||(this.form.modifiedByField={...this.form.modifiedByField,[i]:!0}),this.onBlur(i,!0)},onInsert(i,t){this.onArrayAction(i);const e=[...this.valueGetter(i)||[]];e.splice(t.index,0,t.value),this.valueSetter(i,e)},onUnshift(i,t){this.onInsert(i,{value:t.value,index:0})},onPush(i,t){this.onArrayAction(i);const e=[...this.valueGetter(i)||[],t.value];this.valueSetter(i,e)},onPop(i){this.onArrayAction(i);const t=[...this.valueGetter(i)||[]],e=t.pop();return this.valueSetter(i,t),e},onRemove(i,t){this.onArrayAction(i);const e=[...this.valueGetter(i)||[]],s=e.splice(t.index,1);return this.valueSetter(i,e),s},onReplace(i,t){this.onArrayAction(i);const e=[...this.valueGetter(i)||[]];e.splice(t.index,1,t.value),this.valueSetter(i,e)},onMove(i,t){this.onArrayAction(i);const e=[...this.valueGetter(i)||[]],s=e[t.prevIndex];e.splice(t.prevIndex,1),e.splice(t.nextIndex,0,s),this.valueSetter(i,e)},onDestroy(){this.unmounted=!0,this._accumulatorTimeout&&clearTimeout(this._accumulatorTimeout)}},render(){const i={onSubmit:this.onSubmit,onChange:this.handleFieldChange,onFormreset:this.resetForm,errors:this.form.errors,valid:this.form.valid,touched:this.form.touched,visited:this.form.visited,modified:this.form.modified,submitted:this.form.submitted,allowSubmit:this.form.allowSubmit,valueGetter:this.valueGetter};return this.$props.renderForm?this.$props.renderForm(i):d.getDefaultSlots(this)}});exports.Form=n;
package/Form.mjs CHANGED
@@ -5,7 +5,7 @@
5
5
  * Licensed under commercial license. See LICENSE.md in the package root for more information
6
6
  *-------------------------------------------------------------------------------------------
7
7
  */
8
- import { getDefaultSlots as h, clone as l, guid as u, canUseDOM as a, cloneObject as n, validatePackage as f } from "@progress/kendo-vue-common";
8
+ import { getDefaultSlots as u, clone as l, guid as a, canUseDOM as n, cloneObject as h, validatePackage as f } from "@progress/kendo-vue-common";
9
9
  import { packageMetadata as m } from "./package-metadata.mjs";
10
10
  import { defineComponent as c } from "vue";
11
11
  const F = 0, B = /* @__PURE__ */ c({
@@ -15,7 +15,9 @@ const F = 0, B = /* @__PURE__ */ c({
15
15
  renderForm: [Object, Function],
16
16
  initialValues: Object,
17
17
  validator: Function,
18
- ignoreModified: Boolean
18
+ ignoreModified: Boolean,
19
+ errors: Object,
20
+ onChange: Function
19
21
  },
20
22
  emits: {
21
23
  submitclick: null,
@@ -50,7 +52,7 @@ const F = 0, B = /* @__PURE__ */ c({
50
52
  valueGetter: this.valueGetter,
51
53
  allowSubmit: !1,
52
54
  validate: this.validate,
53
- onChange: this.onChange,
55
+ onChange: this.handleFieldChange,
54
56
  onSubmit: this.onSubmit,
55
57
  onFormReset: this.resetForm,
56
58
  registerField: this.onFieldRegister,
@@ -83,6 +85,9 @@ const F = 0, B = /* @__PURE__ */ c({
83
85
  },
84
86
  "form.visitedByField"(i) {
85
87
  this.form.visited = this.isFormVisited(i, this.fields);
88
+ },
89
+ errors(i) {
90
+ this.form.errors = this.getErrors(), this.form.allowSubmit = this.allowSubmit(), this.form.valid = this.isValid();
86
91
  }
87
92
  },
88
93
  methods: {
@@ -111,13 +116,13 @@ const F = 0, B = /* @__PURE__ */ c({
111
116
  return !1;
112
117
  });
113
118
  }
114
- }), this.formErrors() && n(this.formErrors(), i), i;
119
+ }), this.formErrors() && h(this.formErrors(), i), this.$props.errors && h(this.$props.errors, i), i;
115
120
  },
116
121
  /**
117
122
  * @hidden
118
123
  */
119
124
  accumulatedForceUpdate() {
120
- this._accumulatorTimeout && clearTimeout(this._accumulatorTimeout), a && (this._accumulatorTimeout = window.setTimeout(() => {
125
+ this._accumulatorTimeout && clearTimeout(this._accumulatorTimeout), n && (this._accumulatorTimeout = window.setTimeout(() => {
121
126
  this._accumulatorTimeout = void 0;
122
127
  }, F));
123
128
  },
@@ -125,7 +130,7 @@ const F = 0, B = /* @__PURE__ */ c({
125
130
  * @hidden
126
131
  */
127
132
  resetForm() {
128
- this.form.values = l(this.$props.initialValues), this.id = u(), this.form.touchedByField = {}, this.form.visitedByField = {}, this.form.modifiedByField = {}, this.form.submitted = !1;
133
+ this.form.values = l(this.$props.initialValues), this.id = a(), this.form.touchedByField = {}, this.form.visitedByField = {}, this.form.modifiedByField = {}, this.form.submitted = !1;
129
134
  },
130
135
  /**
131
136
  * Method for resetting the form state outside the form component.
@@ -170,14 +175,14 @@ const F = 0, B = /* @__PURE__ */ c({
170
175
  * > Use `onChange` only if you cannot achieve the desired behavior
171
176
  * through the Field component by FormRenderProps.
172
177
  */
173
- onChange(i, t) {
178
+ handleFieldChange(i, t) {
174
179
  const {
175
180
  value: e
176
181
  } = t;
177
182
  this.addField(i), this.form.modifiedByField[i] || (this.form.modifiedByField = {
178
183
  ...this.form.modifiedByField,
179
184
  [i]: !0
180
- }), this.valueSetter(i, e);
185
+ }), this.valueSetter(i, e), this.$props.onChange && this.$props.onChange(i, e, this.valueGetter);
181
186
  },
182
187
  onFocus(i) {
183
188
  this.form.visitedByField[i] || (this.form.visitedByField = {
@@ -286,7 +291,20 @@ const F = 0, B = /* @__PURE__ */ c({
286
291
  }
287
292
  },
288
293
  render() {
289
- return h(this);
294
+ const i = {
295
+ onSubmit: this.onSubmit,
296
+ onChange: this.handleFieldChange,
297
+ onFormreset: this.resetForm,
298
+ errors: this.form.errors,
299
+ valid: this.form.valid,
300
+ touched: this.form.touched,
301
+ visited: this.form.visited,
302
+ modified: this.form.modified,
303
+ submitted: this.form.submitted,
304
+ allowSubmit: this.form.allowSubmit,
305
+ valueGetter: this.valueGetter
306
+ };
307
+ return this.$props.renderForm ? this.$props.renderForm(i) : u(this);
290
308
  }
291
309
  });
292
310
  export {
package/FormElement.d.ts CHANGED
@@ -6,6 +6,8 @@
6
6
  *-------------------------------------------------------------------------------------------
7
7
  */
8
8
  import { PropType } from 'vue';
9
+ import { ResponsiveFormBreakPoint } from './interfaces/ResponsiveFormBreakPoint';
10
+ import { Gutters } from './interfaces/Gutters';
9
11
  /**
10
12
  * Represents the props of the Kendo U for Vue FormElement component.
11
13
  */
@@ -26,6 +28,16 @@ export interface FormElementProps {
26
28
  * If set to `true` enable the horizontal layout of the form editors.
27
29
  */
28
30
  horizontal?: boolean;
31
+ /**
32
+ * Defines the number of columns in the form. Can be a number or an array of responsive breakpoints.
33
+ */
34
+ cols?: number | ResponsiveFormBreakPoint[];
35
+ /**
36
+ * Defines the gutters for the form layout. You can specify gutters for rows and columns.
37
+ * Accepts a number (treated as px), a CSS string, a `Gutters` object with `cols`/`rows` keys,
38
+ * or an array of responsive breakpoints.
39
+ */
40
+ gutters?: string | number | Gutters | ResponsiveFormBreakPoint[];
29
41
  /**
30
42
  * @hidden
31
43
  */
@@ -38,9 +50,15 @@ declare const FormElement: import('vue').DefineComponent<import('vue').ExtractPr
38
50
  horizontal: PropType<boolean>;
39
51
  size: {
40
52
  type: PropType<"small" | "medium" | "large">;
41
- validator: (value: string) => boolean;
53
+ default: string;
54
+ validator: (value: any) => any;
42
55
  };
43
- }>, {}, {}, {
56
+ cols: PropType<number | ResponsiveFormBreakPoint[]>;
57
+ gutters: PropType<string | number | ResponsiveFormBreakPoint[] | Gutters>;
58
+ }>, {}, {
59
+ columnClass: string;
60
+ gapStyle: string;
61
+ }, {
44
62
  formElementClassName(): {
45
63
  [x: string]: any;
46
64
  'k-form': boolean;
@@ -48,11 +66,18 @@ declare const FormElement: import('vue').DefineComponent<import('vue').ExtractPr
48
66
  };
49
67
  }, {
50
68
  handleSubmit(e: any): void;
69
+ _updateColumnClass(): void;
70
+ _setupColsObserver(): void;
51
71
  }, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<import('vue').ExtractPropTypes<{
52
72
  horizontal: PropType<boolean>;
53
73
  size: {
54
74
  type: PropType<"small" | "medium" | "large">;
55
- validator: (value: string) => boolean;
75
+ default: string;
76
+ validator: (value: any) => any;
56
77
  };
57
- }>> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, true, {}, any>;
78
+ cols: PropType<number | ResponsiveFormBreakPoint[]>;
79
+ gutters: PropType<string | number | ResponsiveFormBreakPoint[] | Gutters>;
80
+ }>> & Readonly<{}>, {
81
+ size: "small" | "medium" | "large";
82
+ }, {}, {}, {}, string, import('vue').ComponentProvideOptions, true, {}, any>;
58
83
  export { FormElement };
package/FormElement.js CHANGED
@@ -5,4 +5,4 @@
5
5
  * Licensed under commercial license. See LICENSE.md in the package root for more information
6
6
  *-------------------------------------------------------------------------------------------
7
7
  */
8
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o=require("vue"),r=require("./package-metadata.js"),t=require("@progress/kendo-vue-common"),n=o.defineComponent({name:"KendoFormElement",props:{horizontal:Boolean,size:{type:String,validator:function(e){return["small","medium","large"].includes(e)}}},created(){t.validatePackage(r.packageMetadata)},inject:{kendoForm:{default:null}},computed:{formElementClassName(){const{size:e}=this.$props;return{"k-form":!0,[`k-form-${t.kendoThemeMaps.sizeMap[e]||e}`]:e,"k-form-horizontal":this.$props.horizontal===!0}}},methods:{handleSubmit(e){this.kendoForm&&this.kendoForm.onSubmit(e)}},render(){const e=t.getDefaultSlots(this);return o.createVNode("form",{class:this.formElementClassName,onSubmit:this.handleSubmit},[e])}});exports.FormElement=n;
8
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o=require("vue"),u=require("./package-metadata.js"),s=require("@progress/kendo-vue-common"),t=require("./utils.js"),h=o.defineComponent({name:"KendoFormElement",props:{horizontal:Boolean,size:{type:String,default:"medium",validator:function(e){return[null,"small","medium","large"].includes(e)}},cols:[Number,Array],gutters:[String,Number,Object,Array]},data(){return{columnClass:"",gapStyle:""}},created(){s.validatePackage(u.packageMetadata),this._resizeObserver=null},inject:{kendoForm:{default:null}},mounted(){var e;this._handlePasteEvent=r=>{var n;const i=(n=r.detail)==null?void 0:n.fieldValues;i&&this.kendoForm&&Object.entries(i).forEach(([l,a])=>{this.kendoForm.onChange(l,{value:a})})},(e=this.$el)==null||e.addEventListener(s.KENDO_PASTE_EVENT_NAME,this._handlePasteEvent),this.$props.cols&&this._setupColsObserver()},beforeUnmount(){var e;this._resizeObserver&&this.$el&&(this._resizeObserver.unobserve(this.$el),this._resizeObserver.disconnect()),(e=this.$el)==null||e.removeEventListener(s.KENDO_PASTE_EVENT_NAME,this._handlePasteEvent)},watch:{cols(e){e?this._setupColsObserver():(this._resizeObserver&&this.$el&&(this._resizeObserver.unobserve(this.$el),this._resizeObserver.disconnect(),this._resizeObserver=null),this.columnClass="")}},computed:{formElementClassName(){const{size:e}=this.$props;return{"k-form":!0,[`k-form-${s.kendoThemeMaps.sizeMap[e]||e}`]:e,"k-form-horizontal":this.$props.horizontal===!0}}},methods:{handleSubmit(e){this.kendoForm&&this.kendoForm.onSubmit(e)},_updateColumnClass(){const e=typeof window!="undefined"?window.innerWidth:0,r=this.$el?t.getElementInnerWidth(this.$el):e,i=t.calculateColumns(this.$props.cols,r);this.columnClass=t.generateColumnClass(i);const n=t.calculateGutters(this.$props.gutters,r);this.gapStyle=t.generateGuttersStyling(n,{rows:"0px",cols:"32px"})},_setupColsObserver(){this._resizeObserver&&(this._resizeObserver.disconnect(),this._resizeObserver=null),this._updateColumnClass(),this.$el&&typeof window!="undefined"&&"ResizeObserver"in window&&(this._resizeObserver=new ResizeObserver(()=>this._updateColumnClass()),this._resizeObserver.observe(this.$el))}},render(){const e=s.getDefaultSlots(this);return o.createVNode("form",{class:this.formElementClassName,onSubmit:this.handleSubmit},[this.$props.cols?o.createVNode("div",{class:`k-form-layout k-d-grid ${this.columnClass}`,style:{gap:this.gapStyle||"0px 32px"}},[e]):e])}});exports.FormElement=h;
package/FormElement.mjs CHANGED
@@ -5,28 +5,59 @@
5
5
  * Licensed under commercial license. See LICENSE.md in the package root for more information
6
6
  *-------------------------------------------------------------------------------------------
7
7
  */
8
- import { defineComponent as t, createVNode as o } from "vue";
9
- import { packageMetadata as r } from "./package-metadata.mjs";
10
- import { getDefaultSlots as m, kendoThemeMaps as n, validatePackage as a } from "@progress/kendo-vue-common";
11
- const d = /* @__PURE__ */ t({
8
+ import { defineComponent as a, createVNode as i } from "vue";
9
+ import { packageMetadata as h } from "./package-metadata.mjs";
10
+ import { getDefaultSlots as m, kendoThemeMaps as u, KENDO_PASTE_EVENT_NAME as o, validatePackage as d } from "@progress/kendo-vue-common";
11
+ import { getElementInnerWidth as c, calculateColumns as p, generateColumnClass as f, calculateGutters as b, generateGuttersStyling as v } from "./utils.mjs";
12
+ const g = /* @__PURE__ */ a({
12
13
  name: "KendoFormElement",
13
14
  props: {
14
15
  horizontal: Boolean,
15
16
  size: {
16
17
  type: String,
18
+ default: "medium",
17
19
  validator: function(e) {
18
- return ["small", "medium", "large"].includes(e);
20
+ return [null, "small", "medium", "large"].includes(e);
19
21
  }
20
- }
22
+ },
23
+ cols: [Number, Array],
24
+ gutters: [String, Number, Object, Array]
25
+ },
26
+ data() {
27
+ return {
28
+ columnClass: "",
29
+ gapStyle: ""
30
+ };
21
31
  },
22
32
  created() {
23
- a(r);
33
+ d(h), this._resizeObserver = null;
24
34
  },
25
35
  inject: {
26
36
  kendoForm: {
27
37
  default: null
28
38
  }
29
39
  },
40
+ mounted() {
41
+ var e;
42
+ this._handlePasteEvent = (s) => {
43
+ var r;
44
+ const t = (r = s.detail) == null ? void 0 : r.fieldValues;
45
+ t && this.kendoForm && Object.entries(t).forEach(([n, l]) => {
46
+ this.kendoForm.onChange(n, {
47
+ value: l
48
+ });
49
+ });
50
+ }, (e = this.$el) == null || e.addEventListener(o, this._handlePasteEvent), this.$props.cols && this._setupColsObserver();
51
+ },
52
+ beforeUnmount() {
53
+ var e;
54
+ this._resizeObserver && this.$el && (this._resizeObserver.unobserve(this.$el), this._resizeObserver.disconnect()), (e = this.$el) == null || e.removeEventListener(o, this._handlePasteEvent);
55
+ },
56
+ watch: {
57
+ cols(e) {
58
+ e ? this._setupColsObserver() : (this._resizeObserver && this.$el && (this._resizeObserver.unobserve(this.$el), this._resizeObserver.disconnect(), this._resizeObserver = null), this.columnClass = "");
59
+ }
60
+ },
30
61
  computed: {
31
62
  formElementClassName() {
32
63
  const {
@@ -34,7 +65,7 @@ const d = /* @__PURE__ */ t({
34
65
  } = this.$props;
35
66
  return {
36
67
  "k-form": !0,
37
- [`k-form-${n.sizeMap[e] || e}`]: e,
68
+ [`k-form-${u.sizeMap[e] || e}`]: e,
38
69
  "k-form-horizontal": this.$props.horizontal === !0
39
70
  };
40
71
  }
@@ -42,16 +73,33 @@ const d = /* @__PURE__ */ t({
42
73
  methods: {
43
74
  handleSubmit(e) {
44
75
  this.kendoForm && this.kendoForm.onSubmit(e);
76
+ },
77
+ _updateColumnClass() {
78
+ const e = typeof window != "undefined" ? window.innerWidth : 0, s = this.$el ? c(this.$el) : e, t = p(this.$props.cols, s);
79
+ this.columnClass = f(t);
80
+ const r = b(this.$props.gutters, s);
81
+ this.gapStyle = v(r, {
82
+ rows: "0px",
83
+ cols: "32px"
84
+ });
85
+ },
86
+ _setupColsObserver() {
87
+ this._resizeObserver && (this._resizeObserver.disconnect(), this._resizeObserver = null), this._updateColumnClass(), this.$el && typeof window != "undefined" && "ResizeObserver" in window && (this._resizeObserver = new ResizeObserver(() => this._updateColumnClass()), this._resizeObserver.observe(this.$el));
45
88
  }
46
89
  },
47
90
  render() {
48
91
  const e = m(this);
49
- return o("form", {
92
+ return i("form", {
50
93
  class: this.formElementClassName,
51
94
  onSubmit: this.handleSubmit
52
- }, [e]);
95
+ }, [this.$props.cols ? i("div", {
96
+ class: `k-form-layout k-d-grid ${this.columnClass}`,
97
+ style: {
98
+ gap: this.gapStyle || "0px 32px"
99
+ }
100
+ }, [e]) : e]);
53
101
  }
54
102
  });
55
103
  export {
56
- d as FormElement
104
+ g as FormElement
57
105
  };
@@ -0,0 +1,85 @@
1
+ /**
2
+ * @license
3
+ *-------------------------------------------------------------------------------------------
4
+ * Copyright © 2026 Progress Software Corporation. All rights reserved.
5
+ * Licensed under commercial license. See LICENSE.md in the package root for more information
6
+ *-------------------------------------------------------------------------------------------
7
+ */
8
+ import { PropType } from 'vue';
9
+ import { ResponsiveFormBreakPoint } from './interfaces/ResponsiveFormBreakPoint';
10
+ import { Gutters } from './interfaces/Gutters';
11
+ /**
12
+ * Represents the props of the Kendo UI for Vue FormFieldSet component.
13
+ */
14
+ export interface FormFieldSetProps {
15
+ /**
16
+ * Defines the number of columns of the fieldset.
17
+ * Can be a number or an array of responsive breakpoints.
18
+ *
19
+ * @example
20
+ * ```vue
21
+ * <FormFieldSet :cols="2" legend="Address" />
22
+ * ```
23
+ */
24
+ cols?: number | ResponsiveFormBreakPoint[];
25
+ /**
26
+ * Defines the colspan for the fieldset related to the parent `FormElement` columns.
27
+ * Can be a number or an array of responsive breakpoints.
28
+ *
29
+ * @example
30
+ * ```vue
31
+ * <FormFieldSet :col-span="2" legend="Address" />
32
+ * ```
33
+ */
34
+ colSpan?: number | ResponsiveFormBreakPoint[];
35
+ /**
36
+ * Defines the gutters for the fieldset layout.
37
+ * Accepts a number (px), a CSS string, a `Gutters` object with `cols`/`rows` keys,
38
+ * or an array of responsive breakpoints.
39
+ * Defaults to `{ rows: '0px', cols: '16px' }`.
40
+ *
41
+ * @example
42
+ * ```vue
43
+ * <FormFieldSet :gutters="{ rows: '8px', cols: '24px' }" legend="Address" />
44
+ * ```
45
+ */
46
+ gutters?: string | number | Gutters | ResponsiveFormBreakPoint[];
47
+ /**
48
+ * Defines the legend text for the fieldset.
49
+ *
50
+ * @example
51
+ * ```vue
52
+ * <FormFieldSet legend="Personal Information" />
53
+ * ```
54
+ */
55
+ legend?: string;
56
+ /**
57
+ * @hidden
58
+ */
59
+ [customProp: string]: any;
60
+ }
61
+ /**
62
+ * @hidden
63
+ */
64
+ declare const FormFieldSet: import('vue').DefineComponent<import('vue').ExtractPropTypes<{
65
+ cols: PropType<number | ResponsiveFormBreakPoint[]>;
66
+ colSpan: PropType<number | ResponsiveFormBreakPoint[]>;
67
+ gutters: PropType<string | number | ResponsiveFormBreakPoint[] | Gutters>;
68
+ legend: PropType<string>;
69
+ }>, {}, {
70
+ columnClass: string;
71
+ colSpanClass: string;
72
+ gapStyle: string;
73
+ }, {
74
+ fieldsetClass(): string;
75
+ divClass(): string;
76
+ }, {
77
+ _update(): void;
78
+ _setupObserver(): void;
79
+ }, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<import('vue').ExtractPropTypes<{
80
+ cols: PropType<number | ResponsiveFormBreakPoint[]>;
81
+ colSpan: PropType<number | ResponsiveFormBreakPoint[]>;
82
+ gutters: PropType<string | number | ResponsiveFormBreakPoint[] | Gutters>;
83
+ legend: PropType<string>;
84
+ }>> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, true, {}, any>;
85
+ export { FormFieldSet };
@@ -0,0 +1,8 @@
1
+ /**
2
+ * @license
3
+ *-------------------------------------------------------------------------------------------
4
+ * Copyright © 2026 Progress Software Corporation. All rights reserved.
5
+ * Licensed under commercial license. See LICENSE.md in the package root for more information
6
+ *-------------------------------------------------------------------------------------------
7
+ */
8
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const i=require("vue"),d=require("./package-metadata.js"),o=require("@progress/kendo-vue-common"),s=require("./utils.js"),l={rows:"0px",cols:"16px"},c=i.defineComponent({name:"KendoFormFieldSet",props:{cols:[Number,Array],colSpan:[Number,Array],gutters:[String,Number,Object,Array],legend:String},data(){return{columnClass:"",colSpanClass:"",gapStyle:""}},created(){o.validatePackage(d.packageMetadata),this._resizeObserver=null,this._formElement=null},mounted(){var e;this._formElement=((e=this.$el)==null?void 0:e.closest("form"))||null,(this.$props.cols!==void 0||this.$props.colSpan!==void 0)&&this._setupObserver()},beforeUnmount(){this._resizeObserver&&this._formElement&&(this._resizeObserver.unobserve(this._formElement),this._resizeObserver.disconnect())},watch:{cols(e){e!==void 0?this._setupObserver():(this._resizeObserver&&this._formElement&&(this._resizeObserver.unobserve(this._formElement),this._resizeObserver.disconnect(),this._resizeObserver=null),this.columnClass="",this.gapStyle="")},colSpan(e){e!==void 0?this._setupObserver():this.colSpanClass=""},gutters(){this._update()}},computed:{fieldsetClass(){return["k-form-fieldset",this.colSpanClass].filter(Boolean).join(" ")},divClass(){return["k-form-layout","k-d-grid",this.columnClass].filter(Boolean).join(" ")}},methods:{_update(){const e=typeof window!="undefined"?window.innerWidth:0,t=this._formElement?s.getElementInnerWidth(this._formElement):e;if(this.$props.cols!==void 0){const r=s.calculateColumns(this.$props.cols,t);this.columnClass=s.generateColumnClass(r)}if(this.$props.colSpan!==void 0){const r=s.calculateColSpan(this.$props.colSpan,t);this.colSpanClass=s.generateColSpanClass(r)}const a=this.$props.cols!==void 0?l:void 0,n=this.$props.gutters!==void 0?this.$props.gutters:a;if(n!==void 0){const r=s.calculateGutters(n,t);this.gapStyle=s.generateGuttersStyling(r,l)}else this.gapStyle=""},_setupObserver(){this._resizeObserver&&(this._resizeObserver.disconnect(),this._resizeObserver=null),this._update(),this._formElement&&typeof window!="undefined"&&"ResizeObserver"in window&&(this._resizeObserver=new ResizeObserver(()=>this._update()),this._resizeObserver.observe(this._formElement))}},render(){const e=o.getDefaultSlots(this),{legend:t}=this.$props;return i.createVNode("fieldset",{class:this.fieldsetClass},[t&&i.createVNode("legend",{class:"k-form-legend"},[t]),this.$props.cols?i.createVNode("div",{class:this.divClass,style:{gap:this.gapStyle||"0px 16px"}},[e]):e])}});exports.FormFieldSet=c;
@@ -0,0 +1,99 @@
1
+ /**
2
+ * @license
3
+ *-------------------------------------------------------------------------------------------
4
+ * Copyright © 2026 Progress Software Corporation. All rights reserved.
5
+ * Licensed under commercial license. See LICENSE.md in the package root for more information
6
+ *-------------------------------------------------------------------------------------------
7
+ */
8
+ import { defineComponent as l, createVNode as r } from "vue";
9
+ import { packageMetadata as a } from "./package-metadata.mjs";
10
+ import { getDefaultSlots as d, validatePackage as p } from "@progress/kendo-vue-common";
11
+ import { getElementInnerWidth as c, calculateColumns as h, generateColumnClass as u, calculateColSpan as f, generateColSpanClass as m, calculateGutters as _, generateGuttersStyling as b } from "./utils.mjs";
12
+ const n = {
13
+ rows: "0px",
14
+ cols: "16px"
15
+ }, C = /* @__PURE__ */ l({
16
+ name: "KendoFormFieldSet",
17
+ props: {
18
+ cols: [Number, Array],
19
+ colSpan: [Number, Array],
20
+ gutters: [String, Number, Object, Array],
21
+ legend: String
22
+ },
23
+ data() {
24
+ return {
25
+ columnClass: "",
26
+ colSpanClass: "",
27
+ gapStyle: ""
28
+ };
29
+ },
30
+ created() {
31
+ p(a), this._resizeObserver = null, this._formElement = null;
32
+ },
33
+ mounted() {
34
+ var e;
35
+ this._formElement = ((e = this.$el) == null ? void 0 : e.closest("form")) || null, (this.$props.cols !== void 0 || this.$props.colSpan !== void 0) && this._setupObserver();
36
+ },
37
+ beforeUnmount() {
38
+ this._resizeObserver && this._formElement && (this._resizeObserver.unobserve(this._formElement), this._resizeObserver.disconnect());
39
+ },
40
+ watch: {
41
+ cols(e) {
42
+ e !== void 0 ? this._setupObserver() : (this._resizeObserver && this._formElement && (this._resizeObserver.unobserve(this._formElement), this._resizeObserver.disconnect(), this._resizeObserver = null), this.columnClass = "", this.gapStyle = "");
43
+ },
44
+ colSpan(e) {
45
+ e !== void 0 ? this._setupObserver() : this.colSpanClass = "";
46
+ },
47
+ gutters() {
48
+ this._update();
49
+ }
50
+ },
51
+ computed: {
52
+ fieldsetClass() {
53
+ return ["k-form-fieldset", this.colSpanClass].filter(Boolean).join(" ");
54
+ },
55
+ divClass() {
56
+ return ["k-form-layout", "k-d-grid", this.columnClass].filter(Boolean).join(" ");
57
+ }
58
+ },
59
+ methods: {
60
+ _update() {
61
+ const e = typeof window != "undefined" ? window.innerWidth : 0, s = this._formElement ? c(this._formElement) : e;
62
+ if (this.$props.cols !== void 0) {
63
+ const t = h(this.$props.cols, s);
64
+ this.columnClass = u(t);
65
+ }
66
+ if (this.$props.colSpan !== void 0) {
67
+ const t = f(this.$props.colSpan, s);
68
+ this.colSpanClass = m(t);
69
+ }
70
+ const o = this.$props.cols !== void 0 ? n : void 0, i = this.$props.gutters !== void 0 ? this.$props.gutters : o;
71
+ if (i !== void 0) {
72
+ const t = _(i, s);
73
+ this.gapStyle = b(t, n);
74
+ } else
75
+ this.gapStyle = "";
76
+ },
77
+ _setupObserver() {
78
+ this._resizeObserver && (this._resizeObserver.disconnect(), this._resizeObserver = null), this._update(), this._formElement && typeof window != "undefined" && "ResizeObserver" in window && (this._resizeObserver = new ResizeObserver(() => this._update()), this._resizeObserver.observe(this._formElement));
79
+ }
80
+ },
81
+ render() {
82
+ const e = d(this), {
83
+ legend: s
84
+ } = this.$props;
85
+ return r("fieldset", {
86
+ class: this.fieldsetClass
87
+ }, [s && r("legend", {
88
+ class: "k-form-legend"
89
+ }, [s]), this.$props.cols ? r("div", {
90
+ class: this.divClass,
91
+ style: {
92
+ gap: this.gapStyle || "0px 16px"
93
+ }
94
+ }, [e]) : e]);
95
+ }
96
+ });
97
+ export {
98
+ C as FormFieldSet
99
+ };
@@ -12,4 +12,4 @@
12
12
  * Licensed under commercial license. See LICENSE.md in the package root for more information
13
13
  *-------------------------------------------------------------------------------------------
14
14
  */
15
- !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("vue"),require("@progress/kendo-vue-common")):"function"==typeof define&&define.amd?define(["exports","vue","@progress/kendo-vue-common"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).KendoVueForm={},e.Vue,e.KendoVueCommon)}(this,function(e,t,i){"use strict";const o=t.defineComponent({name:"KendoField",props:{component:[String,Number,Boolean,Object],validator:[Function,Array],name:String},created(){return this.kendoForm?this.kendoForm.registerField(this.$props.name,this.$props.validator):void 0},inject:{kendoForm:{default:null}},emits:["change"],methods:{handleOnChange(e){const t=e&&(void 0!==e.value?e.value:e.target?e.target.value:e.target);this.kendoForm.onChange(this.$props.name,{value:t}),this.$emit("change",e)},onNativeComponentChange(e){this.kendoForm.onChange(this.$props.name,{value:e.target.value})},handleOnBlur(){this.kendoForm.onBlur(this.$props.name)},handleOnFocus(){this.kendoForm.onFocus(this.$props.name)}},render(){const e=i.getDefaultSlots(this),{name:o,component:s,id:r}=this.$props;if(!this.kendoForm)return null;const n=this.kendoForm.values[o];if("string"==typeof s&&("input"===s||"textarea"===s))return t.h(s,{onBlur:this.handleOnBlur,onFocus:this.handleOnFocus,name:o,value:n||""});if(s){const d=i.templateRendering.call(this,s,i.getListeners.call(this));return i.getTemplate.call(this,{h:t.h,template:d,additionalProps:{value:n,validationMessage:this.kendoForm.errors[o],touched:this.kendoForm.touchedByField[o],modified:this.kendoForm.modifiedByField[o],visited:this.kendoForm.visitedByField[o],valid:!(this.kendoForm.errors[o]&&this.kendoForm.touchedByField[o]),name:o,id:r,...this.$attrs},additionalListeners:{change:this.handleOnChange,blur:this.handleOnBlur,focus:this.handleOnFocus},defaultSlots:e})}}}),s={name:"@progress/kendo-vue-form",productName:"Kendo UI for Vue",productCode:"KENDOUIVUE",productCodes:["KENDOUIVUE"],publishDate:0,version:"8.2.0-develop.1",licensingDocsUrl:"https://www.telerik.com/kendo-vue-ui/my-license/"},r=t.defineComponent({name:"KendoForm",inheritAttrs:!1,props:{renderForm:[Object,Function],initialValues:Object,validator:Function,ignoreModified:Boolean},emits:{submitclick:null,submit:null},created(){this._accumulatorTimeout=void 0,i.validatePackage(s),this.form.values=i.clone(this.$props.initialValues)},mounted(){this.form.errors=this.getErrors(),this.form.allowSubmit=this.allowSubmit(),this.form.valid=this.isValid()},unmounted(){this.onDestroy()},data(){return{validatorsByField:{},fields:[],unmounted:!1,form:{id:this.id,errors:{},values:{},modifiedByField:{},touchedByField:{},visitedByField:{},valid:!1,modified:!1,touched:!1,visited:!1,submitted:!1,valueGetter:this.valueGetter,allowSubmit:!1,validate:this.validate,onChange:this.onChange,onSubmit:this.onSubmit,onFormReset:this.resetForm,registerField:this.onFieldRegister,onFocus:this.onFocus,onBlur:this.onBlur,onUnshift:this.onUnshift,onPush:this.onPush,onInsert:this.onInsert,onPop:this.onPop,onRemove:this.onRemove,onReplace:this.onReplace,onMove:this.onMove}}},provide(){return{kendoForm:this.$data.form}},watch:{"form.values"(){this.form.errors=this.getErrors(),this.form.allowSubmit=this.allowSubmit(),this.form.valid=this.isValid()},"form.touchedByField"(e){this.form.touched=this.isFormTouched(e,this.fields),this.form.allowSubmit=this.allowSubmit()},"form.modifiedByField"(e){this.form.modified=this.isFormModified(e,this.fields),this.form.allowSubmit=this.allowSubmit()},"form.visitedByField"(e){this.form.visited=this.isFormVisited(e,this.fields)}},methods:{isValid(){return this.isFormValid(this.form.errors)},formErrors(){if(this.$props.validator)return this.$props.validator(this.form.values,this.valueGetter)},getErrors(){const e={},t=this.validatorsByField;return Object.keys(this.fields).forEach(i=>{if(e[i]="",t[i]){const o=[];t[i].forEach(e=>{Array.isArray(e)?o.push(...e):o.push(e)}),o.find(t=>{if(t){const o=t(this.valueGetter(i),this.valueGetter,{name:i});if(o)return e[i]=o,!0}return!1})}}),this.formErrors()&&i.cloneObject(this.formErrors(),e),e},accumulatedForceUpdate(){this._accumulatorTimeout&&clearTimeout(this._accumulatorTimeout),i.canUseDOM&&(this._accumulatorTimeout=window.setTimeout(()=>{this._accumulatorTimeout=void 0},0))},resetForm(){this.form.values=i.clone(this.$props.initialValues),this.id=i.guid(),this.form.touchedByField={},this.form.visitedByField={},this.form.modifiedByField={},this.form.submitted=!1},onReset(){this.resetForm()},addField(e){this.fields[e]=!0},validate(e){const t={},i=e||this.fields;Object.keys(i).forEach(e=>{t[e]=!0}),this.form.touchedByField={...t}},onSubmit(e){const t={},i=this.fields;e&&("function"==typeof e.preventDefault&&e.preventDefault(),"function"==typeof e.stopPropagation&&e.stopPropagation()),Object.keys(i).forEach(e=>{t[e]=!0}),this.form.visitedByField={...t},this.form.touchedByField={...t};const o=this.form.values,s=this.isValid(),r=this.isFormModified(this.form.modifiedByField,i);this.$emit("submitclick",{values:o,isValid:s,isModified:r,event:e}),s&&(this.$props.ignoreModified||r)&&(this.form.submitted=!0,this.$emit("submit",o,e))},onChange(e,t){const{value:i}=t;this.addField(e),this.form.modifiedByField[e]||(this.form.modifiedByField={...this.form.modifiedByField,[e]:!0}),this.valueSetter(e,i)},onFocus(e){this.form.visitedByField[e]||(this.form.visitedByField={...this.form.visitedByField,[e]:!0})},onBlur(e){this.form.touchedByField[e]||(this.onFocus(e),this.form.touchedByField={...this.form.touchedByField,[e]:!0})},onFieldRegister(e,t){this.addField(e);const i=this.validatorsByField[e]||[],o=i.length;return this.validatorsByField={...this.validatorsByField,[e]:[...i,t]},this.accumulatedForceUpdate(),()=>{if(this._unmounted)return;const t=[...this.validatorsByField[e]||[]],i=!!t[o];t[o]=void 0,this.validatorsByField={...this.validatorsByField,[e]:t},i&&this.accumulatedForceUpdate()}},isFormValid:e=>!Object.keys(e).some(t=>!!e[t]),isFormModified:(e,t)=>Object.keys(t).some(t=>e[t]),isFormHasNotTouched:(e,t)=>Object.keys(t).some(t=>!e[t]),isFormTouched:(e,t)=>Object.keys(t).some(t=>e[t]),isFormVisited:(e,t)=>Object.keys(t).some(t=>e[t]),formHasNotTouched(){return this.isFormHasNotTouched(this.form.touchedByField,this.fields)},allowSubmit(){return this.formHasNotTouched()&&!this.isValid()||this.isValid()&&(this.$props.ignoreModified||this.isFormModified(this.form.modifiedByField,this.fields))},valueGetter(e){return this.form.values[e]},valueSetter(e,t){this.form.values={...this.form.values,[e]:t}},onArrayAction(e){this.addField(e),this.form.modifiedByField[e]||(this.form.modifiedByField={...this.form.modifiedByField,[e]:!0}),this.onBlur(e,!0)},onInsert(e,t){this.onArrayAction(e);const i=[...this.valueGetter(e)||[]];i.splice(t.index,0,t.value),this.valueSetter(e,i)},onUnshift(e,t){this.onInsert(e,{value:t.value,index:0})},onPush(e,t){this.onArrayAction(e);const i=[...this.valueGetter(e)||[],t.value];this.valueSetter(e,i)},onPop(e){this.onArrayAction(e);const t=[...this.valueGetter(e)||[]],i=t.pop();return this.valueSetter(e,t),i},onRemove(e,t){this.onArrayAction(e);const i=[...this.valueGetter(e)||[]],o=i.splice(t.index,1);return this.valueSetter(e,i),o},onReplace(e,t){this.onArrayAction(e);const i=[...this.valueGetter(e)||[]];i.splice(t.index,1,t.value),this.valueSetter(e,i)},onMove(e,t){this.onArrayAction(e);const i=[...this.valueGetter(e)||[]],o=i[t.prevIndex];i.splice(t.prevIndex,1),i.splice(t.nextIndex,0,o),this.valueSetter(e,i)},onDestroy(){this.unmounted=!0,this._accumulatorTimeout&&clearTimeout(this._accumulatorTimeout)}},render(){return i.getDefaultSlots(this)}}),n=t.defineComponent({name:"KendoFieldArray",props:{value:[String,Number,Boolean,Object,Array],component:[String,Number,Boolean,Object],validationMessage:String,touched:Boolean,modified:Boolean,validator:[Function,Array],visited:Boolean,valid:Boolean,name:String,id:String},created(){return this.kendoForm?this.kendoForm.registerField(this.$props.name,this.$props.validator):void 0},methods:{onUnshift(e){this.kendoForm.onUnshift(this.$props.name,e)},onPush(e){this.kendoForm.onPush(this.$props.name,e)},onInsert(e){this.kendoForm.onInsert(this.$props.name,e)},onPop(){this.kendoForm.onPop(this.$props.name)},onRemove(e){this.kendoForm.onRemove(this.$props.name,e)},onReplace(e){this.kendoForm.onReplace(this.$props.name,e)},onMove(e){this.kendoForm.onMove(this.$props.name,e)}},inject:{kendoForm:{default:null}},render(){const{name:e,component:o,id:s}=this.$props;if(!this.kendoForm)return null;const r=this.kendoForm.values[e];if(o){const n=o?i.templateRendering.call(this,o,i.getListeners.call(this)):null;return i.getTemplate.call(this,{h:t.h,template:n,additionalProps:{value:r,validationMessage:this.kendoForm.errors[e],touched:this.kendoForm.touchedByField[e],modified:this.kendoForm.modifiedByField[e],visited:this.kendoForm.visitedByField[e],valid:!(this.kendoForm.errors[e]&&this.kendoForm.touchedByField[e]),name:e,id:s,...this.$attrs},additionalListeners:{unshift:this.onUnshift,push:this.onPush,insert:this.onInsert,pop:this.onPop,remove:this.onRemove,replace:this.onReplace,move:this.onMove}})}}}),d=t.defineComponent({name:"KendoFieldWrapper",props:{dir:String,horizontal:Boolean},created(){i.validatePackage(s)},computed:{fieldClassName(){return{"k-form-field":!0,"k-rtl":"rtl"===this.$props.dir}}},render(){const e=i.getDefaultSlots(this);return t.createVNode("div",{class:this.fieldClassName},[e])}}),a=t.defineComponent({name:"KendoFormElement",props:{horizontal:Boolean,size:{type:String,validator:function(e){return["small","medium","large"].includes(e)}}},created(){i.validatePackage(s)},inject:{kendoForm:{default:null}},computed:{formElementClassName(){const{size:e}=this.$props;return{"k-form":!0,[`k-form-${i.kendoThemeMaps.sizeMap[e]||e}`]:e,"k-form-horizontal":!0===this.$props.horizontal}}},methods:{handleSubmit(e){this.kendoForm&&this.kendoForm.onSubmit(e)}},render(){const e=i.getDefaultSlots(this);return t.createVNode("form",{class:this.formElementClassName,onSubmit:this.handleSubmit},[e])}});e.Field=o,e.FieldArray=n,e.FieldWrapper=d,e.Form=r,e.FormElement=a});
15
+ !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("vue"),require("@progress/kendo-vue-common")):"function"==typeof define&&define.amd?define(["exports","vue","@progress/kendo-vue-common"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).KendoVueForm={},e.Vue,e.KendoVueCommon)}(this,function(e,t,s){"use strict";const i=t.defineComponent({name:"KendoField",props:{component:[String,Number,Boolean,Object],validator:[Function,Array],name:String,colSpan:[Number,Array]},created(){return this.kendoForm?this.kendoForm.registerField(this.$props.name,this.$props.validator):void 0},inject:{kendoForm:{default:null}},emits:["change"],methods:{handleOnChange(e){const t=e&&(void 0!==e.value?e.value:e.target?e.target.value:e.target);this.kendoForm.onChange(this.$props.name,{value:t}),this.$emit("change",e)},onNativeComponentChange(e){this.kendoForm.onChange(this.$props.name,{value:e.target.value})},handleOnBlur(){this.kendoForm.onBlur(this.$props.name)},handleOnFocus(){this.kendoForm.onFocus(this.$props.name)}},render(){const e=s.getDefaultSlots(this),{name:i,component:o,id:r,colSpan:n}=this.$props;if(!this.kendoForm)return null;const l=this.kendoForm.values[i];if("string"==typeof o&&("input"===o||"textarea"===o))return t.h(o,{onBlur:this.handleOnBlur,onFocus:this.handleOnFocus,name:i,value:l||""});if(o){const d=s.templateRendering.call(this,o,s.getListeners.call(this));return s.getTemplate.call(this,{h:t.h,template:d,additionalProps:{value:l,validationMessage:this.kendoForm.errors[i],touched:this.kendoForm.touchedByField[i],modified:this.kendoForm.modifiedByField[i],visited:this.kendoForm.visitedByField[i],valid:!(this.kendoForm.errors[i]&&this.kendoForm.touchedByField[i]),name:i,id:r,...void 0!==n?{colSpan:n}:{},...this.$attrs},additionalListeners:{change:this.handleOnChange,blur:this.handleOnBlur,focus:this.handleOnFocus},defaultSlots:e})}}}),o={name:"@progress/kendo-vue-form",productName:"Kendo UI for Vue",productCode:"KENDOUIVUE",productCodes:["KENDOUIVUE"],publishDate:0,version:"8.3.0-develop.1",licensingDocsUrl:"https://www.telerik.com/kendo-vue-ui/my-license/"},r=t.defineComponent({name:"KendoForm",inheritAttrs:!1,props:{renderForm:[Object,Function],initialValues:Object,validator:Function,ignoreModified:Boolean,errors:Object,onChange:Function},emits:{submitclick:null,submit:null},created(){this._accumulatorTimeout=void 0,s.validatePackage(o),this.form.values=s.clone(this.$props.initialValues)},mounted(){this.form.errors=this.getErrors(),this.form.allowSubmit=this.allowSubmit(),this.form.valid=this.isValid()},unmounted(){this.onDestroy()},data(){return{validatorsByField:{},fields:[],unmounted:!1,form:{id:this.id,errors:{},values:{},modifiedByField:{},touchedByField:{},visitedByField:{},valid:!1,modified:!1,touched:!1,visited:!1,submitted:!1,valueGetter:this.valueGetter,allowSubmit:!1,validate:this.validate,onChange:this.handleFieldChange,onSubmit:this.onSubmit,onFormReset:this.resetForm,registerField:this.onFieldRegister,onFocus:this.onFocus,onBlur:this.onBlur,onUnshift:this.onUnshift,onPush:this.onPush,onInsert:this.onInsert,onPop:this.onPop,onRemove:this.onRemove,onReplace:this.onReplace,onMove:this.onMove}}},provide(){return{kendoForm:this.$data.form}},watch:{"form.values"(){this.form.errors=this.getErrors(),this.form.allowSubmit=this.allowSubmit(),this.form.valid=this.isValid()},"form.touchedByField"(e){this.form.touched=this.isFormTouched(e,this.fields),this.form.allowSubmit=this.allowSubmit()},"form.modifiedByField"(e){this.form.modified=this.isFormModified(e,this.fields),this.form.allowSubmit=this.allowSubmit()},"form.visitedByField"(e){this.form.visited=this.isFormVisited(e,this.fields)},errors(e){this.form.errors=this.getErrors(),this.form.allowSubmit=this.allowSubmit(),this.form.valid=this.isValid()}},methods:{isValid(){return this.isFormValid(this.form.errors)},formErrors(){if(this.$props.validator)return this.$props.validator(this.form.values,this.valueGetter)},getErrors(){const e={},t=this.validatorsByField;return Object.keys(this.fields).forEach(s=>{if(e[s]="",t[s]){const i=[];t[s].forEach(e=>{Array.isArray(e)?i.push(...e):i.push(e)}),i.find(t=>{if(t){const i=t(this.valueGetter(s),this.valueGetter,{name:s});if(i)return e[s]=i,!0}return!1})}}),this.formErrors()&&s.cloneObject(this.formErrors(),e),this.$props.errors&&s.cloneObject(this.$props.errors,e),e},accumulatedForceUpdate(){this._accumulatorTimeout&&clearTimeout(this._accumulatorTimeout),s.canUseDOM&&(this._accumulatorTimeout=window.setTimeout(()=>{this._accumulatorTimeout=void 0},0))},resetForm(){this.form.values=s.clone(this.$props.initialValues),this.id=s.guid(),this.form.touchedByField={},this.form.visitedByField={},this.form.modifiedByField={},this.form.submitted=!1},onReset(){this.resetForm()},addField(e){this.fields[e]=!0},validate(e){const t={},s=e||this.fields;Object.keys(s).forEach(e=>{t[e]=!0}),this.form.touchedByField={...t}},onSubmit(e){const t={},s=this.fields;e&&("function"==typeof e.preventDefault&&e.preventDefault(),"function"==typeof e.stopPropagation&&e.stopPropagation()),Object.keys(s).forEach(e=>{t[e]=!0}),this.form.visitedByField={...t},this.form.touchedByField={...t};const i=this.form.values,o=this.isValid(),r=this.isFormModified(this.form.modifiedByField,s);this.$emit("submitclick",{values:i,isValid:o,isModified:r,event:e}),o&&(this.$props.ignoreModified||r)&&(this.form.submitted=!0,this.$emit("submit",i,e))},handleFieldChange(e,t){const{value:s}=t;this.addField(e),this.form.modifiedByField[e]||(this.form.modifiedByField={...this.form.modifiedByField,[e]:!0}),this.valueSetter(e,s),this.$props.onChange&&this.$props.onChange(e,s,this.valueGetter)},onFocus(e){this.form.visitedByField[e]||(this.form.visitedByField={...this.form.visitedByField,[e]:!0})},onBlur(e){this.form.touchedByField[e]||(this.onFocus(e),this.form.touchedByField={...this.form.touchedByField,[e]:!0})},onFieldRegister(e,t){this.addField(e);const s=this.validatorsByField[e]||[],i=s.length;return this.validatorsByField={...this.validatorsByField,[e]:[...s,t]},this.accumulatedForceUpdate(),()=>{if(this._unmounted)return;const t=[...this.validatorsByField[e]||[]],s=!!t[i];t[i]=void 0,this.validatorsByField={...this.validatorsByField,[e]:t},s&&this.accumulatedForceUpdate()}},isFormValid:e=>!Object.keys(e).some(t=>!!e[t]),isFormModified:(e,t)=>Object.keys(t).some(t=>e[t]),isFormHasNotTouched:(e,t)=>Object.keys(t).some(t=>!e[t]),isFormTouched:(e,t)=>Object.keys(t).some(t=>e[t]),isFormVisited:(e,t)=>Object.keys(t).some(t=>e[t]),formHasNotTouched(){return this.isFormHasNotTouched(this.form.touchedByField,this.fields)},allowSubmit(){return this.formHasNotTouched()&&!this.isValid()||this.isValid()&&(this.$props.ignoreModified||this.isFormModified(this.form.modifiedByField,this.fields))},valueGetter(e){return this.form.values[e]},valueSetter(e,t){this.form.values={...this.form.values,[e]:t}},onArrayAction(e){this.addField(e),this.form.modifiedByField[e]||(this.form.modifiedByField={...this.form.modifiedByField,[e]:!0}),this.onBlur(e,!0)},onInsert(e,t){this.onArrayAction(e);const s=[...this.valueGetter(e)||[]];s.splice(t.index,0,t.value),this.valueSetter(e,s)},onUnshift(e,t){this.onInsert(e,{value:t.value,index:0})},onPush(e,t){this.onArrayAction(e);const s=[...this.valueGetter(e)||[],t.value];this.valueSetter(e,s)},onPop(e){this.onArrayAction(e);const t=[...this.valueGetter(e)||[]],s=t.pop();return this.valueSetter(e,t),s},onRemove(e,t){this.onArrayAction(e);const s=[...this.valueGetter(e)||[]],i=s.splice(t.index,1);return this.valueSetter(e,s),i},onReplace(e,t){this.onArrayAction(e);const s=[...this.valueGetter(e)||[]];s.splice(t.index,1,t.value),this.valueSetter(e,s)},onMove(e,t){this.onArrayAction(e);const s=[...this.valueGetter(e)||[]],i=s[t.prevIndex];s.splice(t.prevIndex,1),s.splice(t.nextIndex,0,i),this.valueSetter(e,s)},onDestroy(){this.unmounted=!0,this._accumulatorTimeout&&clearTimeout(this._accumulatorTimeout)}},render(){const e={onSubmit:this.onSubmit,onChange:this.handleFieldChange,onFormreset:this.resetForm,errors:this.form.errors,valid:this.form.valid,touched:this.form.touched,visited:this.form.visited,modified:this.form.modified,submitted:this.form.submitted,allowSubmit:this.form.allowSubmit,valueGetter:this.valueGetter};return this.$props.renderForm?this.$props.renderForm(e):s.getDefaultSlots(this)}}),n=t.defineComponent({name:"KendoFieldArray",props:{value:[String,Number,Boolean,Object,Array],component:[String,Number,Boolean,Object],validationMessage:String,touched:Boolean,modified:Boolean,validator:[Function,Array],visited:Boolean,valid:Boolean,name:String,id:String},created(){return this.kendoForm?this.kendoForm.registerField(this.$props.name,this.$props.validator):void 0},methods:{onUnshift(e){this.kendoForm.onUnshift(this.$props.name,e)},onPush(e){this.kendoForm.onPush(this.$props.name,e)},onInsert(e){this.kendoForm.onInsert(this.$props.name,e)},onPop(){this.kendoForm.onPop(this.$props.name)},onRemove(e){this.kendoForm.onRemove(this.$props.name,e)},onReplace(e){this.kendoForm.onReplace(this.$props.name,e)},onMove(e){this.kendoForm.onMove(this.$props.name,e)}},inject:{kendoForm:{default:null}},render(){const{name:e,component:i,id:o}=this.$props;if(!this.kendoForm)return null;const r=this.kendoForm.values[e];if(i){const n=i?s.templateRendering.call(this,i,s.getListeners.call(this)):null;return s.getTemplate.call(this,{h:t.h,template:n,additionalProps:{value:r,validationMessage:this.kendoForm.errors[e],touched:this.kendoForm.touchedByField[e],modified:this.kendoForm.modifiedByField[e],visited:this.kendoForm.visitedByField[e],valid:!(this.kendoForm.errors[e]&&this.kendoForm.touchedByField[e]),name:e,id:o,...this.$attrs},additionalListeners:{unshift:this.onUnshift,push:this.onPush,insert:this.onInsert,pop:this.onPop,remove:this.onRemove,replace:this.onReplace,move:this.onMove}})}}});function l(e){let t=e.clientWidth;const s=getComputedStyle(e);return t-=(parseFloat(s.paddingLeft)||0)+(parseFloat(s.borderLeftWidth)||0),t-=(parseFloat(s.paddingRight)||0)+(parseFloat(s.borderRightWidth)||0),t}function d(e,t){var s,i;if(null==e||!e.length||null==t)return"";for(const[o,r]of e.entries()){const n=o>0&&void 0!==e[o-1].maxWidth?e[o-1].maxWidth:void 0,l=o<e.length-1&&void 0!==e[o+1].minWidth?e[o+1].minWidth:void 0,d=null!=(s=r.minWidth)?s:void 0!==n?n+1:0,a=null!=(i=r.maxWidth)?i:void 0!==l?l-1:1/0;if(t>=d&&t<=a)return r.value}return""}function a(e,t){if(!e)return null;if(Array.isArray(e)&&e.length>0){const s=d(e,t)||null;return"string"==typeof s?parseInt(s,10):s}return"number"==typeof e?e:null}function h(e){return e&&e>0?`k-grid-cols-${e}`:""}function u(e,t){if(!e)return null;if("number"==typeof e)return e;if(Array.isArray(e)&&e.length>0){const s=d(e,t)||null;return"string"==typeof s?parseInt(s,10):s}return null}function m(e){return e?`k-col-span-${e}`:""}function c(e){if(null==e)return null;if("number"==typeof e)return`${e}px`;const t=e.trim(),s=parseInt(t,10);return!isNaN(s)&&Number.isFinite(s)?s.toString()===t?`${s}px`:e:null}function p(e,t){if(!e)return null;if("number"==typeof e)return{cols:e,rows:e};if("string"==typeof e){if(!e.includes(" "))return{cols:e,rows:e};const t=e.split(" ");return{cols:t[1],rows:t[0]}}if(Array.isArray(e)){const s=d(e,t)||null;return null!==s?{cols:s,rows:s}:null}if("object"==typeof e){const s=e,i={rows:null,cols:null};return void 0!==s.cols&&null!==s.cols&&("number"==typeof s.cols||"string"==typeof s.cols?i.cols=s.cols:Array.isArray(s.cols)&&(i.cols=d(s.cols,t)||null)),void 0!==s.rows&&("number"==typeof s.rows||"string"==typeof s.rows?i.rows=s.rows:Array.isArray(s.rows)&&(i.rows=d(s.rows,t)||null)),i}return null}function f(e,t){var s,i,o,r;const n=c(null!=(i=null!=(s=null==e?void 0:e.rows)?s:t.rows)?i:"0px"),l=c(null!=(r=null!=(o=null==e?void 0:e.cols)?o:t.cols)?r:"32px");return`${null!=n?n:"0px"} ${null!=l?l:"32px"}`}const v=t.defineComponent({name:"KendoFieldWrapper",props:{dir:String,horizontal:Boolean,colSpan:[Number,Array]},data:()=>({colSpanClass:""}),created(){s.validatePackage(o),this._resizeObserver=null,this._formElement=null},mounted(){var e;void 0!==this.$props.colSpan&&(this._formElement=(null==(e=this.$el)?void 0:e.closest("form"))||null,this._setupColSpanObserver())},beforeUnmount(){this._resizeObserver&&this._formElement&&(this._resizeObserver.unobserve(this._formElement),this._resizeObserver.disconnect(),this._resizeObserver=null)},watch:{colSpan(e){var t;void 0!==e?(this._formElement=(null==(t=this.$el)?void 0:t.closest("form"))||null,this._setupColSpanObserver()):(this._resizeObserver&&this._formElement&&(this._resizeObserver.unobserve(this._formElement),this._resizeObserver.disconnect(),this._resizeObserver=null),this.colSpanClass="")}},computed:{fieldClassName(){return{"k-form-field":!0,"k-rtl":"rtl"===this.$props.dir,...this.colSpanClass?{[this.colSpanClass]:!0}:{}}}},methods:{_updateColSpanClass(){const e="undefined"!=typeof window?window.innerWidth:0,t=this._formElement?l(this._formElement):e,s=u(this.$props.colSpan,t);this.colSpanClass=m(s)},_setupColSpanObserver(){this._resizeObserver&&(this._resizeObserver.disconnect(),this._resizeObserver=null),this._updateColSpanClass(),this._formElement&&"undefined"!=typeof window&&"ResizeObserver"in window&&(this._resizeObserver=new ResizeObserver(()=>this._updateColSpanClass()),this._resizeObserver.observe(this._formElement))}},render(){const e=s.getDefaultSlots(this);return t.createVNode("div",{class:this.fieldClassName},[e])}}),F=t.defineComponent({name:"KendoFormElement",props:{horizontal:Boolean,size:{type:String,default:"medium",validator:function(e){return[null,"small","medium","large"].includes(e)}},cols:[Number,Array],gutters:[String,Number,Object,Array]},data:()=>({columnClass:"",gapStyle:""}),created(){s.validatePackage(o),this._resizeObserver=null},inject:{kendoForm:{default:null}},mounted(){var e;this._handlePasteEvent=e=>{var t;const s=null==(t=e.detail)?void 0:t.fieldValues;s&&this.kendoForm&&Object.entries(s).forEach(([e,t])=>{this.kendoForm.onChange(e,{value:t})})},null==(e=this.$el)||e.addEventListener(s.KENDO_PASTE_EVENT_NAME,this._handlePasteEvent),this.$props.cols&&this._setupColsObserver()},beforeUnmount(){var e;this._resizeObserver&&this.$el&&(this._resizeObserver.unobserve(this.$el),this._resizeObserver.disconnect()),null==(e=this.$el)||e.removeEventListener(s.KENDO_PASTE_EVENT_NAME,this._handlePasteEvent)},watch:{cols(e){e?this._setupColsObserver():(this._resizeObserver&&this.$el&&(this._resizeObserver.unobserve(this.$el),this._resizeObserver.disconnect(),this._resizeObserver=null),this.columnClass="")}},computed:{formElementClassName(){const{size:e}=this.$props;return{"k-form":!0,[`k-form-${s.kendoThemeMaps.sizeMap[e]||e}`]:e,"k-form-horizontal":!0===this.$props.horizontal}}},methods:{handleSubmit(e){this.kendoForm&&this.kendoForm.onSubmit(e)},_updateColumnClass(){const e="undefined"!=typeof window?window.innerWidth:0,t=this.$el?l(this.$el):e,s=a(this.$props.cols,t);this.columnClass=h(s);const i=p(this.$props.gutters,t);this.gapStyle=f(i,{rows:"0px",cols:"32px"})},_setupColsObserver(){this._resizeObserver&&(this._resizeObserver.disconnect(),this._resizeObserver=null),this._updateColumnClass(),this.$el&&"undefined"!=typeof window&&"ResizeObserver"in window&&(this._resizeObserver=new ResizeObserver(()=>this._updateColumnClass()),this._resizeObserver.observe(this.$el))}},render(){const e=s.getDefaultSlots(this);return t.createVNode("form",{class:this.formElementClassName,onSubmit:this.handleSubmit},[this.$props.cols?t.createVNode("div",{class:`k-form-layout k-d-grid ${this.columnClass}`,style:{gap:this.gapStyle||"0px 32px"}},[e]):e])}}),b={rows:"0px",cols:"16px"},y=t.defineComponent({name:"KendoFormFieldSet",props:{cols:[Number,Array],colSpan:[Number,Array],gutters:[String,Number,Object,Array],legend:String},data:()=>({columnClass:"",colSpanClass:"",gapStyle:""}),created(){s.validatePackage(o),this._resizeObserver=null,this._formElement=null},mounted(){var e;this._formElement=(null==(e=this.$el)?void 0:e.closest("form"))||null,(void 0!==this.$props.cols||void 0!==this.$props.colSpan)&&this._setupObserver()},beforeUnmount(){this._resizeObserver&&this._formElement&&(this._resizeObserver.unobserve(this._formElement),this._resizeObserver.disconnect())},watch:{cols(e){void 0!==e?this._setupObserver():(this._resizeObserver&&this._formElement&&(this._resizeObserver.unobserve(this._formElement),this._resizeObserver.disconnect(),this._resizeObserver=null),this.columnClass="",this.gapStyle="")},colSpan(e){void 0!==e?this._setupObserver():this.colSpanClass=""},gutters(){this._update()}},computed:{fieldsetClass(){return["k-form-fieldset",this.colSpanClass].filter(Boolean).join(" ")},divClass(){return["k-form-layout","k-d-grid",this.columnClass].filter(Boolean).join(" ")}},methods:{_update(){const e="undefined"!=typeof window?window.innerWidth:0,t=this._formElement?l(this._formElement):e;if(void 0!==this.$props.cols){const e=a(this.$props.cols,t);this.columnClass=h(e)}if(void 0!==this.$props.colSpan){const e=u(this.$props.colSpan,t);this.colSpanClass=m(e)}const s=void 0!==this.$props.cols?b:void 0,i=void 0!==this.$props.gutters?this.$props.gutters:s;if(void 0!==i){const e=p(i,t);this.gapStyle=f(e,b)}else this.gapStyle=""},_setupObserver(){this._resizeObserver&&(this._resizeObserver.disconnect(),this._resizeObserver=null),this._update(),this._formElement&&"undefined"!=typeof window&&"ResizeObserver"in window&&(this._resizeObserver=new ResizeObserver(()=>this._update()),this._resizeObserver.observe(this._formElement))}},render(){const e=s.getDefaultSlots(this),{legend:i}=this.$props;return t.createVNode("fieldset",{class:this.fieldsetClass},[i&&t.createVNode("legend",{class:"k-form-legend"},[i]),this.$props.cols?t.createVNode("div",{class:this.divClass,style:{gap:this.gapStyle||"0px 16px"}},[e]):e])}});e.Field=i,e.FieldArray=n,e.FieldWrapper=v,e.Form=r,e.FormElement=F,e.FormFieldSet=y});
package/index.d.mts CHANGED
@@ -21,4 +21,7 @@ import { KeyValue } from './interfaces/KeyValue.js';
21
21
  import { FieldWrapper, FieldWrapperProps } from './FieldWrapper.js';
22
22
  import { FormElement, FormElementProps } from './FormElement.js';
23
23
  import { FormSubmitClickEvent } from './interfaces/FormSubmitClickEvent.js';
24
- export { FieldArray, type FieldArrayProps, type FieldArrayRenderProps, Field, type FieldProps, type FieldRenderProps, Form, type FormProps, type FormRenderProps, type FieldInjectedProps, type FormValidatorType, type FieldValidatorType, type KeyValue, FieldWrapper, type FieldWrapperProps, FormElement, type FormElementProps, type FormSubmitClickEvent };
24
+ import { ResponsiveFormBreakPoint } from './interfaces/ResponsiveFormBreakPoint.js';
25
+ import { Gutters } from './interfaces/Gutters.js';
26
+ import { FormFieldSet, FormFieldSetProps } from './FormFieldSet.js';
27
+ export { FieldArray, type FieldArrayProps, type FieldArrayRenderProps, Field, type FieldProps, type FieldRenderProps, Form, type FormProps, type FormRenderProps, type FieldInjectedProps, type FormValidatorType, type FieldValidatorType, type KeyValue, FieldWrapper, type FieldWrapperProps, FormElement, type FormElementProps, type FormSubmitClickEvent, type ResponsiveFormBreakPoint, type Gutters, FormFieldSet, type FormFieldSetProps };
package/index.d.ts CHANGED
@@ -21,4 +21,7 @@ import { KeyValue } from './interfaces/KeyValue';
21
21
  import { FieldWrapper, FieldWrapperProps } from './FieldWrapper';
22
22
  import { FormElement, FormElementProps } from './FormElement';
23
23
  import { FormSubmitClickEvent } from './interfaces/FormSubmitClickEvent';
24
- export { FieldArray, type FieldArrayProps, type FieldArrayRenderProps, Field, type FieldProps, type FieldRenderProps, Form, type FormProps, type FormRenderProps, type FieldInjectedProps, type FormValidatorType, type FieldValidatorType, type KeyValue, FieldWrapper, type FieldWrapperProps, FormElement, type FormElementProps, type FormSubmitClickEvent };
24
+ import { ResponsiveFormBreakPoint } from './interfaces/ResponsiveFormBreakPoint';
25
+ import { Gutters } from './interfaces/Gutters';
26
+ import { FormFieldSet, FormFieldSetProps } from './FormFieldSet';
27
+ export { FieldArray, type FieldArrayProps, type FieldArrayRenderProps, Field, type FieldProps, type FieldRenderProps, Form, type FormProps, type FormRenderProps, type FieldInjectedProps, type FormValidatorType, type FieldValidatorType, type KeyValue, FieldWrapper, type FieldWrapperProps, FormElement, type FormElementProps, type FormSubmitClickEvent, type ResponsiveFormBreakPoint, type Gutters, FormFieldSet, type FormFieldSetProps };
package/index.js CHANGED
@@ -5,4 +5,4 @@
5
5
  * Licensed under commercial license. See LICENSE.md in the package root for more information
6
6
  *-------------------------------------------------------------------------------------------
7
7
  */
8
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./Field.js"),r=require("./Form.js"),i=require("./FieldArray.js"),l=require("./FieldWrapper.js"),o=require("./FormElement.js");exports.Field=e.Field;exports.Form=r.Form;exports.FieldArray=i.FieldArray;exports.FieldWrapper=l.FieldWrapper;exports.FormElement=o.FormElement;
8
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./Field.js"),r=require("./Form.js"),i=require("./FieldArray.js"),F=require("./FieldWrapper.js"),o=require("./FormElement.js"),l=require("./FormFieldSet.js");exports.Field=e.Field;exports.Form=r.Form;exports.FieldArray=i.FieldArray;exports.FieldWrapper=F.FieldWrapper;exports.FormElement=o.FormElement;exports.FormFieldSet=l.FormFieldSet;
package/index.mjs CHANGED
@@ -7,13 +7,15 @@
7
7
  */
8
8
  import { Field as e } from "./Field.mjs";
9
9
  import { Form as p } from "./Form.mjs";
10
- import { FieldArray as f } from "./FieldArray.mjs";
11
- import { FieldWrapper as F } from "./FieldWrapper.mjs";
10
+ import { FieldArray as F } from "./FieldArray.mjs";
11
+ import { FieldWrapper as x } from "./FieldWrapper.mjs";
12
12
  import { FormElement as d } from "./FormElement.mjs";
13
+ import { FormFieldSet as a } from "./FormFieldSet.mjs";
13
14
  export {
14
15
  e as Field,
15
- f as FieldArray,
16
- F as FieldWrapper,
16
+ F as FieldArray,
17
+ x as FieldWrapper,
17
18
  p as Form,
18
- d as FormElement
19
+ d as FormElement,
20
+ a as FormFieldSet
19
21
  };
@@ -6,6 +6,7 @@
6
6
  *-------------------------------------------------------------------------------------------
7
7
  */
8
8
  import { FieldValidatorType } from './FieldValidator';
9
+ import { ResponsiveFormBreakPoint } from './ResponsiveFormBreakPoint';
9
10
  /**
10
11
  * Represents the props of the Field component that is used inside the Kendo U for Vue Form component.
11
12
  */
@@ -40,6 +41,17 @@ export interface FieldProps {
40
41
  * That why this event should be used only for executing custom logic.
41
42
  */
42
43
  onChange?: (event: any) => void;
44
+ /**
45
+ * Sets how many columns the field spans in the form layout.
46
+ * Requires the parent `FormElement` to have the `cols` prop set.
47
+ * Accepts a number or an array of responsive breakpoints.
48
+ *
49
+ * @example
50
+ * ```vue
51
+ * <Field name="fullName" :component="Input" :col-span="2" />
52
+ * ```
53
+ */
54
+ colSpan?: number | ResponsiveFormBreakPoint[];
43
55
  /**
44
56
  * @hidden
45
57
  */
@@ -21,6 +21,20 @@ export interface FormProps {
21
21
  initialValues?: {
22
22
  [name: string]: any;
23
23
  };
24
+ /**
25
+ * Validation errors that override field and form validators.
26
+ *
27
+ * Provides validation errors directly as an object, unlike the `validator` prop which expects a callback.
28
+ * When both `validator` and `errors` exist for a field, the `errors` prop takes precedence.
29
+ *
30
+ * @example
31
+ * ```vue
32
+ * <Form :errors="serverErrors" @submit="handleSubmit" :render-form="renderForm" />
33
+ * ```
34
+ */
35
+ errors?: {
36
+ [name: string]: string;
37
+ };
24
38
  /**
25
39
  * The validation function for the Form level.
26
40
  * Should return key-value pair where the key is the field path and the value is the error message.
@@ -30,6 +44,18 @@ export interface FormProps {
30
44
  * Currently, `validator` supports only synchronous functions.
31
45
  */
32
46
  validator?: FormValidatorType;
47
+ /**
48
+ * Fires each time any field value changes.
49
+ *
50
+ * The third parameter `valueGetter` allows accessing other field values,
51
+ * useful for cross-field validation or clearing related errors.
52
+ *
53
+ * @example
54
+ * ```vue
55
+ * <Form :on-change="handleChange" :render-form="renderForm" />
56
+ * ```
57
+ */
58
+ onChange?: (fieldName: string, value: any, valueGetter: (name: string) => any) => void;
33
59
  /**
34
60
  * The submission handler for the Form.
35
61
  * Called when at least one field has been modified, the user pressed
@@ -0,0 +1,25 @@
1
+ /**
2
+ * @license
3
+ *-------------------------------------------------------------------------------------------
4
+ * Copyright © 2026 Progress Software Corporation. All rights reserved.
5
+ * Licensed under commercial license. See LICENSE.md in the package root for more information
6
+ *-------------------------------------------------------------------------------------------
7
+ */
8
+ import { ResponsiveFormBreakPoint } from './ResponsiveFormBreakPoint';
9
+ /**
10
+ * Represents the [gutters](https://developer.mozilla.org/en-US/docs/Web/CSS/gap) configuration for a form layout.
11
+ * It allows defining the spacing between the columns and rows of the form.
12
+ * Each property can be a number or an array of responsive breakpoints.
13
+ */
14
+ export interface Gutters {
15
+ /**
16
+ * Defines the gutters for the columns in the form.
17
+ * Can be a number or an array of responsive breakpoints.
18
+ */
19
+ cols?: string | number | ResponsiveFormBreakPoint[];
20
+ /**
21
+ * Defines the gutters for the rows in the form.
22
+ * Can be a number or an array of responsive breakpoints.
23
+ */
24
+ rows?: string | number | ResponsiveFormBreakPoint[];
25
+ }
@@ -0,0 +1,25 @@
1
+ /**
2
+ * @license
3
+ *-------------------------------------------------------------------------------------------
4
+ * Copyright © 2026 Progress Software Corporation. All rights reserved.
5
+ * Licensed under commercial license. See LICENSE.md in the package root for more information
6
+ *-------------------------------------------------------------------------------------------
7
+ */
8
+ /**
9
+ * Defines responsive breakpoints for form layouts.
10
+ * Each breakpoint sets minimum and maximum widths and values for columns or spacing at different screen sizes.
11
+ */
12
+ export interface ResponsiveFormBreakPoint {
13
+ /**
14
+ * Sets the minimum screen width in pixels for this breakpoint.
15
+ */
16
+ minWidth?: number;
17
+ /**
18
+ * Sets the maximum screen width in pixels for this breakpoint.
19
+ */
20
+ maxWidth?: number;
21
+ /**
22
+ * Sets the number of columns or spacing for form controls at this screen size.
23
+ */
24
+ value: number | string;
25
+ }
@@ -5,4 +5,4 @@
5
5
  * Licensed under commercial license. See LICENSE.md in the package root for more information
6
6
  *-------------------------------------------------------------------------------------------
7
7
  */
8
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e={name:"@progress/kendo-vue-form",productName:"Kendo UI for Vue",productCode:"KENDOUIVUE",productCodes:["KENDOUIVUE"],publishDate: 1776348799,version:"8.2.0-develop.1",licensingDocsUrl:"https://www.telerik.com/kendo-vue-ui/my-license/"};exports.packageMetadata=e;
8
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e={name:"@progress/kendo-vue-form",productName:"Kendo UI for Vue",productCode:"KENDOUIVUE",productCodes:["KENDOUIVUE"],publishDate: 1776857191,version:"8.3.0-develop.1",licensingDocsUrl:"https://www.telerik.com/kendo-vue-ui/my-license/"};exports.packageMetadata=e;
@@ -10,8 +10,8 @@ const e = {
10
10
  productName: "Kendo UI for Vue",
11
11
  productCode: "KENDOUIVUE",
12
12
  productCodes: ["KENDOUIVUE"],
13
- publishDate: 1776348799,
14
- version: "8.2.0-develop.1",
13
+ publishDate: 1776857191,
14
+ version: "8.3.0-develop.1",
15
15
  licensingDocsUrl: "https://www.telerik.com/kendo-vue-ui/my-license/"
16
16
  };
17
17
  export {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@progress/kendo-vue-form",
3
- "version": "8.2.0-develop.1",
3
+ "version": "8.3.0-develop.1",
4
4
  "description": "TODO",
5
5
  "author": "Progress",
6
6
  "license": "SEE LICENSE IN LICENSE.md",
@@ -25,7 +25,7 @@
25
25
  "sideEffects": false,
26
26
  "peerDependencies": {
27
27
  "@progress/kendo-licensing": "^1.7.2",
28
- "@progress/kendo-vue-common": "8.2.0-develop.1",
28
+ "@progress/kendo-vue-common": "8.3.0-develop.1",
29
29
  "vue": "^3.0.2"
30
30
  },
31
31
  "dependencies": {},
@@ -45,7 +45,7 @@
45
45
  "package": {
46
46
  "productName": "Kendo UI for Vue",
47
47
  "productCode": "KENDOUIVUE",
48
- "publishDate": 1776348799,
48
+ "publishDate": 1776857191,
49
49
  "licensingDocsUrl": "https://www.telerik.com/kendo-vue-ui/my-license/"
50
50
  }
51
51
  },
package/utils.d.ts ADDED
@@ -0,0 +1,62 @@
1
+ /**
2
+ * @license
3
+ *-------------------------------------------------------------------------------------------
4
+ * Copyright © 2026 Progress Software Corporation. All rights reserved.
5
+ * Licensed under commercial license. See LICENSE.md in the package root for more information
6
+ *-------------------------------------------------------------------------------------------
7
+ */
8
+ import { ResponsiveFormBreakPoint } from './interfaces/ResponsiveFormBreakPoint';
9
+ import { Gutters } from './interfaces/Gutters';
10
+ /**
11
+ * Returns the inner width of a DOM element, excluding padding and borders.
12
+ * Named `getElementInnerWidth` to avoid confusion with `window.innerWidth`.
13
+ * @hidden
14
+ */
15
+ export declare function getElementInnerWidth(element: HTMLElement): number;
16
+ /**
17
+ * Returns the value for the current container width based on responsive breakpoints.
18
+ *
19
+ * Breakpoints MUST be provided in ascending order (by minWidth / maxWidth). The function
20
+ * relies on positional lookup — the previous entry's `maxWidth` fills a missing `minWidth`,
21
+ * and the next entry's `minWidth` fills a missing `maxWidth`. Misordered breakpoints will
22
+ * silently produce incorrect lookups; order is not validated here for performance.
23
+ * @hidden
24
+ */
25
+ export declare function processBreakpoints(breakpoints: ResponsiveFormBreakPoint[], containerWidth: number): number | string;
26
+ /**
27
+ * @hidden
28
+ */
29
+ export declare function calculateColumns(cols: number | ResponsiveFormBreakPoint[] | undefined, containerWidth: number): number | null;
30
+ /**
31
+ * @hidden
32
+ */
33
+ export declare function generateColumnClass(columnsNumber: number | null): string;
34
+ /**
35
+ * @hidden
36
+ */
37
+ export declare function calculateColSpan(colSpan: number | ResponsiveFormBreakPoint[], containerWidth: number): number | null;
38
+ /**
39
+ * @hidden
40
+ */
41
+ export declare function generateColSpanClass(colSpan: number | null): string;
42
+ /**
43
+ * @hidden
44
+ */
45
+ export declare function processCssValue(value: number | string | null | undefined): string | null;
46
+ /**
47
+ * @hidden
48
+ */
49
+ export declare function calculateGutters(gutters: number | string | ResponsiveFormBreakPoint[] | Gutters | undefined, containerWidth: number): {
50
+ cols: number | string | null;
51
+ rows: number | string | null;
52
+ } | null;
53
+ /**
54
+ * @hidden
55
+ */
56
+ export declare function generateGuttersStyling(gutters: {
57
+ cols?: number | string | null;
58
+ rows?: number | string | null;
59
+ } | null, defaultGutters: {
60
+ cols?: number | string | null;
61
+ rows?: number | string | null;
62
+ }): string;
package/utils.js ADDED
@@ -0,0 +1,8 @@
1
+ /**
2
+ * @license
3
+ *-------------------------------------------------------------------------------------------
4
+ * Copyright © 2026 Progress Software Corporation. All rights reserved.
5
+ * Licensed under commercial license. See LICENSE.md in the package root for more information
6
+ *-------------------------------------------------------------------------------------------
7
+ */
8
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const f=" ";function p(n){let e=n.clientWidth;const r=getComputedStyle(n);return e-=(parseFloat(r.paddingLeft)||0)+(parseFloat(r.borderLeftWidth)||0),e-=(parseFloat(r.paddingRight)||0)+(parseFloat(r.borderRightWidth)||0),e}function i(n,e){var r,l;if(!(n!=null&&n.length)||e==null)return"";for(const[t,o]of n.entries()){const s=t>0&&n[t-1].maxWidth!==void 0?n[t-1].maxWidth:void 0,u=t<n.length-1&&n[t+1].minWidth!==void 0?n[t+1].minWidth:void 0,a=(r=o.minWidth)!=null?r:s!==void 0?s+1:0,d=(l=o.maxWidth)!=null?l:u!==void 0?u-1:1/0;if(e>=a&&e<=d)return o.value}return""}function y(n,e){if(!n)return null;if(Array.isArray(n)&&n.length>0){const r=i(n,e)||null;return typeof r=="string"?parseInt(r,10):r}else if(typeof n=="number")return n;return null}function m(n){return n&&n>0?`k-grid-cols-${n}`:""}function C(n,e){if(!n)return null;if(typeof n=="number")return n;if(Array.isArray(n)&&n.length>0){const r=i(n,e)||null;return typeof r=="string"?parseInt(r,10):r}return null}function h(n){return n?`k-col-span-${n}`:""}function c(n){if(n==null)return null;if(typeof n=="number")return`${n}px`;const e=n.trim(),r=parseInt(e,10);return!isNaN(r)&&Number.isFinite(r)?r.toString()===e?`${r}px`:n:null}function w(n,e){if(!n)return null;if(typeof n=="number")return{cols:n,rows:n};if(typeof n=="string"){if(!n.includes(f))return{cols:n,rows:n};const r=n.split(f);return{cols:r[1],rows:r[0]}}else if(Array.isArray(n)){const r=i(n,e)||null;return r!==null?{cols:r,rows:r}:null}else if(typeof n=="object"){const r=n,l={rows:null,cols:null};return r.cols!==void 0&&r.cols!==null&&(typeof r.cols=="number"||typeof r.cols=="string"?l.cols=r.cols:Array.isArray(r.cols)&&(l.cols=i(r.cols,e)||null)),r.rows!==void 0&&(typeof r.rows=="number"||typeof r.rows=="string"?l.rows=r.rows:Array.isArray(r.rows)&&(l.rows=i(r.rows,e)||null)),l}return null}function x(n,e){var t,o,s,u;const r=c((o=(t=n==null?void 0:n.rows)!=null?t:e.rows)!=null?o:"0px"),l=c((u=(s=n==null?void 0:n.cols)!=null?s:e.cols)!=null?u:"32px");return`${r!=null?r:"0px"} ${l!=null?l:"32px"}`}exports.calculateColSpan=C;exports.calculateColumns=y;exports.calculateGutters=w;exports.generateColSpanClass=h;exports.generateColumnClass=m;exports.generateGuttersStyling=x;exports.getElementInnerWidth=p;exports.processBreakpoints=i;exports.processCssValue=c;
package/utils.mjs ADDED
@@ -0,0 +1,93 @@
1
+ /**
2
+ * @license
3
+ *-------------------------------------------------------------------------------------------
4
+ * Copyright © 2026 Progress Software Corporation. All rights reserved.
5
+ * Licensed under commercial license. See LICENSE.md in the package root for more information
6
+ *-------------------------------------------------------------------------------------------
7
+ */
8
+ function p(n) {
9
+ let i = n.clientWidth;
10
+ const r = getComputedStyle(n);
11
+ return i -= (parseFloat(r.paddingLeft) || 0) + (parseFloat(r.borderLeftWidth) || 0), i -= (parseFloat(r.paddingRight) || 0) + (parseFloat(r.borderRightWidth) || 0), i;
12
+ }
13
+ function f(n, i) {
14
+ var r, o;
15
+ if (!(n != null && n.length) || i == null)
16
+ return "";
17
+ for (const [e, l] of n.entries()) {
18
+ const t = e > 0 && n[e - 1].maxWidth !== void 0 ? n[e - 1].maxWidth : void 0, s = e < n.length - 1 && n[e + 1].minWidth !== void 0 ? n[e + 1].minWidth : void 0, c = (r = l.minWidth) != null ? r : t !== void 0 ? t + 1 : 0, d = (o = l.maxWidth) != null ? o : s !== void 0 ? s - 1 : 1 / 0;
19
+ if (i >= c && i <= d)
20
+ return l.value;
21
+ }
22
+ return "";
23
+ }
24
+ function y(n, i) {
25
+ if (!n)
26
+ return null;
27
+ if (Array.isArray(n) && n.length > 0) {
28
+ const r = f(n, i) || null;
29
+ return typeof r == "string" ? parseInt(r, 10) : r;
30
+ } else if (typeof n == "number")
31
+ return n;
32
+ return null;
33
+ }
34
+ function a(n) {
35
+ return n && n > 0 ? `k-grid-cols-${n}` : "";
36
+ }
37
+ function A(n, i) {
38
+ if (!n)
39
+ return null;
40
+ if (typeof n == "number")
41
+ return n;
42
+ if (Array.isArray(n) && n.length > 0) {
43
+ const r = f(n, i) || null;
44
+ return typeof r == "string" ? parseInt(r, 10) : r;
45
+ }
46
+ return null;
47
+ }
48
+ function C(n) {
49
+ return n ? `k-col-span-${n}` : "";
50
+ }
51
+ function u(n) {
52
+ if (n == null)
53
+ return null;
54
+ if (typeof n == "number")
55
+ return `${n}px`;
56
+ const i = n.trim(), r = parseInt(i, 10);
57
+ return !isNaN(r) && Number.isFinite(r) ? r.toString() === i ? `${r}px` : n : null;
58
+ }
59
+ function m(n, i) {
60
+ if (!n)
61
+ return null;
62
+ if (typeof n == "number")
63
+ return { cols: n, rows: n };
64
+ if (typeof n == "string") {
65
+ if (!n.includes(" "))
66
+ return { cols: n, rows: n };
67
+ const r = n.split(" ");
68
+ return { cols: r[1], rows: r[0] };
69
+ } else if (Array.isArray(n)) {
70
+ const r = f(n, i) || null;
71
+ return r !== null ? { cols: r, rows: r } : null;
72
+ } else if (typeof n == "object") {
73
+ const r = n, o = { rows: null, cols: null };
74
+ return r.cols !== void 0 && r.cols !== null && (typeof r.cols == "number" || typeof r.cols == "string" ? o.cols = r.cols : Array.isArray(r.cols) && (o.cols = f(r.cols, i) || null)), r.rows !== void 0 && (typeof r.rows == "number" || typeof r.rows == "string" ? o.rows = r.rows : Array.isArray(r.rows) && (o.rows = f(r.rows, i) || null)), o;
75
+ }
76
+ return null;
77
+ }
78
+ function h(n, i) {
79
+ var e, l, t, s;
80
+ const r = u((l = (e = n == null ? void 0 : n.rows) != null ? e : i.rows) != null ? l : "0px"), o = u((s = (t = n == null ? void 0 : n.cols) != null ? t : i.cols) != null ? s : "32px");
81
+ return `${r != null ? r : "0px"} ${o != null ? o : "32px"}`;
82
+ }
83
+ export {
84
+ A as calculateColSpan,
85
+ y as calculateColumns,
86
+ m as calculateGutters,
87
+ C as generateColSpanClass,
88
+ a as generateColumnClass,
89
+ h as generateGuttersStyling,
90
+ p as getElementInnerWidth,
91
+ f as processBreakpoints,
92
+ u as processCssValue
93
+ };