input-states-react
Version:
Reusable UI components for forms and steps
1,111 lines (1,110 loc) • 37.1 kB
JavaScript
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
};