UNPKG

@react-form-builder/core

Version:

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

1,827 lines (1,826 loc) 161 kB
import { jsx as u, Fragment as xe, jsxs as it } from "@emotion/react/jsx-runtime"; import * as Kn from "react"; import { createContext as qn, useContext as at, useMemo as P, useEffect as K, useState as lt, useCallback as ye, createElement as Oe, forwardRef as Hn, Fragment as Un, useRef as _n, useImperativeHandle as Jn } from "react"; import { cx as ie, css as ae } from "@emotion/css"; import { makeAutoObservable as H, reaction as ct, configure as Zn, observable as F, autorun as dt, makeObservable as yr, runInAction as gr } from "mobx"; import { FluentResource as Lt, FluentBundle as Gn } from "@fluent/bundle"; import { CacheProvider as Qn } from "@emotion/react"; import Bt from "@emotion/cache"; import { z as D } from "zod"; import { observer as vr } from "mobx-react"; function Xn(t, e) { return t.reduce((r, n, o, s) => ((r[e(n, o, s)] ||= []).push(n), r), {}); } const Wt = Symbol("key"); function br(t, e, r, n = {}) { const o = Object.keys(n).map((s) => `${s}=${n[s]}`).join("_"); return `${t}_${e}_${r ? `${r}_` : ""}${o}`; } function ut(t, e, r = {}) { return br("autorun", t, e, r); } function N(t, e = {}) { return br("observable", t, void 0, e); } let Kt = 0; function wr(t) { t[Wt] || (++Kt, t[Wt] = `actionData_${Kt}`); } function Cr(t) { const e = t.events; e && Object.values(e).forEach((r) => r.forEach(wr)), t.children?.forEach(Cr); } function le(t) { return t?.computeType === "function"; } function ht(t) { return t?.computeType === "localization"; } function Er(t) { return le(t) || ht(t); } function W(t) { return t.dataKey ?? t.key; } class A { /** * The React component key. */ key = ""; /** * The component data key. */ dataKey; /** * The component type of the form viewer. */ type = ""; /** * The component properties. */ props = {}; /** * The component CSS styles. */ css; /** * The component wrapper CSS styles. */ wrapperCss; /** * The component styles for the `style` attribute. */ style; /** * The component wrapper styles for the `style` attribute. */ wrapperStyle; /** * The set of event handlers. */ events; /** * The array of child components. */ children; /** * The component value validation settings. */ schema; /** * The set of arbitrary HTML attributes added to the component. */ htmlAttributes; /** * The tooltip settings. */ tooltipProps; /** * The modal settings. */ modal; /** * The name of the occupied component property in the parent component. */ slot; /** * The condition for binding a child element to a parent element. */ slotCondition; /** * The expression or function to conditionally render a component. */ renderWhen; /** * Disables data binding for the component. */ disableDataBinding; /** * Creates the component settings. * @param key the React component key. * @param type the component type of the form viewer. */ constructor(e, r) { this.key = e, this.type = r, H(this, void 0, { name: N("ComponentStore", { key: e }) }); } /** * Correctly creates the {@link ComponentStore} from deserialized data. * @param value the deserialized data. * @returns the component Store. */ static createFromObject(e) { const r = Object.assign(new A(e.key, e.type), e); return Cr(r), r; } /** * Adds the event handler for component. * @param store the target {@link ComponentStore}. * @param eventName the target event name. * @param data the {@link ActionData}. */ static addEventHandler(e, r, n) { wr(n), e.events ??= {}, e.events[r] ??= [], e.events[r].push(n); } /** * Returns a clone of the specified component settings. * @param store the component settings. * @returns the clone of the specified component settings. */ static clone(e) { const r = JSON.parse(JSON.stringify(e)); return A.createFromObject(r); } } function Dr(t) { return typeof t == "string"; } function Vr(t) { return typeof t == "number"; } function Re(t) { return typeof t == "object" && typeof t.then == "function"; } function G(t) { return typeof t == "object"; } function x(t, e) { const r = vr(e); return r.displayName = t, r; } const za = new A("", ""), Je = {}; function ft(t) { const e = t.name; if (Je[e]) throw new Error(`Component feature ${e} is already registered`); Je[e] = t; } function I(t) { ft({ name: t, allowMultiple: !1 }); } function Pr(t) { const e = Je[t]; if (!e) throw new Error(`ComponentFeature ${t} is not registered`); return e; } function Yn(t, e, r) { const n = Pr(e), o = { ...t }, s = o[e]; return o[e] = n.allowMultiple ? s ? [...s, r] : [r] : r, o; } function ce(t, ...e) { let r = t ?? {}; return e.forEach((n) => { r = Yn(r, n.name, n.value); }), r; } const eo = "component-is-preset"; I(eo); const pt = "component-role"; ft({ name: pt, allowMultiple: !0 }); const Fr = "disable-main-component-properties"; I(Fr); const mt = "disable-tooltip-properties"; I(mt); const yt = "disable-style-properties"; I(yt); const gt = "disable-additional-properties"; I(gt); const to = "disable-styles-for-classname-editor"; I(to); const ro = "enable-inline-styles-editor"; I(ro); const Te = "hide-from-component-palette"; I(Te); const Sr = "disable-component-remove"; I(Sr); const xr = "disable-component-styling"; I(xr); const Or = "disable-component-wrapper-styling"; I(Or); const vt = "skip-children-during-field-collection"; I(vt); const Rr = "event-handlers"; ft({ name: Rr, allowMultiple: !1 }); const no = "disable-action-editors"; I(no); const oo = { /** * @inheritDoc */ get get() { return {}; }, /** * @inheritDoc */ get wrapperClassName() { return ""; }, /** * @inheritDoc */ get wrapperStyle() { }, /** * @inheritDoc */ get propsWithoutChildren() { return {}; }, /** * @inheritDoc */ get ownProps() { return {}; }, /** * @inheritDoc */ onDidMount() { }, /** * @inheritDoc */ onWillUnmount() { }, /** * @inheritDoc */ get isReadOnly() { return !1; }, /** * @inheritDoc */ get isDisabled() { return !1; } }; function so(t) { return () => { const e = at(t); if (!e) throw new Error(`The context ${t.displayName} was not found!`); return e; }; } function io(t) { return t.Provider; } function ee(t, e = null) { const r = qn(e); r.displayName = t; const n = so(r), o = io(r); return [n, o, r]; } function E(t) { return typeof t > "u"; } function q(t) { return t === null; } function La(t) { return typeof t == "number"; } function J(t) { return t !== null && typeof t == "object"; } function Tr(t) { return q(t) || E(t) ? !0 : typeof t == "string" || Array.isArray(t) ? t.length === 0 : t instanceof Map || t instanceof Set ? t.size === 0 : J(t) ? Object.keys(t).length === 0 : !1; } function ao(t) { if (!t) return ["", ""]; try { if (typeof Intl < "u" && Intl.Segmenter) { const o = new Intl.Segmenter(void 0, { granularity: "grapheme" }).segment(t)[Symbol.iterator]().next(); if (!o.done) { const s = String(o.value.segment); return [s, t.slice(s.length)]; } return ["", ""]; } } catch { } const e = [...t]; return [e[0] ?? "", e.slice(1).join("")]; } function bt(t) { if (!t) return ""; const [e, r] = ao(t); return e.toUpperCase() + r; } function Ar(t) { const e = String(t ?? ""); if (!e) return []; const r = e.replace(new RegExp("(\\p{Ll})(\\p{Lu})", "gu"), "$1 $2"); try { if (typeof Intl < "u" && Intl.Segmenter) { const n = new Intl.Segmenter(void 0, { granularity: "word" }), o = []; for (const s of n.segment(r)) { const i = s, a = String(i.segment); (i.isWordLike ?? /[\p{L}\p{N}]/u.test(a)) && o.push(a); } return o; } } catch { } return r.split(/[^\p{L}\p{N}]+/u).filter(Boolean); } function lo(t) { const e = Ar(t); if (e.length === 0) return ""; const r = e[0].toLowerCase(), n = e.slice(1).map((o) => bt(o.toLowerCase())); return [r, ...n].join(""); } function Ba(t) { return bt(t); } function kr(t) { const e = Ar(t); return e.length === 0 ? "" : e.map((r) => bt(r.toLowerCase())).join(" "); } function Wa(t) { return (t || "").toUpperCase(); } function wt(t = "") { return `${t}${++wt.counter}`; } wt.counter = 0; function Ze(t, ...e) { for (const r of e) { if (!J(t) || !J(r)) { Object.assign(t, r); continue; } for (const n of Object.keys(r)) { const o = r[n], s = t[n]; J(o) && J(s) ? Ze(s, o) : t[n] = o; } } return t; } function co(t, e = 0) { let r; return (...o) => { E(r) || clearTimeout(r), r = setTimeout(() => t(...o), e); }; } function Ge(t, e) { if (t === e) return !0; if (t == null || e == null) return !1; if (t instanceof Date && e instanceof Date) return t.getTime() === e.getTime(); if (Array.isArray(t) && Array.isArray(e)) { if (t.length !== e.length) return !1; for (let r = 0; r < t.length; r++) if (!Ge(t[r], e[r])) return !1; return !0; } if (typeof t == "object" && typeof e == "object") { const r = Object.keys(t), n = Object.keys(e); if (r.length !== n.length) return !1; for (const o of r) if (!Object.prototype.hasOwnProperty.call(e, o) || !Ge(t[o], e[o])) return !1; return !0; } return !1; } function qt(t, e, r) { if (r) { if (Array.isArray(t) && Array.isArray(e)) { if (t.length !== e.length) return !1; for (let n = 0; n < t.length; n++) { const o = r(t[n], e[n], n); if (!E(o)) { if (!o) return !1; continue; } if (!qt(t[n], e[n], r)) return !1; } return !0; } if (J(t) && J(e)) { const n = /* @__PURE__ */ new Set([...Object.keys(t), ...Object.keys(e)]); for (const o of n) { const s = r(t[o], e[o], o); if (!E(s)) { if (!s) return !1; continue; } if (!qt(t[o], e[o], r)) return !1; } return !0; } } return Ge(t, e); } function oe(t, e = /* @__PURE__ */ new WeakMap()) { if (t === null || typeof t != "object") return t; if (e.has(t)) return e.get(t); if (t instanceof Date) return new Date(t.getTime()); if (t instanceof RegExp) { const o = new RegExp(t.source, t.flags); return o.lastIndex = t.lastIndex, o; } if (t instanceof Map) { const o = /* @__PURE__ */ new Map(); return e.set(t, o), t.forEach((s, i) => { o.set(oe(i, e), oe(s, e)); }), o; } if (t instanceof Set) { const o = /* @__PURE__ */ new Set(); return e.set(t, o), t.forEach((s) => o.add(oe(s, e))), o; } if (ArrayBuffer.isView(t)) return new t.constructor(t); if (t instanceof ArrayBuffer) return t.slice(0); if (Array.isArray(t)) { const o = []; e.set(t, o); for (const s of t) o.push(oe(s, e)); return o; } const r = Object.getPrototypeOf(t), n = Object.create(r); e.set(t, n); for (const o of Reflect.ownKeys(t)) { const s = Object.getOwnPropertyDescriptor(t, o); s && ("value" in s && (s.value = oe(t[o], e)), Object.defineProperty(n, o, s)); } return n; } const uo = (t, e) => { const r = [...t]; return t.forEach((n, o) => { o in e && (r[o] = Nr(n, e[o] ?? void 0)); }), r; }, Ht = (t) => !(!G(t) || t instanceof Date), Nr = (t, e) => Array.isArray(t) ? Array.isArray(e) ? uo(t, e) : t : Array.isArray(e) ? t : Ht(t) && Ht(e) ? Ct(t, e) : t, Ct = (t, e) => { const r = { ...t }; return Object.keys(e).forEach((n) => { if (n in t) { if (E(t[n])) return; r[n] = Nr(t[n], e[n]); return; } r[n] = e[n]; }), r; }; class Ut { handlers = []; /** * Adds a handler to the list of subscribers. * @param handler the handler function to be added. */ subscribe(e) { this.handlers.push(e); } /** * Removes the specified event handler from the list of handlers. * @param handler the event handler to remove. */ unsubscribe(e) { this.handlers = this.handlers.filter((r) => r !== e); } /** * Returns true if the object has subscribers, false otherwise. * @returns true if the object has handlers registered for events, otherwise returns false. */ get isSubscribed() { return this.handlers.length > 0; } /** * Invokes the event by calling all registered event handlers. * @param sender the sender of the event. * @param eventArgs the event arguments. */ invoke(e, r) { [...this.handlers].forEach((n) => n(e, r)); } /** * Dispose method to release all handlers. */ dispose() { this.handlers = []; } } function De(t, e) { e(t), t.children?.forEach((r) => De(r, e)); } function ho(t, e, r = 0) { if (t === e) return r; if (t.children) { r = r + 1; for (const n of t.children) { const o = ho(n, e, r); if (o) return o; } } } function _t(t, e) { let r = 1; const n = lo(t.type), o = () => `${n}${r}`; for (; e.has(o()); ) r++; return t.key = o(), t.key; } function be(t) { return typeof t.disableReaction == "function"; } class fo { /** * Constructs a new instance of the ComponentKeyChangedEventArgs class. * @param oldKey the old key. * @param newKey the new key. */ constructor(e, r) { this.oldKey = e, this.newKey = r; } } class po { /** * An event that occurs after a component key change. */ onAfterKeyChanged = new Ut(); /** * An event that occurs before a component is removed from the component tree. */ onBeforeDelete = new Ut(); /** * Unsubscribe from all events. */ dispose() { this.onAfterKeyChanged.dispose(), this.onBeforeDelete.dispose(); } } const Jt = (t) => { const e = {}; return Object.entries(t.data).forEach(([r, n]) => { e[r] = n ?? ""; }), e; }; class mo { #e; #t; #r; _state = {}; /** * The unique identifier. */ id; /** * The component settings. */ store; /** * The component metadata. */ model; /** * The field with the form data. */ field; /** * The parent node in the component data tree. */ parent; /** * The child nodes in the component data tree. */ children = []; /** * User defined properties of the React component. */ userDefinedProps; /** * If true, then validation is in progress. */ validating = !1; /** * Specifies the root component for the data in the component tree. **Internal use only.** */ dataRootProvider; /** * Specifies the index in the array if the component is in the component array. * This is not an index in a parent-child structure. */ index; /** * The state of the component. **Internal use only. */ componentState = oo; /** * The function for getting initial data. **Internal use only.** */ getInitialData; /** * The function for updating initial data. **Internal use only.** */ setInitialData; /** * Constructor. * @param componentStore the component settings. * @param model the component metadata for the form viewer. * @param childFactory the factory function that creates {@link ComponentData} instance. * @param getFormValidationResult the function that returns a form validation results. */ constructor(e, r, n, o) { this.store = e, this.model = r, this.id = wt(`${this.model.type}_`), this.#r = o, e.children?.forEach((i) => { n(i).setParent(this); }), H(this, void 0, { name: N("ComponentData", { key: e.key }) }); const s = () => ct(() => this.key, (i, a) => { this.invokeOnAfterKeyChanged(this, new fo(a, i)); }); this.#e = [s()]; } /** * Sets the new parent for this node. * @param newParent the new parent. */ setParent(e) { this.parent?.removeChild(this), e.addChild(this), this.parent = e; } /** * Inserts the given node after this node. * @param inserted the node to insert. */ insertAfterMe(e) { this.insert(e, "after"); } /** * Inserts the given node before this node. * @param inserted the node to insert. */ insertBeforeMe(e) { this.insert(e, "before"); } /** * @inheritDoc */ get state() { return this._state; } /** * @returns the root component for the data in the component tree. */ get dataRoot() { return this.dataRootProvider?.dataRoot ?? this.parent?.dataRoot ?? this; } /** * @returns the initial data. */ get initialData() { return this.dataRoot.getInitialData?.(); } /** * Updates the initial data. **Internal use only.** * @param key the initial data key. * @param value the initial data value. */ updateInitialData(e, r) { this.dataRoot.setInitialData?.(e, r); } /** * @returns the key of this node (same as the key of the ComponentStore). */ get key() { return this.store.key; } /** * @returns the ComponentDataEvents object. */ get events() { return this.#t || (this.#t = new po()), this.#t; } /** * Find the node with the given key. * @param key the key to find. * @returns the node or undefined if not found. */ findByKey(e) { if (this.key === e) return this; for (let r = 0; r < this.children.length; r++) { const o = this.children[r].findByKey(e); if (o) return o; } } /** * Assigns unique keys to the items in the tree. * @param root the root of the tree to unify keys. Defaults to the root of this tree. * @returns the map of new keys to old keys. */ unifyKeys(e) { const r = /* @__PURE__ */ new Map(), n = []; return De(e, ({ key: o }) => { n.push(o); }), De(this, (o) => { const s = _t(o.store, new Set(n)); r.set(s, o.key), n.push(s); }), r; } /** * Assigns unique keys to the items in the tree. */ unifyTree() { const e = /* @__PURE__ */ new Map(); De(this, ({ key: o, store: s }) => { const i = e.get(o) ?? /* @__PURE__ */ new Set(); i.add(s), e.set(o, i); }); const n = new Set(e.keys()); e.forEach((o, s) => { if (o.size <= 1) return; [...o].slice(1).forEach((a) => { const c = _t(a, n); n.add(c); }); }); } /** * @returns all the fields in the tree as a map. Starts from this node. */ get fields() { const e = this.collectAllFields(/* @__PURE__ */ new Map()), r = /* @__PURE__ */ new Map(); return e.forEach((n, o) => { r.set(W(o.store), n); }), r; } /** * @returns an array of all component fields, including non-unique data keys. */ get allComponentFields() { const e = this.collectAllFields(/* @__PURE__ */ new Map()), r = []; return e.forEach((n, o) => { r.push({ dataKey: W(o.store), field: n }); }), r; } /** * @returns an array of all fields, including non-unique data keys. */ get allFields() { return this.allComponentFields.map((e) => e.field); } /** * @returns an array of all children components. */ get allChildren() { return this.collectAllChildren([]); } /** * Deletes this node from the tree. */ delete() { this.parent?.removeChild(this); const e = this.collectAllNodesAsArray([]); this.invokeOnBeforeDeleted(e), this.disposeNodes(e); } /** * @inheritDoc */ get data() { const e = { ...this.generatedData() }, r = G(this.initialData) ? { ...this.initialData } : {}; return Ct(e, r); } /** * @returns the generated form data. */ generatedData() { const e = {}; for (const { dataKey: r, field: n } of this.allComponentFields) if (n.storeDataInParentForm) { const o = n.value || {}; Object.keys(o).forEach((s) => e[s] = o[s]); } else e[r] = n.value; return e; } /** * @returns the object to read and modify parent data (available for array elements). */ get parentData() { if (typeof this.nearestIndex == "number") return this.parent?.data ?? this.rootData; } /** * @returns the object to read and modify root form data. */ get rootData() { return this.root.data; } /** * @inheritDoc */ get errors() { const e = {}; for (const { dataKey: r, field: n } of this.allComponentFields) { n.error && (e[r] = n.error); const o = n.errors; o && (Array.isArray(o) ? e[r] = o : (n.storeDataInParentForm && Object.keys(o).forEach((s) => e[s] = o[s]), !n.storeDataInParentForm && Object.keys(o).length > 0 && (e[r] = o))); } return e; } /** * @inheritDoc */ set errors(e) { this.allComponentFields.forEach((r) => { const n = e[r.dataKey]; r.field.setError(n); }); } /** * @inheritDoc */ get hasErrors() { return Object.keys(this.errors).length > 0; } /** * @inheritDoc */ setAllErrors(e) { this.allFields.forEach((r) => r.error = e); } /** * @inheritDoc */ async validate() { return await this.validateForm(), this.errors; } /** * @inheritDoc */ async getValidationResult() { let e; const r = async ({ dataKey: o, field: s }) => { const i = await s.getValidationResult(); if (Tr(i)) return; e ??= {}; let a = e; if (!s.storeDataInParentForm) { const c = Array.isArray(i) ? [] : {}; e[o] ??= c, a = e[o]; } Ze(a, i); }; return await Promise.allSettled(this.allComponentFields.map(r)), (await this.#r?.())?.forEach((o) => { e ??= {}, Ze(e, o); }), e; } /** * @inheritDoc */ get isValidating() { return this.validating; } /** * @inheritDoc */ reset(e = !0) { e && this.clearInitialData(), this.allFields.forEach((r) => { be(r) && r.disableReaction(), r.reset(); }), this.allFields.forEach((r) => { be(r) && r.enableReaction(); }); } /** * @inheritDoc */ clear(e = !0) { e && this.clearInitialData(), this.allFields.forEach((r) => { be(r) && r.disableReaction(), r.clear(); }), this.allFields.forEach((r) => { be(r) && r.enableReaction(); }); } /** * Dispose method that releases resources used by the object. * It disposes the field and all the children objects. */ dispose() { const e = this.collectAllNodesAsArray([]); this.disposeNodes(e); } /** * @returns true if it has no parent {@link ComponentData}, false otherwise. */ get isRoot() { return !this.parent; } /** * @returns the root of the component tree. */ get root() { return this.parent ? this.parent.root : this; } /** * @returns the index in the array if the component is in the component array * (looks for the nearest index in the component hierarchy). */ get nearestIndex() { return E(this.index) ? this.parent?.nearestIndex : this.index; } async validateForm() { this.validating = !0; try { await Promise.allSettled([...this.allFields].map((n) => n.validate())); const e = await this.#r?.(); if (!e?.length) return; const r = this.allComponentFields; e.forEach((n) => { n && r.forEach(({ field: o, dataKey: s }) => { if (n[s]) return o.setError(n[s]); if (o.storeDataInParentForm) return o.setError(n); }); }); } finally { this.validating = !1; } } insert(e, r) { const n = r === "before" ? 0 : 1; if (!this.parent) throw new Error(`Cannot insert without parent. Key = ${this.key}`); e.parent?.removeChild(e), e.parent = this.parent; const o = this.parent.children, s = o.indexOf(this); if (s < 0) throw new Error(`Cannot insert not existing element into ComponentData. Key = ${this.key}`); o.splice(s + n, 0, e), this.parent.store.children ??= []; const i = this.parent.store.children, a = i.indexOf(this.store); if (a < 0) throw new Error(`Cannot insert not existing element into ComponentStore. Key = ${this.key}`); i.splice(a + n, 0, e.store), e.store.slot = this.store.slot, e.store.slotCondition = this.store.slotCondition; } /** * Disposes the nodes by calling the disposers, disposing the field, * and resetting the parent and children properties to undefined and an empty array, respectively. * @param nodes the array of ComponentData objects representing the nodes to dispose. */ disposeNodes(e) { e.forEach((r) => { r.#t?.dispose(), r.#e.forEach((n) => n()), r.field?.dispose(), r.parent = void 0, r.children = []; }); } collectAllNodesAsArray(e) { e.push(this); for (let r = 0; r < this.children.length; r++) this.children[r].collectAllNodesAsArray(e); return e; } collectAllFields(e) { if (this.field && e.set(this, this.field), this.model.isFeatureEnabled(vt)) return e; for (let r = 0; r < this.children.length; r++) this.children[r].collectAllFields(e); return e; } collectAllChildren(e) { e.push(this); for (let r = 0; r < this.children.length; r++) this.children[r].collectAllChildren(e); return e; } addChild(e) { this.children.indexOf(e) < 0 && this.children.push(e), this.store.children ??= [], this.store.children.indexOf(e.store) < 0 && this.store.children.push(e.store); } removeChild(e) { const r = this.children.indexOf(e); r > -1 && this.children.splice(r, 1), this.store.children ??= []; const n = this.store.children.indexOf(e.store); n > -1 && this.store.children.splice(n, 1); } invokeOnAfterKeyChanged(e, r) { this.#t?.onAfterKeyChanged.isSubscribed && this.#t.onAfterKeyChanged.invoke(e, r), this.parent?.invokeOnAfterKeyChanged(e, r); } invokeOnBeforeDeleted(e) { this.#t?.onBeforeDelete.isSubscribed && e.forEach((r) => this.#t?.onBeforeDelete.invoke(r, void 0)), this.parent?.invokeOnBeforeDeleted(e); } clearInitialData() { const e = this.initialData; e && G(e) && Object.keys(e).forEach((r) => delete e[r]); } } const [ /** * @returns the instance of the ComponentData of the currently rendered component. */ j, /** * Context provider for the useComponentData hook. **Internal use only.** */ Ir ] = ee("ComponentDataContext"), yo = (t) => { const { id: e } = j(); return P(() => { const r = {}; return t.labeled && (r["aria-labelledby"] = `${e}-label`), r["aria-errormessage"] = `${e}-error`, r; }, [e, t.labeled]); }, go = () => { const { id: t } = j(); return P(() => ({ "aria-errormessage": `${t}-error` }), [t]); }, vo = () => { const { field: t } = j(), e = !!t?.error; return P(() => ({ "aria-invalid": e }), [e]); }, Ka = (t) => { const e = vo(), r = yo(t); return P(() => ({ ...r, ...e }), [r, e]); }; class M { /** * Creates component metadata for the form viewer. * @param component the React component. * @param name the component name. * @param actionsInitializer the function to initialize actions in the component. * @param valued the name of the component property where the component value is stored. * @param valueType the type of the component value. * @param defaultProps the component's default property values. * @param css the component's CSS values. * @param wrapperCss the component's wrapper CSS values. * @param typeName the component type name. * @param kind the component kind. * @param readOnly the name of the component property that stores the read-only flag. * @param propsBindingTypes the component property binding types. * @param uncontrolledValue the value for the uncontrolled (undefined) state. * @param disabled the name of the component property that stores the disabled flag. * @param dataBindingType the type of component data binding. * @param features the component features that provide additional information about component's characteristic. * @template T the type of React component properties. */ constructor(e, r, n, o, s, i, a, c, d, p = "component", m, f = {}, w, v, R = "none", z = {}) { this.actionsInitializer = n, this.valued = o, this.valueType = s, this.defaultProps = i, this.css = a, this.wrapperCss = c, this.typeName = d, this.kind = p, this.readOnly = m, this.propsBindingTypes = f, this.uncontrolledValue = w, this.disabled = v, this.dataBindingType = R, this.features = z, this.valued && this.dataBindingType === "none" && (this.dataBindingType = "twoWay"), this.component = vr(e), this.component.displayName = e.displayName || e.name, this.#e = r; } #e; /** * The React component. */ component; /** * @returns the component name, or type if there is no component name. */ get name() { return this.#e ?? this.type; } /** * @returns the component type name. */ get type() { return this.typeName || this.component.displayName || this.component.name; } /** * Returns true if feature is present in the component feature set and equals value, false otherwise. * @param name the feature name. * @param value the feature value. * @returns true if feature is present in the component feature set and equals value, false otherwise. */ hasFeatureValue(e, r) { const n = this.features[e]; return n ? Pr(e).allowMultiple ? Array.isArray(n) ? n.indexOf(r) >= 0 : !1 : n === r : !1; } /** * Returns true if feature is present in the component feature set and equals `true`, false otherwise. * @param name the feature name. * @returns true if feature is present in the component feature set and equals `true`, false otherwise. */ isFeatureEnabled(e) { return this.features[e] === !0; } /** * Returns true if the role is defined in the component's roles, false otherwise. * @param value the component role. * @returns true if the role is defined in the component's roles, false otherwise. */ hasComponentRole(e) { return this.hasFeatureValue(pt, e); } } var Y = /* @__PURE__ */ ((t) => (t.LTR = "ltr", t.RTL = "rtl", t))(Y || {}); const [ /** * **Internal use only.** */ k, /** * **Internal use only.** */ Et, /** * **Internal use only.** */ bo ] = ee("StoreContext"), [ /** * @returns the {@link BuilderMode} builder mode value. */ Dt, /** * The BuilderMode context provider. */ qa ] = ee("BuilderModeContext", "viewer"), wo = (t, e) => { const r = Dt(); return P(() => r === "builder" ? t : e, [t, r, e]); }, jr = "closeCurrentModal", Vt = (async function() { }).constructor; class O { /** * Creates a new instance of the ActionDefinition class. * @param func the function of an action. * @param body the source code of the Action. * @param params the parameters of the Action. */ constructor(e, r, n = {}) { this.func = e, this.body = r, this.params = n; } /** * Creates an action from the function. * @param func the function of an action. * @param params the parameters of the Action. * @returns the new instance of the ActionDefinition class. */ static functionalAction(e, r = {}) { return new O(e, void 0, r); } /** * Creates an action from the source code. * @param body the source code of the Action. * @param params the parameters of the Action. * @returns the new instance of the ActionDefinition class. */ static sourceAction(e, r = {}) { const n = Vt("e, args", e); return new O(n, e, r); } /** * Correctly creates the {@link ActionDefinition} from deserialized data. * @param value the deserialized data. * @returns the ActionDefinition instance. */ static createFromObject(e) { return O.sourceAction(e.body, e.params); } } const Co = (t) => { const e = {}; return t && Object.keys(t).forEach((r) => { const n = t[r]; e[r] = O.createFromObject(n); }), e; }, Zt = "beforeShow", Z = "beforeHide", Qe = "modalState", Eo = O.functionalAction(async (t, e) => { const { modalKey: r, useFormData: n } = e; if (!r) { console.warn(`Modal ${r} is missing`); return; } const { formData: o } = t.store, s = o.findByKey(r); if (!s) { console.warn(`Component ${r} is not found`); return; } const i = e[Zt], a = i ? await i(void 0, void 0, e) : void 0; if (a === !1) return; const c = n === !0 ? o.data : G(a) ? a : void 0, d = G(c) ? JSON.parse(JSON.stringify(c)) : void 0; s.userDefinedProps ??= {}, s.userDefinedProps[Qe] = { open: !0, initialData: d, [Z]: e[Z] }; }, { modalKey: "string", useFormData: "boolean", [Zt]: "function", [Z]: "function" }), Do = O.functionalAction(async (t, e) => { const r = t.store.formViewerPropsStore.context?.modalContext ?? {}, n = r[Z], o = n ? await n(t, e) : void 0; o?.[Z] && delete o[Z]; const s = r[jr]; s?.(o); }, { result: "string" }); function Ve(t) { return new Proxy({}, { get(e, r) { return r === "toJSON" ? () => t.data : t.data[r]; }, set(e, r, n) { let o = !1; return t.allComponentFields.filter(({ dataKey: s }) => s === r).forEach(({ field: s }) => { o = !0, s.setValue(n); }), o || t.updateInitialData(r, n), !0; }, ownKeys() { return Reflect.ownKeys(t.data); }, getOwnPropertyDescriptor(e, r) { return Object.getOwnPropertyDescriptor(t.data, r); } }); } const Mr = () => { K(() => { Zn({ enforceActions: "never" }); }, []); }, $r = "validator-", Vo = (t) => `${$r}${t}`, Ha = (t) => t.startsWith($r); class Ae { /** * Creates a localization language for the form builder. * @param code the language code, for example, 'en'. * @param dialect the dialect code, for example, 'US'. * @param name the name of the language, for example 'English'. * @param description the description of the language, for example 'American English'. * @param bidi the type of text layout, for example, BiDi.LTR. */ constructor(e, r, n, o, s = Y.LTR) { this.code = e, this.dialect = r, this.name = n, this.description = o, this.bidi = s; } /** * @returns the full code of the Language i.e. en-US, en-GB etc. */ get fullCode() { return `${this.code}-${this.dialect}`; } /** * Clones an existing instance of the language. * @param source the cloning object. * @returns the object clone. */ static clone(e) { return new Ae(e.code, e.dialect, e.name, e.description, e.bidi); } } const pe = new Ae("en", "US", "English", "American English"); class Xe extends Error { /** * Creates a new LocalizationError. * @param name the error name. * @param message the error message. */ constructor(e, r) { super(r), this.name = e; } } const zr = ".", Pt = "__DOT__"; function Ye(t) { return t.replace(new RegExp(`\\${Pt}`, "g"), zr); } function Po(t) { return t.replace(new RegExp(`\\${zr}`, "g"), Pt); } const Fo = (t) => typeof t == "string" || typeof t == "number" || t instanceof Date ? !0 : !E(t?.value), Gt = (t) => Object.entries(t).map(([e, r]) => `${e} = ${r}`).join(` `), Qt = (t) => new Xe(t.message, t.name), Be = (t, e, r = !1) => { t.forEach((n) => { n.name.indexOf("Attempt to override") > -1 || console.warn(n); }), r && Array.isArray(e) && e.length > 0 && console.warn(e); }, Xt = (t) => new Gn(t, { useIsolating: !1 }); function Yt(t, e) { return new Proxy(t, { get(r, n) { return n in r ? r[n] : (e.push(Ye(n)), ""); }, getOwnPropertyDescriptor(r, n) { return n in r ? Reflect.getOwnPropertyDescriptor(r, n) : { value: "", writable: !0, configurable: !0 }; } }); } class So { #e = /* @__PURE__ */ new Map(); #t = pe.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. */ #r(e, r, n, o) { o = o ?? this.#n(e); const s = Gt(r), i = new Lt(s), a = o.addResource(i); return n.length = 0, a.forEach((c) => n.push(Qt(c))), Be(n), o; } /** * 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. */ #n(e) { const r = this.#e.get(e) ?? Xt(e); return this.#e.set(e, r), r; } /** * 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. */ #o(e, r) { return e.getMessage(r)?.value ?? void 0; } /** * @inheritDoc */ set language(e) { this.#t = e; } /** * @inheritDoc */ get language() { return this.#t; } /** * @inheritDoc */ addMessages(e, r) { const n = Gt(r), o = this.#n(e), s = new Lt(n); return o.addResource(s, { allowOverrides: !0 }).map(Qt); } /** * @inheritDoc */ localizeProperties(e, r, n, o, s = "component") { const i = `${o.key}_${s}_`, a = {}, c = n.fullCode, d = [], { defaultBundle: p, formBundle: m } = this.#i(e, c, d); return Object.entries(o.props).forEach(([f, w]) => { if (!ht(w)) return; const v = `${i}${f}`, R = this.#a(v, m, p); if (!R) { a[f] = "[NOT LOCALIZED]"; return; } a[f] = this.#l(R, m, r); }), a; } /** * @inheritDoc */ getCompatibleId(e) { return e.replace(/\s/g, "_"); } /** * @inheritDoc */ localizeErrorMessage(e, r, n, o, s) { const i = Vo(s), a = `${o.key}_${i}_message`, c = [], { defaultBundle: d, formBundle: p } = this.#i(e, n.fullCode, c), m = this.#a(a, p, d); return m ? this.#l(m, p, r) : void 0; } /** * @inheritDoc */ testLocalization(e, r, n, o) { const s = Po(e), i = [], a = n.fullCode, c = this.#r(a, { [`${r}`]: s }, i, Xt(a)), d = c.getMessage(r); if (!d?.value) return [new Xe("MessageError", "Incorrect format")]; const p = [], m = Jt(o), f = [], w = Yt(this.#s(m), f), v = Ye(c.formatPattern(d.value, w, p)); return Be(p, f, !0), p.length > 0 ? p.map((R) => new Xe("MessageFormatError", R.message)) : v; } /** * 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, r, n) { const o = e.defaultLanguage.fullCode, s = o !== r ? e.localization.getItems(o) : void 0, i = e.localization.getItems(r), a = s ? this.#r(o, s, n) : void 0, c = i ? this.#r(r, i, n) : void 0; return { defaultBundle: a, 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, r, n) { const o = r ? this.#o(r, e) : void 0, s = n ? this.#o(n, e) : void 0; return o ?? 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. */ #l(e, r, n) { const o = [], s = Jt(n), i = [], a = Yt(this.#s(s), i), c = r?.formatPattern(e, a, o); return Be(o, i), c ? Ye(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. */ #s = (e, r = "") => { const n = {}; for (const [o, s] of Object.entries(e)) { const i = r ? `${r}${Pt}${o}` : o; Fo(s) ? n[this.getCompatibleId(i)] = s : typeof s == "boolean" ? n[this.getCompatibleId(i)] = s ? "true" : "false" : typeof s == "object" && !q(s) && Object.assign(n, this.#s(s, i)); } return n; }; } const er = { LTR: Bt({ key: Y.LTR }), RTL: Bt({ key: Y.RTL, prepend: !0 }) }, xo = ae` display: flex; width: 100%; height: 100%; `, Oo = "optimajet-formviewer", Ro = ie(Oo, xo), Lr = ([t, ...e], r, n) => t ? /* @__PURE__ */ u(t, { language: r, children: Lr(e, r, n) }) : n, To = (t) => { const e = k(), r = e.displayedLanguage, n = r.bidi == Y.RTL ? er.RTL : er.LTR; return K(() => { e.formViewerPropsStore.view.getCssLoaders(r.bidi).forEach((s) => { s().catch((i) => console.error(i)); }); }, [r, e.formViewerPropsStore.view]), /* @__PURE__ */ u("div", { dir: r.bidi, lang: r.fullCode, className: Ro, children: /* @__PURE__ */ u(Qn, { value: n, children: Lr(e.formViewerPropsStore.view.viewerWrappers, r, t.children) }) }); }, Br = x("ViewerLocalizationProvider", To), Ao = (t) => { if (typeof t == "string") return t; if (t && typeof t == "object" && "message" in t) { const e = t.message; if (typeof e == "string") return e; } return ""; }, Wr = ({ children: t }) => { const [e] = lt(globalThis.onerror); return K(() => (globalThis.onerror = (r) => { if (Ao(r).includes("ResizeObserver")) { const o = document.getElementById( "webpack-dev-server-client-overlay-div" ), s = document.getElementById( "webpack-dev-server-client-overlay" ); return s && s.setAttribute("style", "display: none"), o && o.setAttribute("style", "display: none"), !0; } return !1; }, () => { globalThis.onerror = e; }), [e]), /* @__PURE__ */ u(xe, { children: t }); }, [ /** * **Internal use only.** */ Q, /** * **Internal use only.** */ Kr ] = ee("FormViewerPropsContext"), ko = () => { const t = k(), e = t.form.errorType, r = t.formViewerPropsStore.view, n = Q(); return P(() => { const o = n.errorWrapper ? new M(n.errorWrapper) : st; return (e ? r.find(e) : o) ?? st; }, [e, r, n.errorWrapper]); }; class se { /** * Constructor. * @param error the error. * @param result the result. * @param exceptions the exceptions. * @param warning the warning. */ constructor(e = !1, r, n, o) { this.error = e, this.result = r, this.exceptions = n, this.warning = o; } /** * Creates a new instance of the CalculableResult class with a successful result. * @param result the calculable result. * @returns the new instance of CalculableResult class. */ static success(e) { return new se(!1, e); } /** * Creates a new instance of CalculableResult class with an error. * @param exceptions the exception array. * @returns the new instance of CalculableResult class. */ static error(e) { return new se(!0, void 0, e); } /** * Creates a new instance of the CalculableResult class with a warning result. * @param result the calculable result. * @returns the new instance of CalculableResult class. */ static warning(e) { return new se(!1, e, void 0, !0); } } const tr = /* @__PURE__ */ new Map(), No = (t) => { const e = tr.get(t); if (e) return e; const r = new Function("form", t); return tr.set(t, r), r; }, qr = (t, e) => { try { const n = No(t)(e); return se.success(n); } catch (r) { return se.error([ r, { name: "Function source", message: t } ]); } }, Ft = (t, e) => qr(t.fnSource || "", e), Hr = (t, e) => { if (le(t)) return Ft(t, e).result; const r = t.value || ""; return qr(`return ${r}`, e).result; }, Io = (t, e) => { const r = {}; return Object.keys(t.props).forEach((n) => { const o = t.props[n]; if (o) { if (le(o)) { const { result: s, error: i, exceptions: a } = Ft(o, e); if (i) { const c = `Error in the calculable field '${n}' of the '${t.key}' component `; console.warn(c, a); return; } r[n] = s; return; } E(o.value) || (r[n] = o.value); } }), r; }, rr = /\/\*[^*]*\*+([^/*][^*]*\*+)*\//g; function et(t, e) { const r = t && typeof t.type == "string", n = r ? t : e; for (const o in t) { const s = t[o]; Array.isArray(s) ? s.forEach(function(i) { et(i, n); }) : s && typeof s == "object" && et(s, n); } return r && Object.defineProperty(t, "parent", { configurable: !0, writable: !0, enumerable: !1, value: e || null }), t; } function _(t) { return t ? t.replace(/^\s+|\s+$/g, "") : ""; } function jo(t, e) { e = e || {}; let r = 1, n = 1; function o(h) { const l = h.match(/\n/g); l && (r += l.length); const b = h.lastIndexOf(` `); n = ~b ? h.length - b : n + h.length; } function s() { const h = { line: r, column: n }; return function(l) { return l.position = { start: h, end: { line: r, column: n }, source: e.source }, w(), l; }; } const i = []; function a(h) { const l = new Error(`${e.source}:${r}:${n}: ${h}`); if (l.reason = h, l.filename = e.source, l.line = r, l.column = n, l.source = t, e.silent) i.push(l); else throw l; } function c() { const h = m(); return { type: "stylesheet", stylesheet: { source: e.source, rules: h, parsingErrors: i } }; } function d() { return f(/^{\s*/); } function p() { return f(/^}/); } function m() { let h; const l = []; for (w(), v(l); t.length && t.charAt(0) != "}" && (h = Bn() || Wn()); ) h !== !1 && (l.push(h), v(l)); return l; } function f(h) { const l = h.exec(t); if (!l) return; const b = l[0]; return o(b), t = t.slice(b.length), l; } function w() { f(/^\s*/); } function v(h) { let l; for (h = h || []; l = R(); ) l !== !1 && h.push(l); return h; } function R() { const h = s(); if (t.charAt(0) != "/" || t.charAt(1) != "*") return; let l = 2; for (; t.charAt(l) != "" && (t.charAt(l) != "*" || t.charAt(l + 1) != "/"); ) ++l; if (l += 2, t.charAt(l - 1) === "") return a("End of comment missing"); const b = t.slice(2, l - 2); return n += 2, o(b), t = t.slice(l), n += 2, h({ type: "comment", comment: b }); } function z() { const h = f(/^([^{]+)/); if (h) return _(h[0]).replace(/\/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*\/+/g, "").replace(/"(?:\\"|[^"])*"|'(?:\\'|[^'])*'/g, function(l) { return l.replace(/,/g, "‌"); }).split(/\s*(?![^(]*\)),\s*/).map(function(l) { return l.replace(/\u200C/g, ","); }); } function $() { const h = s(); let l = f(/^(\*?[-#\/\*\\\w]+(\[[0-9a-z_-]+\])?)\s*/); if (!l) return; if (l = _(l[0]), !f(/^:\s*/)) return a("property missing ':'"); const b = f(/^((?:'(?:\\'|.)*?'|"(?:\\"|.)*?"|\([^\)]*?\)|[^};])+)/), V = h({ type: "declaration", property: l.replace(rr, ""), value: b ? _(b[0]).replace(rr, "") : "" }); return f(/^[;\s]*/), V; } function X() { const h = []; if (!d()) return a("missing '{'"); v(h); let l; for (; l = $(); ) l !== !1 && (h.push(l), v(h)); return p() ? h : a("missing '}'"); } function On() { let h; const l = [], b = s(); for (; h = f(/^((\d+\.\d+|\.\d+|\d+)%?|[a-z]+)\s*/); ) l.push(h[1]), f(/^,\s*/); if (l.length) return b({ type: "keyframe", values: l, declarations: X() }); } function Rn() { const h = s(); let l = f(/^@([-\w]+)?keyframes\s*/); if (!l) return; const b = l[1]; if (l = f(/^([-\w]+)\s*/), !l) return a("@keyframes missing name"); const V = l[1]; if (!d()) return a("@keyframes missing '{'"); let L, ve = v(); for (; L = On(); ) ve.push(L), ve = ve.concat(v()); return p() ? h({ type: "keyframes", name: V, vendor: b, keyframes: ve }) : a("@keyframes missing '}'"); } function Tn() { const h = s(), l = f(/^@supports *([^{]+)/); if (!l) return; const b = _(l[1]); if (!d()) return a("@supports missing '{'"); const V = v().concat(m()); return p() ? h({ type: "supports", supports: b, rules: V }) : a("@supports missing '}'"); } function An() { const h = s(); if (!f(/^@host\s*/)) return; if (!d()) return a("@host missing '{'"); const b = v().concat(m()); return p() ? h({ type: "host", rules: b }) : a("@host missing '}'"); } function kn() { const h = s(), l = f(/^@media *([^{]+)/); if (!l) return; const b = _(l[1]); if (!d()) return a("@media missing '{'"); const V = v().concat(m()); return p() ? h({ type: "media", media: b, rules: V }) : a("@media missing '}'"); } function Nn() { const h = s(), l = f(/^@custom-media\s+(--[^\s]+)\s*([^{;]+);/); if (l) return h({ type: "custom-media", name: _(l[1]), media: _(l[2]) }); } function In() { const h = s(); if (!f(/^@page */)) return; const b = z() || []; if (!d()) return a("@page missing '{'"); let V = v(), L; for (; L = $(); ) V.push(L), V = V.concat(v()); return p() ? h({ type: "page", selectors: b, declarations: V }) : a("@page missing '}'"); } function jn() {