@geomak/ui 5.7.1 → 5.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +295 -58
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +338 -18
- package/dist/index.d.ts +338 -18
- package/dist/index.js +286 -59
- package/dist/index.js.map +1 -1
- package/dist/styles.css +30 -52
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -2200,6 +2200,7 @@ function FieldLabel({
|
|
|
2200
2200
|
required,
|
|
2201
2201
|
helperText,
|
|
2202
2202
|
horizontal = false,
|
|
2203
|
+
align = "start",
|
|
2203
2204
|
style,
|
|
2204
2205
|
width,
|
|
2205
2206
|
className = ""
|
|
@@ -2211,7 +2212,10 @@ function FieldLabel({
|
|
|
2211
2212
|
style: { width: horizontal ? width : void 0, ...style },
|
|
2212
2213
|
className: [
|
|
2213
2214
|
"flex items-center gap-1",
|
|
2214
|
-
horizontal ? "
|
|
2215
|
+
horizontal ? "flex-shrink-0 whitespace-nowrap" : "",
|
|
2216
|
+
// Only the 'start' alignment needs the top nudge; 'center' relies
|
|
2217
|
+
// on the row's items-center to line up with a short control.
|
|
2218
|
+
horizontal && align === "start" ? "mt-2" : "",
|
|
2215
2219
|
className
|
|
2216
2220
|
].filter(Boolean).join(" "),
|
|
2217
2221
|
children: [
|
|
@@ -2232,6 +2236,7 @@ function Field({
|
|
|
2232
2236
|
layout = "vertical",
|
|
2233
2237
|
required,
|
|
2234
2238
|
helperText,
|
|
2239
|
+
labelAlign = "start",
|
|
2235
2240
|
labelStyle,
|
|
2236
2241
|
labelWidth,
|
|
2237
2242
|
className = "",
|
|
@@ -2244,7 +2249,7 @@ function Field({
|
|
|
2244
2249
|
{
|
|
2245
2250
|
className: [
|
|
2246
2251
|
"flex",
|
|
2247
|
-
horizontal ?
|
|
2252
|
+
horizontal ? `flex-row gap-3 ${labelAlign === "center" ? "items-center" : "items-start"}` : "flex-col gap-1.5",
|
|
2248
2253
|
className
|
|
2249
2254
|
].filter(Boolean).join(" "),
|
|
2250
2255
|
children: [
|
|
@@ -2256,6 +2261,7 @@ function Field({
|
|
|
2256
2261
|
required,
|
|
2257
2262
|
helperText,
|
|
2258
2263
|
horizontal,
|
|
2264
|
+
align: labelAlign,
|
|
2259
2265
|
style: labelStyle,
|
|
2260
2266
|
width: labelWidth
|
|
2261
2267
|
}
|
|
@@ -2599,15 +2605,7 @@ function Dropdown({
|
|
|
2599
2605
|
hasError && /* @__PURE__ */ jsxRuntime.jsx("div", { id: errorId, className: "text-status-error text-xs mt-1", children: errorMessage })
|
|
2600
2606
|
] });
|
|
2601
2607
|
}
|
|
2602
|
-
var SHIMMER =
|
|
2603
|
-
"relative overflow-hidden rounded-sm bg-surface-raised",
|
|
2604
|
-
'before:absolute before:inset-0 before:content-[""]',
|
|
2605
|
-
"before:bg-gradient-to-r before:from-transparent before:via-white/30 before:to-transparent",
|
|
2606
|
-
"before:animate-[shimmer_1.6s_linear_infinite]",
|
|
2607
|
-
// Respect prefers-reduced-motion — the resting bg-surface-raised is still
|
|
2608
|
-
// a perfectly legible placeholder for users who have animations off.
|
|
2609
|
-
"motion-reduce:before:hidden"
|
|
2610
|
-
].join(" ");
|
|
2608
|
+
var SHIMMER = "oxy-skeleton rounded-sm bg-surface-raised";
|
|
2611
2609
|
function SkeletonBox({ width, height = 16, radius, className = "", style }) {
|
|
2612
2610
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2613
2611
|
"span",
|
|
@@ -3714,14 +3712,15 @@ function Checkbox({
|
|
|
3714
3712
|
// legacy alias
|
|
3715
3713
|
onChange,
|
|
3716
3714
|
label,
|
|
3715
|
+
description,
|
|
3717
3716
|
name,
|
|
3718
3717
|
htmlFor,
|
|
3719
3718
|
errorMessage,
|
|
3719
|
+
helperText,
|
|
3720
3720
|
disabled = false,
|
|
3721
|
+
required,
|
|
3721
3722
|
layout = "horizontal",
|
|
3722
|
-
labelPosition = "right"
|
|
3723
|
-
helperText,
|
|
3724
|
-
required
|
|
3723
|
+
labelPosition = "right"
|
|
3725
3724
|
}) {
|
|
3726
3725
|
const isChecked = checked ?? value ?? false;
|
|
3727
3726
|
const labelFirst = labelPosition === "left";
|
|
@@ -3734,11 +3733,12 @@ function Checkbox({
|
|
|
3734
3733
|
name,
|
|
3735
3734
|
checked: isChecked,
|
|
3736
3735
|
disabled,
|
|
3736
|
+
required,
|
|
3737
3737
|
onCheckedChange: (c) => onChange?.({ target: { checked: !!c, id: htmlFor, name } }),
|
|
3738
3738
|
className: [
|
|
3739
|
-
"relative flex h-[18px] w-[18px] flex-shrink-0 items-center justify-center",
|
|
3739
|
+
"relative mt-0.5 flex h-[18px] w-[18px] flex-shrink-0 items-center justify-center",
|
|
3740
3740
|
"rounded-sm border transition-colors duration-150",
|
|
3741
|
-
"border-border-strong
|
|
3741
|
+
hasError ? "border-status-error" : "border-border-strong",
|
|
3742
3742
|
"data-[state=checked]:bg-accent data-[state=checked]:border-accent",
|
|
3743
3743
|
// Focus halo matches the field tokens for a consistent look.
|
|
3744
3744
|
"focus:outline-none focus-visible:ring-[3px] focus-visible:ring-focus-ring",
|
|
@@ -3750,33 +3750,60 @@ function Checkbox({
|
|
|
3750
3750
|
children: /* @__PURE__ */ jsxRuntime.jsx(CheckboxPrimitive__namespace.Indicator, { className: "flex items-center justify-center data-[state=checked]:animate-check-pop", children: /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "11", height: "9", viewBox: "0 0 11 9", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M1 4.5L4 7.5L10 1", stroke: "white", strokeWidth: "1.8", strokeLinecap: "round", strokeLinejoin: "round" }) }) })
|
|
3751
3751
|
}
|
|
3752
3752
|
);
|
|
3753
|
-
const
|
|
3754
|
-
label,
|
|
3755
|
-
|
|
3756
|
-
|
|
3753
|
+
const labelText = label != null && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3754
|
+
"label",
|
|
3755
|
+
{
|
|
3756
|
+
htmlFor,
|
|
3757
|
+
className: ["block select-none text-sm text-foreground leading-snug", disabled ? "cursor-not-allowed opacity-50" : "cursor-pointer"].join(" "),
|
|
3758
|
+
children: [
|
|
3759
|
+
label,
|
|
3760
|
+
required && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-status-error ml-0.5", "aria-hidden": "true", children: "*" })
|
|
3761
|
+
]
|
|
3762
|
+
}
|
|
3763
|
+
);
|
|
3764
|
+
const descriptionEl = description != null && /* @__PURE__ */ jsxRuntime.jsx(
|
|
3765
|
+
"label",
|
|
3766
|
+
{
|
|
3767
|
+
htmlFor,
|
|
3768
|
+
className: `block text-xs text-foreground-secondary mt-0.5 ${disabled ? "opacity-50 cursor-not-allowed" : "cursor-pointer"}`,
|
|
3769
|
+
children: description
|
|
3770
|
+
}
|
|
3771
|
+
);
|
|
3772
|
+
let content;
|
|
3773
|
+
if (layout === "vertical") {
|
|
3774
|
+
content = /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex flex-col items-start gap-1.5", children: [
|
|
3775
|
+
labelFirst ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
3776
|
+
labelText,
|
|
3777
|
+
box
|
|
3778
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
3779
|
+
box,
|
|
3780
|
+
labelText
|
|
3781
|
+
] }),
|
|
3782
|
+
descriptionEl
|
|
3783
|
+
] });
|
|
3784
|
+
} else if (labelFirst) {
|
|
3785
|
+
content = /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex flex-col", children: [
|
|
3786
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex items-start gap-2.5", children: [
|
|
3787
|
+
labelText,
|
|
3788
|
+
box
|
|
3789
|
+
] }),
|
|
3790
|
+
descriptionEl
|
|
3791
|
+
] });
|
|
3792
|
+
} else {
|
|
3793
|
+
content = /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex items-start gap-2.5", children: [
|
|
3794
|
+
box,
|
|
3795
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex flex-col", children: [
|
|
3796
|
+
labelText,
|
|
3797
|
+
descriptionEl
|
|
3798
|
+
] })
|
|
3799
|
+
] });
|
|
3800
|
+
}
|
|
3757
3801
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
3758
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-
|
|
3759
|
-
|
|
3760
|
-
"label",
|
|
3761
|
-
{
|
|
3762
|
-
htmlFor,
|
|
3763
|
-
className: [
|
|
3764
|
-
"inline-flex",
|
|
3765
|
-
layout === "vertical" ? "flex-col items-start gap-1.5" : "flex-row items-center gap-2.5",
|
|
3766
|
-
disabled ? "cursor-not-allowed opacity-50" : "cursor-pointer"
|
|
3767
|
-
].join(" "),
|
|
3768
|
-
children: labelFirst ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
3769
|
-
labelEl,
|
|
3770
|
-
box
|
|
3771
|
-
] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
3772
|
-
box,
|
|
3773
|
-
labelEl
|
|
3774
|
-
] })
|
|
3775
|
-
}
|
|
3776
|
-
),
|
|
3802
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start gap-1", children: [
|
|
3803
|
+
content,
|
|
3777
3804
|
helperText != null && /* @__PURE__ */ jsxRuntime.jsx(FieldHelpIcon, { text: helperText })
|
|
3778
3805
|
] }),
|
|
3779
|
-
|
|
3806
|
+
hasError && /* @__PURE__ */ jsxRuntime.jsx("span", { id: errorId, className: "text-xs text-status-error mt-0.5", children: errorMessage })
|
|
3780
3807
|
] });
|
|
3781
3808
|
}
|
|
3782
3809
|
var DOT_SIZE = {
|
|
@@ -3928,6 +3955,7 @@ function Switch({
|
|
|
3928
3955
|
layout,
|
|
3929
3956
|
required,
|
|
3930
3957
|
helperText,
|
|
3958
|
+
labelAlign: "center",
|
|
3931
3959
|
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2.5", children: [
|
|
3932
3960
|
offLabel != null && /* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: id, className: stateLabel(!isOn), children: offLabel }),
|
|
3933
3961
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -4217,19 +4245,17 @@ function TreeSelect({
|
|
|
4217
4245
|
setOpen(false);
|
|
4218
4246
|
}
|
|
4219
4247
|
};
|
|
4220
|
-
return /* @__PURE__ */ jsxRuntime.
|
|
4221
|
-
|
|
4222
|
-
|
|
4223
|
-
|
|
4224
|
-
|
|
4225
|
-
|
|
4226
|
-
|
|
4227
|
-
|
|
4228
|
-
|
|
4229
|
-
|
|
4230
|
-
|
|
4231
|
-
),
|
|
4232
|
-
/* @__PURE__ */ jsxRuntime.jsxs(Popover__namespace.Root, { open: open && !disabled, onOpenChange: (o) => !disabled && setOpen(o), children: [
|
|
4248
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4249
|
+
Field,
|
|
4250
|
+
{
|
|
4251
|
+
label,
|
|
4252
|
+
htmlFor,
|
|
4253
|
+
errorId,
|
|
4254
|
+
errorMessage,
|
|
4255
|
+
layout,
|
|
4256
|
+
required,
|
|
4257
|
+
helperText,
|
|
4258
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsxs(Popover__namespace.Root, { open: open && !disabled, onOpenChange: (o) => !disabled && setOpen(o), children: [
|
|
4233
4259
|
/* @__PURE__ */ jsxRuntime.jsx(Popover__namespace.Trigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4234
4260
|
"button",
|
|
4235
4261
|
{
|
|
@@ -4293,10 +4319,9 @@ function TreeSelect({
|
|
|
4293
4319
|
)
|
|
4294
4320
|
}
|
|
4295
4321
|
) })
|
|
4296
|
-
] })
|
|
4297
|
-
|
|
4298
|
-
|
|
4299
|
-
] });
|
|
4322
|
+
] }) })
|
|
4323
|
+
}
|
|
4324
|
+
);
|
|
4300
4325
|
}
|
|
4301
4326
|
function TreeNodeRow({
|
|
4302
4327
|
node,
|
|
@@ -6248,7 +6273,7 @@ function useForm(options = {}) {
|
|
|
6248
6273
|
isValid: store.isValid,
|
|
6249
6274
|
getValue: store.getValue,
|
|
6250
6275
|
getValues: store.getValues,
|
|
6251
|
-
setValue: (name, value) => store.setValue(name, value),
|
|
6276
|
+
setValue: (name, value, opts) => store.setValue(name, value, opts),
|
|
6252
6277
|
setValues: (patch) => store.setValues(patch),
|
|
6253
6278
|
setError: store.setError,
|
|
6254
6279
|
validateField: (name) => store.validateField(name),
|
|
@@ -6358,6 +6383,208 @@ function useFieldArray(name) {
|
|
|
6358
6383
|
};
|
|
6359
6384
|
}
|
|
6360
6385
|
|
|
6386
|
+
// src/components/forms/creditCard.ts
|
|
6387
|
+
var CARD_BRANDS = [
|
|
6388
|
+
{ id: "amex", label: "American Express", short: "AMEX", color: "#1F72CD", pattern: /^3[47]/, lengths: [15], cvv: 4, gaps: [4, 10] },
|
|
6389
|
+
{ id: "visa", label: "Visa", short: "VISA", color: "#1A1F71", pattern: /^4/, lengths: [16, 18, 19], cvv: 3, gaps: [4, 8, 12, 16] },
|
|
6390
|
+
{ id: "mastercard", label: "Mastercard", short: "MC", color: "#EB001B", pattern: /^(5[1-5]|2[2-7])/, lengths: [16], cvv: 3, gaps: [4, 8, 12] },
|
|
6391
|
+
{ id: "discover", label: "Discover", short: "DISC", color: "#FF6000", pattern: /^(6011|64[4-9]|65)/, lengths: [16, 19], cvv: 3, gaps: [4, 8, 12] },
|
|
6392
|
+
{ id: "diners", label: "Diners Club", short: "DINERS", color: "#0079BE", pattern: /^(36|38|30[0-5])/, lengths: [14, 16, 19], cvv: 3, gaps: [4, 10] },
|
|
6393
|
+
{ id: "jcb", label: "JCB", short: "JCB", color: "#0B4EA2", pattern: /^35/, lengths: [16, 17, 18, 19], cvv: 3, gaps: [4, 8, 12] }
|
|
6394
|
+
];
|
|
6395
|
+
var onlyDigits = (s) => (s || "").replace(/\D/g, "");
|
|
6396
|
+
function detectBrand(value) {
|
|
6397
|
+
const d = onlyDigits(value);
|
|
6398
|
+
if (!d) return null;
|
|
6399
|
+
return CARD_BRANDS.find((b) => b.pattern.test(d)) ?? null;
|
|
6400
|
+
}
|
|
6401
|
+
function maxCardLength(value) {
|
|
6402
|
+
const b = detectBrand(value);
|
|
6403
|
+
return b ? Math.max(...b.lengths) : 19;
|
|
6404
|
+
}
|
|
6405
|
+
function luhnValid(value) {
|
|
6406
|
+
const s = onlyDigits(value);
|
|
6407
|
+
if (s.length < 12) return false;
|
|
6408
|
+
let sum = 0;
|
|
6409
|
+
let double = false;
|
|
6410
|
+
for (let i = s.length - 1; i >= 0; i--) {
|
|
6411
|
+
let n = s.charCodeAt(i) - 48;
|
|
6412
|
+
if (double) {
|
|
6413
|
+
n *= 2;
|
|
6414
|
+
if (n > 9) n -= 9;
|
|
6415
|
+
}
|
|
6416
|
+
sum += n;
|
|
6417
|
+
double = !double;
|
|
6418
|
+
}
|
|
6419
|
+
return sum % 10 === 0;
|
|
6420
|
+
}
|
|
6421
|
+
function formatCardNumber(value) {
|
|
6422
|
+
const brand = detectBrand(value);
|
|
6423
|
+
const digits = onlyDigits(value).slice(0, maxCardLength(value));
|
|
6424
|
+
const gaps = brand?.gaps ?? [4, 8, 12, 16];
|
|
6425
|
+
let out = "";
|
|
6426
|
+
for (let i = 0; i < digits.length; i++) {
|
|
6427
|
+
if (gaps.includes(i)) out += " ";
|
|
6428
|
+
out += digits[i];
|
|
6429
|
+
}
|
|
6430
|
+
return out;
|
|
6431
|
+
}
|
|
6432
|
+
function cardNumberError(value) {
|
|
6433
|
+
const d = onlyDigits(value);
|
|
6434
|
+
if (!d) return "Card number is required";
|
|
6435
|
+
const brand = detectBrand(d);
|
|
6436
|
+
if (!brand) return "Unsupported card type";
|
|
6437
|
+
if (!brand.lengths.includes(d.length)) return "Card number is incomplete";
|
|
6438
|
+
if (!luhnValid(d)) return "Card number looks invalid";
|
|
6439
|
+
return void 0;
|
|
6440
|
+
}
|
|
6441
|
+
function formatExpiry(value) {
|
|
6442
|
+
let d = onlyDigits(value).slice(0, 4);
|
|
6443
|
+
if (d.length === 1 && d > "1") d = "0" + d;
|
|
6444
|
+
if (d.length <= 2) return d;
|
|
6445
|
+
return `${d.slice(0, 2)}/${d.slice(2)}`;
|
|
6446
|
+
}
|
|
6447
|
+
function expiryError(value, now = /* @__PURE__ */ new Date()) {
|
|
6448
|
+
if (!value) return "Expiry is required";
|
|
6449
|
+
const m = value.match(/^(\d{2})\/(\d{2})$/);
|
|
6450
|
+
if (!m) return "Use MM/YY";
|
|
6451
|
+
const mm = Number(m[1]);
|
|
6452
|
+
const yy = Number(m[2]);
|
|
6453
|
+
if (mm < 1 || mm > 12) return "Invalid month";
|
|
6454
|
+
const endOfMonth = new Date(2e3 + yy, mm, 0, 23, 59, 59, 999);
|
|
6455
|
+
if (endOfMonth < now) return "Card has expired";
|
|
6456
|
+
return void 0;
|
|
6457
|
+
}
|
|
6458
|
+
function cvvError(value, cardNumber) {
|
|
6459
|
+
const need = detectBrand(cardNumber)?.cvv ?? 3;
|
|
6460
|
+
const d = onlyDigits(value);
|
|
6461
|
+
if (!d) return "CVV is required";
|
|
6462
|
+
if (d.length !== need) return `CVV must be ${need} digits`;
|
|
6463
|
+
return void 0;
|
|
6464
|
+
}
|
|
6465
|
+
var toCard = (vals) => {
|
|
6466
|
+
const number = String(vals.number ?? "");
|
|
6467
|
+
return {
|
|
6468
|
+
number: onlyDigits(number),
|
|
6469
|
+
name: String(vals.name ?? ""),
|
|
6470
|
+
expiry: String(vals.expiry ?? ""),
|
|
6471
|
+
cvv: onlyDigits(String(vals.cvv ?? "")),
|
|
6472
|
+
brand: detectBrand(number)?.id ?? null
|
|
6473
|
+
};
|
|
6474
|
+
};
|
|
6475
|
+
function BrandMark({ brand }) {
|
|
6476
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex items-center gap-1.5", "aria-live": "polite", children: [
|
|
6477
|
+
/* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "28", height: "18", viewBox: "0 0 28 18", fill: "none", "aria-hidden": "true", children: [
|
|
6478
|
+
/* @__PURE__ */ jsxRuntime.jsx("rect", { x: "0.5", y: "0.5", width: "27", height: "17", rx: "3", fill: "var(--color-surface-raised)", stroke: "var(--color-border)" }),
|
|
6479
|
+
/* @__PURE__ */ jsxRuntime.jsx("rect", { x: "0.5", y: "3.75", width: "27", height: "3.5", fill: brand ? brand.color : "var(--color-border-strong)" })
|
|
6480
|
+
] }),
|
|
6481
|
+
brand && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] font-bold uppercase tracking-wide", style: { color: brand.color }, children: brand.short }),
|
|
6482
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: brand ? brand.label : "Unknown card type" })
|
|
6483
|
+
] });
|
|
6484
|
+
}
|
|
6485
|
+
function CreditCardForm({
|
|
6486
|
+
onSubmit,
|
|
6487
|
+
onChange,
|
|
6488
|
+
defaultValue,
|
|
6489
|
+
size = "md",
|
|
6490
|
+
disabled,
|
|
6491
|
+
requireName = true,
|
|
6492
|
+
hideSubmit = false,
|
|
6493
|
+
submitLabel = "Pay",
|
|
6494
|
+
className = "",
|
|
6495
|
+
style
|
|
6496
|
+
}) {
|
|
6497
|
+
const initial = React8.useRef({
|
|
6498
|
+
number: formatCardNumber(defaultValue?.number ?? ""),
|
|
6499
|
+
name: defaultValue?.name ?? "",
|
|
6500
|
+
expiry: formatExpiry(defaultValue?.expiry ?? ""),
|
|
6501
|
+
cvv: onlyDigits(defaultValue?.cvv ?? "")
|
|
6502
|
+
}).current;
|
|
6503
|
+
const form = useForm({ initialValues: initial });
|
|
6504
|
+
const numberStr = String(form.values.number ?? "");
|
|
6505
|
+
const brand = detectBrand(numberStr);
|
|
6506
|
+
React8.useEffect(() => {
|
|
6507
|
+
onChange?.(toCard(form.values));
|
|
6508
|
+
}, [form.values.number, form.values.name, form.values.expiry, form.values.cvv]);
|
|
6509
|
+
const numberBind = form.fieldNative("number", {
|
|
6510
|
+
required: "Card number is required",
|
|
6511
|
+
validate: (v) => cardNumberError(String(v))
|
|
6512
|
+
});
|
|
6513
|
+
const nameBind = form.fieldNative("name", requireName ? { required: "Cardholder name is required" } : void 0);
|
|
6514
|
+
const expiryBind = form.fieldNative("expiry", {
|
|
6515
|
+
required: "Expiry is required",
|
|
6516
|
+
validate: (v) => expiryError(String(v))
|
|
6517
|
+
});
|
|
6518
|
+
const cvvBind = form.fieldNative("cvv", {
|
|
6519
|
+
required: "CVV is required",
|
|
6520
|
+
validate: (v) => cvvError(String(v), numberStr)
|
|
6521
|
+
});
|
|
6522
|
+
const cvvLen = brand?.cvv ?? 3;
|
|
6523
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
6524
|
+
Form,
|
|
6525
|
+
{
|
|
6526
|
+
form,
|
|
6527
|
+
onFinish: (vals) => onSubmit?.(toCard(vals)),
|
|
6528
|
+
className: `flex flex-col gap-4 ${className}`.trim(),
|
|
6529
|
+
style,
|
|
6530
|
+
children: [
|
|
6531
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6532
|
+
TextInput,
|
|
6533
|
+
{
|
|
6534
|
+
...numberBind,
|
|
6535
|
+
label: "Card number",
|
|
6536
|
+
placeholder: "1234 5678 9012 3456",
|
|
6537
|
+
size,
|
|
6538
|
+
disabled,
|
|
6539
|
+
value: numberStr,
|
|
6540
|
+
onChange: (e) => form.setValue("number", formatCardNumber(e.target.value), { touch: true }),
|
|
6541
|
+
suffix: /* @__PURE__ */ jsxRuntime.jsx(BrandMark, { brand })
|
|
6542
|
+
}
|
|
6543
|
+
),
|
|
6544
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
6545
|
+
TextInput,
|
|
6546
|
+
{
|
|
6547
|
+
...nameBind,
|
|
6548
|
+
label: "Cardholder name",
|
|
6549
|
+
placeholder: "Jane Appleseed",
|
|
6550
|
+
size,
|
|
6551
|
+
disabled,
|
|
6552
|
+
value: String(form.values.name ?? ""),
|
|
6553
|
+
onChange: (e) => form.setValue("name", e.target.value, { touch: true })
|
|
6554
|
+
}
|
|
6555
|
+
),
|
|
6556
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start gap-3", children: [
|
|
6557
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
6558
|
+
TextInput,
|
|
6559
|
+
{
|
|
6560
|
+
...expiryBind,
|
|
6561
|
+
label: "Expiry",
|
|
6562
|
+
placeholder: "MM/YY",
|
|
6563
|
+
size,
|
|
6564
|
+
disabled,
|
|
6565
|
+
value: String(form.values.expiry ?? ""),
|
|
6566
|
+
onChange: (e) => form.setValue("expiry", formatExpiry(e.target.value), { touch: true })
|
|
6567
|
+
}
|
|
6568
|
+
) }),
|
|
6569
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
6570
|
+
TextInput,
|
|
6571
|
+
{
|
|
6572
|
+
...cvvBind,
|
|
6573
|
+
label: "CVV",
|
|
6574
|
+
placeholder: cvvLen === 4 ? "1234" : "123",
|
|
6575
|
+
size,
|
|
6576
|
+
disabled,
|
|
6577
|
+
value: String(form.values.cvv ?? ""),
|
|
6578
|
+
onChange: (e) => form.setValue("cvv", onlyDigits(e.target.value).slice(0, cvvLen), { touch: true })
|
|
6579
|
+
}
|
|
6580
|
+
) })
|
|
6581
|
+
] }),
|
|
6582
|
+
!hideSubmit && /* @__PURE__ */ jsxRuntime.jsx(Button, { content: submitLabel, buttonType: "submit", variant: "primary", disabled })
|
|
6583
|
+
]
|
|
6584
|
+
}
|
|
6585
|
+
);
|
|
6586
|
+
}
|
|
6587
|
+
|
|
6361
6588
|
Object.defineProperty(exports, "COLORS", {
|
|
6362
6589
|
enumerable: true,
|
|
6363
6590
|
get: function () { return chunk255PCZIW_cjs.colors_default; }
|
|
@@ -6379,12 +6606,14 @@ exports.AutoComplete = AutoComplete;
|
|
|
6379
6606
|
exports.Avatar = Avatar;
|
|
6380
6607
|
exports.Box = Box;
|
|
6381
6608
|
exports.Button = Button;
|
|
6609
|
+
exports.CARD_BRANDS = CARD_BRANDS;
|
|
6382
6610
|
exports.Catalog = Catalog;
|
|
6383
6611
|
exports.CatalogCarousel = CatalogCarousel;
|
|
6384
6612
|
exports.CatalogGrid = CatalogGrid;
|
|
6385
6613
|
exports.Checkbox = Checkbox;
|
|
6386
6614
|
exports.ColorPicker = ColorPicker;
|
|
6387
6615
|
exports.ContextMenu = ContextMenu;
|
|
6616
|
+
exports.CreditCardForm = CreditCardForm;
|
|
6388
6617
|
exports.DateRangePicker = DateRangePicker;
|
|
6389
6618
|
exports.Drawer = Drawer;
|
|
6390
6619
|
exports.Dropdown = Dropdown;
|
|
@@ -6439,8 +6668,16 @@ exports.Tree = Tree;
|
|
|
6439
6668
|
exports.TreeSelect = TreeSelect;
|
|
6440
6669
|
exports.Typography = Typography;
|
|
6441
6670
|
exports.Wizard = Wizard;
|
|
6671
|
+
exports.cardNumberError = cardNumberError;
|
|
6672
|
+
exports.cvvError = cvvError;
|
|
6673
|
+
exports.detectBrand = detectBrand;
|
|
6674
|
+
exports.expiryError = expiryError;
|
|
6442
6675
|
exports.fieldShell = fieldShell;
|
|
6676
|
+
exports.formatCardNumber = formatCardNumber;
|
|
6677
|
+
exports.formatExpiry = formatExpiry;
|
|
6443
6678
|
exports.isRequired = isRequired;
|
|
6679
|
+
exports.luhnValid = luhnValid;
|
|
6680
|
+
exports.onlyDigits = onlyDigits;
|
|
6444
6681
|
exports.patterns = patterns;
|
|
6445
6682
|
exports.runFieldRules = runFieldRules;
|
|
6446
6683
|
exports.useFieldArray = useFieldArray;
|