UNPKG

input-states-react

Version:

Reusable UI components for forms and steps

1,071 lines (1,070 loc) 35.9 kB
import le, { forwardRef as X, useState as F, useRef as P, useImperativeHandle as q, useEffect as ce, useLayoutEffect as fe, Fragment as me } from "react"; var Q = { exports: {} }, J = {}; /** * @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 ne; function pe() { if (ne) return J; ne = 1; var n = Symbol.for("react.transitional.element"), s = Symbol.for("react.fragment"); function r(o, d, f) { var b = null; if (f !== void 0 && (b = "" + f), d.key !== void 0 && (b = "" + d.key), "key" in d) { f = {}; for (var N in d) N !== "key" && (f[N] = d[N]); } else f = d; return d = f.ref, { $$typeof: n, type: o, key: b, ref: d !== void 0 ? d : null, props: f }; } return J.Fragment = s, J.jsx = r, J.jsxs = r, J; } var Z = {}; /** * @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 se; function he() { return se || (se = 1, process.env.NODE_ENV !== "production" && function() { function n(e) { if (e == null) return null; if (typeof e == "function") return e.$$typeof === U ? null : e.displayName || e.name || null; if (typeof e == "string") return e; switch (e) { case T: return "Fragment"; case k: return "Profiler"; case g: return "StrictMode"; case Y: return "Suspense"; case G: return "SuspenseList"; case W: return "Activity"; } if (typeof e == "object") switch (typeof e.tag == "number" && console.error( "Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue." ), e.$$typeof) { case h: return "Portal"; case M: return (e.displayName || "Context") + ".Provider"; case _: return (e._context.displayName || "Context") + ".Consumer"; case V: var i = e.render; return e = e.displayName, e || (e = i.displayName || i.name || "", e = e !== "" ? "ForwardRef(" + e + ")" : "ForwardRef"), e; case w: return i = e.displayName || null, i !== null ? i : n(e.type) || "Memo"; case H: i = e._payload, e = e._init; try { return n(e(i)); } catch { } } return null; } function s(e) { return "" + e; } function r(e) { try { s(e); var i = !1; } catch { i = !0; } if (i) { i = console; var p = i.error, j = typeof Symbol == "function" && Symbol.toStringTag && e[Symbol.toStringTag] || e.constructor.name || "Object"; return p.call( i, "The provided key is an unsupported type %s. This value must be coerced to a string before using it here.", j ), s(e); } } function o(e) { if (e === T) return "<>"; if (typeof e == "object" && e !== null && e.$$typeof === H) return "<...>"; try { var i = n(e); return i ? "<" + i + ">" : "<...>"; } catch { return "<...>"; } } function d() { var e = D.A; return e === null ? null : e.getOwner(); } function f() { return Error("react-stack-top-frame"); } function b(e) { if (m.call(e, "key")) { var i = Object.getOwnPropertyDescriptor(e, "key").get; if (i && i.isReactWarning) return !1; } return e.key !== void 0; } function N(e, i) { function p() { v || (v = !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)", i )); } p.isReactWarning = !0, Object.defineProperty(e, "key", { get: p, configurable: !0 }); } function x() { var e = n(this.type); return L[e] || (L[e] = !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." )), e = this.props.ref, e !== void 0 ? e : null; } function R(e, i, p, j, C, S, K, ee) { return p = S.ref, e = { $$typeof: c, type: e, key: i, props: S, _owner: C }, (p !== void 0 ? p : null) !== null ? Object.defineProperty(e, "ref", { enumerable: !1, get: x }) : Object.defineProperty(e, "ref", { enumerable: !1, value: null }), e._store = {}, Object.defineProperty(e._store, "validated", { configurable: !1, enumerable: !1, writable: !0, value: 0 }), Object.defineProperty(e, "_debugInfo", { configurable: !1, enumerable: !1, writable: !0, value: null }), Object.defineProperty(e, "_debugStack", { configurable: !1, enumerable: !1, writable: !0, value: K }), Object.defineProperty(e, "_debugTask", { configurable: !1, enumerable: !1, writable: !0, value: ee }), Object.freeze && (Object.freeze(e.props), Object.freeze(e)), e; } function a(e, i, p, j, C, S, K, ee) { var y = i.children; if (y !== void 0) if (j) if (E(y)) { for (j = 0; j < y.length; j++) l(y[j]); Object.freeze && Object.freeze(y); } 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 l(y); if (m.call(i, "key")) { y = n(e); var z = Object.keys(i).filter(function(de) { return de !== "key"; }); j = 0 < z.length ? "{key: someKey, " + z.join(": ..., ") + ": ...}" : "{key: someKey}", I[y + j] || (z = 0 < z.length ? "{" + z.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} />`, j, y, z, y ), I[y + j] = !0); } if (y = null, p !== void 0 && (r(p), y = "" + p), b(i) && (r(i.key), y = "" + i.key), "key" in i) { p = {}; for (var te in i) te !== "key" && (p[te] = i[te]); } else p = i; return y && N( p, typeof e == "function" ? e.displayName || e.name || "Unknown" : e ), R( e, y, S, C, d(), p, K, ee ); } function l(e) { typeof e == "object" && e !== null && e.$$typeof === c && e._store && (e._store.validated = 1); } var u = le, c = Symbol.for("react.transitional.element"), h = Symbol.for("react.portal"), T = Symbol.for("react.fragment"), g = Symbol.for("react.strict_mode"), k = Symbol.for("react.profiler"), _ = Symbol.for("react.consumer"), M = Symbol.for("react.context"), V = Symbol.for("react.forward_ref"), Y = Symbol.for("react.suspense"), G = Symbol.for("react.suspense_list"), w = Symbol.for("react.memo"), H = Symbol.for("react.lazy"), W = Symbol.for("react.activity"), U = Symbol.for("react.client.reference"), D = u.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE, m = Object.prototype.hasOwnProperty, E = Array.isArray, O = console.createTask ? console.createTask : function() { return null; }; u = { "react-stack-bottom-frame": function(e) { return e(); } }; var v, L = {}, $ = u["react-stack-bottom-frame"].bind( u, f )(), A = O(o(f)), I = {}; Z.Fragment = T, Z.jsx = function(e, i, p, j, C) { var S = 1e4 > D.recentlyCreatedOwnerStacks++; return a( e, i, p, !1, j, C, S ? Error("react-stack-top-frame") : $, S ? O(o(e)) : A ); }, Z.jsxs = function(e, i, p, j, C) { var S = 1e4 > D.recentlyCreatedOwnerStacks++; return a( e, i, p, !0, j, C, S ? Error("react-stack-top-frame") : $, S ? O(o(e)) : A ); }; }()), Z; } var oe; function ge() { return oe || (oe = 1, process.env.NODE_ENV === "production" ? Q.exports = pe() : Q.exports = he()), Q.exports; } var t = ge(); const ue = (n) => /* @__PURE__ */ t.jsxs( "svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg", ...n, children: [ /* @__PURE__ */ t.jsx( "path", { d: "M12 22C17.5228 22 22 17.5228 22 12C22 6.47715 17.5228 2 12 2C6.47715 2 2 6.47715 2 12C2 17.5228 6.47715 22 12 22Z", stroke: "#FF0000", strokeWidth: "2", strokeMiterlimit: "10" } ), /* @__PURE__ */ t.jsx( "path", { d: "M12 17V11", stroke: "#FF0000", strokeWidth: "2", strokeMiterlimit: "10" } ), /* @__PURE__ */ t.jsx( "path", { d: "M11.9998 7.5C12.4415 7.5 12.7995 7.85807 12.7996 8.2998C12.7996 8.74163 12.4416 9.09961 11.9998 9.09961C11.558 9.0995 11.2 8.74157 11.2 8.2998C11.2001 7.85813 11.5581 7.50011 11.9998 7.5Z", fill: "#FF0000", stroke: "#FF0000", strokeMiterlimit: "10" } ) ] } ), re = (n) => /* @__PURE__ */ t.jsx( "svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg", ...n, children: /* @__PURE__ */ t.jsx( "path", { d: "M2 12.6924L8.245 19L22 5", stroke: "#2DCD73", strokeWidth: "2", strokeMiterlimit: "10" } ) } ), xe = X( ({ height: n = 200, checked: s, onChange: r, children: o, errorMessage: d = "กรุณากรอกข้อมูลให้ถูกต้อง", requireFullScroll: f = !0, scrollThreshold: b = 0.95 }, N) => { const [x, R] = F(!1), [a, l] = F(!1), [u, c] = F(!1), [h, T] = F(0), g = P(null), k = P(null); q(N, () => ({ validate: () => (R(!0), s === !0), focus: () => { k.current && k.current.scrollIntoView({ behavior: "smooth", block: "center" }), setTimeout(() => { g.current && g.current.focus(); }, 300); } })); const _ = P(null), [M, V] = F(!1); ce(() => { const w = _.current, H = () => { w.scrollTop + w.clientHeight >= w.scrollHeight - 1 && (V(!0), l(!1), c(!0)); }; if (w.scrollHeight <= w.clientHeight && V(!0), w) return w.scrollHeight <= w.clientHeight && (V(!0), c(!0)), w.addEventListener("scroll", H), () => w.removeEventListener("scroll", H); }, []); const Y = () => { M || l(!0); }, G = (w) => { const H = w.target, W = H.scrollTop, U = H.scrollHeight, D = H.clientHeight, m = W / (U - D); T(Math.min(m, 1)), m >= b && c(!0); }; return /* @__PURE__ */ t.jsxs("div", { className: "input-group consent-scroll-box", ref: k, children: [ /* @__PURE__ */ t.jsxs("label", { className: "consent-container", onClick: Y, children: [ /* @__PURE__ */ t.jsx( "input", { ref: g, type: "checkbox", checked: s, disabled: !M, onChange: (w) => { M && (r(w.target.checked), l(!1)), R(!0); } } ), /* @__PURE__ */ t.jsx("span", { className: "custom-checkbox", children: s ? /* @__PURE__ */ t.jsxs("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", children: [ /* @__PURE__ */ t.jsx( "rect", { x: "2", y: "2", width: "20", height: "20", rx: "4", stroke: "#007BFF", strokeWidth: "2" } ), /* @__PURE__ */ t.jsx("path", { d: "M7 12L10 15L17 8", stroke: "#007BFF", strokeWidth: "2" }) ] }) : /* @__PURE__ */ t.jsx("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", children: /* @__PURE__ */ t.jsx( "rect", { x: "2", y: "2", width: "20", height: "20", rx: "4", stroke: "#ccc", strokeWidth: "2" } ) }) }), /* @__PURE__ */ t.jsxs("div", { className: "scroll-container", style: { position: "relative", width: "100%" }, children: [ /* @__PURE__ */ t.jsx( "div", { ref: _, className: `scroll-content ${a ? "error" : ""}`, style: { height: n, border: `1px solid ${a ? "var(--font-color-error-pws)" : "#ddd"}` }, onScroll: G, tabIndex: 0, children: /* @__PURE__ */ t.jsx("div", { dangerouslySetInnerHTML: { __html: o } }) } ), f && /* @__PURE__ */ t.jsx( "div", { style: { position: "absolute", bottom: "8px", right: "8px", backgroundColor: u ? "" : "#007bff", color: "white", padding: "4px 8px", borderRadius: "12px", fontSize: "12px", fontWeight: "bold" }, children: u ? /* @__PURE__ */ t.jsx(re, {}) : `${Math.round(h * 100)}%` } ) ] }) ] }), a ? /* @__PURE__ */ t.jsx("div", { className: "text-error-message", children: "※ กรุณาเลื่อนอ่านข้อมูลให้ครบก่อนติ๊กยินยอม" }) : x && !s ? /* @__PURE__ */ t.jsx("div", { className: "text-error-message", children: d || "※ กรุณายินยอมก่อนดำเนินการต่อ" }) : null ] }); } ), ve = X( ({ head: n, label: s, value: r, onChange: o, errorMessage: d, required: f }, b) => { const [N, x] = F(!1), a = ((h) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(h))(r), u = N && (f || r !== "") && !a, c = P(null); return q(b, () => ({ validate: () => (x(!0), a), focus: () => { c.current && (c.current.focus(), setTimeout(() => { const h = c.current.getBoundingClientRect(); window.scrollTo({ top: window.scrollY + h.top - 80 - 24, behavior: "smooth" }); }, 10)); } })), /* @__PURE__ */ t.jsxs( "div", { className: `input-group ${u ? "error" : ""} ${!u && N && a ? "valid" : ""}`, children: [ n && /* @__PURE__ */ t.jsx("div", { className: "group-label", children: n }), /* @__PURE__ */ t.jsxs("div", { className: "input-inner", children: [ /* @__PURE__ */ t.jsx( "input", { ref: c, type: "email", className: "form-input", placeholder: " ", value: r, onChange: (h) => { o(h.target.value), x(!0); }, onBlur: () => x(!0) } ), /* @__PURE__ */ t.jsxs("label", { className: "input-label", children: [ s, f && " " ] }), /* @__PURE__ */ t.jsx("span", { className: "validation-icon valid-icon", children: /* @__PURE__ */ t.jsx(re, {}) }), /* @__PURE__ */ t.jsx("span", { className: "validation-icon error-icon", children: /* @__PURE__ */ t.jsx(ue, {}) }), u && /* @__PURE__ */ t.jsx("div", { className: "text-error-message", children: d }) ] }) ] } ); } ); function be({ html: n, children: s, className: r = "", style: o = {} }) { return n ? /* @__PURE__ */ t.jsx( "div", { className: `text-default label-standard ${r}`, style: o, dangerouslySetInnerHTML: { __html: n } } ) : /* @__PURE__ */ t.jsx("div", { className: `text-default label-standard ${r}`, style: o, children: s }); } const ie = (n, s = 0) => { const r = (n ?? "").toString().replace(/,/g, ""); if (r === "") return ""; if (r.endsWith(".") && s > 0) { const d = r.slice(0, -1); if (d === "" && r === ".") return "0."; const f = parseFloat(d); return isNaN(f) ? r : f.toLocaleString(void 0, { minimumFractionDigits: 0, // Format integer part only maximumFractionDigits: 0 }) + "."; } const o = parseFloat(r); return isNaN(o) ? r : o.toLocaleString(void 0, { minimumFractionDigits: s, maximumFractionDigits: s }); }, B = (n, s) => { let r = "", o = !1; typeof n != "string" && (n = (n ?? "").toString()); for (let d = 0; d < n.length; d++) { const f = n[d]; /\d/.test(f) ? r += f : f === "." && !o && s > 0 ? (r += ".", o = !0) : f === "-" && d === 0 && r === "" && (r += "-"); } return r === "." && s > 0 ? "0." : r === "-." && s > 0 ? "-0." : r.startsWith(".") && s > 0 && r.length > 1 ? "0" + r : r.startsWith("-.") && s > 0 && r.length > 2 ? "-0" + r.substring(1) : r; }, Ee = X( ({ head: n = "หัวข้อ", label: s = "Label", suggest: r = "", value: o, // Expects a raw number or numeric string (unformatted) onChange: d, min: f = -1 / 0, max: b = 1 / 0, errorMessage: N = "กรุณากรอกข้อมูลให้ถูกต้อง", required: x = !1, maxDigit: R = null, // Max digits for the integer part decimalPlaces: a = 0 }, l) => { const [u, c] = F(""), [h, T] = F(!1), [g, k] = F(!1), _ = P(null), M = P({ value: "", cursor: 0 }); ce(() => { const m = o == null ? "" : o.toString(), E = B(m, a); if (!g) c(ie(E, a)); else { const O = B(u, a); E !== O && (c(E), _.current && (M.current = { value: E, cursor: E.length })); } }, [o, g, a]); const V = parseFloat( B(u, a) ), Y = B(u, a), G = !x && Y === "" || Y === "-" && !x || // Allow just "-" if not required !isNaN(V) && V >= f && V <= b; q(l, () => ({ validate: () => { T(!0); const m = B(u, a); if (!x && m === "" || m === "-" && !x) return !0; const E = parseFloat(m); return !isNaN(E) && E >= f && E <= b; }, focus: () => { _.current && (_.current.focus(), setTimeout(() => { const m = _.current.getBoundingClientRect(); window.scrollTo({ top: window.scrollY + m.top - 100 - 24, behavior: "smooth" }); }, 10)); } })); const w = h && !G && !!N, H = () => { k(!0); const m = B(u, a); c(m), _.current && (M.current = { value: m, cursor: m.length }); }, W = (m) => { const E = m.target.value, O = m.target.selectionStart; M.current = { value: E, cursor: O }; let v = "", L = !1, $ = !1; for (let C = 0; C < E.length; C++) { const S = E[C]; /\d/.test(S) ? v += S : S === "." && !L && a > 0 ? (v += S, L = !0) : S === "-" && C === 0 && !$ && (v += S, $ = !0); } v === "." && a > 0 && (v = "0."), v === "-." && a > 0 && (v = "-0."); let A = "", I = v; v.startsWith("-") && (A = "-", I = v.substring(1)); let [e, i] = I.split("."); e = e || "", R && e.length > R && (e = e.slice(0, R)), i !== void 0 ? (a != null && i.length > a && (i = i.slice(0, a)), I = e + "." + i) : I = e, v = A + I; let p = e; if (e) { const C = parseFloat(e); (!isNaN(C) || e.match(/^0+$/)) && (p = C.toLocaleString(void 0, { minimumFractionDigits: 0, maximumFractionDigits: 0 })); } let j = A + p; i !== void 0 ? j += "." + i : I.endsWith(".") && a > 0 && I.length > 0 && e.length >= 0 && (j === A && I === "." ? j = A + "0." : j.endsWith(".") || (j += ".")), v === "0." && a > 0 && (j = "0."), v === "-0." && a > 0 && (j = "-0."), c(j), d(v), h || T(!0); }; fe(() => { if (g && _.current) { const m = _.current, { value: E, cursor: O } = M.current, v = u; if (E === v && m.value === v && m.selectionStart === O) return; let L = 0; for (let e = 0; e < O; e++) E[e] !== "," && L++; let $ = 0, A = 0; for (let e = 0; e < v.length && (v[e] !== "," && A++, $++, !(A >= L)); e++) ; if (A < L && A === 0 && v.length > 0) $ = 0, v.startsWith("-") && ($ = 1); else if (A < L) { let e = 0, i = 0; for (let p = 0; p < v.length && (v[p] !== "," && i++, e++, !(i >= A)); p++) ; $ = e; } const I = Math.max( 0, Math.min($, m.value.length) ); m.value === v && m.setSelectionRange(I, I); } }, [u, g]); const U = () => { k(!1), T(!0); const m = B(u, a); let E = m; if (m === "" || m === "-") c(m === "-" ? "-" : ""), E = m === "-" ? "-" : ""; else { const O = parseFloat(m); isNaN(O) ? (c(m), E = m) : (E = O.toFixed(a), c(ie(E, a))); } d(E); }, D = u; return /* @__PURE__ */ t.jsxs( "div", { className: `input-group numeric-input-wrapper ${w ? "error" : ""}`, children: [ n && /* @__PURE__ */ t.jsx("div", { className: "group-label", children: n }), /* @__PURE__ */ t.jsxs("div", { className: "numeric-input-inner", children: [ /* @__PURE__ */ t.jsx("span", { className: "left-label", children: s }), /* @__PURE__ */ t.jsx( "input", { ref: _, type: "text", value: D, onChange: W, onFocus: H, onBlur: U, className: `numeric-input ${w ? "input-error" : ""}`, placeholder: r, inputMode: "decimal", onKeyDown: (m) => { m.key; } } ) ] }), w && /* @__PURE__ */ t.jsx("div", { className: "text-error-message", children: N }) ] } ); } ), je = X( ({ head: n, name: s, options: r, value: o, onChange: d, errorMessage: f = "กรุณากรอกข้อมูลให้ถูกต้อง", direction: b = "horizontal" // ✅ เพิ่มตรงนี้ vertical }, N) => { const [x, R] = F(!1), [a, l] = F(null), u = P(null), c = P(null); q(N, () => ({ validate: () => (R(!0), !!o), focus: () => { u.current && u.current.scrollIntoView({ behavior: "smooth", block: "center" }), setTimeout(() => { c.current && c.current.focus(); }, 300); } })); const h = x && !o, T = b === "vertical" ? "radio-options-row-Vertical" : "radio-options-row-Horizontal"; return /* @__PURE__ */ t.jsxs("div", { ref: u, className: "input-group radio-group-horizontal", children: [ n && /* @__PURE__ */ t.jsx("div", { className: "group-label", children: n }), /* @__PURE__ */ t.jsx("div", { className: T, children: r.map((g, k) => { const _ = o === g.value, M = a === g.value; return /* @__PURE__ */ t.jsxs( "label", { className: "radio-option", onMouseEnter: () => l(g.value), onMouseLeave: () => l(null), children: [ /* @__PURE__ */ t.jsx( "input", { ref: k === 0 ? c : null, type: "radio", name: s, value: g.value, checked: _, onChange: d } ), /* @__PURE__ */ t.jsx("span", { className: "custom-radio-customForm", children: _ ? /* @__PURE__ */ t.jsxs("svg", { width: "25", height: "25", viewBox: "0 0 24 24", fill: "none", children: [ /* @__PURE__ */ t.jsx( "circle", { cx: "12", cy: "12", r: "10", stroke: "#0064FF", strokeWidth: "2" } ), /* @__PURE__ */ t.jsx( "path", { d: "M7 12L10 15L16 8", stroke: "#0064FF", strokeWidth: "2" } ) ] }) : M ? /* @__PURE__ */ t.jsx("svg", { width: "25", height: "25", viewBox: "0 0 24 24", fill: "none", children: /* @__PURE__ */ t.jsx( "circle", { cx: "12", cy: "12", r: "10", stroke: "#0064FF", strokeWidth: "2" } ) }) : /* @__PURE__ */ t.jsx("svg", { width: "25", height: "25", viewBox: "0 0 24 24", fill: "none", children: /* @__PURE__ */ t.jsx( "circle", { cx: "12", cy: "12", r: "10", stroke: "#ccc", strokeWidth: "2" } ) }) }), /* @__PURE__ */ t.jsx("span", { className: "radio-text", children: g.label }) ] }, g.value ); }) }), h && /* @__PURE__ */ t.jsx("div", { className: "text-error-message", children: f || "กรุณาเลือกเพศ" }) ] }); } ), Ne = X( ({ head: n, label: s, value: r, onChange: o, errorMessage: d = "กรุณากรอกข้อมูลให้ถูกต้อง", required: f }, b) => { const [N, x] = F(!1), R = P(null), a = /^[a-zA-Z\u0E00-\u0E7F\s]+$/, u = ((g) => { const k = g || ""; return !f || k.trim() !== "" && a.test(k); })(r), h = N && (f || r !== "") && !u, T = (g) => { let k = g.target.value; k = k.replace(/[^a-zA-Z\u0E00-\u0E7F\s]/g, ""), o(k), x(!0); }; return q(b, () => ({ validate: () => (x(!0), u), focus: () => { R.current && (R.current.focus(), setTimeout(() => { const g = R.current.getBoundingClientRect(); window.scrollTo({ top: window.scrollY + g.top - 80 - 24, behavior: "smooth" }); }, 10)); } })), /* @__PURE__ */ t.jsxs( "div", { className: `input-group ${h ? "error" : ""} ${!h && N && u ? "valid" : ""}`, children: [ n && /* @__PURE__ */ t.jsx("div", { className: "group-label", children: n }), /* @__PURE__ */ t.jsxs("div", { className: "input-inner", children: [ /* @__PURE__ */ t.jsx( "input", { ref: R, type: "text", className: "form-input", placeholder: " ", value: r || "", onChange: T, onBlur: () => x(!0) } ), /* @__PURE__ */ t.jsxs("label", { className: "input-label", children: [ s, f && " " ] }), /* @__PURE__ */ t.jsx("span", { className: "validation-icon valid-icon", children: /* @__PURE__ */ t.jsx(re, {}) }), /* @__PURE__ */ t.jsx("span", { className: "validation-icon error-icon", children: /* @__PURE__ */ t.jsx(ue, {}) }), h && /* @__PURE__ */ t.jsx("div", { className: "text-error-message", children: d }) ] }) ] } ); } ), Re = ({ children: n, type: s = "button", className: r = "", ...o }) => /* @__PURE__ */ t.jsx( "button", { type: s, className: `btn-primary ${r}`, ...o, children: n } ), Se = ({ steps: n, initialStep: s = 1 }) => { const [r, o] = F(s), [d, f] = F({}), b = (a) => { console.log( `Stepper: Step ${r} completed. Data:`, a ), f((l) => ({ ...l, [r - 1]: a })), r < n.length ? o((l) => l + 1) : console.log("Stepper: All steps completed!"); }, N = (a) => { a < r && o(a); }, x = n[r - 1]; let R; return x && (R = le.cloneElement(x.component, { onStepComplete: b, stepsData: d // ✅ ส่งเข้าไปให้ step })), /* @__PURE__ */ t.jsxs("div", { className: "stepper-container", children: [ /* @__PURE__ */ t.jsx("div", { className: "stepper-row", children: n.map((a, l) => { const u = l + 1, c = u < r, h = u === r, T = c; let g = "stepper-item__indicator"; c ? g += " stepper-item__indicator--completed" : h ? g += " stepper-item__indicator--active" : g += " stepper-item__indicator--upcoming", T && (g += " stepper-item__indicator--clickable"); let k = "stepper-item__label"; c || h ? k += " stepper-item__label--highlighted" : k += " stepper-item__label--dimmed"; let _ = "stepper-line"; return c && (_ += " stepper-line--completed"), /* @__PURE__ */ t.jsxs(me, { children: [ /* @__PURE__ */ t.jsxs("div", { className: "stepper-item", children: [ /* @__PURE__ */ t.jsx( "div", { className: g, onClick: () => T ? N(u) : null, children: c ? ( // ไอคอนเครื่องหมายถูกสำหรับขั้นตอนที่เสร็จสมบูรณ์ /* @__PURE__ */ t.jsx( "svg", { className: "stepper-item__icon", viewBox: "0 0 20 20", fill: "currentColor", children: /* @__PURE__ */ t.jsx( "path", { fillRule: "evenodd", d: "M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z", clipRule: "evenodd" } ) } ) ) : ( // หมายเลขขั้นตอนสำหรับขั้นตอนที่กำลังใช้งานอยู่หรือกำลังจะมาถึง /* @__PURE__ */ t.jsx("span", { className: "stepper-item__number", children: u }) ) } ), /* @__PURE__ */ t.jsx("p", { className: k, children: a.name }) ] }), u < n.length && /* @__PURE__ */ t.jsx("div", { className: _ }) ] }, a.name + l); }) }), /* @__PURE__ */ t.jsx("div", { className: "stepper-content", children: R }) ] }); }; function Ce(n) { const s = {}; return n.forEach((r) => { var o; (!r.type || r.type === "input") && r.name && (r.name === "consent" ? s[r.name] = !1 : s[r.name] = ((o = r.props) == null ? void 0 : o.defaultValue) ?? ""); }), s; } const ke = { RadioGroup: je, NumericTextInput: Ee, EmailInput: ve, ConsentCheckbox: xe, TextInput: Ne, StandardLabel: be }; function ye(n) { return (n || []).map((s) => { const r = typeof s.component == "string" ? s.component.trim() : s.component; return { ...s, component: typeof r == "string" ? ke[r] : r }; }); } function we() { const [n, s] = F({}); return { errors: n, setErrors: s, clearFieldError: (o) => { s((d) => { const { [o]: f, ...b } = d; return b; }); } }; } const ae = (n, s, r) => (o) => { var f; const d = ((f = o == null ? void 0 : o.target) == null ? void 0 : f.value) ?? o; s((b) => ({ ...b, [n]: d })), r((b) => { const { [n]: N, ...x } = b; return x; }); }; function Te(n, s) { const r = {}; return Object.keys(n).forEach((o) => { var d; (d = n[o].current) != null && d.validate() || (r[o] = s[o]); }), r; } const Fe = ({ onFormSubmitAndValidated: n, // Callback เมื่อฟอร์มผ่าน validation และ submit สำเร็จ fields: s, // Array ของ config field ทั้งหมด formData: r, // State object ของข้อมูลในฟอร์มแต่ละช่อง setFormData: o, // Setter สำหรับเปลี่ยนค่า formData buttonLabel: d }) => { const { errors: f, setErrors: b } = we(), [N, x] = F(!1), R = Object.fromEntries( s.filter((l) => l.type !== "label" && l.name).map((l) => [l.name, P()]) ), a = async (l) => { l.preventDefault(), x(!0); const u = Te( R, Object.fromEntries( s.filter((c) => !c.type || c.type !== "label").map((c) => [c.name, c.errorMessage]) ) ); if (b(u), Object.keys(u).length > 0) { const c = Object.keys(u)[0], h = R[c]; h && h.current && typeof h.current.focus == "function" && h.current.focus(), x(!1); return; } try { await new Promise((c) => setTimeout(c, 3e3)), n && n(r); } catch (c) { console.error(c), alert("เกิดข้อผิดพลาด กรุณาลองใหม่อีกครั้ง"); } x(!1); }; return /* @__PURE__ */ t.jsxs("form", { onSubmit: a, children: [ s.map((l, u) => { if (!l.component) return null; if (l.type === "custom") { const T = l.component; return /* @__PURE__ */ t.jsx(T, { ...l.props }, u); } const c = l.component, h = R[l.name]; return l.name === "consent" ? /* @__PURE__ */ t.jsx( c, { ref: h, ...l.props, checked: !!r[l.name], onChange: ae( l.name, o, () => { }, l.errorMessage ), errorMessage: l.errorMessage }, u ) : /* @__PURE__ */ t.jsx( c, { ref: h, ...l.props, value: r[l.name], onChange: ae( l.name, o, () => { }, l.errorMessage ), errorMessage: l.errorMessage }, u ); }), /* @__PURE__ */ t.jsx("div", { className: "submit-container", children: /* @__PURE__ */ t.jsx( Re, { type: "submit", className: "btn-primary", disabled: N, children: d } ) }) ] }); }; function Ae(n) { const s = parseInt((n || "").toString().replace(/[^\d]/g, ""), 10); return isNaN(s) ? "-" : s.toLocaleString(); } export { Fe as BaseForm, Re as ButtonPrimary, xe as ConsentCheckbox, ve as EmailInput, be as Label, Ee as NumericTextInput, je as RadioGroup, Se as Stepper, Ne as TextInput, Ae as formatNumber, Ce as getInitialFormData, ye as mapFieldComponents, ae as updateFieldState, we as useFormErrors, Te as validateFields };