vue-formic-dynamic-forms
Version:
Powerful library for creating dynamic, validated forms in Vue 3 based on JSON schemas
1,568 lines • 60.2 kB
JavaScript
var Te = Object.defineProperty;
var Re = (a, e, i) => e in a ? Te(a, e, { enumerable: !0, configurable: !0, writable: !0, value: i }) : a[e] = i;
var Z = (a, e, i) => Re(a, typeof e != "symbol" ? e + "" : e, i);
import { ref as Q, computed as C, watch as $e, readonly as J, reactive as Le, defineComponent as _, createElementBlock as m, createCommentVNode as v, openBlock as c, normalizeClass as A, renderSlot as F, createElementVNode as $, createTextVNode as K, toDisplayString as S, mergeProps as X, onMounted as Se, onUnmounted as Ve, Fragment as Y, renderList as H, withDirectives as we, withModifiers as fe, vShow as Ee, useSlots as Oe, createBlock as ce, resolveDynamicComponent as Me, createSlots as me, withCtx as pe, normalizeProps as Ne, guardReactiveProps as He, unref as E } from "vue";
const le = {
equals: (a, e) => a === e,
notEquals: (a, e) => a !== e,
contains: (a, e) => typeof a == "string" && typeof e == "string" || Array.isArray(a) ? a.includes(e) : !1,
notContains: (a, e) => !le.contains(a, e),
gt: (a, e) => {
const i = Number(a), s = Number(e);
return !isNaN(i) && !isNaN(s) && i > s;
},
gte: (a, e) => {
const i = Number(a), s = Number(e);
return !isNaN(i) && !isNaN(s) && i >= s;
},
lt: (a, e) => {
const i = Number(a), s = Number(e);
return !isNaN(i) && !isNaN(s) && i < s;
},
lte: (a, e) => {
const i = Number(a), s = Number(e);
return !isNaN(i) && !isNaN(s) && i <= s;
},
empty: (a) => a == null ? !0 : typeof a == "string" ? a.trim() === "" : Array.isArray(a) ? a.length === 0 : typeof a == "object" ? Object.keys(a).length === 0 : !1,
notEmpty: (a) => !le.empty(a),
in: (a, e) => Array.isArray(e) && e.includes(a),
notIn: (a, e) => !le.in(a, e)
};
function ze(a, e) {
const i = Pe(e, a.field), s = le[a.operator];
return s ? a.operator === "in" || a.operator === "notIn" ? s(i, a.values || []) : a.operator === "empty" || a.operator === "notEmpty" ? s(i) : s(i, a.value) : (console.warn(`Unknown operator: ${a.operator}`), !1);
}
function se(a, e, i = "and") {
if (!a || a.length === 0)
return !0;
const s = a.map((f) => ze(f, e));
return i === "and" ? s.every((f) => f) : s.some((f) => f);
}
function Ae(a, e) {
const i = a.logic || "and";
let s = !0, f = !1, r = !1;
return a.show && (s = se(a.show, e, i)), a.hide && se(a.hide, e, i) && (s = !1), a.required && (f = se(a.required, e, i)), a.disabled && (r = se(a.disabled, e, i)), { visible: s, required: f, disabled: r };
}
function Pe(a, e) {
return e.split(".").reduce((i, s) => i && typeof i == "object" ? i[s] : void 0, a);
}
class Ie {
constructor(e = {}) {
Z(this, "formData", {});
Z(this, "fieldConditions", /* @__PURE__ */ new Map());
Z(this, "cache", /* @__PURE__ */ new Map());
this.formData = { ...e };
}
/**
* Обновляет данные формы
*/
updateFormData(e) {
this.formData = { ...e }, this.cache.clear();
}
/**
* Регистрирует условия для поля
*/
registerFieldConditions(e, i) {
this.fieldConditions.set(e, i), this.cache.delete(e);
}
/**
* Получает состояние поля на основе условий
*/
getFieldState(e) {
const i = e;
if (this.cache.has(i))
return this.cache.get(i);
const s = this.fieldConditions.get(e);
let f = { visible: !0, required: !1, disabled: !1 };
return s && (f = Ae(s, this.formData)), this.cache.set(i, f), f;
}
/**
* Получает состояния всех зарегистрированных полей
*/
getAllFieldStates() {
const e = {};
for (const i of this.fieldConditions.keys())
e[i] = this.getFieldState(i);
return e;
}
/**
* Проверяет, зависит ли поле от других полей
*/
getFieldDependencies(e) {
const i = this.fieldConditions.get(e);
if (!i) return [];
const s = /* @__PURE__ */ new Set(), f = (r) => {
r && r.forEach((l) => {
s.add(l.field);
});
};
return f(i.show), f(i.hide), f(i.required), f(i.disabled), Array.from(s);
}
/**
* Получает все поля, которые зависят от указанного поля
*/
getDependentFields(e) {
const i = [];
for (const s of this.fieldConditions.keys())
this.getFieldDependencies(s).includes(e) && i.push(s);
return i;
}
}
function Ge(a, e) {
var ie;
const {
formData: i,
validationEngine: s,
conditionsEngine: f,
validateOnChange: r = !0,
validateOnBlur: l = !0,
debounceValidation: o = 300
} = e, t = Q({
value: a.defaultValue ?? "",
error: null,
touched: !1,
dirty: !1,
validating: !1,
valid: !0,
visible: !0,
disabled: !1,
required: ((ie = a.validation) == null ? void 0 : ie.required) ?? !1
}), b = Q([]), w = Q(!1), O = C({
get: () => t.value.value,
set: (g) => {
t.value.value = g, t.value.dirty = !0, i.value[a.name] = g, r && n();
}
}), h = C(() => t.value.visible), q = C(() => {
var g;
return t.value.disabled || ((g = a.attributes) == null ? void 0 : g.disabled);
}), I = C(() => t.value.required), M = C(() => !!t.value.error), G = C(() => t.value.validating), d = C(() => {
var g, B;
return a.conditions ? Ae(a.conditions, i.value) : {
visible: !0,
required: ((g = a.validation) == null ? void 0 : g.required) ?? !1,
disabled: ((B = a.attributes) == null ? void 0 : B.disabled) ?? !1
};
});
$e(d, (g) => {
t.value.visible = g.visible, t.value.required = g.required, t.value.disabled = g.disabled;
}, { immediate: !0 });
async function n() {
t.value.validating = !0;
try {
let g;
return o > 0 ? g = await s.validateFieldDebounced(
a,
t.value.value,
i.value,
o
) : g = await s.validateField(
a,
t.value.value,
i.value
), t.value.error = g.error || null, t.value.valid = g.isValid, g;
} finally {
t.value.validating = !1;
}
}
function k() {
}
function y() {
t.value.touched = !0, l && n();
}
function D(g) {
const B = g.target;
let L = B.value;
switch (a.type) {
case "number":
if (B.value === "")
L = "";
else {
const U = B.valueAsNumber;
L = isNaN(U) ? B.value : U;
}
break;
case "checkbox":
L = B.checked;
break;
case "date":
case "datetime-local":
L = B.valueAsDate || B.value;
break;
case "file":
L = B.files;
break;
default:
L = B.value;
}
O.value = L;
}
function N(g) {
D(g);
}
async function W() {
if (Array.isArray(a.options)) {
b.value = a.options;
return;
}
if (typeof a.options == "function") {
w.value = !0;
try {
b.value = await a.options();
} catch {
b.value = [];
} finally {
w.value = !1;
}
}
}
function x() {
t.value.value = a.defaultValue ?? "", t.value.error = null, t.value.touched = !1, t.value.dirty = !1, t.value.validating = !1, t.value.valid = !0, i.value[a.name] = t.value.value;
}
function re(g) {
O.value = g;
}
function ae(g) {
t.value.error = g, t.value.valid = !g;
}
function ne() {
ae(null);
}
const te = C(() => {
var B, L, U, u, p, V, j, z, De, ge, Ce, ke, Fe;
const g = {
id: `field-${a.name}`,
name: a.name,
type: a.type,
value: O.value,
required: I.value,
disabled: q.value,
readonly: (B = a.attributes) == null ? void 0 : B.readonly,
placeholder: (L = a.attributes) == null ? void 0 : L.placeholder,
autocomplete: (U = a.attributes) == null ? void 0 : U.autocomplete,
pattern: (u = a.attributes) == null ? void 0 : u.pattern,
min: (p = a.attributes) == null ? void 0 : p.min,
max: (V = a.attributes) == null ? void 0 : V.max,
step: (j = a.attributes) == null ? void 0 : j.step,
multiple: (z = a.attributes) == null ? void 0 : z.multiple,
accept: (De = a.attributes) == null ? void 0 : De.accept,
rows: (ge = a.attributes) == null ? void 0 : ge.rows,
cols: (Ce = a.attributes) == null ? void 0 : Ce.cols,
maxlength: (ke = a.attributes) == null ? void 0 : ke.maxlength,
minlength: (Fe = a.attributes) == null ? void 0 : Fe.minlength,
"aria-invalid": M.value ? "true" : "false",
"aria-describedby": M.value ? `field-${a.name}-error` : void 0
};
return Object.fromEntries(
Object.entries(g).filter(([, je]) => je !== void 0)
);
}), oe = C(() => {
const g = [];
return a.fieldClass && g.push(a.fieldClass), M.value && a.errorClass && g.push(a.errorClass), g.join(" ");
});
function de() {
i.value[a.name] = t.value.value, a.options && W(), a.conditions && f.registerFieldConditions(a.name, a.conditions);
}
return de(), {
// Состояние
fieldState: J(t),
fieldValue: O,
fieldOptions: J(b),
loadingOptions: J(w),
// Вычисляемые свойства
isVisible: h,
isDisabled: q,
isRequired: I,
hasError: M,
isValidating: G,
// Методы
validateField: n,
resetField: x,
setValue: re,
setError: ae,
clearError: ne,
loadOptions: W,
// Обработчики событий
handleFocus: k,
handleBlur: y,
handleInput: D,
handleChange: N,
// Атрибуты для привязки
inputAttrs: te,
inputClasses: oe,
// Схема поля
fieldSchema: J(a)
};
}
function R(a, e, i) {
return (s) => ({
type: a,
validate: e,
message: s || i || `Validation failed for ${a}`
});
}
const We = R(
"required",
(a) => a == null ? !1 : typeof a == "string" ? a.trim().length > 0 : Array.isArray(a) ? a.length > 0 : typeof a == "boolean" ? !0 : typeof a == "number" ? !isNaN(a) : !0,
"Это поле обязательно для заполнения"
), Ue = (a, e) => R(
"minLength",
(i) => i == null || i === "" ? !0 : String(i).length >= a,
e || `Минимальная длина: ${a} символов`
)(), Ye = (a, e) => R(
"maxLength",
(i) => i == null || i === "" ? !0 : String(i).length <= a,
e || `Максимальная длина: ${a} символов`
)(), Ke = (a, e) => R(
"min",
(i) => {
if (i == null || i === "") return !0;
const s = Number(i);
return !isNaN(s) && s >= a;
},
e || `Минимальное значение: ${a}`
)(), Ze = (a, e) => R(
"max",
(i) => {
if (i == null || i === "") return !0;
const s = Number(i);
return !isNaN(s) && s <= a;
},
e || `Максимальное значение: ${a}`
)(), Je = R(
"email",
(a) => a ? /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(String(a)) : !0,
"Введите корректный email адрес"
), Qe = R(
"url",
(a) => {
if (!a) return !0;
try {
return new URL(String(a)), !0;
} catch {
return !1;
}
},
"Введите корректный URL"
), Xe = (a, e) => R(
"pattern",
(i) => i ? (typeof a == "string" ? new RegExp(a) : a).test(String(i)) : !0,
e || "Значение не соответствует требуемому формату"
)(), _e = (a, e) => R(
"oneOf",
(i) => i == null ? !0 : a.includes(i),
e || `Значение должно быть одним из: ${a.join(", ")}`
)(), xe = (a, e) => R(
"notOneOf",
(i) => i == null ? !0 : !a.includes(i),
e || `Значение не может быть одним из: ${a.join(", ")}`
)(), ea = R(
"number",
(a) => a == null || a === "" ? !0 : !isNaN(Number(a)),
"Значение должно быть числом"
), aa = R(
"integer",
(a) => {
if (a == null || a === "") return !0;
const e = Number(a);
return !isNaN(e) && Number.isInteger(e);
},
"Значение должно быть целым числом"
), ta = (a, e) => R(
"custom",
a,
e || "Кастомная валидация не прошла"
)(), ia = (a, e) => R(
"sameAs",
(i, s) => {
const f = s[a];
return i === f;
},
e || `Значение должно совпадать с полем ${a}`
)(), sa = (a, e) => R(
"differentFrom",
(i, s) => {
const f = s[a];
return i !== f;
},
e || `Значение должно отличаться от поля ${a}`
)(), P = {
required: We,
minLength: Ue,
maxLength: Ye,
min: Ke,
max: Ze,
email: Je,
url: Qe,
pattern: Xe,
oneOf: _e,
notOneOf: xe,
number: ea,
integer: aa,
custom: ta,
sameAs: ia,
differentFrom: sa
};
function ye(a) {
if (typeof window < "u")
switch (a) {
case "yup":
return !!window.yup;
case "zod":
return !!window.z;
case "vee-validate":
return !!window.VeeValidate;
default:
return !1;
}
return !1;
}
const la = {
name: "yup",
isAvailable() {
return ye("yup");
},
async validate(a, e, i) {
if (!this.isAvailable())
return [{
field: "unknown",
message: "Yup library is not available",
type: "error",
value: e
}];
try {
return await a.validate(e, {
context: i,
abortEarly: !1
}), [];
} catch (s) {
return s.inner ? s.inner.map((f) => ({
field: f.path || "unknown",
message: f.message,
type: f.type || "validation",
value: f.value
})) : [{
field: s.path || "unknown",
message: s.message,
type: s.type || "validation",
value: e
}];
}
}
}, ra = {
name: "zod",
isAvailable() {
return ye("zod");
},
async validate(a, e, i) {
if (!this.isAvailable())
return [{
field: "unknown",
message: "Zod library is not available",
type: "error",
value: e
}];
try {
return a.parse(e), [];
} catch (s) {
return s.errors ? s.errors.map((f) => {
var r;
return {
field: ((r = f.path) == null ? void 0 : r.join(".")) || "unknown",
message: f.message,
type: f.code || "validation",
value: e
};
}) : [{
field: "unknown",
message: s.message || "Validation failed",
type: "validation",
value: e
}];
}
}
}, na = {
name: "vee-validate",
isAvailable() {
return ye("vee-validate");
},
async validate(a, e, i) {
if (!this.isAvailable())
return [{
field: "unknown",
message: "VeeValidate library is not available",
type: "error",
value: e
}];
try {
let s;
if (typeof a == "string") {
if (s = window.VeeValidate[a], !s)
throw new Error(`VeeValidate rule "${a}" not found`);
} else
s = a;
const f = await s(e, [], { form: i });
return f === !0 || f === void 0 ? [] : [{
field: "unknown",
message: typeof f == "string" ? f : "Validation failed",
type: "vee-validate",
value: e
}];
} catch (s) {
return [{
field: "unknown",
message: s.message || "Validation failed",
type: "vee-validate",
value: e
}];
}
}
}, qe = /* @__PURE__ */ new Map([
["yup", la],
["zod", ra],
["vee-validate", na]
]);
function ue(a) {
const e = qe.get(a);
return e && e.isAvailable() ? e : null;
}
function yt() {
return Array.from(qe.values()).filter((a) => a.isAvailable());
}
class oa {
constructor() {
Z(this, "abortControllers", /* @__PURE__ */ new Map());
Z(this, "validationCache", /* @__PURE__ */ new Map());
Z(this, "debounceTimers", /* @__PURE__ */ new Map());
}
/**
* Валидирует одно поле
*/
async validateField(e, i, s, f) {
const r = e.name;
this.cancelFieldValidation(r);
const l = new AbortController();
this.abortControllers.set(r, l);
const o = {
fieldName: r,
fieldValue: i,
formData: s,
formSchema: f == null ? void 0 : f.formSchema,
abortSignal: l.signal,
...f
};
try {
const t = await this.validateWithBuiltinValidators(
e,
i,
s,
o
);
if (t.length > 0)
return {
field: r,
isValid: !1,
error: t[0].message,
pending: !1
};
const b = await this.validateWithExternalValidators(
e,
i,
s,
o
);
return b.length > 0 ? {
field: r,
isValid: !1,
error: b[0].message,
pending: !1
} : {
field: r,
isValid: !0,
pending: !1
};
} catch (t) {
return t.name === "AbortError" ? {
field: r,
isValid: !1,
pending: !0
} : {
field: r,
isValid: !1,
error: t.message || "Ошибка валидации",
pending: !1
};
} finally {
this.abortControllers.delete(r);
}
}
/**
* Валидирует всю форму
*/
async validateForm(e, i) {
const s = e.map(
(o) => this.validateField(o, i[o.name], i)
), f = await Promise.allSettled(s), r = {}, l = [];
return f.forEach((o, t) => {
const b = e[t];
if (o.status === "fulfilled") {
const w = o.value;
!w.isValid && w.error && (r[b.name] = w.error, l.push({
field: b.name,
message: w.error,
type: "validation",
value: i[b.name]
}));
} else
r[b.name] = "Ошибка валидации", l.push({
field: b.name,
message: "Ошибка валидации",
type: "error",
value: i[b.name]
});
}), {
isValid: Object.keys(r).length === 0,
errors: r,
fieldErrors: l
};
}
/**
* Валидация с встроенными валидаторами
*/
async validateWithBuiltinValidators(e, i, s, f) {
const r = [], l = e.validation;
if (!l) return r;
const o = [];
l.required && o.push(P.required(l.message)), l.minLength !== void 0 && o.push(P.minLength(l.minLength, l.message)), l.maxLength !== void 0 && o.push(P.maxLength(l.maxLength, l.message)), l.min !== void 0 && o.push(P.min(l.min, l.message)), l.max !== void 0 && o.push(P.max(l.max, l.message)), l.email && o.push(P.email(l.message)), l.url && o.push(P.url(l.message)), l.pattern && o.push(P.pattern(l.pattern, l.message)), l.custom && o.push(P.custom(l.custom, l.message));
for (const t of o)
try {
const b = await t.validate(i, s, e.name);
if (b !== !0) {
r.push({
field: e.name,
message: typeof b == "string" ? b : t.message || "Ошибка валидации",
type: t.type,
value: i
});
break;
}
} catch (b) {
r.push({
field: e.name,
message: b.message || "Ошибка валидации",
type: "error",
value: i
});
break;
}
return r;
}
/**
* Валидация с внешними валидаторами
*/
async validateWithExternalValidators(e, i, s, f) {
const r = e.externalValidation;
if (!r) return [];
const l = [];
if (r.yup) {
const o = ue("yup");
if (o)
try {
const t = await o.validate(r.yup, i, s);
l.push(...t);
} catch {
}
}
if (r.zod) {
const o = ue("zod");
if (o)
try {
const t = await o.validate(r.zod, i, s);
l.push(...t);
} catch {
}
}
if (r.veeValidate) {
const o = ue("vee-validate");
if (o)
try {
const t = await o.validate(r.veeValidate, i, s);
l.push(...t);
} catch {
}
}
if (r.custom)
try {
const o = await r.custom(i, s);
o !== !0 && l.push({
field: e.name,
message: typeof o == "string" ? o : "Кастомная валидация не прошла",
type: "custom",
value: i
});
} catch (o) {
l.push({
field: e.name,
message: o.message || "Ошибка кастомной валидации",
type: "custom-error",
value: i
});
}
return l;
}
/**
* Отменяет валидацию поля
*/
cancelFieldValidation(e) {
const i = this.abortControllers.get(e);
i && (i.abort(), this.abortControllers.delete(e));
const s = this.debounceTimers.get(e);
s && (clearTimeout(s), this.debounceTimers.delete(e));
}
/**
* Валидация с debounce
*/
validateFieldDebounced(e, i, s, f = 300) {
return new Promise((r) => {
const l = e.name, o = this.debounceTimers.get(l);
o && clearTimeout(o);
const t = setTimeout(() => {
this.debounceTimers.delete(l), this.validateField(e, i, s).then(r);
}, f);
this.debounceTimers.set(l, t);
});
}
/**
* Очистка ресурсов
*/
dispose() {
for (const e of this.abortControllers.values())
e.abort();
this.abortControllers.clear();
for (const e of this.debounceTimers.values())
clearTimeout(e);
this.debounceTimers.clear(), this.validationCache.clear();
}
}
function da(a, e) {
var g, B, L, U;
const {
schema: i,
initialData: s = {},
validateOnChange: f = ((g = i.config) == null ? void 0 : g.validateOnChange) ?? !0,
validateOnBlur: r = ((B = i.config) == null ? void 0 : B.validateOnBlur) ?? !0,
validateOnSubmit: l = ((L = i.config) == null ? void 0 : L.validateOnSubmit) ?? !0,
resetOnSubmit: o = ((U = i.config) == null ? void 0 : U.resetOnSubmit) ?? !1,
debounceValidation: t = 300
} = a, b = new oa(), w = new Ie(s), O = Q({}), h = Le({
values: {},
errors: {},
touched: {},
dirty: {},
isSubmitting: !1,
isValidating: !1,
isValid: !0,
isDirty: !1,
submitCount: 0,
fields: {}
}), q = /* @__PURE__ */ new Map();
function I() {
const u = {};
i.fields.forEach((p) => {
var z;
const V = s[p.name] ?? p.defaultValue ?? M(p.type);
u[p.name] = V;
const j = Ge(p, {
formData: O,
validationEngine: b,
conditionsEngine: w,
validateOnChange: f,
validateOnBlur: r,
debounceValidation: t
});
q.set(p.name, j), h.fields[p.name] = {
value: V,
error: null,
touched: !1,
dirty: !1,
validating: !1,
valid: !0,
visible: !0,
disabled: !1,
required: ((z = p.validation) == null ? void 0 : z.required) ?? !1
};
}), O.value = { ...u }, h.values = { ...u }, w.updateFormData(O.value);
}
function M(u) {
switch (u) {
case "checkbox":
return !1;
case "number":
case "range":
return 0;
case "multiselect":
return [];
case "file":
return null;
default:
return "";
}
}
const G = C(() => i.fields.filter((u) => {
const p = q.get(u.name);
return (p == null ? void 0 : p.isVisible.value) ?? !0;
})), d = C(() => Object.values(h.errors).every((u) => !u)), n = C(() => Object.values(h.dirty).some((u) => u)), k = C(() => Object.entries(h.errors).filter(([, u]) => u).map(([u, p]) => ({
field: u,
message: p,
type: "validation",
value: O.value[u]
})));
$e(O, (u) => {
if (h.values = { ...u }, w.updateFormData(u), Object.keys(u).forEach((p) => {
var j;
const V = s[p] ?? ((j = i.fields.find((z) => z.name === p)) == null ? void 0 : j.defaultValue);
h.dirty[p] = u[p] !== V;
}), h.isDirty = n.value, e != null && e.change) {
const p = Object.keys(u).find(
(V) => u[V] !== h.values[V]
);
p && e.change(p, u[p], u);
}
}, { deep: !0 });
async function y() {
h.isValidating = !0;
try {
const u = await b.validateForm(i.fields, O.value);
return h.errors = { ...u.errors }, h.isValid = u.isValid, Object.keys(h.fields).forEach((p) => {
h.fields[p].error = u.errors[p] || null, h.fields[p].valid = !u.errors[p];
}), e != null && e.validate && e.validate(u.errors), u;
} finally {
h.isValidating = !1;
}
}
async function D(u) {
const p = q.get(u);
if (!p) return !1;
const V = await p.validateField();
return h.errors[u] = V.error || "", h.fields[u].error = V.error || null, h.fields[u].valid = V.isValid, h.fields[u].validating = V.pending || !1, V.isValid;
}
async function N() {
if (!h.isSubmitting) {
h.isSubmitting = !0, h.submitCount++;
try {
Object.keys(h.fields).forEach((p) => {
h.touched[p] = !0, h.fields[p].touched = !0;
});
let u = !0;
l && (u = (await y()).isValid), e != null && e.submit && await e.submit(O.value, u), o && u && W();
} finally {
h.isSubmitting = !1;
}
}
}
function W() {
q.forEach((u) => {
u.resetField();
}), h.errors = {}, h.touched = {}, h.dirty = {}, h.isDirty = !1, h.isValid = !0, h.submitCount = 0, Object.keys(h.fields).forEach((u) => {
var j;
const p = i.fields.find((z) => z.name === u), V = (p == null ? void 0 : p.defaultValue) ?? M((p == null ? void 0 : p.type) || "text");
h.fields[u] = {
value: V,
error: null,
touched: !1,
dirty: !1,
validating: !1,
valid: !0,
visible: !0,
disabled: !1,
required: ((j = p == null ? void 0 : p.validation) == null ? void 0 : j.required) ?? !1
};
}), e != null && e.reset && e.reset();
}
function x(u) {
Object.entries(u).forEach(([p, V]) => {
const j = q.get(p);
j && j.setValue(V);
});
}
function re(u) {
Object.entries(u).forEach(([p, V]) => {
const j = q.get(p);
j && j.setError(V), h.errors[p] = V, h.fields[p] && (h.fields[p].error = V, h.fields[p].valid = !V);
}), h.isValid = d.value;
}
function ae() {
q.forEach((u) => {
u.clearError();
}), h.errors = {}, Object.keys(h.fields).forEach((u) => {
h.fields[u].error = null, h.fields[u].valid = !0;
}), h.isValid = !0;
}
function ne(u) {
return q.get(u);
}
function te() {
const u = {};
return q.forEach((p, V) => {
u[V] = p;
}), u;
}
function oe(u) {
e != null && e.focus && e.focus(u, O.value[u]);
}
function de(u) {
h.touched[u] = !0, h.fields[u] && (h.fields[u].touched = !0), e != null && e.blur && e.blur(u, O.value[u]);
}
function ie() {
b.dispose();
}
return I(), {
// Данные
formData: J(O),
formState: J(h),
schema: J(i),
// Поля
fields: te(),
visibleFields: G,
// Состояние
isFormValid: d,
isFormDirty: n,
fieldErrors: k,
// Методы валидации
validateForm: y,
validateField: D,
// Методы управления формой
submitForm: N,
resetForm: W,
setFormValues: x,
setFormErrors: re,
clearFormErrors: ae,
// Получение данных
getFieldData: ne,
getAllFieldsData: te,
// Обработчики событий
handleFieldFocus: oe,
handleFieldBlur: de,
// Движки
validationEngine: b,
conditionsEngine: w,
// Очистка
dispose: ie
};
}
const ua = ["for"], fa = {
key: 0,
class: "field-required"
}, ca = {
key: 0,
class: "field-description"
}, ma = { class: "field-input-wrapper" }, pa = ["innerHTML"], ha = ["innerHTML"], va = {
key: 0,
class: "field-validating"
}, ba = ["innerHTML"], ya = ["id"], Da = /* @__PURE__ */ _({
__name: "BaseField",
props: {
fieldData: {}
},
setup(a) {
const e = a, i = C(() => {
const r = ["dynamic-field", `field-type-${e.fieldData.fieldSchema.type}`];
return e.fieldData.fieldSchema.wrapperClass && r.push(e.fieldData.fieldSchema.wrapperClass), e.fieldData.hasError.value && r.push("field-error"), e.fieldData.isDisabled.value && r.push("field-disabled"), e.fieldData.fieldState.value.touched && r.push("field-touched"), e.fieldData.fieldState.value.dirty && r.push("field-dirty"), r.join(" ");
}), s = C(() => {
const r = ["field-label"];
return e.fieldData.fieldSchema.labelClass && r.push(e.fieldData.fieldSchema.labelClass), r.join(" ");
}), f = C(() => {
const r = ["field-error-message"];
return e.fieldData.fieldSchema.errorClass && r.push(e.fieldData.fieldSchema.errorClass), r.join(" ");
});
return (r, l) => r.fieldData.isVisible.value ? (c(), m("div", {
key: 0,
class: A(i.value)
}, [
F(r.$slots, "label", {
field: r.fieldData.fieldSchema,
required: r.fieldData.isRequired.value
}, () => [
r.fieldData.fieldSchema.label ? (c(), m("label", {
key: 0,
for: r.fieldData.inputAttrs.value.id,
class: A(s.value)
}, [
K(S(r.fieldData.fieldSchema.label) + " ", 1),
r.fieldData.isRequired.value ? (c(), m("span", fa, "*")) : v("", !0)
], 10, ua)) : v("", !0)
], !0),
F(r.$slots, "description", {
field: r.fieldData.fieldSchema
}, () => [
r.fieldData.fieldSchema.description ? (c(), m("div", ca, S(r.fieldData.fieldSchema.description), 1)) : v("", !0)
], !0),
$("div", ma, [
F(r.$slots, "prefix", {
field: r.fieldData.fieldSchema
}, () => {
var o;
return [
(o = r.fieldData.fieldSchema.slots) != null && o.prefix ? (c(), m("div", {
key: 0,
class: "field-prefix",
innerHTML: r.fieldData.fieldSchema.slots.prefix
}, null, 8, pa)) : v("", !0)
];
}, !0),
F(r.$slots, "input", {
field: r.fieldData,
attrs: r.fieldData.inputAttrs,
classes: r.fieldData.inputClasses
}, () => [
$("input", X(r.fieldData.inputAttrs, {
class: [r.fieldData.inputClasses, "field-input"],
onInput: l[0] || (l[0] = //@ts-ignore
(...o) => r.fieldData.handleInput && r.fieldData.handleInput(...o)),
onChange: l[1] || (l[1] = //@ts-ignore
(...o) => r.fieldData.handleChange && r.fieldData.handleChange(...o)),
onFocus: l[2] || (l[2] = //@ts-ignore
(...o) => r.fieldData.handleFocus && r.fieldData.handleFocus(...o)),
onBlur: l[3] || (l[3] = //@ts-ignore
(...o) => r.fieldData.handleBlur && r.fieldData.handleBlur(...o))
}), null, 16)
], !0),
F(r.$slots, "suffix", {
field: r.fieldData.fieldSchema
}, () => {
var o;
return [
(o = r.fieldData.fieldSchema.slots) != null && o.suffix ? (c(), m("div", {
key: 0,
class: "field-suffix",
innerHTML: r.fieldData.fieldSchema.slots.suffix
}, null, 8, ha)) : v("", !0)
];
}, !0),
r.fieldData.isValidating.value ? (c(), m("div", va, [
F(r.$slots, "validating", {}, () => [
l[4] || (l[4] = $("span", { class: "validation-spinner" }, "⟳", -1))
], !0)
])) : v("", !0)
]),
F(r.$slots, "help", {
field: r.fieldData.fieldSchema
}, () => {
var o;
return [
(o = r.fieldData.fieldSchema.slots) != null && o.help ? (c(), m("div", {
key: 0,
class: "field-help",
innerHTML: r.fieldData.fieldSchema.slots.help
}, null, 8, ba)) : v("", !0)
];
}, !0),
F(r.$slots, "error", {
field: r.fieldData,
error: r.fieldData.fieldState.value.error
}, () => [
r.fieldData.hasError.value ? (c(), m("div", {
key: 0,
id: `field-${r.fieldData.fieldSchema.name}-error`,
class: A(f.value)
}, S(r.fieldData.fieldState.value.error), 11, ya)) : v("", !0)
], !0)
], 2)) : v("", !0);
}
}), ee = (a, e) => {
const i = a.__vccOpts || a;
for (const [s, f] of e)
i[s] = f;
return i;
}, T = /* @__PURE__ */ ee(Da, [["__scopeId", "data-v-fbd766f5"]]), ga = ["for"], Ca = {
key: 0,
class: "field-required"
}, ka = {
key: 0,
class: "field-description"
}, Fa = { class: "field-input-wrapper" }, $a = {
key: 0,
value: ""
}, Sa = ["value", "disabled", "title"], Va = { class: "selected-values" }, wa = ["onClick"], Ea = {
key: 0,
class: "placeholder"
}, Oa = { class: "multiselect-dropdown" }, Aa = ["value", "checked", "disabled", "onChange"], qa = {
key: 0,
class: "option-description"
}, Ba = {
key: 0,
class: "field-loading"
}, ja = {
key: 1,
class: "field-validating"
}, Ta = ["innerHTML"], Ra = ["id"], La = /* @__PURE__ */ _({
__name: "SelectField",
props: {
fieldData: {}
},
setup(a) {
const e = a, i = Q(!1), s = Q(null), f = C(() => {
const d = { ...e.fieldData.inputAttrs.value }, { multiple: n, type: k, ...y } = d;
return {
...y,
multiple: e.fieldData.fieldSchema.type === "multiselect"
};
}), r = C(() => e.fieldData.inputClasses), l = C(() => {
if (e.fieldData.fieldSchema.type !== "multiselect") return [];
const d = e.fieldData.fieldValue.value || [];
return (e.fieldData.fieldOptions.value || []).filter(
(k) => d.includes(k.value)
);
}), o = C(() => {
const d = ["dynamic-field", `field-type-${e.fieldData.fieldSchema.type}`];
return e.fieldData.fieldSchema.wrapperClass && d.push(e.fieldData.fieldSchema.wrapperClass), e.fieldData.hasError.value && d.push("field-error"), e.fieldData.isDisabled.value && d.push("field-disabled"), d.join(" ");
}), t = C(() => {
const d = ["field-label"];
return e.fieldData.fieldSchema.labelClass && d.push(e.fieldData.fieldSchema.labelClass), d.join(" ");
}), b = C(() => {
const d = ["field-error-message"];
return e.fieldData.fieldSchema.errorClass && d.push(e.fieldData.fieldSchema.errorClass), d.join(" ");
});
function w(d) {
const n = d.target;
e.fieldData.fieldValue.value = n.value;
}
function O(d) {
s.value = d;
}
function h() {
e.fieldData.isDisabled.value || (i.value = !i.value);
}
function q(d) {
return (e.fieldData.fieldValue.value || []).includes(d);
}
function I(d, n) {
const k = n.target, y = e.fieldData.fieldValue.value || [];
k.checked ? e.fieldData.fieldValue.value = [...y, d] : e.fieldData.fieldValue.value = y.filter((D) => D !== d);
}
function M(d) {
const n = e.fieldData.fieldValue.value || [];
e.fieldData.fieldValue.value = n.filter((k) => k !== d);
}
function G(d) {
const n = d.target;
s.value && !s.value.contains(n) && (i.value = !1);
}
return Se(() => {
document.addEventListener("click", G);
}), Ve(() => {
document.removeEventListener("click", G);
}), (d, n) => d.fieldData.isVisible.value ? (c(), m("div", {
key: 0,
class: A(o.value)
}, [
F(d.$slots, "label", {
field: d.fieldData.fieldSchema,
required: d.fieldData.isRequired.value
}, () => [
d.fieldData.fieldSchema.label ? (c(), m("label", {
key: 0,
for: d.fieldData.inputAttrs.value.id,
class: A(t.value)
}, [
K(S(d.fieldData.fieldSchema.label) + " ", 1),
d.fieldData.isRequired.value ? (c(), m("span", Ca, "*")) : v("", !0)
], 10, ga)) : v("", !0)
], !0),
F(d.$slots, "description", {
field: d.fieldData.fieldSchema
}, () => [
d.fieldData.fieldSchema.description ? (c(), m("div", ka, S(d.fieldData.fieldSchema.description), 1)) : v("", !0)
], !0),
$("div", Fa, [
F(d.$slots, "input", {
field: d.fieldData,
attrs: f.value,
classes: r.value,
options: d.fieldData.fieldOptions,
loading: d.fieldData.loadingOptions.value
}, () => {
var k, y;
return [
d.fieldData.fieldSchema.type === "select" ? (c(), m("select", X({ key: 0 }, f.value, {
class: [r.value, "field-select"],
onChange: w,
onFocus: n[0] || (n[0] = //@ts-ignore
(...D) => d.fieldData.handleFocus && d.fieldData.handleFocus(...D)),
onBlur: n[1] || (n[1] = //@ts-ignore
(...D) => d.fieldData.handleBlur && d.fieldData.handleBlur(...D))
}), [
d.fieldData.isRequired.value ? v("", !0) : (c(), m("option", $a, S(((k = d.fieldData.fieldSchema.attributes) == null ? void 0 : k.placeholder) || "Выберите значение"), 1)),
(c(!0), m(Y, null, H(d.fieldData.fieldOptions.value, (D) => (c(), m("option", {
key: D.value,
value: D.value,
disabled: D.disabled,
title: D.description
}, S(D.label), 9, Sa))), 128))
], 16)) : d.fieldData.fieldSchema.type === "multiselect" ? (c(), m("div", {
key: 1,
class: "multiselect-container",
ref: O
}, [
$("div", {
class: A(["multiselect-input", [r.value, "field-multiselect"]]),
onClick: h
}, [
$("div", Va, [
(c(!0), m(Y, null, H(l.value, (D) => (c(), m("span", {
key: D.value,
class: "selected-tag"
}, [
K(S(D.label) + " ", 1),
$("button", {
type: "button",
onClick: fe((N) => M(D.value), ["stop"]),
class: "tag-remove"
}, " × ", 8, wa)
]))), 128)),
l.value.length === 0 ? (c(), m("span", Ea, S(((y = d.fieldData.fieldSchema.attributes) == null ? void 0 : y.placeholder) || "Выберите значения"), 1)) : v("", !0)
]),
n[2] || (n[2] = $("div", { class: "multiselect-arrow" }, "▼", -1))
], 2),
we($("div", Oa, [
(c(!0), m(Y, null, H(d.fieldData.fieldOptions.value, (D) => (c(), m("label", {
key: D.value,
class: A(["multiselect-option", { disabled: D.disabled }])
}, [
$("input", {
type: "checkbox",
value: D.value,
checked: q(D.value),
disabled: D.disabled,
onChange: (N) => I(D.value, N)
}, null, 40, Aa),
$("span", null, S(D.label), 1),
D.description ? (c(), m("div", qa, S(D.description), 1)) : v("", !0)
], 2))), 128))
], 512), [
[Ee, i.value]
])
])) : v("", !0)
];
}, !0),
d.fieldData.loadingOptions.value ? (c(), m("div", Ba, [
F(d.$slots, "loading", {}, () => [
n[3] || (n[3] = $("span", { class: "loading-spinner" }, "⟳", -1))
], !0)
])) : v("", !0),
d.fieldData.isValidating.value ? (c(), m("div", ja, [
F(d.$slots, "validating", {}, () => [
n[4] || (n[4] = $("span", { class: "validation-spinner" }, "⟳", -1))
], !0)
])) : v("", !0)
]),
F(d.$slots, "help", {
field: d.fieldData.fieldSchema
}, () => {
var k;
return [
(k = d.fieldData.fieldSchema.slots) != null && k.help ? (c(), m("div", {
key: 0,
class: "field-help",
innerHTML: d.fieldData.fieldSchema.slots.help
}, null, 8, Ta)) : v("", !0)
];
}, !0),
F(d.$slots, "error", {
field: d.fieldData,
error: d.fieldData.fieldState.value.error
}, () => [
d.fieldData.hasError.value ? (c(), m("div", {
key: 0,
id: `field-${d.fieldData.fieldSchema.name}-error`,
class: A(b.value)
}, S(d.fieldData.fieldState.value.error), 11, Ra)) : v("", !0)
], !0)
], 2)) : v("", !0);
}
}), he = /* @__PURE__ */ ee(La, [["__scopeId", "data-v-043da355"]]), Ma = { class: "radio-fieldset" }, Na = {
key: 0,
class: "field-required"
}, Ha = {
key: 0,
class: "field-description"
}, za = { class: "radio-group" }, Pa = ["name", "value", "checked", "disabled", "required"], Ia = { class: "radio-label" }, Ga = {
key: 0,
class: "option-description"
}, Wa = {
key: 0,
class: "field-loading"
}, Ua = ["innerHTML"], Ya = ["id"], Ka = /* @__PURE__ */ _({
__name: "RadioField",
props: {
fieldData: {}
},
setup(a) {
const e = a, i = C(() => {
const l = ["dynamic-field", "field-type-radio"];
return e.fieldData.fieldSchema.wrapperClass && l.push(e.fieldData.fieldSchema.wrapperClass), e.fieldData.hasError.value && l.push("field-error"), e.fieldData.isDisabled.value && l.push("field-disabled"), l.join(" ");
}), s = C(() => {
const l = ["field-label"];
return e.fieldData.fieldSchema.labelClass && l.push(e.fieldData.fieldSchema.labelClass), l.join(" ");
}), f = C(() => {
const l = ["field-error-message"];
return e.fieldData.fieldSchema.errorClass && l.push(e.fieldData.fieldSchema.errorClass), l.join(" ");
});
function r(l) {
const o = l.target;
e.fieldData.fieldValue.value = o.value;
}
return (l, o) => l.fieldData.isVisible.value ? (c(), m("div", {
key: 0,
class: A(i.value)
}, [
F(l.$slots, "label", {
field: l.fieldData.fieldSchema,
required: l.fieldData.isRequired.value
}, () => [
$("fieldset", Ma, [
l.fieldData.fieldSchema.label ? (c(), m("legend", {
key: 0,
class: A(s.value)
}, [
K(S(l.fieldData.fieldSchema.label) + " ", 1),
l.fieldData.isRequired.value ? (c(), m("span", Na, "*")) : v("", !0)
], 2)) : v("", !0),
F(l.$slots, "description", {
field: l.fieldData.fieldSchema
}, () => [
l.fieldData.fieldSchema.description ? (c(), m("div", Ha, S(l.fieldData.fieldSchema.description), 1)) : v("", !0)
], !0),
$("div", za, [
F(l.$slots, "input", {
field: l.fieldData,
options: l.fieldData.fieldOptions,
loading: l.fieldData.loadingOptions.value
}, () => [
(c(!0), m(Y, null, H(l.fieldData.fieldOptions.value, (t) => (c(), m("label", {
key: t.value,
class: A(["radio-option", { disabled: t.disabled || l.fieldData.isDisabled.value }])
}, [
$("input", {
type: "radio",
name: l.fieldData.fieldSchema.name,
value: t.value,
checked: l.fieldData.fieldValue.value === t.value,
disabled: t.disabled || l.fieldData.isDisabled.value,
required: l.fieldData.isRequired.value,
class: "radio-input",
onChange: r,
onFocus: o[0] || (o[0] = //@ts-ignore
(...b) => l.fieldData.handleFocus && l.fieldData.handleFocus(...b)),
onBlur: o[1] || (o[1] = //@ts-ignore
(...b) => l.fieldData.handleBlur && l.fieldData.handleBlur(...b))
}, null, 40, Pa),
$("span", Ia, S(t.label), 1),
t.description ? (c(), m("div", Ga, S(t.description), 1)) : v("", !0)
], 2))), 128))
], !0),
l.fieldData.loadingOptions.value ? (c(), m("div", Wa, [
F(l.$slots, "loading", {}, () => [
o[2] || (o[2] = $("span", { class: "loading-spinner" }, "⟳", -1))
], !0)
])) : v("", !0)
])
])
], !0),
F(l.$slots, "help", {
field: l.fieldData.fieldSchema
}, () => {
var t;
return [
(t = l.fieldData.fieldSchema.slots) != null && t.help ? (c(), m("div", {
key: 0,
class: "field-help",
innerHTML: l.fieldData.fieldSchema.slots.help
}, null, 8, Ua)) : v("", !0)
];
}, !0),
F(l.$slots, "error", {
field: l.fieldData,
error: l.fieldData.fieldState.value.error
}, () => [
l.fieldData.hasError.value ? (c(), m("div", {
key: 0,
id: `field-${l.fieldData.fieldSchema.name}-error`,
class: A(f.value)
}, S(l.fieldData.fieldState.value.error), 11, Ya)) : v("", !0)
], !0)
], 2)) : v("", !0);
}
}), Be = /* @__PURE__ */ ee(Ka, [["__scopeId", "data-v-25e2da68"]]), Za = { class: "checkbox-container" }, Ja = { class: "checkbox-content" }, Qa = {
key: 0,
class: "field-required"
}, Xa = {
key: 0,
class: "field-description"
}, _a = ["innerHTML"], xa = ["id"], et = /* @__PURE__ */ _({
__name: "CheckboxField",
props: {
fieldData: {}
},
setup(a) {
const e = a, i = C(() => ({
...{ ...e.fieldData.inputAttrs },
type: "checkbox",
checked: !!e.fieldData.fieldValue.value
})), s = C(() => e.fieldData.inputClasses), f = C(() => {
const t = ["dynamic-field", "field-type-checkbox"];
return e.fieldData.fieldSchema.wrapperClass && t.push(e.fieldData.fieldSchema.wrapperClass), e.fieldData.hasError.value && t.push("field-error"), e.fieldData.isDisabled.value && t.push("field-disabled"), e.fieldData.fieldState.value.touched && t.push("field-touched"), e.fieldData.fieldState.value.dirty && t.push("field-dirty"), t.join(" ");
}), r = C(() => {
const t = ["field-label"];
return e.fieldData.fieldSchema.labelClass && t.push(e.fieldData.fieldSchema.labelClass), t.join(" ");
}), l = C(() => {
const t = ["field-error-message"];
return e.fieldData.fieldSchema.errorClass && t.push(e.fieldData.fieldSchema.errorClass), t.join(" ");
});
function o(t) {
const b = t.target;
e.fieldData.fieldValue.value = b.checked;
}
return (t, b) => t.fieldData.isVisible.value ? (c(), m("div", {
key: 0,
class: A(f.value)
}, [
F(t.$slots, "input", {
field: t.fieldData,
attrs: i.value,
classes: s.value
}, () => [
$("label", Za, [
$("input", X(i.value, {
class: [s.value, "checkbox-input"],
onChange: o,
onFocus: b[0] || (b[0] = //@ts-ignore
(...w) => t.fieldData.handleFocus && t.fieldData.handleFocus(...w)),
onBlur: b[1] || (b[1] = //@ts-ignore
(...w) => t.fieldData.handleBlur && t.fieldData.handleBlur(...w))
}), null, 16),
b[2] || (b[2] = $("span", { class: "checkbox-checkmark" }, null, -1)),
$("div", Ja, [
F(t.$slots, "label", {
field: t.fieldData.fieldSchema,
required: t.fieldData.isRequired.value
}, () => [
t.fieldData.fieldSchema.label ? (c(), m("span", {
key: 0,
class: A(r.value)
}, [
K(S(t.fieldData.fieldSchema.label) + " ", 1),
t.fieldData.isRequired.value ? (c(), m("span", Qa, "*")) : v("", !0)
], 2)) : v("", !0)
], !0),
F(t.$slots, "description", {
field: t.fieldData.fieldSchema
}, () => [
t.fieldData.fieldSchema.description ? (c(), m("div", Xa, S(t.fieldData.fieldSchema.description), 1)) : v("", !0)
], !0)
])
])
], !0),
F(t.$slots, "help", {
field: t.fieldData.fieldSchema
}, () => {
var w;
return [
(w = t.fieldData.fieldSchema.slots) != null && w.help ? (c(), m("div", {
key: 0,
class: "field-help",
innerHTML: t.fieldData.fieldSchema.slots.help
}, null, 8, _a)) : v("", !0)
];
}, !0),
F(t.$slots, "error", {
field: t.fieldData,
error: t.fieldData.fieldState.value.error
}, () => [
t.fieldData.hasError.value ? (c(), m("div", {
key: 0,
id: `field-${t.fieldData.fieldSchema.name}-error`,
class: A(l.value)
}, S(t.fieldData.fieldState.value.error), 11, xa)) : v("", !0)
], !0)
], 2)) : v("", !0);
}
}), ve = /* @__PURE__ */ ee(et, [["__scopeId", "data-v-ed1081e8"]]), be = /* @__PURE__ */ _({
__name: "DynamicField",
props: {
fieldData: {},
customComponents: { default: () => ({}) }
},
setup(a) {
const e = a, i = Oe(), s = C(() => Object.keys(i).map((o) => ({ name: o, slot: i[o] }))), f = {
// Текстовые поля
text: T,
email: T,
password: T,
url: T,
tel: T,
number: T,
textarea: T,
hidden: T,
date: T,
"datetime-local": T,
time: T,
file: T,
range: T,
color: T,
// Выбор из списка
select: he,
multiselect: he,
// Радио кнопки
radio: Be,
// Чекбоксы и переключатели
checkbox: ve,
switch: ve
}, r = C(() => {
const o = e.fieldData.fieldSchema;
if (o.component) {
if (e.customComponents[o.component])
return e.customComponents[o.component];
console.warn(`Custom component "${o.component}" not found for field "${o.name}"`);
}
const t = f[o.type];
return t || (console.warn(`No component found for field type "${o.type}", using BaseField`), T);
}), l = C(() => ({
...e.fieldData.fieldSchema.props || {}
}));
return (o, t) => (c(), ce(Me(r.value), X({ fieldData: o.fieldData }, l.value), me({ _: 2 }, [
H(s.value, (b, w) => ({
name: b.name,
fn: pe((O) => [
F(o.$slots, b.name, Ne(He(O)))
])
}))
]), 1040, ["fieldData"]));
}
}), at = {
key: 0,
class: "form-header"
}, tt = {
key: 0,
class: "form-title"
}, it = {
key: 1,
class: "form-description"
}, st = {
key: 0,
class: "form-errors"
}, lt = { class: "form-errors-list" }, rt = { class: "form-body" }, nt = { class: "form-fieldset" }, ot = ["onClick"], dt = {
key: 1,
class: "form-group-description"
}, ut = { class: "form-actions" }, ft = ["disabled"], ct = {
key: 0,
class: "submit-spinner"
}, mt = ["disabled"], pt = /* @__PURE__ */ _({
__name: "DynamicForm",
props: {
schema: {},
initialData: { default: () => ({}) },
customComponents: { default: () => ({}) },
validateOnChange: { type: Boolean },
validateOnBlur: { type: Boolean },
validateOnSubmit: { type: Boolean },
reset