UNPKG

formguardian-react

Version:

A reusable, customizable Form Validator Widget for React with comprehensive validation, error handling, and micro-animations.

1,102 lines (1,101 loc) 33 kB
import le, { useState as $, useRef as ae, useEffect as z, useCallback as k } from "react"; var C = { exports: {} }, F = {}; /** * @license React * react-jsx-runtime.production.js * * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ var K; function ue() { if (K) return F; K = 1; var e = Symbol.for("react.transitional.element"), s = Symbol.for("react.fragment"); function a(n, i, d) { var b = null; if (d !== void 0 && (b = "" + d), i.key !== void 0 && (b = "" + i.key), "key" in i) { d = {}; for (var y in i) y !== "key" && (d[y] = i[y]); } else d = i; return i = d.ref, { $$typeof: e, type: n, key: b, ref: i !== void 0 ? i : null, props: d }; } return F.Fragment = s, F.jsx = a, F.jsxs = a, F; } var O = {}; /** * @license React * react-jsx-runtime.development.js * * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ var ee; function de() { return ee || (ee = 1, process.env.NODE_ENV !== "production" && (function() { function e(r) { if (r == null) return null; if (typeof r == "function") return r.$$typeof === D ? null : r.displayName || r.name || null; if (typeof r == "string") return r; switch (r) { case p: return "Fragment"; case E: return "Profiler"; case g: return "StrictMode"; case L: return "Suspense"; case I: return "SuspenseList"; case Y: return "Activity"; } if (typeof r == "object") switch (typeof r.tag == "number" && console.error( "Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue." ), r.$$typeof) { case m: return "Portal"; case S: return r.displayName || "Context"; case w: return (r._context.displayName || "Context") + ".Consumer"; case V: var u = r.render; return r = r.displayName, r || (r = u.displayName || u.name || "", r = r !== "" ? "ForwardRef(" + r + ")" : "ForwardRef"), r; case q: return u = r.displayName || null, u !== null ? u : e(r.type) || "Memo"; case A: u = r._payload, r = r._init; try { return e(r(u)); } catch { } } return null; } function s(r) { return "" + r; } function a(r) { try { s(r); var u = !1; } catch { u = !0; } if (u) { u = console; var h = u.error, T = typeof Symbol == "function" && Symbol.toStringTag && r[Symbol.toStringTag] || r.constructor.name || "Object"; return h.call( u, "The provided key is an unsupported type %s. This value must be coerced to a string before using it here.", T ), s(r); } } function n(r) { if (r === p) return "<>"; if (typeof r == "object" && r !== null && r.$$typeof === A) return "<...>"; try { var u = e(r); return u ? "<" + u + ">" : "<...>"; } catch { return "<...>"; } } function i() { var r = _.A; return r === null ? null : r.getOwner(); } function d() { return Error("react-stack-top-frame"); } function b(r) { if (J.call(r, "key")) { var u = Object.getOwnPropertyDescriptor(r, "key").get; if (u && u.isReactWarning) return !1; } return r.key !== void 0; } function y(r, u) { function h() { M || (M = !0, console.error( "%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)", u )); } h.isReactWarning = !0, Object.defineProperty(r, "key", { get: h, configurable: !0 }); } function x() { var r = e(this.type); return G[r] || (G[r] = !0, console.error( "Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release." )), r = this.props.ref, r !== void 0 ? r : null; } function j(r, u, h, T, P, W) { var v = h.ref; return r = { $$typeof: o, type: r, key: u, props: h, _owner: T }, (v !== void 0 ? v : null) !== null ? Object.defineProperty(r, "ref", { enumerable: !1, get: x }) : Object.defineProperty(r, "ref", { enumerable: !1, value: null }), r._store = {}, Object.defineProperty(r._store, "validated", { configurable: !1, enumerable: !1, writable: !0, value: 0 }), Object.defineProperty(r, "_debugInfo", { configurable: !1, enumerable: !1, writable: !0, value: null }), Object.defineProperty(r, "_debugStack", { configurable: !1, enumerable: !1, writable: !0, value: P }), Object.defineProperty(r, "_debugTask", { configurable: !1, enumerable: !1, writable: !0, value: W }), Object.freeze && (Object.freeze(r.props), Object.freeze(r)), r; } function R(r, u, h, T, P, W) { var v = u.children; if (v !== void 0) if (T) if (ie(v)) { for (T = 0; T < v.length; T++) f(v[T]); Object.freeze && Object.freeze(v); } else console.error( "React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead." ); else f(v); if (J.call(u, "key")) { v = e(r); var B = Object.keys(u).filter(function(ce) { return ce !== "key"; }); T = 0 < B.length ? "{key: someKey, " + B.join(": ..., ") + ": ...}" : "{key: someKey}", Q[v + T] || (B = 0 < B.length ? "{" + B.join(": ..., ") + ": ...}" : "{}", console.error( `A props object containing a "key" prop is being spread into JSX: let props = %s; <%s {...props} /> React keys must be passed directly to JSX without using spread: let props = %s; <%s key={someKey} {...props} />`, T, v, B, v ), Q[v + T] = !0); } if (v = null, h !== void 0 && (a(h), v = "" + h), b(u) && (a(u.key), v = "" + u.key), "key" in u) { h = {}; for (var H in u) H !== "key" && (h[H] = u[H]); } else h = u; return v && y( h, typeof r == "function" ? r.displayName || r.name || "Unknown" : r ), j( r, v, h, i(), P, W ); } function f(r) { l(r) ? r._store && (r._store.validated = 1) : typeof r == "object" && r !== null && r.$$typeof === A && (r._payload.status === "fulfilled" ? l(r._payload.value) && r._payload.value._store && (r._payload.value._store.validated = 1) : r._store && (r._store.validated = 1)); } function l(r) { return typeof r == "object" && r !== null && r.$$typeof === o; } var c = le, o = Symbol.for("react.transitional.element"), m = Symbol.for("react.portal"), p = Symbol.for("react.fragment"), g = Symbol.for("react.strict_mode"), E = Symbol.for("react.profiler"), w = Symbol.for("react.consumer"), S = Symbol.for("react.context"), V = Symbol.for("react.forward_ref"), L = Symbol.for("react.suspense"), I = Symbol.for("react.suspense_list"), q = Symbol.for("react.memo"), A = Symbol.for("react.lazy"), Y = Symbol.for("react.activity"), D = Symbol.for("react.client.reference"), _ = c.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE, J = Object.prototype.hasOwnProperty, ie = Array.isArray, U = console.createTask ? console.createTask : function() { return null; }; c = { react_stack_bottom_frame: function(r) { return r(); } }; var M, G = {}, X = c.react_stack_bottom_frame.bind( c, d )(), Z = U(n(d)), Q = {}; O.Fragment = p, O.jsx = function(r, u, h) { var T = 1e4 > _.recentlyCreatedOwnerStacks++; return R( r, u, h, !1, T ? Error("react-stack-top-frame") : X, T ? U(n(r)) : Z ); }, O.jsxs = function(r, u, h) { var T = 1e4 > _.recentlyCreatedOwnerStacks++; return R( r, u, h, !0, T ? Error("react-stack-top-frame") : X, T ? U(n(r)) : Z ); }; })()), O; } var re; function fe() { return re || (re = 1, process.env.NODE_ENV === "production" ? C.exports = ue() : C.exports = de()), C.exports; } var t = fe(); function me(e, s = 300) { let a = null; return (...n) => { a && clearTimeout(a), a = setTimeout(() => { e(...n); }, s); }; } function be(e, s = 1e3) { let a = !1, n = null; const i = (...d) => { e(...d); }; return (...d) => { a ? n = d : (i(...d), a = !0, setTimeout(() => { a = !1, n && (i(...n), n = null); }, s)); }; } const ne = { required: (e) => typeof e == "string" ? e.trim().length > 0 : Array.isArray(e) ? e.length > 0 : e != null && e !== "", email: (e) => typeof e != "string" ? !1 : /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(e), minLength: (e, s) => { if (typeof e != "string") return !1; const a = s?.value ?? s?.minLength ?? 0; return e.length >= a; }, maxLength: (e, s) => { if (typeof e != "string") return !1; const a = s?.value ?? s?.maxLength ?? 1 / 0; return e.length <= a; }, pattern: (e, s) => { if (typeof e != "string") return !1; const a = s?.value; return a ? (typeof a == "string" ? new RegExp(a) : a).test(e) : !0; }, match: (e, s) => { if (typeof e != "string") return !1; const a = s?.value; return a ? (typeof a == "string" ? new RegExp(a) : a).test(e) : !0; }, custom: (e, s) => s?.custom ? s.custom(e) : !0, number: (e) => !isNaN(Number(e)) && e !== "", url: (e) => { if (typeof e != "string") return !1; try { return new URL(e), !0; } catch { return !1; } }, phone: (e) => typeof e != "string" ? !1 : /^\d{10}$/.test(e) }, te = { required: "This field is required", email: "Please enter a valid email address", minLength: "This field must be at least {value} characters", maxLength: "This field must not exceed {value} characters", pattern: "This field format is invalid", match: "This field does not match the required pattern", custom: "This field is invalid", number: "Please enter a valid number", url: "Please enter a valid URL", phone: "Please enter a valid phone number" }; async function se(e, s, a) { let n; if (typeof s == "string" ? n = { type: s } : n = s, n.type === "custom" && n.custom) return { isValid: await n.custom(e, a), message: n.message || te[n.type] }; if (n.type === "match" && n.matchField && a) { const x = a[n.matchField]; return { isValid: e === x, message: n.message || `This field must match ${n.matchField}` }; } if (!((x) => x in ne)(n.type)) return { isValid: !0, message: "" }; const d = ne[n.type]; if (!d) return { isValid: !0, message: "" }; const b = await d(e, n); let y = n.message || te[n.type]; return n.value !== void 0 && (y = y.replace("{value}", String(n.value))), { isValid: b, message: y }; } async function pe(e, s) { const a = {}; return await Promise.all( s.map(async (n) => { if (!(!n.validators || n.validators.length === 0)) for (const i of n.validators) { const { isValid: d, message: b } = await se(e[n.name], i, e); if (!d) { a[n.name] = b; break; } } }) ), a; } function Be(e) { return e == null ? !0 : typeof e == "string" ? e.trim().length === 0 : Array.isArray(e) ? e.length === 0 : typeof e == "object" ? Object.keys(e).length === 0 : !1; } function Ae(e, s) { const a = {}; return Object.entries(e).forEach(([n, i]) => { const d = s.find((b) => b.name === n); if (i === "" && d?.type !== "password") { a[n] = void 0; return; } if (typeof i == "string") { a[n] = i.trim(); return; } a[n] = i; }), a; } function ge(e, s = "onBlur", a = 300) { const [n, i] = $(() => { const l = {}, c = {}; return e.forEach((o) => { l[o.name] = o.defaultValue ?? "", c[o.name] = !1; }), { values: l, errors: {}, touched: c, isValidating: !1, isValid: !0 }; }), d = k( async (l, c) => { const o = e.find((g) => g.name === l); if (!o || !o.validators) return ""; const m = Array.isArray(o.validators) ? o.validators.map((g) => typeof g == "string" ? { type: g } : g) : [{ type: o.validators[0] }], p = { ...n.values, [l]: c }; for (const g of m) { const { isValid: E, message: w } = await se(c, g, p); if (!E) return w; } return ""; }, [e, n.values] ), b = ae(null); z(() => { b.current = me(async (l, c) => { const o = await d(l, c); i((m) => { const p = { ...m.errors, [l]: o }, g = Object.values(p).every((S) => !S), E = { ...m.touched }, w = m.values[l]; return o && (typeof w == "string" && w.trim().length > 0 || typeof w != "string" && w !== void 0 && w !== null) && (E[l] = !0), { ...m, errors: p, touched: E, isValid: g }; }); }, a); }, [d, a]); const y = k( async (l, c) => { i((o) => ({ ...o, values: { ...o.values, [l]: c } })), s === "onChange" && b.current?.(l, c); }, [s] ), x = k(async (l) => { if (i((c) => ({ ...c, touched: { ...c.touched, [l]: !0 } })), s === "onBlur") { const c = n.values[l], o = await d(l, c); i((m) => { const p = { ...m.errors, [l]: o }, g = Object.values(p).every((E) => !E); return { ...m, errors: p, isValid: g }; }); } }, [s, n.values, d]), j = k(async () => { i((m) => ({ ...m, isValidating: !0 })); const l = e.map((m) => ({ name: m.name, validators: m.validators?.map( (p) => typeof p == "string" ? { type: p } : p ) })), c = await pe(n.values, l), o = Object.keys(c).length === 0; return i((m) => ({ ...m, errors: c, isValid: o, isValidating: !1 })), o; }, [e, n.values]), R = k(() => { const l = {}, c = {}; e.forEach((o) => { l[o.name] = o.defaultValue ?? "", c[o.name] = !1; }), i({ values: l, errors: {}, touched: c, isValidating: !1, isValid: !0 }); }, [e]), f = k( (l) => { i((c) => ({ ...c, values: { ...c.values, ...l } })); }, [] ); return { formState: n, setFieldValue: y, setFieldTouched: x, validateFormFields: j, validateSingleField: d, resetForm: R, setFieldValues: f, setFormState: i }; } function he(e, s, a, n = 1e3, i) { const [d, b] = $(!1), [y, x] = $(null), [j, R] = $(!1), f = ae(null); return z(() => { f.current = be(async (c) => { c && c.preventDefault(), b(!0), x(null); try { if (!await s()) { i && i((m) => { const p = {}; return Object.keys(m.values).forEach((g) => { p[g] = !0; }), { ...m, touched: p }; }), x("Please fix the errors in the form"), b(!1); return; } R(!0), setTimeout(() => R(!1), n), await e(a), b(!1); } catch (o) { const m = o instanceof Error ? o.message : "An error occurred during submission"; x(m), b(!1); } }, n); }, [e, s, a, n]), { handleSubmit: k((c) => { f.current?.(c); }, []), isSubmitting: d, isThrottled: j, submitError: y, setSubmitError: x }; } const N = { spacingBase: "1rem", borderRadius: "0.5rem", fontSize: "1rem", fontWeight: "500", fontFamily: '"Inter", "Segoe UI", system-ui, sans-serif', transitionDuration: "0.2s", shadowSm: "0 1px 2px rgba(0, 0, 0, 0.05)", shadowMd: "0 4px 12px rgba(0, 0, 0, 0.08)", shadowLg: "0 8px 24px rgba(0, 0, 0, 0.12)" }, oe = { name: "modern", ...N, primary: "#1e40af", // Deep vibrant blue secondary: "#7c3aed", // Purple accent success: "#10b981", // Emerald green danger: "#f43f5e", // Vibrant red warning: "#f59e0b", // Amber background: "linear-gradient(135deg, #dbeafe 0%, #f0fdf4 100%)", inputBg: "#ffffff", inputBorder: "#60a5fa", inputBorderHover: "#3b82f6", inputBorderFocus: "#1e40af", inputText: "#0f172a", labelText: "#1e40af", errorText: "#dc2626", successText: "#059669" }, xe = { name: "dark", ...N, primary: "#f43f5e", // Vibrant pink secondary: "#06b6d4", // Cyan success: "#34d399", // Emerald danger: "#ff6b6b", // Bright red warning: "#fbbf24", // Gold background: "linear-gradient(135deg, #0f172a 0%, #1e293b 100%)", inputBg: "#1e293b", inputBorder: "#38bdf8", inputBorderHover: "#22d3ee", inputBorderFocus: "#f43f5e", inputText: "#f1f5f9", labelText: "#f43f5e", errorText: "#ff6b6b", successText: "#34d399" }, ye = { name: "minimal", ...N, borderRadius: "0.25rem", primary: "#d946ef", // Magenta secondary: "#ec4899", // Pink success: "#22d3ee", // Cyan danger: "#ef4444", // Red warning: "#fbbf24", // Gold background: "#ffffff", inputBg: "#f9fafb", inputBorder: "#d946ef", inputBorderHover: "#ec4899", inputBorderFocus: "#d946ef", inputText: "#0f172a", labelText: "#d946ef", errorText: "#ef4444", successText: "#22d3ee" }, Te = { name: "gradient", ...N, borderRadius: "0.75rem", primary: "#ec4899", // Hot pink secondary: "#06b6d4", // Cyan success: "#10b981", // Emerald danger: "#ff1744", // Bright red warning: "#ffb300", // Amber background: "linear-gradient(135deg, #fce7f3 0%, #e0e7ff 100%)", inputBg: "#fef2f9", inputBorder: "#f472b6", inputBorderHover: "#ec4899", inputBorderFocus: "#ec4899", inputText: "#831843", labelText: "#ec4899", errorText: "#ff1744", successText: "#10b981" }, ve = { name: "ocean", ...N, borderRadius: "0.5rem", primary: "#0ea5e9", // Sky blue secondary: "#06b6d4", // Cyan success: "#10b981", // Emerald danger: "#f43f5e", // Red warning: "#fbbf24", // Gold background: "linear-gradient(135deg, #cffafe 0%, #e0f2fe 100%)", inputBg: "#ecf9fd", inputBorder: "#38bdf8", inputBorderHover: "#0ea5e9", inputBorderFocus: "#0284c7", inputText: "#065f46", labelText: "#0284c7", errorText: "#f43f5e", successText: "#10b981" }, je = { name: "sunset", ...N, borderRadius: "0.625rem", primary: "#f97316", // Vibrant orange secondary: "#ec4899", // Pink success: "#22c55e", // Green danger: "#f43f5e", // Red warning: "#fbbf24", // Gold background: "linear-gradient(135deg, #fed7aa 0%, #fbcfe8 100%)", inputBg: "#fff7ed", inputBorder: "#fb923c", inputBorderHover: "#f97316", inputBorderFocus: "#f97316", inputText: "#7c2d12", labelText: "#f97316", errorText: "#f43f5e", successText: "#22c55e" }, Ee = { name: "purple", ...N, borderRadius: "0.625rem", primary: "#a78bfa", // Light purple secondary: "#ec4899", // Pink success: "#06b6d4", // Cyan danger: "#ff4757", // Red warning: "#fbbf24", // Gold background: "linear-gradient(135deg, #ede9fe 0%, #f3e8ff 100%)", inputBg: "#faf5ff", inputBorder: "#c4b5fd", inputBorderHover: "#a78bfa", inputBorderFocus: "#7c3aed", inputText: "#581c87", labelText: "#7c3aed", errorText: "#ff4757", successText: "#06b6d4" }, Re = { name: "forest", ...N, borderRadius: "0.5rem", primary: "#059669", // Teal green secondary: "#14b8a6", // Turquoise success: "#10b981", // Green danger: "#f43f5e", // Red warning: "#fbbf24", // Gold background: "linear-gradient(135deg, #d1fae5 0%, #e0f2fe 100%)", inputBg: "#ecfdf5", inputBorder: "#6ee7b7", inputBorderHover: "#2dd4bf", inputBorderFocus: "#059669", inputText: "#065f46", labelText: "#059669", errorText: "#f43f5e", successText: "#10b981" }, we = { modern: oe, dark: xe, minimal: ye, gradient: Te, ocean: ve, sunset: je, purple: Ee, forest: Re }; function _e(e) { return typeof e == "string" ? we[e] || oe : e; } function ke(e) { return { "--form-primary": e.primary, "--form-secondary": e.secondary, "--form-success": e.success, "--form-danger": e.danger, "--form-warning": e.warning, "--form-background": e.background, "--form-input-bg": e.inputBg, "--form-input-border": e.inputBorder, "--form-input-border-hover": e.inputBorderHover, "--form-input-border-focus": e.inputBorderFocus, "--form-input-text": e.inputText, "--form-label-text": e.labelText, "--form-error-text": e.errorText, "--form-success-text": e.successText, "--form-spacing-base": e.spacingBase, "--form-border-radius": e.borderRadius, "--form-font-size": e.fontSize, "--form-font-weight": e.fontWeight, "--form-font-family": e.fontFamily, "--form-transition-duration": e.transitionDuration, "--form-shadow-sm": e.shadowSm, "--form-shadow-md": e.shadowMd, "--form-shadow-lg": e.shadowLg }; } const Se = ({ field: e, value: s, error: a, touched: n, onChange: i, onBlur: d, disabled: b = !1, showAnimation: y = !0 }) => { const x = k( (o) => { const m = o.target.type === "checkbox" ? o.target.checked : o.target.value; i(e.name, m); }, [e.name, i] ), j = k(() => { d(e.name); }, [e.name, d]), R = k(() => { }, []), f = n && a, l = [ "form-group", f && y && "has-error" ].filter(Boolean).join(" "), c = [ "form-input", f && "error", !f && s && "success" ].filter(Boolean).join(" "); switch (e.type) { case "textarea": return /* @__PURE__ */ t.jsxs("div", { className: l, children: [ e.label && /* @__PURE__ */ t.jsxs("label", { className: `form-label ${f ? "error" : ""}`, children: [ e.label, e.required && /* @__PURE__ */ t.jsx("span", { className: "required-indicator", children: "*" }) ] }), /* @__PURE__ */ t.jsx( "textarea", { id: e.name, name: e.name, placeholder: e.placeholder, value: String(s ?? ""), onChange: x, onBlur: j, onFocus: R, disabled: b || e.disabled, rows: e.rows || 4, className: `${c} form-textarea`, "aria-invalid": !!f, "aria-describedby": f ? `${e.name}-error` : void 0 } ), f && /* @__PURE__ */ t.jsxs("div", { id: `${e.name}-error`, className: "form-error", children: [ /* @__PURE__ */ t.jsx("span", { className: "error-icon", children: "⚠" }), /* @__PURE__ */ t.jsx("span", { children: a }) ] }) ] }); case "select": return /* @__PURE__ */ t.jsxs("div", { className: l, children: [ e.label && /* @__PURE__ */ t.jsxs("label", { className: `form-label ${f ? "error" : ""}`, children: [ e.label, e.required && /* @__PURE__ */ t.jsx("span", { className: "required-indicator", children: "*" }) ] }), /* @__PURE__ */ t.jsxs( "select", { id: e.name, name: e.name, value: String(s ?? ""), onChange: x, onBlur: j, onFocus: R, disabled: b || e.disabled, className: `${c} form-select`, "aria-invalid": !!f, "aria-describedby": f ? `${e.name}-error` : void 0, children: [ /* @__PURE__ */ t.jsxs("option", { value: "", children: [ "Select ", e.label || e.name ] }), e.options?.map((o) => /* @__PURE__ */ t.jsx("option", { value: o.value, children: o.label }, o.value)) ] } ), f && /* @__PURE__ */ t.jsxs("div", { id: `${e.name}-error`, className: "form-error", children: [ /* @__PURE__ */ t.jsx("span", { className: "error-icon", children: "⚠" }), /* @__PURE__ */ t.jsx("span", { children: a }) ] }) ] }); case "checkbox": if (e.options && e.options.length > 0) { const o = Array.isArray(s) ? s : []; return /* @__PURE__ */ t.jsxs("div", { className: l, children: [ e.label && /* @__PURE__ */ t.jsxs("label", { className: `form-label ${f ? "error" : ""}`, children: [ e.label, e.required && /* @__PURE__ */ t.jsx("span", { className: "required-indicator", children: "*" }) ] }), /* @__PURE__ */ t.jsx("div", { style: { display: "flex", flexDirection: "column", gap: "0.5rem", marginTop: "0.5rem" }, children: e.options.map((m) => /* @__PURE__ */ t.jsxs("label", { style: { display: "flex", alignItems: "center", cursor: "pointer" }, children: [ /* @__PURE__ */ t.jsx( "input", { type: "checkbox", name: e.name, value: m.value, checked: o.includes(m.value), onChange: (p) => { let g = o.slice(); p.target.checked ? g.push(m.value) : g = g.filter((E) => E !== m.value), i(e.name, g); }, onBlur: j, disabled: b || e.disabled, className: "form-checkbox" } ), /* @__PURE__ */ t.jsx("span", { style: { marginLeft: "0.5rem" }, children: m.label }) ] }, m.value)) }), f && /* @__PURE__ */ t.jsxs("div", { id: `${e.name}-error`, className: "form-error", children: [ /* @__PURE__ */ t.jsx("span", { className: "error-icon", children: "⚠" }), /* @__PURE__ */ t.jsx("span", { children: a }) ] }) ] }); } return /* @__PURE__ */ t.jsxs("div", { className: l, children: [ /* @__PURE__ */ t.jsxs("label", { style: { display: "flex", alignItems: "center", cursor: "pointer" }, children: [ /* @__PURE__ */ t.jsx( "input", { id: e.name, name: e.name, type: "checkbox", checked: !!s, onChange: x, onBlur: j, onFocus: R, disabled: b || e.disabled, className: "form-checkbox", "aria-invalid": !!f } ), /* @__PURE__ */ t.jsx("span", { className: "form-label", style: { margin: 0 }, children: e.label || e.placeholder }) ] }), f && /* @__PURE__ */ t.jsxs("div", { id: `${e.name}-error`, className: "form-error", children: [ /* @__PURE__ */ t.jsx("span", { className: "error-icon", children: "⚠" }), /* @__PURE__ */ t.jsx("span", { children: a }) ] }) ] }); case "radio": return /* @__PURE__ */ t.jsxs("div", { className: l, children: [ e.label && /* @__PURE__ */ t.jsxs("label", { className: "form-label", children: [ e.label, e.required && /* @__PURE__ */ t.jsx("span", { className: "required-indicator", children: "*" }) ] }), /* @__PURE__ */ t.jsx("fieldset", { children: e.options?.map((o) => /* @__PURE__ */ t.jsxs("label", { style: { display: "flex", alignItems: "center", marginBottom: "0.5rem", cursor: "pointer" }, children: [ /* @__PURE__ */ t.jsx( "input", { name: e.name, type: "radio", value: o.value, checked: s === o.value, onChange: x, onBlur: j, disabled: b || e.disabled, className: "form-radio" } ), /* @__PURE__ */ t.jsx("span", { style: { marginLeft: "0.5rem" }, children: o.label }) ] }, o.value)) }), f && /* @__PURE__ */ t.jsxs("div", { id: `${e.name}-error`, className: "form-error", children: [ /* @__PURE__ */ t.jsx("span", { className: "error-icon", children: "⚠" }), /* @__PURE__ */ t.jsx("span", { children: a }) ] }) ] }); default: return /* @__PURE__ */ t.jsxs("div", { className: l, children: [ e.label && /* @__PURE__ */ t.jsxs("label", { className: `form-label ${f ? "error" : ""}`, children: [ e.label, e.required && /* @__PURE__ */ t.jsx("span", { className: "required-indicator", children: "*" }) ] }), /* @__PURE__ */ t.jsx( "input", { id: e.name, name: e.name, type: e.type || "text", placeholder: e.placeholder, value: String(s ?? ""), onChange: x, onBlur: j, onFocus: R, disabled: b || e.disabled, minLength: e.minLength, maxLength: e.maxLength, pattern: typeof e.pattern == "string" ? e.pattern : void 0, className: c, "aria-invalid": !!f, "aria-describedby": f ? `${e.name}-error` : void 0 } ), f && /* @__PURE__ */ t.jsxs("div", { id: `${e.name}-error`, className: "form-error", children: [ /* @__PURE__ */ t.jsx("span", { className: "error-icon", children: "⚠" }), /* @__PURE__ */ t.jsx("span", { children: a }) ] }) ] }); } }, Fe = ({ fields: e, onSubmit: s, validationMode: a = "onBlur", customization: n, submitButtonText: i = "Submit", resetButtonText: d = "Reset", showResetButton: b = !1, disabled: y = !1, className: x, submitThrottleMs: j = 1e3, theme: R = "modern" }) => { const { formState: f, setFieldValue: l, setFieldTouched: c, validateFormFields: o, resetForm: m, setFormState: p } = ge(e, a), { handleSubmit: g, isSubmitting: E, isThrottled: w, submitError: S, setSubmitError: V } = he( s, o, f.values, j, p ); z(() => { !Object.values(f.errors).some(Boolean) && S && V(null); }, [f.errors, S, V]); const L = _e(R), I = ke(L), q = [ "form-container", x, n?.containerClass ].filter(Boolean).join(" "), A = [ "form-button", "primary", n?.buttonClass, E && "loading" ].filter(Boolean).join(" "), Y = [ "form-button", "secondary", n?.buttonClass ].filter(Boolean).join(" "), D = [ n?.formClass ].filter(Boolean).join(" "); return /* @__PURE__ */ t.jsx("div", { style: I, children: /* @__PURE__ */ t.jsx("form", { onSubmit: g, className: D, children: /* @__PURE__ */ t.jsxs("div", { className: q, children: [ e.map((_) => /* @__PURE__ */ t.jsx( Se, { field: _, value: f.values[_.name], error: f.errors[_.name] || "", touched: f.touched[_.name] || !1, onChange: l, onBlur: c, disabled: y || _.disabled, showAnimation: n?.showAnimations !== !1 }, _.name )), S && /* @__PURE__ */ t.jsx("div", { className: "error-boundary", children: /* @__PURE__ */ t.jsxs("span", { children: [ "⚠ ", S ] }) }), /* @__PURE__ */ t.jsxs("div", { style: { display: "flex", gap: "1rem", marginTop: "1rem" }, children: [ /* @__PURE__ */ t.jsx( "button", { type: "submit", disabled: y || E || w, className: A, children: E ? "Submitting..." : i } ), b && /* @__PURE__ */ t.jsx( "button", { type: "button", onClick: m, disabled: y || E, className: Y, children: d } ) ] }) ] }) }) }); }; export { Fe as DynamicForm, Se as FormField, xe as darkTheme, Re as forestTheme, ke as generateThemeVariables, _e as getTheme, Te as gradientTheme, Be as isEmpty, ye as minimalTheme, oe as modernTheme, ve as oceanTheme, Ee as purpleTheme, Ae as sanitizeValues, je as sunsetTheme, we as themes, he as useFormSubmission, ge as useFormValidator, se as validateField, pe as validateForm };