UNPKG

input-states-react

Version:

Reusable UI components for forms and steps

1,111 lines (1,110 loc) 37.1 kB
import le, { forwardRef as Z, useState as F, useRef as P, useImperativeHandle as q, useEffect as ne, useLayoutEffect as be, Fragment as Ee, createRef as je } 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 se; function Ne() { if (se) return J; se = 1; var n = Symbol.for("react.transitional.element"), s = Symbol.for("react.fragment"); function r(a, i, u) { var x = null; if (u !== void 0 && (x = "" + u), i.key !== void 0 && (x = "" + i.key), "key" in i) { u = {}; for (var R in i) R !== "key" && (u[R] = i[R]); } else u = i; return i = u.ref, { $$typeof: n, type: a, key: x, ref: i !== void 0 ? i : null, props: u }; } return J.Fragment = s, J.jsx = r, J.jsxs = r, J; } var X = {}; /** * @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 oe; function Re() { return oe || (oe = 1, process.env.NODE_ENV !== "production" && function() { function n(e) { if (e == null) return null; if (typeof e == "function") return e.$$typeof === W ? null : e.displayName || e.name || null; if (typeof e == "string") return e; switch (e) { case d: return "Fragment"; case k: return "Profiler"; case f: return "StrictMode"; case V: return "Suspense"; case U: return "SuspenseList"; case M: 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 y: return (e.displayName || "Context") + ".Provider"; case S: return (e._context.displayName || "Context") + ".Consumer"; case D: var l = e.render; return e = e.displayName, e || (e = l.displayName || l.name || "", e = e !== "" ? "ForwardRef(" + e + ")" : "ForwardRef"), e; case B: return l = e.displayName || null, l !== null ? l : n(e.type) || "Memo"; case T: l = e._payload, e = e._init; try { return n(e(l)); } catch { } } return null; } function s(e) { return "" + e; } function r(e) { try { s(e); var l = !1; } catch { l = !0; } if (l) { l = console; var p = l.error, _ = typeof Symbol == "function" && Symbol.toStringTag && e[Symbol.toStringTag] || e.constructor.name || "Object"; return p.call( l, "The provided key is an unsupported type %s. This value must be coerced to a string before using it here.", _ ), s(e); } } function a(e) { if (e === d) return "<>"; if (typeof e == "object" && e !== null && e.$$typeof === T) return "<...>"; try { var l = n(e); return l ? "<" + l + ">" : "<...>"; } catch { return "<...>"; } } function i() { var e = Y.A; return e === null ? null : e.getOwner(); } function u() { return Error("react-stack-top-frame"); } function x(e) { if (g.call(e, "key")) { var l = Object.getOwnPropertyDescriptor(e, "key").get; if (l && l.isReactWarning) return !1; } return e.key !== void 0; } function R(e, l) { function p() { j || (j = !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)", l )); } p.isReactWarning = !0, Object.defineProperty(e, "key", { get: p, configurable: !0 }); } function N() { var e = n(this.type); return $[e] || ($[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 v(e, l, p, _, H, L, ee, re) { return p = L.ref, e = { $$typeof: o, type: e, key: l, props: L, _owner: H }, (p !== void 0 ? p : null) !== null ? Object.defineProperty(e, "ref", { enumerable: !1, get: N }) : 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: ee }), Object.defineProperty(e, "_debugTask", { configurable: !1, enumerable: !1, writable: !0, value: re }), Object.freeze && (Object.freeze(e.props), Object.freeze(e)), e; } function c(e, l, p, _, H, L, ee, re) { var A = l.children; if (A !== void 0) if (_) if (b(A)) { for (_ = 0; _ < A.length; _++) E(A[_]); Object.freeze && Object.freeze(A); } 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 E(A); if (g.call(l, "key")) { A = n(e); var G = Object.keys(l).filter(function(ve) { return ve !== "key"; }); _ = 0 < G.length ? "{key: someKey, " + G.join(": ..., ") + ": ...}" : "{key: someKey}", C[A + _] || (G = 0 < G.length ? "{" + G.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} />`, _, A, G, A ), C[A + _] = !0); } if (A = null, p !== void 0 && (r(p), A = "" + p), x(l) && (r(l.key), A = "" + l.key), "key" in l) { p = {}; for (var te in l) te !== "key" && (p[te] = l[te]); } else p = l; return A && R( p, typeof e == "function" ? e.displayName || e.name || "Unknown" : e ), v( e, A, L, H, i(), p, ee, re ); } function E(e) { typeof e == "object" && e !== null && e.$$typeof === o && e._store && (e._store.validated = 1); } var m = le, o = Symbol.for("react.transitional.element"), h = Symbol.for("react.portal"), d = Symbol.for("react.fragment"), f = Symbol.for("react.strict_mode"), k = Symbol.for("react.profiler"), S = Symbol.for("react.consumer"), y = Symbol.for("react.context"), D = Symbol.for("react.forward_ref"), V = Symbol.for("react.suspense"), U = Symbol.for("react.suspense_list"), B = Symbol.for("react.memo"), T = Symbol.for("react.lazy"), M = Symbol.for("react.activity"), W = Symbol.for("react.client.reference"), Y = m.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE, g = Object.prototype.hasOwnProperty, b = Array.isArray, I = console.createTask ? console.createTask : function() { return null; }; m = { "react-stack-bottom-frame": function(e) { return e(); } }; var j, $ = {}, O = m["react-stack-bottom-frame"].bind( m, u )(), w = I(a(u)), C = {}; X.Fragment = d, X.jsx = function(e, l, p, _, H) { var L = 1e4 > Y.recentlyCreatedOwnerStacks++; return c( e, l, p, !1, _, H, L ? Error("react-stack-top-frame") : O, L ? I(a(e)) : w ); }, X.jsxs = function(e, l, p, _, H) { var L = 1e4 > Y.recentlyCreatedOwnerStacks++; return c( e, l, p, !0, _, H, L ? Error("react-stack-top-frame") : O, L ? I(a(e)) : w ); }; }()), X; } var ae; function Se() { return ae || (ae = 1, process.env.NODE_ENV === "production" ? Q.exports = Ne() : Q.exports = Re()), Q.exports; } var t = Se(); const ue = (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" } ) } ), de = Z( ({ height: n = 200, checked: s, onChange: r, children: a, errorMessage: i = "", errorConsentNotScrolled: u = "", requireFullScroll: x = !0, scrollThreshold: R = 0.95 }, N) => { const [v, c] = F(!1), [E, m] = F(!1), [o, h] = F(!1), [d, f] = F(0), k = P(null), S = P(null); q(N, () => ({ validate: () => (c(!0), s === !0), focus: () => { S.current && S.current.scrollIntoView({ behavior: "smooth", block: "center" }), setTimeout(() => { k.current && k.current.focus(); }, 300); } })); const y = P(null), [D, V] = F(!1); ne(() => { const T = y.current, M = () => { T.scrollTop + T.clientHeight >= T.scrollHeight - 1 && (V(!0), m(!1), h(!0)); }; if (T.scrollHeight <= T.clientHeight && V(!0), T) return T.scrollHeight <= T.clientHeight && (V(!0), h(!0)), T.addEventListener("scroll", M), () => T.removeEventListener("scroll", M); }, []), ne(() => { s && y.current && (y.current.scrollTo({ top: y.current.scrollHeight, behavior: "smooth" // ลื่นๆ }), h(!0), f(1), V(!0)); }, [s]); const U = () => { D || m(!0); }, B = (T) => { const M = T.target, W = M.scrollTop, Y = M.scrollHeight, g = M.clientHeight, b = W / (Y - g); f(Math.min(b, 1)), b >= R && h(!0); }; return ( // <div className="input-group consent-scroll-box" ref={containerRef}> /* @__PURE__ */ t.jsx("div", { className: " input-group consent-scroll-box", ref: S, children: /* @__PURE__ */ t.jsxs("label", { className: "consent-container", onClick: U, children: [ /* @__PURE__ */ t.jsx( "input", { ref: k, type: "checkbox", checked: s, disabled: !D, onChange: (T) => { D && (r(T.target.checked), m(!1)), c(!0); } } ), s ? /* @__PURE__ */ t.jsx("span", { className: "checkbox-wrapper checkbox-selected", children: /* @__PURE__ */ t.jsxs("svg", { 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("span", { className: "checkbox-wrapper", children: /* @__PURE__ */ t.jsx("svg", { 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: y, className: `scroll-content ${E ? "error" : ""}`, style: { height: n, border: `1px solid ${// showScrollError ? "var(--input-Error-Border-Color)" : "var(--input-Defualt-Border-Color)" v && !s || E ? "var(--input-Error-Border-Color)" : "var(--input-Defualt-Border-Color)"}` }, onScroll: B, tabIndex: 0, children: /* @__PURE__ */ t.jsx("div", { dangerouslySetInnerHTML: { __html: a } }) } ), /* @__PURE__ */ t.jsx( "div", { className: `text-error-message no-margin ${E || v && !s ? "keep-space-showing" : "keep-space-hidden"}`, children: E ? u : v && !s ? i || u : "" } ), x && /* @__PURE__ */ t.jsx( "div", { style: { position: "absolute", bottom: "27px", right: "8px", backgroundColor: o ? "" : "#007bff", color: "white", padding: "4px 8px", borderRadius: "12px", fontSize: "12px", fontWeight: "bold" }, children: o ? /* @__PURE__ */ t.jsx(ue, {}) : `${Math.round(d * 100)}%` } ) ] } ) ] }) }) ); } ), fe = Z( ({ head: n, label: s, value: r, onChange: a, errorMessage: i, required: u, maxLength: x = 100 }, R) => { const [N, v] = F(!1), E = ((d) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(d))(r), o = N && (u || r !== "") && !E, h = P(null); return q(R, () => ({ validate: () => (v(!0), E), focus: () => { h.current && (h.current.focus(), setTimeout(() => { const d = h.current.getBoundingClientRect(); window.scrollTo({ top: window.scrollY + d.top - 80 - 24, behavior: "smooth" }); }, 10)); } })), /* @__PURE__ */ t.jsxs(t.Fragment, { children: [ n && /* @__PURE__ */ t.jsx("div", { className: "group-label", children: n }), /* @__PURE__ */ t.jsxs( "div", { className: `input-group email-input-wrapper ${o ? "error" : ""} ${!o && N && E ? "valid" : ""}`, children: [ /* @__PURE__ */ t.jsxs("div", { className: "email-input-inner ", children: [ /* @__PURE__ */ t.jsx( "input", { ref: h, maxLength: x, type: "text", className: "email-input", placeholder: " ", value: r, onChange: (d) => { a(d.target.value), v(!0); }, onBlur: () => v(!0) } ), /* @__PURE__ */ t.jsxs("label", { className: "email-input-label", children: [ s, u && " " ] }), /* @__PURE__ */ t.jsx("span", { className: "validation-icon valid-icon" }), /* @__PURE__ */ t.jsx("span", { className: "validation-icon error-icon" }) ] }), o && /* @__PURE__ */ t.jsx("div", { className: "text-error-message", children: i }) ] } ) ] }); } ); function _e({ html: n, children: s, className: r = "", style: a = {} }) { return n ? /* @__PURE__ */ t.jsx( "div", { className: `text-default label-standard ${r}`, style: a, dangerouslySetInnerHTML: { __html: n } } ) : /* @__PURE__ */ t.jsx("div", { className: `text-default label-standard ${r}`, style: a, children: s }); } const ie = (n, s = 0) => { const r = (n ?? "").toString().replace(/,/g, ""); if (r === "") return ""; if (r.endsWith(".") && s > 0) { const i = r.slice(0, -1); if (i === "" && r === ".") return "0."; const u = parseFloat(i); return isNaN(u) ? r : u.toLocaleString(void 0, { minimumFractionDigits: 0, // Format integer part only maximumFractionDigits: 0 }) + "."; } const a = parseFloat(r); return isNaN(a) ? r : a.toLocaleString(void 0, { minimumFractionDigits: s, maximumFractionDigits: s }); }, z = (n, s) => { let r = "", a = !1; typeof n != "string" && (n = (n ?? "").toString()); for (let i = 0; i < n.length; i++) { const u = n[i]; /\d/.test(u) ? r += u : u === "." && !a && s > 0 ? (r += ".", a = !0) : u === "-" && i === 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; }, pe = Z( ({ head: n = "หัวข้อ", label: s = "Label", suggest: r = "", value: a, // Expects a raw number or numeric string (unformatted) onChange: i, min: u = -1 / 0, max: x = 1 / 0, errorMessage: R = "กรุณากรอกข้อมูลให้ถูกต้อง", required: N = !1, maxDigit: v = null, // Max digits for the integer part decimalPlaces: c = 0 }, E) => { const [m, o] = F(""), [h, d] = F(!1), [f, k] = F(!1), S = P(null), y = P({ value: "", cursor: 0 }); ne(() => { const g = a == null ? "" : a.toString(), b = z(g, c); if (!f) o(ie(b, c)); else { const I = z(m, c); b !== I && (o(b), S.current && (y.current = { value: b, cursor: b.length })); } }, [a, f, c]); const D = parseFloat( z(m, c) ), V = z(m, c), U = !N && V === "" || V === "-" && !N || // Allow just "-" if not required !isNaN(D) && D >= u && D <= x; q(E, () => ({ validate: () => { d(!0); const g = z(m, c); if (!N && g === "" || g === "-" && !N) return !0; const b = parseFloat(g); return !isNaN(b) && b >= u && b <= x; }, focus: () => { S.current && (S.current.focus(), setTimeout(() => { const g = S.current.getBoundingClientRect(); window.scrollTo({ top: window.scrollY + g.top - 100 - 24, behavior: "smooth" }); }, 10)); } })); const B = h && !U && !!R, T = () => { k(!0); const g = z(m, c); S.current && (y.current = { value: g, cursor: g.length }); }, M = (g) => { const b = g.target.value, I = g.target.selectionStart; y.current = { value: b, cursor: I }; let j = "", $ = !1; for (let _ = 0; _ < b.length; _++) { const H = b[_]; /\d/.test(H) ? j += H : H === "." && !$ && c > 0 && (j += H, $ = !0); } j === "." && c > 0 && (j = "0."), j === "-." && c > 0 && (j = "-0."); let O = "", w = j; j.startsWith("-") && (O = "-", w = j.substring(1)); let [C, e] = w.split("."); C = C || "", v && C.length > v && (C = C.slice(0, v)), e !== void 0 ? (c != null && e.length > c && (e = e.slice(0, c)), w = C + "." + e) : w = C, j = O + w; let l = C; if (C) { const _ = parseFloat(C); (!isNaN(_) || C.match(/^0+$/)) && (l = _.toLocaleString(void 0, { minimumFractionDigits: 0, maximumFractionDigits: 0 })); } let p = O + l; e !== void 0 ? p += "." + e : w.endsWith(".") && c > 0 && w.length > 0 && C.length >= 0 && (p === O && w === "." ? p = O + "0." : p.endsWith(".") || (p += ".")), j === "0." && c > 0 && (p = "0."), j === "-0." && c > 0 && (p = "-0."), o(p), i(j), h || d(!0); }; be(() => { if (f && S.current) { const g = S.current, { value: b, cursor: I } = y.current, j = m; if (b === j && g.value === j && g.selectionStart === I) return; let $ = 0; for (let e = 0; e < I; e++) b[e] !== "," && $++; let O = 0, w = 0; for (let e = 0; e < j.length && (j[e] !== "," && w++, O++, !(w >= $)); e++) ; if (w < $ && w === 0 && j.length > 0) O = 0, j.startsWith("-") && (O = 1); else if (w < $) { let e = 0, l = 0; for (let p = 0; p < j.length && (j[p] !== "," && l++, e++, !(l >= w)); p++) ; O = e; } const C = Math.max( 0, Math.min(O, g.value.length) ); g.value === j && g.setSelectionRange(C, C); } }, [m, f]); const W = () => { k(!1), d(!0); const g = z(m, c); let b = g; if (g === "" || g === "-") o(g === "-" ? "-" : ""), b = g === "-" ? "-" : ""; else { const I = parseFloat(g); isNaN(I) ? (o(g), b = g) : (b = I.toFixed(c), o(ie(b, c))); } i(b); }, Y = m; return /* @__PURE__ */ t.jsxs(t.Fragment, { children: [ n && /* @__PURE__ */ t.jsx("div", { className: "group-label", children: n }), /* @__PURE__ */ t.jsxs( "div", { className: `input-group numeric-input-wrapper ${B ? "error" : ""}`, children: [ /* @__PURE__ */ t.jsxs("div", { className: "numeric-input-inner", children: [ /* @__PURE__ */ t.jsx("span", { className: "left-label", children: s }), /* @__PURE__ */ t.jsx( "input", { ref: S, type: "text", value: Y, onChange: M, onFocus: T, onBlur: W, className: `numeric-input ${B ? "input-error" : ""}`, placeholder: r, inputMode: "decimal", onKeyDown: (g) => { g.key; } } ) ] }), B && /* @__PURE__ */ t.jsx("div", { className: "text-error-message", children: R }) ] } ) ] }); } ), me = Z( ({ head: n, name: s, options: r, value: a, onChange: i, errorMessage: u = "กรุณากรอกข้อมูลให้ถูกต้อง", direction: x = "horizontal" // ✅ เพิ่มตรงนี้ vertical }, R) => { const [N, v] = F(!1), [c, E] = F(null), m = P(null), o = P(null); q(R, () => ({ validate: () => (v(!0), !!a), focus: () => { m.current && m.current.scrollIntoView({ behavior: "smooth", block: "center" }), setTimeout(() => { o.current && o.current.focus(); }, 300); } })); const h = N && !a, d = x === "vertical" ? "radio-options-row-Vertical" : "radio-options-row-Horizontal"; return /* @__PURE__ */ t.jsxs("div", { ref: m, className: "input-group radio-group-horizontal", children: [ n && /* @__PURE__ */ t.jsx( "div", { className: "group-label", dangerouslySetInnerHTML: { __html: n } } ), /* @__PURE__ */ t.jsx("div", { className: d, children: r.map((f, k) => { const S = a === f.value, y = c === f.value; return /* @__PURE__ */ t.jsxs( "label", { className: "radio-option", onMouseEnter: () => E(f.value), onMouseLeave: () => E(null), children: [ /* @__PURE__ */ t.jsx( "input", { ref: k === 0 ? o : null, type: "radio", name: s, value: f.value, checked: S, onChange: i } ), /* @__PURE__ */ t.jsx("span", { className: "radio-icon", children: S ? /* @__PURE__ */ t.jsxs("svg", { 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" } ) ] }) : y ? /* @__PURE__ */ t.jsx("svg", { 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", { 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: f.label }) ] }, f.value ); }) }), /* @__PURE__ */ t.jsx( "div", { className: `text-error-message ${h ? "keep-space-showing " : "keep-space-hidden"}`, children: u || "กรุณาเลือกเพศ" } ) ] }); } ); function Te(n, s = !0) { const r = /^[a-zA-Z\u0E00-\u0E7F\s]+$/, a = n || ""; return !s || a.trim() !== "" && r.test(a); } const he = Z( ({ head: n, label: s, value: r, onChange: a, errorMessage: i, required: u, maxLength: x = 100 }, R) => { const [N, v] = F(!1), c = Te(r), m = N && (u || r !== "") && !c, o = (d) => { let f = d.target.value; f = f.replace(/[^a-zA-Z\u0E00-\u0E7F\s]/g, ""), a(f), v(!0); }, h = P(null); return q(R, () => ({ validate: () => (v(!0), c), focus: () => { h.current && (h.current.focus(), setTimeout(() => { const d = h.current.getBoundingClientRect(); window.scrollTo({ top: window.scrollY + d.top - 80 - 24, behavior: "smooth" }); }, 10)); } })), /* @__PURE__ */ t.jsxs(t.Fragment, { children: [ n && /* @__PURE__ */ t.jsx("div", { className: "group-label", children: n }), /* @__PURE__ */ t.jsxs( "div", { className: `input-group text-input-wrapper ${m ? "error" : ""} ${!m && N && c ? "valid" : ""}`, children: [ /* @__PURE__ */ t.jsxs("div", { className: "text-input-inner ", children: [ /* @__PURE__ */ t.jsx( "input", { ref: h, maxLength: x, type: "text", className: "text-input", placeholder: " ", value: r, onChange: o, onBlur: () => v(!0) } ), /* @__PURE__ */ t.jsxs("label", { className: "text-input-label", children: [ s, u && " " ] }), /* @__PURE__ */ t.jsx("span", { className: "validation-icon valid-icon", children: c && /* @__PURE__ */ t.jsx(ue, {}) }), /* @__PURE__ */ t.jsx("span", { className: "validation-icon error-icon" }) ] }), m && /* @__PURE__ */ t.jsx("div", { className: "text-error-message", children: i }) ] } ) ] }); } ), ke = ({ children: n, type: s = "button", className: r = "", ...a }) => /* @__PURE__ */ t.jsx( "button", { type: s, className: `${r || "btn-primary-base"}`, ...a, children: n } ), ge = ({ title: n, children: s, collapsible: r = !1, defaultOpen: a = !0 }) => { const [i, u] = F(a); return /* @__PURE__ */ t.jsxs("div", { className: "form-section", children: [ /* @__PURE__ */ t.jsxs( "div", { className: `form-section-header${r ? " collapsible" : ""}`, onClick: () => r && u((x) => !x), children: [ /* @__PURE__ */ t.jsx("h3", { className: "form-section-title", children: n }), r && /* @__PURE__ */ t.jsx("span", { className: "form-section-toggle", children: i ? "▲" : "▼" }) ] } ), (!r || i) && /* @__PURE__ */ t.jsx("div", { className: "form-section-content", children: s }) ] }); }, He = ({ steps: n, initialStep: s = 1 }) => { const [r, a] = F(s), [i, u] = F({}), x = (c) => { u((E) => ({ ...E, [r - 1]: c })), r < n.length ? a((E) => E + 1) : console.log("Stepper: All steps completed!"); }, R = (c) => { c < r && a(c); }, N = n[r - 1]; let v; return N && (v = le.cloneElement(N.component, { onStepComplete: x, stepsData: i // ✅ ส่งเข้าไปให้ step })), /* @__PURE__ */ t.jsxs("div", { className: "stepper-container", children: [ /* @__PURE__ */ t.jsx("div", { className: "stepper-row", children: n.map((c, E) => { const m = E + 1, o = m < r, h = m === r, d = o; let f = "stepper-item__indicator"; o ? f += " stepper-item__indicator--completed" : h ? f += " stepper-item__indicator--active" : f += " stepper-item__indicator--upcoming", d && (f += " stepper-item__indicator--clickable"); let k = "stepper-item__label"; o || h ? k += " stepper-item__label--highlighted" : k += " stepper-item__label--dimmed"; let S = "stepper-line"; return o && (S += " stepper-line--completed"), /* @__PURE__ */ t.jsxs(Ee, { children: [ /* @__PURE__ */ t.jsxs("div", { className: "stepper-item", children: [ /* @__PURE__ */ t.jsx( "div", { className: f, onClick: () => d ? R(m) : null, children: o ? ( // ไอคอนเครื่องหมายถูกสำหรับขั้นตอนที่เสร็จสมบูรณ์ /* @__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: m }) ) } ), /* @__PURE__ */ t.jsx("p", { className: k, children: c.name }) ] }), m < n.length && /* @__PURE__ */ t.jsx("div", { className: S }) ] }, c.name + E); }) }), /* @__PURE__ */ t.jsx("div", { className: "stepper-content", children: v }) ] }); }, we = /* @__PURE__ */ new Set([ me, pe, fe, de, he ]); function K(n = {}) { return !!n.name && we.has(n.component); } function Ce(n, s = {}) { return n.forEach((r) => { if (Array.isArray(r.children)) { Ce(r.children, s); return; } K(r) && (r.name === "consent" ? s[r.name] = !1 : s[r.name] = r.defaultValue ?? ""); }), s; } const ye = { RadioGroup: me, NumericTextInput: pe, EmailInput: fe, ConsentCheckbox: de, TextInput: he, StandardLabel: _e, Section: ge }; function Fe(n = []) { return n.map((s) => { const r = typeof s.component == "string" ? s.component.trim() : s.component, a = { ...s, component: typeof r == "string" ? ye[r] : r }; return Array.isArray(s.children) && (a.children = Fe(s.children)), a; }); } function Ae() { const [n, s] = F({}); return { errors: n, setErrors: s, clearFieldError: (a) => { s((i) => { const { [a]: u, ...x } = i; return x; }); } }; } const ce = (n, s, r) => (a) => { var u; const i = ((u = a == null ? void 0 : a.target) == null ? void 0 : u.value) ?? a; s((x) => ({ ...x, [n]: i })), r((x) => { const { [n]: R, ...N } = x; return N; }); }; function Oe(n, s) { const r = {}; return Object.keys(n).forEach((a) => { var i; (i = n[a].current) != null && i.validate() || (r[a] = s[a]); }), r; } function xe(n) { const s = []; return n.forEach((r) => { Array.isArray(r.children) ? s.push(...xe(r.children)) : s.push(r); }), s; } const Me = ({ onFormSubmitAndValidated: n, // Callback เมื่อฟอร์มผ่าน validation และ submit สำเร็จ fields: s, // Array ของ config field ทั้งหมด formData: r, // State object ของข้อมูลในฟอร์มแต่ละช่อง setFormData: a, // Setter สำหรับเปลี่ยนค่า formData buttonLabel: i }) => { const { setErrors: u } = Ae(), [x, R] = F(!1), N = xe(s), v = P({}); N.filter(K).forEach((o) => { v.current[o.name] || (v.current[o.name] = je()); }); const c = async (o) => { o.preventDefault(), R(!0); const h = Oe( v.current, Object.fromEntries( N.filter(K).map((d) => [d.name, d.errorMessage]) ) ); if (u(h), Object.keys(h).length > 0) { const d = Object.keys(h)[0], f = v.current[d]; f && f.current && typeof f.current.focus == "function" && f.current.focus(), R(!1); return; } try { n && n(r); } catch (d) { console.error(d), alert("เกิดข้อผิดพลาด กรุณาลองใหม่อีกครั้ง"); } R(!1); }, E = (o, h) => { if (o.component === ge && Array.isArray(o.children)) { const k = o.component; return /* @__PURE__ */ t.jsx(k, { ...o.props, children: o.children.map((S, y) => /* @__PURE__ */ t.jsx("div", { children: E(S, y) }, S.name || y)) }, o.name || h); } if (!o.component) return null; if (!K(o) || o.type === "custom") { const k = o.component; return /* @__PURE__ */ t.jsx(k, { ...o.props }, o.name || h); } const d = o.component, f = v.current[o.name]; return o.name === "consent" ? /* @__PURE__ */ t.jsx( d, { ref: f, ...o.props, checked: !!r[o.name], onChange: ce( o.name, a, () => { }, o.errorMessage ), errorMessage: o.errorMessage }, o.name || h ) : /* @__PURE__ */ t.jsx( d, { ref: f, ...o.props, value: r[o.name], onChange: ce( o.name, a, () => { }, o.errorMessage ), errorMessage: o.errorMessage }, o.name || h ); }, m = (o) => o.map((h, d) => E(h, d)); return /* @__PURE__ */ t.jsxs("form", { onSubmit: c, children: [ m(s), /* @__PURE__ */ t.jsx("div", { className: "submit-container ", children: /* @__PURE__ */ t.jsx(ke, { type: "submit", disabled: x, children: i }) }) ] }); }; function $e(n) { const r = (n || "").toString().replace(/[^\d.]/g, ""), a = parseFloat(r); return isNaN(a) ? "-" : a.toLocaleString(); } function Le(n) { const r = (n || "").toString().replace(/[^\d.]/g, ""), a = parseFloat(r); return isNaN(a) ? "-" : Math.round(a).toLocaleString(); } export { ke as ButtonPrimary, de as ConsentCheckbox, fe as EmailInput, Me as FormBuilder, _e as Label, pe as NumericTextInput, me as RadioGroup, ge as Section, He as Stepper, he as TextInput, $e as formatNumber, Ce as getInitialFormData, K as isInputField, Te as isValidText, Fe as mapFieldComponents, Le as roundAndFormatNumber, ce as updateFieldState, Ae as useFormErrors, Oe as validateFields };