UNPKG

@react-form-builder/core

Version:

React JSON Schema Form Builder to create complex, validated, reusable forms with no deep React knowledge required

1,474 lines (1,462 loc) 64.2 kB
import { C as W, i as I, g as Ge, a as Qe, b as ae, c as Ze, d as z, n as C, S as Xe, V as Ye, e as et, f as tt, h as nt, u as ot, j as N, k as rt, l as $, m as F, o as de, p as ce, q as st, r as it, s as q, t as at, v as dt, M as g, w as U, x as we, y as Pe, z as J, A as h, B as ct, D as E, E as S, G as M, H as D, I as Ce, J as lt, K as Fe, T as pt, L as Ee, O as mt, P as ut, Q as ht, R as j, U as De, W as K, X as _, Y as H, Z as le, _ as P, $ as ft, a0 as bt, a1 as yt, a2 as gt, a3 as vt, a4 as wt, a5 as Pt, a6 as Ct, a7 as Ft, a8 as Et, a9 as Dt, aa as Rt, ab as St, ac as Mt, ad as Ot, ae as zt, af as Nt, ag as It, ah as kt, ai as Tt } from "./FormViewerLite-CzR22_a-.js"; import { aL as mr, am as ur, ao as hr, aR as fr, aV as br, aI as yr, bq as gr, a$ as vr, b7 as wr, ba as Pr, al as Cr, b0 as Fr, b2 as Er, ay as Dr, at as Rr, b4 as Sr, aS as Mr, aE as Or, F as zr, b5 as Nr, aK as Ir, ap as kr, aq as Tr, aT as Ar, N as jr, aW as Vr, ar as xr, bo as Br, aX as Lr, aY as Wr, bn as $r, aU as qr, b1 as Ur, aZ as Jr, ak as Kr, bd as _r, aF as Hr, bm as Gr, an as Qr, aN as Zr, bc as Xr, b3 as Yr, as as es, aH as ts, b8 as ns, aM as os, b9 as rs, aj as ss, bg as is, be as as, bk as ds, aJ as cs, bl as ls, av as ps, bp as ms, au as us, bh as hs, aw as fs, ax as bs, bb as ys, aO as gs, aP as vs, bf as ws, aQ as Ps, bi as Cs, aG as Fs, bj as Es, aD as Ds, aA as Rs, aB as Ss, aC as Ms, b6 as Os, a_ as zs, az as Ns } from "./FormViewerLite-CzR22_a-.js"; import { jsx as a, jsxs as At, Fragment as jt } from "@emotion/react/jsx-runtime"; import { useMemo as b, useCallback as Re, createElement as Vt } from "react"; import { FluentResource as pe, FluentBundle as xt } from "@fluent/bundle"; const Io = () => (Math.random() * 1e18).toString(36).slice(0, 5).toUpperCase() + "", ko = new W("", ""), Se = "validator-", Bt = (n) => `${Se}${n}`, To = (n) => n.startsWith(Se); class B extends Error { /** * Creates a new LocalizationError. * @param name the error name. * @param message the error message. */ constructor(e, t) { super(t), this.name = e; } } const Me = ".", G = "__DOT__"; function L(n) { return n.replace(new RegExp(`\\${G}`, "g"), Me); } function Lt(n) { return n.replace(new RegExp(`\\${Me}`, "g"), G); } const Wt = (n) => typeof n == "string" || typeof n == "number" || n instanceof Date ? !0 : !I(n?.value), me = (n) => Object.entries(n).map(([e, t]) => `${e} = ${t}`).join(` `), ue = (n) => new B(n.message, n.name), V = (n, e, t = !1) => { n.forEach((o) => { o.name.indexOf("Attempt to override") > -1 || console.warn(o); }), t && Array.isArray(e) && e.length > 0 && console.warn(e); }, he = (n) => new xt(n, { useIsolating: !1 }); function fe(n, e) { return new Proxy(n, { get(t, o) { return o in t ? t[o] : (e.push(L(o)), ""); }, getOwnPropertyDescriptor(t, o) { return o in t ? Reflect.getOwnPropertyDescriptor(t, o) : { value: "", writable: !0, configurable: !0 }; } }); } class $t { #e = /* @__PURE__ */ new Map(); #t = Ge.fullCode; /** * Constructor. * @param locale the language full code, i.e. 'en-US'. */ constructor(e) { this.#t = e ?? this.#t; } /** * Creates a Fluent bundle for the given language and items. * @param languageFullCode the full language code (e.g., 'en-US'). * @param items the localization items to add to the bundle. * @param errors the array to collect any localization errors. * @param bundle the fluent bundle to use. * @returns the created Fluent bundle. */ #n(e, t, o, r) { r = r ?? this.#o(e); const s = me(t), i = new pe(s), d = r.addResource(i); return o.length = 0, d.forEach((c) => o.push(ue(c))), V(o), r; } /** * Gets or creates a Fluent bundle for the given language code. * @param languageFullCode the full language code (e.g., 'en-US'). * @returns the Fluent bundle for the language. */ #o(e) { const t = this.#e.get(e) ?? he(e); return this.#e.set(e, t), t; } /** * Gets the message value from a Fluent bundle. * @param bundle the Fluent bundle to get the message from. * @param id the message ID to retrieve. * @returns the message value or undefined if not found. */ #s(e, t) { return e.getMessage(t)?.value ?? void 0; } /** * @inheritDoc */ set language(e) { this.#t = e; } /** * @inheritDoc */ get language() { return this.#t; } /** * @inheritDoc */ addMessages(e, t) { const o = me(t), r = this.#o(e), s = new pe(o); return r.addResource(s, { allowOverrides: !0 }).map(ue); } /** * @inheritDoc */ localizeProperties(e, t, o, r, s = "component") { const i = `${r.key}_${s}_`, d = {}, c = o.fullCode, p = [], { defaultBundle: m, formBundle: u } = this.#i(e, c, p); return Object.entries(r.props).forEach(([f, w]) => { if (!Qe(w)) return; const l = `${i}${f}`, y = this.#a(l, u, m); if (!y) { d[f] = "[NOT LOCALIZED]"; return; } d[f] = this.#d(y, u, t); }), d; } /** * @inheritDoc */ getCompatibleId(e) { return e.replace(/\s/g, "_"); } /** * @inheritDoc */ localizeErrorMessage(e, t, o, r, s) { const i = Bt(s), d = `${r.key}_${i}_message`, c = [], { defaultBundle: p, formBundle: m } = this.#i(e, o.fullCode, c), u = this.#a(d, m, p); return u ? this.#d(u, m, t) : void 0; } /** * @inheritDoc */ testLocalization(e, t, o, r) { const s = Lt(e), i = [], d = o.fullCode, c = this.#n(d, { [`${t}`]: s }, i, he(d)), p = c.getMessage(t); if (!p?.value) return [new B("MessageError", "Incorrect format")]; const m = [], u = ae(r), f = [], w = fe(this.#r(u), f), l = L(c.formatPattern(p.value, w, m)); return V(m, f, !0), m.length > 0 ? m.map((y) => new B("MessageFormatError", y.message)) : l; } /** * Sets up bundles for default and requested languages. * @param form the form containing localization data. * @param requestedFullCode the requested language full code. * @param errors the array to collect any localization errors. * @returns the object containing default and form bundles. */ #i(e, t, o) { const r = e.defaultLanguage.fullCode, s = r !== t ? e.localization.getItems(r) : void 0, i = e.localization.getItems(t), d = s ? this.#n(r, s, o) : void 0, c = i ? this.#n(t, i, o) : void 0; return { defaultBundle: d, formBundle: c }; } /** * Retrieves a message from bundles with fallback support. * @param messageId the message ID to retrieve. * @param formBundle the primary form bundle. * @param defaultBundle the fallback default bundle. * @returns the message value or undefined if not found. */ #a(e, t, o) { const r = t ? this.#s(t, e) : void 0, s = o ? this.#s(o, e) : void 0; return r ?? s; } /** * Formats a message with form data and handles errors. * @param message the message to format. * @param bundle the bundle to use for formatting. * @param formData the form data for variable substitution. * @returns the formatted result or undefined. */ #d(e, t, o) { const r = [], s = ae(o), i = [], d = fe(this.#r(s), i), c = t?.formatPattern(e, d, r); return V(r, i), c ? L(c) : void 0; } /** * Converts the form data to a Fluent compatible. **Internal use only.** * @param data the form data. * @param parentKey the parent property key. * @returns all the form data that is of the FluentVariable type. * Additionally, the keys of the returned object are converted to the snake case. */ #r = (e, t = "") => { const o = {}; for (const [r, s] of Object.entries(e)) { const i = t ? `${t}${G}${r}` : r; Wt(s) ? o[this.getCompatibleId(i)] = s : typeof s == "boolean" ? o[this.getCompatibleId(i)] = s ? "true" : "false" : typeof s == "object" && !Ze(s) && Object.assign(o, this.#r(s, i)); } return o; }; } const [ /** * @returns the internal FormViewer component for displaying modal windows, templates, etc. **Internal use only.** */ Oe, /** * **Internal use only.** */ qt ] = z("EmbeddedFormViewerContext"), Ut = (n) => { const e = b(() => n.localizationEngine ?? new $t(), [n.localizationEngine]), t = b(() => ({ ...n, localizationEngine: e }), [e, n]); return /* @__PURE__ */ a(Xe, { children: /* @__PURE__ */ a(Ye, { props: t, children: /* @__PURE__ */ a(et, { children: /* @__PURE__ */ a(tt, { children: /* @__PURE__ */ a(nt, {}) }) }) }) }); }, be = C("InternalFormViewer", Ut), Jt = (n) => (ot(), /* @__PURE__ */ a(qt, { value: be, children: /* @__PURE__ */ a(be, { ...n }) })), Ao = C("FormViewer", Jt), [ /** * @returns the {@link BuilderMode} builder mode value. */ k, /** * The BuilderMode context provider. */ jo ] = z("BuilderModeContext", "viewer"), Kt = (n, e) => { const t = k(); return b(() => t === "builder" ? n : e, [n, t, e]); }, _t = (n, e) => { const t = e.key, o = e.modal; return b(() => W.createFromObject({ key: t, type: n, ...o }), [t, n, o]); }, Ht = (n, e) => { const t = N(), o = _t(e, n.store), r = Re((s) => t.localizeComponent("modal", n.dataRoot, s), [t, n]); return b(() => { const s = t.createComponentData(o, !1); return s.dataRootProvider = { get dataRoot() { return n.dataRoot; } }, s.componentState = new rt(s, t, r, () => ({})), s; }, [t, r, o, n.dataRoot]); }, Gt = () => N().form.modalType, ze = () => { const n = Gt(), e = $(); if (n) return e.view.get(n); }, Qt = ({ modalTemplate: n }) => { const e = ze(), t = b(() => n && dt(n) ? q(n) : n, [n]); return e ? n ? /* @__PURE__ */ a("div", { children: `Modal: '${t}'` }) : /* @__PURE__ */ a("div", { children: "Modal: template not specified" }) : /* @__PURE__ */ a("div", { children: "Modal: specify the component to display the modal window to use" }); }, Zt = C("ModalBuilder", Qt), Xt = ({ open: n, handleClose: e, model: t, children: o }) => { const r = F(), d = { ...Ht(r, t.type).componentState.ownProps, open: n, handleClose: e }; return Vt(t.component, d, o); }, Yt = C("ComponentModal", Xt), en = (n) => { const e = $(), t = F(), o = N(), { context: r } = o.formViewerPropsStore, s = ze(), i = Oe(), { modalTemplate: d } = n, { open: c = !1, initialData: p, [ce]: m } = t?.userDefinedProps?.[de] || {}, u = Re((l) => { if (t.userDefinedProps ??= {}, t.userDefinedProps[de].open = !1, l) { const y = st(o.formData); Object.entries(l).forEach(([_e, He]) => { y[_e] = He; }); } }, [t, o.formData]), f = b(() => ({ ...e.context, modalContext: { [it]: u, [ce]: m, parentContext: r } }), [r, e.context, u, m]), w = b(() => ({ ...e, formName: q(d), initialData: p, errors: void 0, onFormDataChange: void 0, readOnly: void 0, disabled: void 0, context: f }), [e, d, p, f]); return !s || !d ? null : /* @__PURE__ */ a(Yt, { model: s, open: c, handleClose: u, children: /* @__PURE__ */ a(at, { props: w, children: /* @__PURE__ */ a(i, { ...w }) }) }); }, tn = C("ModalViewer", en), Ne = (n) => { const e = Kt(Zt, tn); return /* @__PURE__ */ a(e, { ...n }); }; Ne.displayName = "Modal"; const nn = U( {}, { name: J, value: !0 }, { name: Pe, value: !0 }, { name: we, value: !0 } ), Q = new g( Ne, "Modal", void 0, void 0, void 0, void 0, void 0, void 0, void 0, void 0, void 0, void 0, void 0, void 0, void 0, nn ), [ /** * **Internal use only.** */ on, /** * **Internal use only.** */ rn ] = z("RepeaterPropsContext"), Z = (n) => { const { className: e } = on(); return /* @__PURE__ */ a("div", { className: e, children: n.children }); }; Z.displayName = "RepeaterItem"; const sn = new g(Z, "RepeaterItem"), an = h("array").array; class dn extends ct { /** * The function that checks whether a child component can be inserted into a parent component. */ insertPredicate; /** * The default editor. */ defaultEditor; /** * Creates a component property metadata builder. * @param editor the property editor type. * @template T the property type. */ constructor(e) { super(e); } /** * Specifies a function that will create conditions that check if a child component can be bound to a parent slot. * @param slotConditionBuilder the function that returns a string containing the source code of the function to bind child components. * @returns the instance of the metadata property builder. */ withSlotConditionBuilder(e) { return this.setup({ slotConditionBuilder: e }); } /** * @inheritDoc */ build(e) { const t = super.build(e); return t.insertPredicate = this.insertPredicate, t.defaultEditor = this.defaultEditor, t; } /** * Specifies a function that checks whether a child component can be inserted into a parent component. * @param predicate the function that returns a boolean value. * @returns the modified instance of the builder. */ withInsertRestriction(e) { const t = this.clone(); return t.insertPredicate = e, t; } /** * Specifies the default editor for the property. * @param defaultEditor the default editor. * @returns the modified instance of the builder. */ withDefaultEditor(e) { const t = this.clone(); return t.defaultEditor = e, t; } } function X(n) { return new dn(n); } const Ie = X("node").setup({ annotationType: "Container" }), cn = (n) => { const e = k() === "viewer", o = N().parentStore; return e && !n.children ? null : /* @__PURE__ */ a("div", { className: n.wrapperClassName, children: e || o ? n.children : /* @__PURE__ */ a(Z, { children: n.children }) }); }, ke = (n) => /* @__PURE__ */ a(rn, { value: n, children: /* @__PURE__ */ a(cn, { wrapperClassName: n.wrapperClassName, children: n.children }) }); ke.displayName = "Repeater"; const Te = an.valued.setup({ editor: "arrayOfObject" }), Ae = E({ itemRenderWhen: D.notLocalize, value: Te, children: Ie }), { flexDirection: je, gap: Ve } = lt, xe = M({ display: D.default("flex").hideEditor(), flexDirection: je.default("column").named("Item direction").hinted("Item direction"), gap: Ve.default("20px").named("Item gap").hinted("Item gap") }), ln = S(xe), Be = M({ display: D.default("flex").hideEditor(), flexDirection: je.default("column").hinted("Repeater direction"), gap: Ve.default("20px").hinted("Repeater gap") }), pn = S(Be), mn = Ae.filter((n) => !I(n.default)).reduce((n, e) => (n[e.key] = e.default, n), {}), un = U( {}, { name: Ce, value: !0 } ), Y = new g( ke, "Repeater", void 0, "value", "array", mn, ln, pn, "Repeater", "repeater", void 0, void 0, void 0, void 0, void 0, un ), ee = M(Fe), te = S(ee), [ /** * **Internal use only.** */ hn, /** * **Internal use only.** */ fn ] = z("EmbeddedFormContext"), bn = { fontSize: "xx-large", color: "red" }, yn = ({ children: n }) => /* @__PURE__ */ a("span", { style: bn, children: n }), ne = (n) => { const e = $(), t = F(), o = k(), r = Oe(), s = b(() => { const c = { formName: n.formName, formOptions: n.options, onFormDataChange: void 0, formValidators: void 0, disabled: n.disabled, readOnly: n.readOnly, initialState: {} }; return Object.assign({}, e, c); }, [e, n]), i = b(() => ({ embeddedFormProps: n, viewerProps: e, data: t }), [n, e, t]); if (!s.getForm) return /* @__PURE__ */ At(yn, { children: [ "Please define the ", /* @__PURE__ */ a("code", { children: "getForm" }), " property!" ] }); if (I(n.formName) && I(n.options)) return o === "builder" ? /* @__PURE__ */ a("span", { children: "The name of the form and options are not specified, set at least one value to display the form" }) : null; if (!(t.field instanceof pt)) return null; const d = t.field.viewerStore; return /* @__PURE__ */ a(fn, { value: i, children: /* @__PURE__ */ a(Ee, { value: d, children: /* @__PURE__ */ a(r, { ...s }) }) }); }; ne.displayName = "EmbeddedForm"; const gn = { storeDataInParentForm: !0 }, ye = "EmbeddedForm", oe = new g( ne, ye, void 0, "valued", "object", gn, te, void 0, ye, "template", "readOnly", void 0, void 0, "disabled" ), Le = ({ children: n }) => /* @__PURE__ */ a(jt, { children: n }); Le.displayName = "Fragment"; const vn = new g( Le, "Fragment", void 0, void 0, void 0, void 0, void 0, void 0, void 0, "container" ), wn = ({ parentStore: n }) => { const { key: e } = F(), { viewerProps: t, data: o, embeddedFormProps: r } = hn(); return /* @__PURE__ */ a(Ee, { value: n, children: /* @__PURE__ */ a(ut, { value: t, children: /* @__PURE__ */ a(ht, { value: o, children: r[e] }) }) }); }, Pn = C("SlotContent", wn), Cn = { backgroundColor: "rgb(150, 150, 150, 25%)", padding: 5 }, Fn = () => { const { key: n } = F(); return /* @__PURE__ */ a("div", { style: Cn, children: `Slot: '${n}'` }); }, En = C("SlotPlaceholder", Fn), We = () => { const { parentStore: n } = N(); return n ? /* @__PURE__ */ a(Pn, { parentStore: n }) : /* @__PURE__ */ a(En, {}); }; We.displayName = "Slot"; const Dn = U( {}, { name: mt, value: !0 }, { name: J, value: !0 }, { name: Pe, value: !0 }, { name: we, value: !0 } ), re = new g( We, "Slot", void 0, void 0, void 0, void 0, void 0, void 0, void 0, void 0, void 0, void 0, void 0, void 0, void 0, Dn ), $e = (n) => { const { store: e } = F(); return /* @__PURE__ */ a(ne, { ...n, formName: q(e.type) }); }, Rn = new g( $e, j, void 0, j, "object", void 0, te, void 0, j, "template", "readOnly", void 0, void 0, "disabled" ); function Sn(n) { const e = De(n), t = { name: n, storeDataInParentForm: !0 }; return new g( $e, n, void 0, e, "object", t, te, void 0, e, "template", "readOnly", void 0, void 0, "disabled" ); } class T { #e = /* @__PURE__ */ new Map(); #t = /* @__PURE__ */ new Map(); #n = new Array(); /** * Static wrapper for the {@link View} constructor. * @param models the components metadata. * @returns the {@link View} instance. */ static create(e) { return new T(e); } /** * Creates an instance of the {@link View}. * @param models the components metadata. */ constructor(e = []) { this.define(K), this.define(_), this.define(re), this.define(oe), this.define(Rn), this.define(vn), this.define(Y), this.define(sn), this.define(H), this.define(Q), e.forEach(this.define.bind(this)); } /** * @inheritDoc */ define(e) { this.#e.set(e.type, e); } /** * @inheritDoc */ get(e) { const t = this.find(e); if (t) return t; throw new Error(`Type '${e}' is not found!`); } /** * @inheritDoc */ find(e) { return this.#e.get(e); } /** * @inheritDoc */ all() { return [...this.#e.values()]; } /** * @inheritDoc */ filterModels(e) { return [...this.#e.values()].filter(e); } /** * @inheritDoc */ withViewerWrapper = (e) => (this.#n.push(e), this); /** * @inheritDoc */ get viewerWrappers() { return [...this.#n]; } /** * @inheritDoc */ withCssLoader(e, t) { return e === "common" ? (this.#o(le.LTR, t), this.#o(le.RTL, t)) : this.#o(e, t), this; } /** * Sets a CSS loader for the specified BiDi direction. * @param biDi the BiDi direction. * @param loader the loader function that returns a Promise. */ #o(e, t) { this.#t.set(e, [...this.#t.get(e) ?? [], t]); } /** * @inheritDoc */ getCssLoaders(e) { return this.#t.get(e) ?? []; } } const Vo = T.create, ge = P("event").setup({ annotationType: "Event" }), Mn = P("htmlAttributes"), On = P("renderWhen").typed("boolean"), zn = P("tooltipProps"), Nn = P("validation"), R = [ zn.build("tooltipProps"), On.build("renderWhen"), Mn.build("htmlAttributes"), Nn.build("validation"), ge.build(ft), ge.build(bt) ]; class v { /** * Creates the component metadata for the form builder. * @param type the component type name. * @param properties the component's properties metadata. * @param css the component's CSS metadata. * @param wrapperCss the component's wrapper CSS metadata. * @param modules common metadata for the component. * @param customPreview the custom ReactNode to be drawn on the toolbar. * @param valuedAn the metadata for the component value. * @param initialJson the JSON source for the component (instance of {@link ComponentStore} class serialised to JSON). * @param eventListeners the component metadata event listeners. * @param icon the component icon or the icon name. * @param insertRestriction the function that restricts the insertion of a component into another component. */ constructor(e, t, o, r, s, i, d, c, p, m, u) { this.type = e, this.properties = t, this.css = o, this.wrapperCss = r, this.modules = s, this.valuedAn = d, this.initialJson = c, this.eventListeners = p, this.icon = m, this.insertRestriction = u, this.customPreview = i; } /** * @deprecated * The custom ReactNode to be drawn on the toolbar. */ customPreview; } class O { /** * Definer class data. * @template T React component property type. */ data; /** * Static method to create an instance of the component's metadata builder class. * @param component the React component. * @param displayName the display name for the anonymous component. * @returns the instance of the {@link Definer} class. */ static define(e, t) { if (!(t ?? e.displayName ?? e.name)) throw Error("Anonymous components are not allowed!"); const r = new O(e); return t && r.type(t), r; } /** * Static method to create an instance of the preset component's metadata builder class. * @param name the preset name. * @param components the components of the preset. * @returns the instance of the {@link Definer} class. */ static definePreset(e, t) { if (!e) throw Error("Anonymous components are not allowed!"); const o = () => null, r = new O(o).addFeature(yt, !0).type(e).name(e), s = new W("", e); return s.children = t, r.initialJson(JSON.stringify(s)); } constructor(e) { this.data = { component: e }; } /** * Sets the name of the component. * @param name the component name. * @returns the modified Definer class instance. */ name = (e) => this.#e({ name: e }); /** * Sets the kind of the component. * @param kind the component kind. * @returns the modified Definer class instance. */ kind = (e) => this.#e({ kind: e }); /* * Sets the component features that provide additional information about component's characteristic. **Internal use only.** * @param name the feature name. * @param value the feature value. * @returns the modified Definer class instance. */ addFeature = (e, t) => { const o = gt(this.data.features ?? {}, e, t); return this.#e({ features: o }); }; /** * Sets the icon of the component. * @param icon the component icon or the icon name. * @returns the modified Definer class instance. */ icon = (e) => this.#e({ icon: e }); /** * Sets the category of the component. * @param category the component category. * @returns the modified Definer class instance. */ category = (e) => this.#e({ category: e }); /** * Sets the type of the component. * @param type the component type. * @returns the modified Definer class instance. */ type = (e) => (this.data.component.displayName = e, this); /** * Sets the metadata of the component's properties. * @param properties the metadata of the component's properties. * @returns the modified Definer class instance. */ props = (e) => this.#e({ properties: e }); /** * Sets the component CSS metadata. * @param css the component CSS metadata. * @returns the modified Definer class instance. */ css = (e) => this.#e({ cssObject: e }); /** * Sets the component wrapper CSS metadata. * @param css the component wrapper CSS metadata. * @returns the modified Definer class instance. */ wrapperCss = (e) => this.#e({ wrapperCssObject: e }); /** * Adds the metadata of the component's actions. **Internal use only.** * @param fn the function that initializes an actions on a component. * @returns the modified Definer class instance. */ actions = (e) => this.#e({ actionsInitializer: e }); /** * @deprecated * Adds the custom component to be displayed in the component list. **Internal use only.** * @param customPreview the custom component. * @returns the modified Definer class instance. */ preview = (e) => this.#e({ customPreview: e }); /** * @returns the component type name. */ getType() { return this.data.component.displayName || this.data.component.name; } /** * Sets initial component JSON. * @param initialJson the JSON source for the component (instance of {@link ComponentStore} class serialised to JSON). * @returns the modified Definer class instance. */ initialJson = (e) => this.#e({ initialJson: e }); /** * Sets the component metadata event listeners. * @param eventListeners the component metadata event listeners. * @returns the modified Definer class instance. */ eventListeners = (e) => this.#e({ eventListeners: e }); /** * Sets the function that restricts the insertion of a component into another component. * @param insertRestriction the function that restricts the insertion of a component into another component. * @returns the modified Definer class instance. */ insertRestriction = (e) => this.#e({ insertRestriction: e }); /** * Sets the role (e.g., label, tooltip, etc.) for the component. * @param value the component role. * @returns the modified Definer class instance. */ componentRole(e) { return this.addFeature(vt, e); } /** * Hides a component from the component palette. * @param value true to hide the component, false otherwise. * @returns the modified Definer class instance. */ hideFromComponentPalette(e = !0) { return this.addFeature(wt, e); } /** * Prevent this component from being removed. * @param value true to disable removal, false otherwise. * @returns the modified Definer class instance. */ disableRemove(e = !0) { return this.addFeature(Pt, e); } /** * Disables the styling of the component. * @param value true to disable the styling of the component. * @returns the modified Definer class instance. */ withoutStyles(e = !0) { return this.addFeature(Ct, e); } /** * Disables the styling of the component wrapper. * @param value true to disable the styling of the component wrapper. * @returns the modified Definer class instance. */ withoutWrapperStyles(e = !0) { return this.addFeature(Ft, e); } /** * Show or hide 'Styles for className' editor. * @param value if the value is `true` or `undefined`, the editor will be displayed. * @returns the modified Definer class instance. */ showClassNameStylesEditor(e) { return this.addFeature(Et, !e); } /** * Show or hide 'Inline styles' properties editor. * @param value if the value is `true` or `undefined`, the editor will be displayed. * @returns the modified Definer class instance. */ showInlineStylesEditor(e) { return this.addFeature(Dt, e); } /** * Hides child components from the field collection. * It is used when components are dynamically added to the form, for example in the Repeater component. * @param value true if the feature is enabled. * @returns the modified Definer class instance. */ skipChildrenDuringFieldCollection(e = !0) { return this.addFeature(Ce, e); } /** * Show or hide 'Tooltip' properties editor. * @param value if the value is `false` or `undefined`, the editor will be displayed. * @returns the modified Definer class instance. */ hideTooltipEditor(e = !0) { return this.addFeature(J, e); } /** * Overrides event handlers (for example, onChange, onBlur) that are added to the component. * @param eventHandlers the custom event handlers. * @returns the modified instance of the builder. */ overrideEventHandlers(e) { return this.addFeature(Rt, e); } /** * Hides or shows the 'Actions' editors. * @param value if the value is true, the editors will be hidden. * @returns the modified Definer class instance. */ hideActionEditors(e = !0) { return this.addFeature(St, e); } /** * Creates component metadata for the form builder and form viewer. * @returns component metadata for the form builder and form viewer. */ build() { const e = E(this.data.properties), t = M(this.data.cssObject), o = M({ ...Fe, ...this.data.wrapperCssObject }), r = e.filter((l) => l.valued === !0), s = r[0]; r.length > 1 && console.warn(`Several annotations with the "valued" property were found. There should be only one "valued" property in the component description! The annotation with the key "${r[0].key}" will be used.`); const i = s ?? e.find((l) => l.name === "value"), d = e.find((l) => l.readOnly), c = e.find((l) => l.disabled), p = e.reduce((l, y) => (y.bindingType && (l[y.key] = y.bindingType), l), {}), m = { ...this.data.features }, u = e.filter((l) => l.controlsRequiredProp).map((l) => l.key); u.length > 0 && (m[Ot] = u); const f = new g( this.data.component, this.data.name || this.getType(), this.data.actionsInitializer, i?.key, i?.type, Mt(e), S(t), S(o), this.getType(), this.data.kind, d?.key, p, i?.uncontrolledValue, c?.key, i?.dataBindingType, m ), w = new v( this.getType(), e, t, o, R, this.data.customPreview, i, this.data.initialJson, this.data.eventListeners, this.data.icon, this.data.insertRestriction ); return { model: f, meta: w, category: this.data.category }; } /** * Modifies the component's metadata builder with custom options. * @param opts the custom options. * @returns the modified instance of the builder. */ #e(e) { return Object.assign(this.data, e), this; } } const xo = O.define, Bo = O.definePreset, ve = new v(_.type, [], [], [], []), A = h("boolean").typed("boolean"), se = A.setup({ disabled: !0 }), ie = A.setup({ readOnly: !0 }), In = new v( K.type, E({ children: Ie, disabled: se, readOnly: ie }), zt, [], R ), kn = E({ modalTemplate: D.required.setup({ editor: "templateTypePicker" }) }), Tn = P("modalProps"), An = [ Tn.build("modalProps") ], jn = { onCreateNode: (n, e) => { const { form: t } = e; !t.modalType && e instanceof Nt && (t.modalType = e.getFirstComponentTypeWithRole("modal")); } }, Vn = new v( Q.type, kn, [], [], An, void 0, void 0, void 0, jn ), xn = [ ...R ], Bn = new v( Y.type, Ae, xe, Be, xn, void 0, Te.build("value") ), qe = h("object").typed("object"), Ln = A.default(!0).calculable(!1), Wn = new v( oe.type, E({ storeDataInParentForm: Ln, formName: D.setup({ editor: "formNamePicker" }), options: qe, disabled: se, readOnly: ie }), [], ee, R ), $n = new v(re.type, [], [], [], R), qn = A.default(!0).calculable(!1).hinted("Store data in parent form").named("Store data in parent form"), Un = qe.hinted("The additional options for loading the template").named("Template options"); function Jn(n) { const e = De(n); return new v( e, E({ storeDataInParentForm: qn, options: Un, disabled: se, readOnly: ie }), [], ee, R ); } const Kn = new v( H.type, E({ className: D }), [], [], [] ), x = "templates", _n = "structure", Hn = "modal"; class Ue extends T { /** * Creates metadata for form builder components. * @param builderComponents the array of metadata of form builder components. */ constructor(e) { super(e.map(({ model: o }) => o)), this.builderComponents = e, this.builderComponents.push({ meta: In, model: K }), this.builderComponents.push({ meta: ve, model: _ }), this.builderComponents.push({ meta: $n, model: re, category: x }), this.builderComponents.push({ meta: Wn, model: oe, category: x }), this.builderComponents.push({ meta: Bn, model: Y, category: _n }), this.builderComponents.push({ meta: Kn, model: H }), this.builderComponents.push({ meta: Vn, model: Q, category: Hn }), e.map(({ meta: o }) => o).forEach((o) => { this.#e.set(o.type, o); }); } #e = /* @__PURE__ */ new Map(); /** * The function for filtering components on the component palette. */ paletteFilter; /** * The description of the component library in different languages. */ i18nDescriptions; /** * Returns the component metadata for the specified component type name. * @param type the component type name. * @returns the component metadata for the specified component type name. */ getMeta(e) { const t = this.#e.get(e); return t || ve; } /** * Adds the component metadata to the form builder. * @param component the component metadata. */ addComponent(e) { this.define(e.model), this.#e.set(e.meta.type, e.meta); } /** * Removes the component metadata from the form builder. * @param name the component type name. */ removeComponent(e) { this.#e.delete(e); } /** * Returns the component metadata for the specified component type name or undefined. * @param type the component type name. * @returns the component metadata for the specified component type name or undefined. */ findMeta(e) { return this.#e.get(e); } /** * Creates metadata for the form builder for templates from the specified template names. * @param templates the array of template names. * @returns the instance of the {@link BuilderView} class. */ withTemplates(e) { return e.forEach((t) => { const o = Ue.createTemplateComponent(t); this.define(o.model), this.#e.set(o.meta.type, o.meta), this.builderComponents.push(o); }), this; } /** * Sets a function for filtering components on the component palette. * @param filter the component filtering function. * @returns the instance of the {@link BuilderView} class. */ withPaletteFilter(e) { return this.paletteFilter = e, this; } /** * Adds a description of the component library in different languages. * @param i18nDescription the description of the component library in different languages. * @returns the instance of the {@link BuilderView} class. */ withComponentLibraryDescription(e) { return this.i18nDescriptions ??= [], this.i18nDescriptions.push(e), this; } /** * Creates an instance of BuilderComponent for the specified template name. * @param name the template name * @returns the BuilderComponent instance. */ static createTemplateComponent(e) { const t = Sn(e); return { meta: Jn(e), model: t, category: x }; } } const Lo = `declare interface IFormData { /** * @returns the {@link Record} with all the form data. */ get data(): Record<string, unknown> /** * @returns the object to read and modify parent data (available for array elements). */ get parentData(): Record<string, unknown> | undefined /** * @returns the object to read and modify root form data. */ get rootData(): Record<string, unknown> /** * @returns the {@link Record} with all validation error messages. */ get errors(): Record<string, unknown> /** * true if the form contains errors, otherwise false. */ get hasErrors(): boolean /** * @returns A user-defined key-value observable storage. Utilize it to store and share any custom data. */ get state(): Record<string, unknown> /** * Sets the validation error message for all form data fields. * @param message the validation error message. */ setAllErrors(message?: string): void /** * Validates the data in the form. */ validate(): Promise<void> /** * Returns the validation results without triggering an events and changing the state of the form. * @returns the validation results. */ getValidationResult: () => Promise<ValidationMessages> /** * If true, then validation is in progress. */ get isValidating(): boolean /** * Sets the form to its default value. * @param clearInitialData if true, then also clear the initial data. Defaults to true. */ reset(clearInitialData?: boolean): void /** * Clears the form data. * @param clearInitialData if true, then also clear the initial data. Defaults to true. */ clear(clearInitialData?: boolean): void /** * @returns the index in the array if the component is in the component array. */ index?: number }`, Gn = (n, e) => e.reduceScreen((t, o) => o.key === n ? t + 1 : t, 0) === 1, Wo = h("string").calculable(!0).build("className"), $o = h("color").typed("string"), qo = h("date").typed("date"), Uo = (n, e = "}") => h("function").typed("string").calculable(!1).withEditorProps({ beginContextLine: n, endContextLine: e }), Jo = P("key").typed("string").required.hinted("Unique component key").calculable(!1).validated(Gn, { code: "unique_key", message: "The key must be unique!" }).build("key"), Ko = X("nodeArray").setup({ annotationType: "Container", bindingType: "array" }), Qn = h("number").typed("number"), _o = Qn.withEditorProps({ min: 0 }), Ho = h("oneOf").oneOf.bind(h("oneOf").withEditorProps({ creatable: !1 })), Go = h("required").setup({ controlsRequiredProp: !0 }).typed("boolean"), Qo = h("someOf").someOf.bind(h("someOf")), Zo = X("node").setup({ annotationType: "Container" }).withDefaultEditor("string"), Xo = h("time").typed("time"), Yo = P("tooltipType").typed("string"), er = (n, e = !0) => n.map((t) => { if (It(t)) return { value: t.value, label: t.label }; const o = t, r = e ? kt(String(t)) : String(t); return { value: o, label: r }; }), tr = (n) => n instanceof Tt, nr = () => F().field?.error, or = (n, e, t) => new Promise((o, r) => { if (document.getElementById(n)) return o(); const s = document.createElement("link"); s.id = n, s.rel = t, s.href = e, s.onload = () => { o(); }, s.onerror = r, document.head.appendChild(s); }), rr = (n) => { const e = document.getElementById(n); e?.parentNode?.removeChild(e); }, [ /** * @returns the current {@link BuilderTheme} value. */ sr, /** * Context provider for the {@link useBuilderTheme} hook. */ ir ] = z("BuilderThemeContext", "light"); function Zn(n) { return !!n?.fnSource; } function Je(n) { return n?.localized === !0; } function Xn(n) { return typeof n?.finalize == "function"; } class Yn { constructor(e, t) { this.parent = e, this.eventName = t; } buffer = []; current = null; /** * @inheritDoc */ commonAction(e) { return this.commit(), this.current = { type: "common", name: e }, this; } /** * @inheritDoc */ customAction(e) { return this.commit(), this.current = { type: "custom", name: e }, this; } /** * @inheritDoc */ args(e) { if (!this.current) throw new Error("Call default or custom before args"); return this.current.args = e, this; } /** * @inheritDoc */ prop = (e, t) => this.finalize().prop(e, t); /** * @inheritDoc */ localizedProp = (e, t, o) => this.finalize().localizedProp(e, t, o); /** * @inheritDoc */ computedProp = (e, t) => this.finalize().computedProp(e, t); /** * @inheritDoc */ validation = (e) => this.finalize().validation(e); /** * @inheritDoc */ event = (e) => this.finalize().event(e); /** * @inheritDoc */ component = (e, t) => this.finalize().component(e, t); /** * @inheritDoc */ json = () => this.finalize().json(); /** * @inheritDoc */ style = (e, t) => this.finalize().style(e, t); /** * @inheritDoc */ children = (e) => this.finalize().children(e); finalize() { this.commit(), this.parent.events = {}; for (const e of this.buffer) this.parent.addEvent(this.eventName, e); return this.parent; } commit() { this.current && (this.buffer.push(this.current), this.current = null); } } class eo { constructor(e, t) { this.parent = e, this.key = t; } /** * @inheritDoc */ args(e) { return this.finalize(e), this.parent; } /** * @inheritDoc */ prop = (e, t) => this.finalize().prop(e, t); /** * @inheritDoc */ localizedProp = (e, t, o) => this.finalize().localizedProp(e, t, o); /** * @inheritDoc */ computedProp = (e, t) => this.finalize().computedProp(e, t); /** * @inheritDoc */ validation = (e) => this.finalize().validation(e); /** * @inheritDoc */ event = (e) => this.finalize().event(e); /** * @inheritDoc */ component = (e, t) => this.finalize().component(e, t); /** * @inheritDoc */ json = () => this.finalize().json(); /** * @inheritDoc */ style = (e, t) => this.finalize().style(e, t); /** * @inheritDoc */ children = (e) => this.finalize().children(e); finalize(e) { return this.parent.addValidation(this.key, e), this.parent; } } class to { constructor(e, t, o) { this.parent = e, this.key = t, this.type = o; } props = {}; validations = []; events = {}; css = {}; childComponents = []; /** * @inheritDoc */ prop(e, t) { return this.props[e] = { value: t }, this; } /** * @inheritDoc */ localizedProp(e, t, o) { const r = this.props[e]; return Je(r) ? r.values[t] = o : this.props[e] = { localized: !0, values: { [t]: o } }, this; } /** * @inheritDoc */ computedProp(e, t) { return this.props[e] = { fnSource: t }, this; } /** * @inheritDoc */ validation(e) { return new eo(this, e); } /** * @inheritDoc */ event(e) { return new Yn(this, e); } buildComponent() { const e = { key: this.key, type: this.type, props: this.props }; return this.validations.length && (e.schema = { validations: this.validations }), Object.keys(this.events).length && (e.events = this.events), Object.keys(this.css).length && (e.css = this.css), this.childComponents.length && (e.children = this.childComponents), e; } addEvent(e, t) { this.events[e] || (this.events[e] = []), this.events[e].push(t); } addValidation(e, t) { this.validations.push({ key: e, args: t }); } /** * @inheritDoc */ style(e, t) { const o = this.css[t ?? "any"] ??= {}; return typeof e == "object" ? (o.object = { ...o.object, ...e }, this) : (o.string = e, this); } /** * @inheritDoc */ children(e) { const t = new Ke(), o = e(t); return Xn(o) && o.finalize(), this.childComponents = [ ...this.childComponents, ...t.build().form.children ?? [] ], this; } /** * @inheritDoc */ json = () => this.parent.json(); /** * @inheritDoc */ component = (e, t) => this.parent.component(e, t); } class Ke { constructor(e) { this.options = e; } components = []; current = null; /** * @inheritDoc */ component(e, t) { return this.current && this.components.push(this.current.buildComponent()), this.current = new to(this, e, t), this.current; } /** * @inheritDoc */ json() { const e = this.build(), t = JSON.parse(JSON.stringify(e)), o = {}; return this.toComponentProperties(t.form, o), Object.keys(o).length > 0 && (t.localization = o, t.languages = this.toLanguages(o)), JSON.stringify(t); } build() { this.current && (this.components.push(this.current.buildComponent()), this.current = null); const e = { ...this.options, form: { key: "Screen", type: "Screen" } }; return this.components.length && (e.form.children = this.components), e; } toLanguages(e) { return Object.keys(e).map((t) => { const [o, r] = t.split("-"); return { code: o, dialect: r ?? o }; }); } toComponentProperties(e, t) { const o = e.props ?? {}; Object.entries(o).forEach(([s, i]) => { if (Zn(i)) { o[s] = { computeType: "function", fnSource: i.fnSource }; return; } Je(i) && (o[s] = { computeType: "localization" }, Object.entries(i.values).forEach(([d, c]) => { const p = d; t[p] ??= {}, t[p][e.key] ??= {}, t[p][e.key].component ??= {}, t[p][e.key].component[s] = c; })); }), (e.children ?? []).forEach((s) => { this.toComponentProperties(s, t); }); } } function ar(n) { return new Ke(n); } const no = (n) => n.trim() === "", dr = (n, e) => { const t = k(); return b(() => t === "viewer" ? n : typeof n == "string" && no(n) ? e : n ?? e, [e, t, n]); }, oo = { EmbeddedForm: { description: "نموذج مضمن في نموذج آخر", name: "شكل مضمن", props: { disabled: { description: "إذا كان هذا صحيحا ، يتم تعطيل النموذج المضمن", name: "معاق" }, formName: { description: "اسم النموذج", name: "اسم النموذج" }, options: { description: "الخيارات الإضافية لتحميل النموذج المضمن", name: "الخيارات" }, readOnly: { description: "إذا كان هذا صحيحا ، فإن النموذج المضمن للقراءة فقط", name: "للقراءة فقط" }, storeDataInParentForm: { description: "إذا كاذبة ، تظهر بيانات النموذج المتداخلة ككائن متداخل ، صحيح خلاف ذلك", name: "تخزين البيانات في شكل الأصل" } } }, Repeater: { description: "مكون المكرر هو مكون خاص مسؤول عن عرض مجموعة من المكونات المتكررة", name: "مكرر", props: { itemRenderWhen: { description: "التعبير أو الوظيفة لتقديم عنصر مكرر بشكل مشروط", name: "البند تقديم عندما" } } } }, ro = { components: oo }, so = { EmbeddedForm: { description: "Ein Formular, das in ein anderes Formular eingebettet ist", name: "Eingebettetes Formular", props: { disabled: { description: "Wenn true, ist das eingebettete Formular deaktiviert", name: "Behinderte" }, formName: { description: "Der Name des Formulars", name: "Name des Formulars" }, options: { description: "Die zusätzlichen Optionen zum Laden des eingebetteten Formulars", name: "Option" }, readOnly: { description: "Wenn true, ist das eingebettete Formular schreibgeschützt", name: "Schreibgesch" }, storeDataInParentForm: { description: "Wenn false, werden verschachtelte Formulardaten als verschachteltes Objekt angezeigt, andernfalls true", name: "Daten im übergeordneten Formular speichern" } } }, Repeater: { description: "Die Repeater-Komponente ist eine spezielle Komponente, die für die Anzeige eines Arrays sich wiederholender Komponenten verantwortlich ist", name: "Verstärker", props: { itemRenderWhen: { description: "Der Ausdruck oder die Funktion zum bedingten Rendern eines Wiederholungselements", name: "Objekt rendern wann" } } } }, io = { components: so }, ao = { EmbeddedForm: { name: "Embedded form", description: "A form embedded in another form", props: { storeDataInParentForm: { name: "Store data in parent form", description: "If false, nested form data show as nested object, true otherwise" }, formName: { name: "Form name", description: "The form name" }, options: { name: "Options", description: "The additional options for loading the embedded form" }, disabled: { name: "Disabled", description: "If true, the embedded form is disabled" }, readOnly: { name: "Read only", description: "If true, the embedded form is read-only" } } }, Repeater: { name: "Repeater", description: "The Repeater component is a special component that is responsible for displaying an array of repeating components", props: { itemRenderWhen: { name: "Item render when", description: "The expression or function to conditionally render a repeater item" } } } }, co = { components: ao }, lo = { EmbeddedForm: { description: "Un formulario incrustado en otro formulario", name: "Formulario incrustado", props: { disabled: { description: "Si es verdadero, el formulario incrustado está deshabilitado", name: "Discapacitados" }, formName: { description: "El nombre del formulario", name: "Nombre del formulario" }, options: { description: "Las opciones adicionales para cargar el formulario incrustado", name: "Opciones" }, readOnly: { description: "Si es true, el formulario incrustado es de solo lectura", name: "Solo lectura" }, storeDataInParentForm: { description: "Si es falso, los datos del formulario anidado se muestran como objeto anidado, verdadero de lo contrario", name: "Almacenar datos en forma principal" } } }, Repeater: { description: "El componente Repetidor es un componente especial que se encarga de mostrar una matriz de componentes repetidos", name: "Repetidor", props: { itemRenderWhen: { description: "La expresión o función para representar condicionalmente un elemento repetidor", name: "Elemento renderizado cuando" } } } }, po = { components: lo }, mo = { EmbeddedForm: { description: "فرم تعبیه شده در فرم دیگر", name: "فرم تعبیه شده", props: { disabled: { description: "اگر درست باشد ، فرم جاسازی شده غیرفعال است", name: "معلول" }, formName: { description: "نام فرم", name: "نام فرم" }, options: { description: "گزینه های اضافی برای بارگذاری فرم جاسازی شده", name: "گزینه ها" }, readOnly: { description: "اگر درست باشد ، فرم جاسازی شده فقط برای خواندن است", name: "فقط بخوانید" }, storeDataInParentForm: { description: "اگر نادرست باشد ، داده های فرم آشیانه ای به عنوان شی آشیانه ای نشان داده می شوند ، در غیر این صورت درست است", name: "ذخیره اطلاعات در فرم والدین" } } }, Repeater: { description: "م Componentلفه تکرار کننده یک م componentلفه خاص است که وظیفه نمایش آرایه ای از اجزای تکرار را بر عهده دار