@algenium/blocks 1.5.0 → 1.6.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 +756 -9
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +119 -1
- package/dist/index.d.ts +119 -1
- package/dist/index.js +753 -12
- package/dist/index.js.map +1 -1
- package/package.json +5 -1
package/dist/index.cjs
CHANGED
|
@@ -16,6 +16,9 @@ var PopoverPrimitive = require('@radix-ui/react-popover');
|
|
|
16
16
|
var ScrollAreaPrimitive = require('@radix-ui/react-scroll-area');
|
|
17
17
|
var dateFns = require('date-fns');
|
|
18
18
|
var reactDayPicker = require('react-day-picker');
|
|
19
|
+
var valid = require('card-validator');
|
|
20
|
+
|
|
21
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
19
22
|
|
|
20
23
|
function _interopNamespace(e) {
|
|
21
24
|
if (e && e.__esModule) return e;
|
|
@@ -43,6 +46,7 @@ var TogglePrimitive__namespace = /*#__PURE__*/_interopNamespace(TogglePrimitive)
|
|
|
43
46
|
var DialogPrimitive__namespace = /*#__PURE__*/_interopNamespace(DialogPrimitive);
|
|
44
47
|
var PopoverPrimitive__namespace = /*#__PURE__*/_interopNamespace(PopoverPrimitive);
|
|
45
48
|
var ScrollAreaPrimitive__namespace = /*#__PURE__*/_interopNamespace(ScrollAreaPrimitive);
|
|
49
|
+
var valid__default = /*#__PURE__*/_interopDefault(valid);
|
|
46
50
|
|
|
47
51
|
var CalendarContext = React2.createContext(null);
|
|
48
52
|
function useCalendarContext() {
|
|
@@ -3168,7 +3172,7 @@ function DropdownMenuItem({
|
|
|
3168
3172
|
"data-inset": inset,
|
|
3169
3173
|
"data-variant": variant,
|
|
3170
3174
|
className: cn(
|
|
3171
|
-
"focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:*:[svg]:!text-destructive [&_svg:not([class*='text-'])]:text-muted-foreground
|
|
3175
|
+
"relative flex cursor-default select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground data-[highlighted]:[&_svg:not([class*='text-'])]:text-accent-foreground focus:bg-accent focus:text-accent-foreground focus:[&_svg:not([class*='text-'])]:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 data-[variant=destructive]:data-[highlighted]:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/20 dark:data-[variant=destructive]:data-[highlighted]:bg-destructive/20 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:data-[highlighted]:text-destructive data-[variant=destructive]:*:[svg]:!text-destructive [&_svg:not([class*='text-'])]:text-muted-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
3172
3176
|
className
|
|
3173
3177
|
),
|
|
3174
3178
|
...props
|
|
@@ -3186,7 +3190,7 @@ function DropdownMenuCheckboxItem({
|
|
|
3186
3190
|
{
|
|
3187
3191
|
"data-slot": "dropdown-menu-checkbox-item",
|
|
3188
3192
|
className: cn(
|
|
3189
|
-
"
|
|
3193
|
+
"relative flex cursor-default select-none items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground data-[highlighted]:[&_svg:not([class*='text-'])]:text-accent-foreground focus:bg-accent focus:text-accent-foreground focus:[&_svg:not([class*='text-'])]:text-accent-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
3190
3194
|
className
|
|
3191
3195
|
),
|
|
3192
3196
|
checked,
|
|
@@ -3219,7 +3223,7 @@ function DropdownMenuRadioItem({
|
|
|
3219
3223
|
{
|
|
3220
3224
|
"data-slot": "dropdown-menu-radio-item",
|
|
3221
3225
|
className: cn(
|
|
3222
|
-
"
|
|
3226
|
+
"relative flex cursor-default select-none items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground data-[highlighted]:[&_svg:not([class*='text-'])]:text-accent-foreground focus:bg-accent focus:text-accent-foreground focus:[&_svg:not([class*='text-'])]:text-accent-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
3223
3227
|
className
|
|
3224
3228
|
),
|
|
3225
3229
|
...props,
|
|
@@ -3294,7 +3298,7 @@ function DropdownMenuSubTrigger({
|
|
|
3294
3298
|
"data-slot": "dropdown-menu-sub-trigger",
|
|
3295
3299
|
"data-inset": inset,
|
|
3296
3300
|
className: cn(
|
|
3297
|
-
"
|
|
3301
|
+
"flex cursor-default select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden data-[inset]:pl-8 data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground data-[highlighted]:[&_svg:not([class*='text-'])]:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground data-[state=open]:[&_svg:not([class*='text-'])]:text-accent-foreground focus:bg-accent focus:text-accent-foreground focus:[&_svg:not([class*='text-'])]:text-accent-foreground [&_svg:not([class*='text-'])]:text-muted-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
3298
3302
|
className
|
|
3299
3303
|
),
|
|
3300
3304
|
...props,
|
|
@@ -3370,9 +3374,9 @@ var buttonVariants = cva(
|
|
|
3370
3374
|
variant: {
|
|
3371
3375
|
default: "bg-primary text-primary-foreground hover:bg-primary/90",
|
|
3372
3376
|
destructive: "bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
|
|
3373
|
-
outline: "border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:
|
|
3377
|
+
outline: "border bg-background text-foreground shadow-xs hover:bg-accent hover:text-accent-foreground dark:border-input dark:bg-input/30 dark:text-foreground dark:hover:bg-muted dark:hover:text-foreground",
|
|
3374
3378
|
secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
|
|
3375
|
-
ghost: "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
|
|
3379
|
+
ghost: "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50 dark:hover:text-foreground",
|
|
3376
3380
|
link: "text-primary underline-offset-4 hover:underline"
|
|
3377
3381
|
},
|
|
3378
3382
|
size: {
|
|
@@ -3564,7 +3568,7 @@ function ThemeSwitcher({
|
|
|
3564
3568
|
onClick: () => handleThemeClick(key),
|
|
3565
3569
|
className: cn(
|
|
3566
3570
|
"gap-2 cursor-pointer",
|
|
3567
|
-
currentTheme === key && "bg-accent"
|
|
3571
|
+
currentTheme === key && "bg-accent text-accent-foreground [&_svg]:text-accent-foreground"
|
|
3568
3572
|
),
|
|
3569
3573
|
children: [
|
|
3570
3574
|
/* @__PURE__ */ jsxRuntime.jsx(Icon, { className: "h-4 w-4" }),
|
|
@@ -3722,7 +3726,7 @@ function LanguageSwitcher({
|
|
|
3722
3726
|
onClick: () => onLanguageChange?.(key),
|
|
3723
3727
|
className: cn(
|
|
3724
3728
|
"justify-center text-xs font-semibold cursor-pointer px-3",
|
|
3725
|
-
currentLanguage === key && "bg-accent"
|
|
3729
|
+
currentLanguage === key && "bg-accent text-accent-foreground"
|
|
3726
3730
|
),
|
|
3727
3731
|
children: nativeName
|
|
3728
3732
|
},
|
|
@@ -3980,7 +3984,7 @@ function EnvironmentSwitcher({
|
|
|
3980
3984
|
onClick: () => handleSelect(env),
|
|
3981
3985
|
className: cn(
|
|
3982
3986
|
"gap-2 cursor-pointer",
|
|
3983
|
-
environment === env && "bg-accent"
|
|
3987
|
+
environment === env && "bg-accent text-accent-foreground [&_svg]:text-accent-foreground"
|
|
3984
3988
|
),
|
|
3985
3989
|
children: [
|
|
3986
3990
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -7350,6 +7354,746 @@ function formatRelativeTime(dateStr) {
|
|
|
7350
7354
|
if (diffD < 7) return `${diffD}d`;
|
|
7351
7355
|
return date.toLocaleDateString([], { month: "short", day: "numeric" });
|
|
7352
7356
|
}
|
|
7357
|
+
function useDebouncedValue(value, delayMs) {
|
|
7358
|
+
const [debounced, setDebounced] = React2.useState(value);
|
|
7359
|
+
React2.useEffect(() => {
|
|
7360
|
+
const id = window.setTimeout(() => setDebounced(value), delayMs);
|
|
7361
|
+
return () => window.clearTimeout(id);
|
|
7362
|
+
}, [value, delayMs]);
|
|
7363
|
+
return debounced;
|
|
7364
|
+
}
|
|
7365
|
+
function onlyDigits(s, max) {
|
|
7366
|
+
return s.replace(/\D/g, "").slice(0, max);
|
|
7367
|
+
}
|
|
7368
|
+
function formatPan(digits) {
|
|
7369
|
+
const cardInfo = valid__default.default.number(digits).card;
|
|
7370
|
+
const gaps = cardInfo?.gaps ?? [4, 8, 12];
|
|
7371
|
+
const parts = [];
|
|
7372
|
+
let idx = 0;
|
|
7373
|
+
for (const g of gaps) {
|
|
7374
|
+
parts.push(digits.slice(idx, g));
|
|
7375
|
+
idx = g;
|
|
7376
|
+
}
|
|
7377
|
+
parts.push(digits.slice(idx));
|
|
7378
|
+
return parts.filter((p) => p.length > 0).join(" ");
|
|
7379
|
+
}
|
|
7380
|
+
function parseExpiry(raw) {
|
|
7381
|
+
const d = onlyDigits(raw, 4);
|
|
7382
|
+
if (d.length < 4) return null;
|
|
7383
|
+
const mm = Number.parseInt(d.slice(0, 2), 10);
|
|
7384
|
+
const yy = Number.parseInt(d.slice(2, 4), 10);
|
|
7385
|
+
if (mm < 1 || mm > 12) return null;
|
|
7386
|
+
const year = yy < 100 ? 2e3 + yy : yy;
|
|
7387
|
+
const exp = valid__default.default.expirationDate({ month: String(mm), year: String(year) });
|
|
7388
|
+
if (!exp.isValid) return null;
|
|
7389
|
+
return { month: mm, year };
|
|
7390
|
+
}
|
|
7391
|
+
function normalizeBrand(detected) {
|
|
7392
|
+
if (!detected) return "";
|
|
7393
|
+
if (detected === "american-express") return "amex";
|
|
7394
|
+
return detected;
|
|
7395
|
+
}
|
|
7396
|
+
function brandAllowed(detected, accepted) {
|
|
7397
|
+
if (!accepted?.length) return true;
|
|
7398
|
+
if (!detected) return true;
|
|
7399
|
+
const n = normalizeBrand(detected);
|
|
7400
|
+
return accepted.map((a) => a.toLowerCase()).includes(n.toLowerCase());
|
|
7401
|
+
}
|
|
7402
|
+
var inputClassName = "flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 md:text-sm";
|
|
7403
|
+
function CardInput({
|
|
7404
|
+
tokenize,
|
|
7405
|
+
value,
|
|
7406
|
+
onChange,
|
|
7407
|
+
acceptedBrands,
|
|
7408
|
+
requireHolderName = false,
|
|
7409
|
+
labels,
|
|
7410
|
+
disabled = false,
|
|
7411
|
+
largeText = false,
|
|
7412
|
+
className,
|
|
7413
|
+
onError
|
|
7414
|
+
}) {
|
|
7415
|
+
const baseId = React2.useId();
|
|
7416
|
+
const [panDigits, setPanDigits] = React2.useState("");
|
|
7417
|
+
const [expiryRaw, setExpiryRaw] = React2.useState("");
|
|
7418
|
+
const [cvc, setCvc] = React2.useState("");
|
|
7419
|
+
const [holderName, setHolderName] = React2.useState("");
|
|
7420
|
+
const [panFocused, setPanFocused] = React2.useState(false);
|
|
7421
|
+
const [submitting, setSubmitting] = React2.useState(false);
|
|
7422
|
+
const inputClass = largeText ? "text-base py-3" : "";
|
|
7423
|
+
const labelClass = largeText ? "text-base" : "text-sm";
|
|
7424
|
+
const numberValidation = valid__default.default.number(panDigits);
|
|
7425
|
+
const rawBrand = numberValidation.card?.type;
|
|
7426
|
+
const brand = normalizeBrand(rawBrand) || "unknown";
|
|
7427
|
+
const maxPanLen = numberValidation.card?.lengths?.slice(-1)[0] ?? 19;
|
|
7428
|
+
const minPanLenForType = numberValidation.card?.lengths?.[0];
|
|
7429
|
+
const panPastMinimumLength = minPanLenForType !== void 0 && panDigits.length >= minPanLenForType;
|
|
7430
|
+
const cvcSize = rawBrand === "american-express" || brand === "amex" ? 4 : 3;
|
|
7431
|
+
const expiryParsed = parseExpiry(expiryRaw);
|
|
7432
|
+
const expiryValid = expiryRaw.replace(/\D/g, "").length >= 4 && expiryParsed !== null ? valid__default.default.expirationDate({
|
|
7433
|
+
month: String(expiryParsed.month),
|
|
7434
|
+
year: String(expiryParsed.year)
|
|
7435
|
+
}).isValid : false;
|
|
7436
|
+
const cvvValid = cvc.length >= cvcSize && valid__default.default.cvv(cvc, cvcSize).isValid;
|
|
7437
|
+
const panComplete = numberValidation.isValid && brandAllowed(rawBrand, acceptedBrands);
|
|
7438
|
+
const holderOk = !requireHolderName || holderName.trim().length > 1;
|
|
7439
|
+
const canSubmit = panComplete && expiryValid && cvvValid && holderOk && !disabled && !value;
|
|
7440
|
+
const handlePanChange = (e) => {
|
|
7441
|
+
const d = onlyDigits(e.target.value, maxPanLen);
|
|
7442
|
+
setPanDigits(d);
|
|
7443
|
+
};
|
|
7444
|
+
const handleExpiryChange = (e) => {
|
|
7445
|
+
let d = onlyDigits(e.target.value, 4);
|
|
7446
|
+
if (d.length >= 2) d = `${d.slice(0, 2)}/${d.slice(2)}`;
|
|
7447
|
+
setExpiryRaw(d);
|
|
7448
|
+
};
|
|
7449
|
+
const runTokenize = React2.useCallback(async () => {
|
|
7450
|
+
if (!expiryParsed) return;
|
|
7451
|
+
setSubmitting(true);
|
|
7452
|
+
try {
|
|
7453
|
+
const result = await tokenize({
|
|
7454
|
+
pan: panDigits,
|
|
7455
|
+
expMonth: expiryParsed.month,
|
|
7456
|
+
expYear: expiryParsed.year,
|
|
7457
|
+
cvc,
|
|
7458
|
+
holderName: holderName.trim() || void 0
|
|
7459
|
+
});
|
|
7460
|
+
onChange(result);
|
|
7461
|
+
setPanDigits("");
|
|
7462
|
+
setExpiryRaw("");
|
|
7463
|
+
setCvc("");
|
|
7464
|
+
setHolderName("");
|
|
7465
|
+
} catch (err) {
|
|
7466
|
+
const msg = err instanceof Error ? err.message : labels.tokenizeFailed;
|
|
7467
|
+
onError?.(msg);
|
|
7468
|
+
} finally {
|
|
7469
|
+
setSubmitting(false);
|
|
7470
|
+
}
|
|
7471
|
+
}, [
|
|
7472
|
+
cvc,
|
|
7473
|
+
expiryParsed,
|
|
7474
|
+
holderName,
|
|
7475
|
+
labels.tokenizeFailed,
|
|
7476
|
+
onChange,
|
|
7477
|
+
onError,
|
|
7478
|
+
panDigits,
|
|
7479
|
+
tokenize
|
|
7480
|
+
]);
|
|
7481
|
+
const displayPan = panFocused || panDigits.length <= 4 ? formatPan(panDigits) : `\u2022\u2022\u2022\u2022 \u2022\u2022\u2022\u2022 \u2022\u2022\u2022\u2022 ${panDigits.slice(-4)}`;
|
|
7482
|
+
if (value?.tokenId) {
|
|
7483
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
7484
|
+
"div",
|
|
7485
|
+
{
|
|
7486
|
+
className: cn("space-y-3 rounded-lg border bg-muted/30 p-4", className),
|
|
7487
|
+
children: [
|
|
7488
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 text-sm", children: [
|
|
7489
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.CreditCard, { className: "h-4 w-4 text-muted-foreground" }),
|
|
7490
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: value.masked }),
|
|
7491
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-muted-foreground", children: [
|
|
7492
|
+
String(value.expMonth).padStart(2, "0"),
|
|
7493
|
+
"/",
|
|
7494
|
+
String(value.expYear).slice(-2)
|
|
7495
|
+
] })
|
|
7496
|
+
] }),
|
|
7497
|
+
value.holderName ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground", children: value.holderName }) : null,
|
|
7498
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7499
|
+
Button,
|
|
7500
|
+
{
|
|
7501
|
+
type: "button",
|
|
7502
|
+
variant: "outline",
|
|
7503
|
+
size: "sm",
|
|
7504
|
+
disabled,
|
|
7505
|
+
onClick: () => onChange(null),
|
|
7506
|
+
children: labels.replace
|
|
7507
|
+
}
|
|
7508
|
+
)
|
|
7509
|
+
]
|
|
7510
|
+
}
|
|
7511
|
+
);
|
|
7512
|
+
}
|
|
7513
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("space-y-4 rounded-lg border bg-card p-4", className), children: [
|
|
7514
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", children: [
|
|
7515
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7516
|
+
"label",
|
|
7517
|
+
{
|
|
7518
|
+
htmlFor: `${baseId}-pan`,
|
|
7519
|
+
className: cn("font-medium leading-none", labelClass),
|
|
7520
|
+
children: labels.number
|
|
7521
|
+
}
|
|
7522
|
+
),
|
|
7523
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7524
|
+
"input",
|
|
7525
|
+
{
|
|
7526
|
+
id: `${baseId}-pan`,
|
|
7527
|
+
inputMode: "numeric",
|
|
7528
|
+
autoComplete: "cc-number",
|
|
7529
|
+
value: displayPan,
|
|
7530
|
+
onChange: handlePanChange,
|
|
7531
|
+
onFocus: () => setPanFocused(true),
|
|
7532
|
+
onBlur: () => setPanFocused(false),
|
|
7533
|
+
placeholder: "4242 4242 4242 4242",
|
|
7534
|
+
disabled,
|
|
7535
|
+
className: cn(inputClassName, inputClass)
|
|
7536
|
+
}
|
|
7537
|
+
),
|
|
7538
|
+
panDigits.length > 0 && (!numberValidation.isPotentiallyValid || panPastMinimumLength && !numberValidation.isValid) && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-destructive", children: labels.invalidNumber }),
|
|
7539
|
+
panDigits.length > 0 && numberValidation.isPotentiallyValid && !brandAllowed(rawBrand, acceptedBrands) && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-destructive", children: labels.invalidNumber })
|
|
7540
|
+
] }),
|
|
7541
|
+
requireHolderName && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", children: [
|
|
7542
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7543
|
+
"label",
|
|
7544
|
+
{
|
|
7545
|
+
htmlFor: `${baseId}-holder`,
|
|
7546
|
+
className: cn("font-medium leading-none", labelClass),
|
|
7547
|
+
children: labels.holderName
|
|
7548
|
+
}
|
|
7549
|
+
),
|
|
7550
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7551
|
+
"input",
|
|
7552
|
+
{
|
|
7553
|
+
id: `${baseId}-holder`,
|
|
7554
|
+
autoComplete: "cc-name",
|
|
7555
|
+
value: holderName,
|
|
7556
|
+
onChange: (e) => setHolderName(e.target.value),
|
|
7557
|
+
disabled,
|
|
7558
|
+
className: cn(inputClassName, inputClass)
|
|
7559
|
+
}
|
|
7560
|
+
)
|
|
7561
|
+
] }),
|
|
7562
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 gap-4 sm:grid-cols-2", children: [
|
|
7563
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", children: [
|
|
7564
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7565
|
+
"label",
|
|
7566
|
+
{
|
|
7567
|
+
htmlFor: `${baseId}-exp`,
|
|
7568
|
+
className: cn("font-medium leading-none", labelClass),
|
|
7569
|
+
children: labels.expiry
|
|
7570
|
+
}
|
|
7571
|
+
),
|
|
7572
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7573
|
+
"input",
|
|
7574
|
+
{
|
|
7575
|
+
id: `${baseId}-exp`,
|
|
7576
|
+
inputMode: "numeric",
|
|
7577
|
+
autoComplete: "cc-exp",
|
|
7578
|
+
value: expiryRaw,
|
|
7579
|
+
onChange: handleExpiryChange,
|
|
7580
|
+
placeholder: "MM/YY",
|
|
7581
|
+
disabled,
|
|
7582
|
+
className: cn(inputClassName, inputClass)
|
|
7583
|
+
}
|
|
7584
|
+
),
|
|
7585
|
+
expiryRaw.replace(/\D/g, "").length >= 4 && !expiryValid && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-destructive", children: labels.expiredCard })
|
|
7586
|
+
] }),
|
|
7587
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", children: [
|
|
7588
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7589
|
+
"label",
|
|
7590
|
+
{
|
|
7591
|
+
htmlFor: `${baseId}-cvc`,
|
|
7592
|
+
className: cn("font-medium leading-none", labelClass),
|
|
7593
|
+
children: labels.cvc
|
|
7594
|
+
}
|
|
7595
|
+
),
|
|
7596
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7597
|
+
"input",
|
|
7598
|
+
{
|
|
7599
|
+
id: `${baseId}-cvc`,
|
|
7600
|
+
inputMode: "numeric",
|
|
7601
|
+
autoComplete: "cc-csc",
|
|
7602
|
+
value: cvc,
|
|
7603
|
+
onChange: (e) => setCvc(onlyDigits(e.target.value, cvcSize)),
|
|
7604
|
+
placeholder: cvcSize === 4 ? "0000" : "000",
|
|
7605
|
+
disabled,
|
|
7606
|
+
className: cn(inputClassName, inputClass),
|
|
7607
|
+
maxLength: cvcSize
|
|
7608
|
+
}
|
|
7609
|
+
),
|
|
7610
|
+
cvc.length > 0 && !cvvValid && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-destructive", children: labels.invalidCvc })
|
|
7611
|
+
] })
|
|
7612
|
+
] }),
|
|
7613
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
7614
|
+
Button,
|
|
7615
|
+
{
|
|
7616
|
+
type: "button",
|
|
7617
|
+
disabled: !canSubmit || submitting,
|
|
7618
|
+
onClick: () => void runTokenize(),
|
|
7619
|
+
className: "gap-2",
|
|
7620
|
+
children: [
|
|
7621
|
+
submitting ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { className: "h-4 w-4 animate-spin" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CreditCard, { className: "h-4 w-4" }),
|
|
7622
|
+
labels.tokenize
|
|
7623
|
+
]
|
|
7624
|
+
}
|
|
7625
|
+
)
|
|
7626
|
+
] });
|
|
7627
|
+
}
|
|
7628
|
+
function parseInitial(value) {
|
|
7629
|
+
if (!value) {
|
|
7630
|
+
return {
|
|
7631
|
+
street: "",
|
|
7632
|
+
street2: "",
|
|
7633
|
+
city: "",
|
|
7634
|
+
state: "",
|
|
7635
|
+
zip: "",
|
|
7636
|
+
country: "US"
|
|
7637
|
+
};
|
|
7638
|
+
}
|
|
7639
|
+
return {
|
|
7640
|
+
street: value.street ?? "",
|
|
7641
|
+
street2: value.street2 ?? "",
|
|
7642
|
+
city: value.city ?? "",
|
|
7643
|
+
state: value.state ?? "",
|
|
7644
|
+
zip: value.zip ?? "",
|
|
7645
|
+
country: "US"
|
|
7646
|
+
};
|
|
7647
|
+
}
|
|
7648
|
+
var inputClassName2 = "flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 md:text-sm";
|
|
7649
|
+
function USAddressInput({
|
|
7650
|
+
value,
|
|
7651
|
+
onChange,
|
|
7652
|
+
lookupZip,
|
|
7653
|
+
validateAddress,
|
|
7654
|
+
autocomplete,
|
|
7655
|
+
labels,
|
|
7656
|
+
disabled = false,
|
|
7657
|
+
largeText = false,
|
|
7658
|
+
className,
|
|
7659
|
+
onError,
|
|
7660
|
+
showAutocompleteToggle = true
|
|
7661
|
+
}) {
|
|
7662
|
+
const [autocompleteEnabled, setAutocompleteEnabled] = React2.useState(false);
|
|
7663
|
+
const [searchQuery, setSearchQuery] = React2.useState("");
|
|
7664
|
+
const [showSuggestions, setShowSuggestions] = React2.useState(false);
|
|
7665
|
+
const [suggestions, setSuggestions] = React2.useState([]);
|
|
7666
|
+
const [address, setAddress] = React2.useState(
|
|
7667
|
+
() => parseInitial(value)
|
|
7668
|
+
);
|
|
7669
|
+
const [sessionToken] = React2.useState(
|
|
7670
|
+
() => typeof crypto !== "undefined" && crypto.randomUUID ? crypto.randomUUID() : `${Date.now()}-${Math.random()}`
|
|
7671
|
+
);
|
|
7672
|
+
const [loadingAutocomplete, setLoadingAutocomplete] = React2.useState(false);
|
|
7673
|
+
const [loadingZip, setLoadingZip] = React2.useState(false);
|
|
7674
|
+
const [loadingValidate, setLoadingValidate] = React2.useState(false);
|
|
7675
|
+
const [uspsSuggestion, setUspsSuggestion] = React2.useState(
|
|
7676
|
+
null
|
|
7677
|
+
);
|
|
7678
|
+
const searchRef = React2.useRef(null);
|
|
7679
|
+
const suggestionCache = React2.useRef(/* @__PURE__ */ new Map());
|
|
7680
|
+
const warnedRef = React2.useRef({
|
|
7681
|
+
autocomplete: false,
|
|
7682
|
+
zip: false,
|
|
7683
|
+
validate: false
|
|
7684
|
+
});
|
|
7685
|
+
const lastZipLookup = React2.useRef("");
|
|
7686
|
+
const debouncedSearch = useDebouncedValue(searchQuery, 300);
|
|
7687
|
+
const zipDigits = address.zip.replace(/\D/g, "").slice(0, 5);
|
|
7688
|
+
const debouncedZip = useDebouncedValue(zipDigits, 400);
|
|
7689
|
+
const inputClass = largeText ? "text-base py-3" : "";
|
|
7690
|
+
const labelClass = largeText ? "text-base" : "text-sm";
|
|
7691
|
+
React2.useEffect(() => {
|
|
7692
|
+
const handleClickOutside = (event) => {
|
|
7693
|
+
if (searchRef.current && !searchRef.current.contains(event.target)) {
|
|
7694
|
+
setShowSuggestions(false);
|
|
7695
|
+
}
|
|
7696
|
+
};
|
|
7697
|
+
document.addEventListener("mousedown", handleClickOutside);
|
|
7698
|
+
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
7699
|
+
}, []);
|
|
7700
|
+
const valueSyncKey = value == null ? "" : `o:${JSON.stringify(value)}`;
|
|
7701
|
+
React2.useEffect(() => {
|
|
7702
|
+
setAddress(parseInitial(value));
|
|
7703
|
+
}, [valueSyncKey]);
|
|
7704
|
+
const handleFieldChange = (field, fieldValue) => {
|
|
7705
|
+
setAddress((prev) => {
|
|
7706
|
+
const next = field === "country" ? { ...prev, country: "US" } : { ...prev, [field]: fieldValue };
|
|
7707
|
+
onChange(next);
|
|
7708
|
+
return next;
|
|
7709
|
+
});
|
|
7710
|
+
};
|
|
7711
|
+
const allowAutocomplete = Boolean(autocomplete);
|
|
7712
|
+
const allowUspsValidation = Boolean(validateAddress);
|
|
7713
|
+
const allowZipLookup = Boolean(lookupZip);
|
|
7714
|
+
React2.useEffect(() => {
|
|
7715
|
+
if (!allowAutocomplete || !autocompleteEnabled || !autocomplete) return;
|
|
7716
|
+
const q = debouncedSearch.trim();
|
|
7717
|
+
if (q.length < 3) {
|
|
7718
|
+
setSuggestions([]);
|
|
7719
|
+
setShowSuggestions(false);
|
|
7720
|
+
setLoadingAutocomplete(false);
|
|
7721
|
+
return;
|
|
7722
|
+
}
|
|
7723
|
+
const cacheKey = q.toLowerCase();
|
|
7724
|
+
const cached = suggestionCache.current.get(cacheKey);
|
|
7725
|
+
if (cached) {
|
|
7726
|
+
setSuggestions(cached);
|
|
7727
|
+
setShowSuggestions(true);
|
|
7728
|
+
setLoadingAutocomplete(false);
|
|
7729
|
+
return;
|
|
7730
|
+
}
|
|
7731
|
+
const ctrl = new AbortController();
|
|
7732
|
+
setLoadingAutocomplete(true);
|
|
7733
|
+
autocomplete.search(q, sessionToken, ctrl.signal).then((list) => {
|
|
7734
|
+
suggestionCache.current.set(cacheKey, list);
|
|
7735
|
+
setSuggestions(list);
|
|
7736
|
+
setShowSuggestions(list.length > 0);
|
|
7737
|
+
}).catch((e) => {
|
|
7738
|
+
if (e.name === "AbortError") return;
|
|
7739
|
+
if (!warnedRef.current.autocomplete) {
|
|
7740
|
+
onError?.(labels.autocompleteUnavailable);
|
|
7741
|
+
warnedRef.current.autocomplete = true;
|
|
7742
|
+
}
|
|
7743
|
+
setSuggestions([]);
|
|
7744
|
+
setShowSuggestions(false);
|
|
7745
|
+
}).finally(() => setLoadingAutocomplete(false));
|
|
7746
|
+
return () => ctrl.abort();
|
|
7747
|
+
}, [
|
|
7748
|
+
debouncedSearch,
|
|
7749
|
+
allowAutocomplete,
|
|
7750
|
+
autocompleteEnabled,
|
|
7751
|
+
autocomplete,
|
|
7752
|
+
sessionToken,
|
|
7753
|
+
labels.autocompleteUnavailable,
|
|
7754
|
+
onError
|
|
7755
|
+
]);
|
|
7756
|
+
React2.useEffect(() => {
|
|
7757
|
+
if (!allowZipLookup || !lookupZip) return;
|
|
7758
|
+
if (debouncedZip.length !== 5) return;
|
|
7759
|
+
if (debouncedZip === lastZipLookup.current) return;
|
|
7760
|
+
const ctrl = new AbortController();
|
|
7761
|
+
setLoadingZip(true);
|
|
7762
|
+
lookupZip(debouncedZip, ctrl.signal).then((data) => {
|
|
7763
|
+
lastZipLookup.current = debouncedZip;
|
|
7764
|
+
setAddress((prev) => {
|
|
7765
|
+
const cityEmpty = !prev.city.trim();
|
|
7766
|
+
const stateEmpty = !prev.state.trim();
|
|
7767
|
+
const next = { ...prev };
|
|
7768
|
+
if (cityEmpty && data.city) next.city = data.city;
|
|
7769
|
+
if (stateEmpty && data.state) next.state = data.state;
|
|
7770
|
+
next.country = "US";
|
|
7771
|
+
onChange(next);
|
|
7772
|
+
return next;
|
|
7773
|
+
});
|
|
7774
|
+
}).catch(() => {
|
|
7775
|
+
if (!warnedRef.current.zip) {
|
|
7776
|
+
onError?.(labels.zipLookupFailed);
|
|
7777
|
+
warnedRef.current.zip = true;
|
|
7778
|
+
}
|
|
7779
|
+
}).finally(() => setLoadingZip(false));
|
|
7780
|
+
return () => ctrl.abort();
|
|
7781
|
+
}, [
|
|
7782
|
+
debouncedZip,
|
|
7783
|
+
allowZipLookup,
|
|
7784
|
+
lookupZip,
|
|
7785
|
+
onChange,
|
|
7786
|
+
labels.zipLookupFailed,
|
|
7787
|
+
onError
|
|
7788
|
+
]);
|
|
7789
|
+
const handleSelectSuggestion = async (row) => {
|
|
7790
|
+
if (!autocomplete) return;
|
|
7791
|
+
try {
|
|
7792
|
+
const next = await autocomplete.details(
|
|
7793
|
+
row.placeId,
|
|
7794
|
+
AbortSignal.timeout(8e3)
|
|
7795
|
+
);
|
|
7796
|
+
const normalized = {
|
|
7797
|
+
...next,
|
|
7798
|
+
country: "US"
|
|
7799
|
+
};
|
|
7800
|
+
setAddress(normalized);
|
|
7801
|
+
onChange(normalized);
|
|
7802
|
+
setShowSuggestions(false);
|
|
7803
|
+
setSearchQuery("");
|
|
7804
|
+
setUspsSuggestion(null);
|
|
7805
|
+
} catch {
|
|
7806
|
+
onError?.(labels.placeLookupFailed);
|
|
7807
|
+
}
|
|
7808
|
+
};
|
|
7809
|
+
const runUspsValidate = async () => {
|
|
7810
|
+
if (!allowUspsValidation || !validateAddress || disabled) return;
|
|
7811
|
+
setLoadingValidate(true);
|
|
7812
|
+
setUspsSuggestion(null);
|
|
7813
|
+
try {
|
|
7814
|
+
const result = await validateAddress(address, AbortSignal.timeout(8e3));
|
|
7815
|
+
const std = result.standardized;
|
|
7816
|
+
if (result.changed) {
|
|
7817
|
+
setUspsSuggestion(std);
|
|
7818
|
+
}
|
|
7819
|
+
} catch {
|
|
7820
|
+
if (!warnedRef.current.validate) {
|
|
7821
|
+
onError?.(labels.uspsUnavailable);
|
|
7822
|
+
warnedRef.current.validate = true;
|
|
7823
|
+
}
|
|
7824
|
+
} finally {
|
|
7825
|
+
setLoadingValidate(false);
|
|
7826
|
+
}
|
|
7827
|
+
};
|
|
7828
|
+
const applyUspsSuggestion = () => {
|
|
7829
|
+
if (!uspsSuggestion) return;
|
|
7830
|
+
setAddress(uspsSuggestion);
|
|
7831
|
+
onChange(uspsSuggestion);
|
|
7832
|
+
setUspsSuggestion(null);
|
|
7833
|
+
};
|
|
7834
|
+
const showAutocompleteUi = allowAutocomplete && showAutocompleteToggle && autocompleteEnabled;
|
|
7835
|
+
const toggleTitle = labels.autocompleteTitle ?? labels.searchPlaceholder;
|
|
7836
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("space-y-4", className), children: [
|
|
7837
|
+
allowAutocomplete && showAutocompleteToggle && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between rounded-lg border bg-muted/50 p-3", children: [
|
|
7838
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
7839
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.MapPin, { className: "h-4 w-4 text-muted-foreground" }),
|
|
7840
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
7841
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: cn("font-medium", labelClass), children: toggleTitle }),
|
|
7842
|
+
labels.autocompleteDescription ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground", children: labels.autocompleteDescription }) : null
|
|
7843
|
+
] })
|
|
7844
|
+
] }),
|
|
7845
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7846
|
+
"button",
|
|
7847
|
+
{
|
|
7848
|
+
type: "button",
|
|
7849
|
+
role: "switch",
|
|
7850
|
+
"aria-checked": autocompleteEnabled,
|
|
7851
|
+
disabled,
|
|
7852
|
+
onClick: () => setAutocompleteEnabled((v) => !v),
|
|
7853
|
+
className: cn(
|
|
7854
|
+
"relative inline-flex h-6 w-11 shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors",
|
|
7855
|
+
autocompleteEnabled ? "bg-primary" : "bg-input",
|
|
7856
|
+
disabled && "cursor-not-allowed opacity-50"
|
|
7857
|
+
),
|
|
7858
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
7859
|
+
"span",
|
|
7860
|
+
{
|
|
7861
|
+
className: cn(
|
|
7862
|
+
"pointer-events-none block size-5 translate-x-0 rounded-full bg-background shadow-lg ring-0 transition-transform",
|
|
7863
|
+
autocompleteEnabled && "translate-x-5"
|
|
7864
|
+
)
|
|
7865
|
+
}
|
|
7866
|
+
)
|
|
7867
|
+
}
|
|
7868
|
+
)
|
|
7869
|
+
] }),
|
|
7870
|
+
showAutocompleteUi && autocomplete && /* @__PURE__ */ jsxRuntime.jsxs("div", { ref: searchRef, className: "relative", children: [
|
|
7871
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
|
|
7872
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Search, { className: "absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" }),
|
|
7873
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7874
|
+
"input",
|
|
7875
|
+
{
|
|
7876
|
+
value: searchQuery,
|
|
7877
|
+
onChange: (e) => setSearchQuery(e.target.value),
|
|
7878
|
+
placeholder: labels.searchPlaceholder,
|
|
7879
|
+
disabled,
|
|
7880
|
+
className: cn(inputClassName2, "pl-9 pr-9", inputClass)
|
|
7881
|
+
}
|
|
7882
|
+
),
|
|
7883
|
+
loadingAutocomplete && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { className: "absolute right-10 top-1/2 h-4 w-4 -translate-y-1/2 animate-spin text-muted-foreground" }),
|
|
7884
|
+
searchQuery ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
7885
|
+
"button",
|
|
7886
|
+
{
|
|
7887
|
+
type: "button",
|
|
7888
|
+
onClick: () => setSearchQuery(""),
|
|
7889
|
+
className: "absolute right-3 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground",
|
|
7890
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "h-4 w-4" })
|
|
7891
|
+
}
|
|
7892
|
+
) : null
|
|
7893
|
+
] }),
|
|
7894
|
+
showSuggestions && suggestions.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute z-10 mt-1 max-h-48 w-full overflow-y-auto rounded-lg border bg-background shadow-lg", children: suggestions.map((suggestion) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
7895
|
+
"button",
|
|
7896
|
+
{
|
|
7897
|
+
type: "button",
|
|
7898
|
+
onClick: () => void handleSelectSuggestion(suggestion),
|
|
7899
|
+
className: "w-full border-b px-4 py-3 text-left transition-colors last:border-b-0 hover:bg-muted",
|
|
7900
|
+
children: [
|
|
7901
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm font-medium", children: suggestion.mainText }),
|
|
7902
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground", children: suggestion.secondaryText })
|
|
7903
|
+
]
|
|
7904
|
+
},
|
|
7905
|
+
suggestion.placeId
|
|
7906
|
+
)) })
|
|
7907
|
+
] }),
|
|
7908
|
+
allowUspsValidation && uspsSuggestion && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2 rounded-lg border border-amber-200 bg-amber-50 p-3 dark:border-amber-900 dark:bg-amber-950/30", children: [
|
|
7909
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm font-medium text-amber-900 dark:text-amber-100", children: labels.uspsSuggested }),
|
|
7910
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground", children: [
|
|
7911
|
+
uspsSuggestion.street,
|
|
7912
|
+
uspsSuggestion.street2,
|
|
7913
|
+
uspsSuggestion.city,
|
|
7914
|
+
uspsSuggestion.state,
|
|
7915
|
+
uspsSuggestion.zip
|
|
7916
|
+
].filter(Boolean).join(", ") }),
|
|
7917
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap gap-2", children: [
|
|
7918
|
+
/* @__PURE__ */ jsxRuntime.jsx(Button, { type: "button", size: "sm", onClick: applyUspsSuggestion, children: labels.uspsUseSuggestion }),
|
|
7919
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7920
|
+
Button,
|
|
7921
|
+
{
|
|
7922
|
+
type: "button",
|
|
7923
|
+
size: "sm",
|
|
7924
|
+
variant: "outline",
|
|
7925
|
+
onClick: () => setUspsSuggestion(null),
|
|
7926
|
+
children: labels.uspsKeepMine
|
|
7927
|
+
}
|
|
7928
|
+
)
|
|
7929
|
+
] })
|
|
7930
|
+
] }),
|
|
7931
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid gap-4", children: [
|
|
7932
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", children: [
|
|
7933
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7934
|
+
"label",
|
|
7935
|
+
{
|
|
7936
|
+
htmlFor: "blocks-usaddress-street",
|
|
7937
|
+
className: cn("font-medium leading-none", labelClass),
|
|
7938
|
+
children: labels.street
|
|
7939
|
+
}
|
|
7940
|
+
),
|
|
7941
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7942
|
+
"input",
|
|
7943
|
+
{
|
|
7944
|
+
id: "blocks-usaddress-street",
|
|
7945
|
+
value: address.street,
|
|
7946
|
+
onChange: (e) => handleFieldChange("street", e.target.value),
|
|
7947
|
+
placeholder: labels.streetPlaceholder ?? "",
|
|
7948
|
+
disabled,
|
|
7949
|
+
className: cn(inputClassName2, inputClass)
|
|
7950
|
+
}
|
|
7951
|
+
)
|
|
7952
|
+
] }),
|
|
7953
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", children: [
|
|
7954
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
7955
|
+
"label",
|
|
7956
|
+
{
|
|
7957
|
+
htmlFor: "blocks-usaddress-street2",
|
|
7958
|
+
className: cn(
|
|
7959
|
+
`${labelClass} text-muted-foreground`,
|
|
7960
|
+
"leading-none"
|
|
7961
|
+
),
|
|
7962
|
+
children: [
|
|
7963
|
+
labels.street2 ?? "Address line 2",
|
|
7964
|
+
" ",
|
|
7965
|
+
labels.street2OptionalHint ? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xs", children: [
|
|
7966
|
+
"(",
|
|
7967
|
+
labels.street2OptionalHint,
|
|
7968
|
+
")"
|
|
7969
|
+
] }) : null
|
|
7970
|
+
]
|
|
7971
|
+
}
|
|
7972
|
+
),
|
|
7973
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7974
|
+
"input",
|
|
7975
|
+
{
|
|
7976
|
+
id: "blocks-usaddress-street2",
|
|
7977
|
+
value: address.street2 || "",
|
|
7978
|
+
onChange: (e) => handleFieldChange("street2", e.target.value),
|
|
7979
|
+
placeholder: labels.street2Placeholder ?? "",
|
|
7980
|
+
disabled,
|
|
7981
|
+
className: cn(inputClassName2, inputClass)
|
|
7982
|
+
}
|
|
7983
|
+
)
|
|
7984
|
+
] }),
|
|
7985
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 gap-4 sm:grid-cols-2", children: [
|
|
7986
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", children: [
|
|
7987
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7988
|
+
"label",
|
|
7989
|
+
{
|
|
7990
|
+
htmlFor: "blocks-usaddress-city",
|
|
7991
|
+
className: cn("font-medium leading-none", labelClass),
|
|
7992
|
+
children: labels.city
|
|
7993
|
+
}
|
|
7994
|
+
),
|
|
7995
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7996
|
+
"input",
|
|
7997
|
+
{
|
|
7998
|
+
id: "blocks-usaddress-city",
|
|
7999
|
+
value: address.city,
|
|
8000
|
+
onChange: (e) => handleFieldChange("city", e.target.value),
|
|
8001
|
+
placeholder: labels.cityPlaceholder ?? "",
|
|
8002
|
+
disabled,
|
|
8003
|
+
className: cn(inputClassName2, inputClass)
|
|
8004
|
+
}
|
|
8005
|
+
)
|
|
8006
|
+
] }),
|
|
8007
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", children: [
|
|
8008
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
8009
|
+
"label",
|
|
8010
|
+
{
|
|
8011
|
+
htmlFor: "blocks-usaddress-state",
|
|
8012
|
+
className: cn("font-medium leading-none", labelClass),
|
|
8013
|
+
children: labels.state
|
|
8014
|
+
}
|
|
8015
|
+
),
|
|
8016
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
8017
|
+
"input",
|
|
8018
|
+
{
|
|
8019
|
+
id: "blocks-usaddress-state",
|
|
8020
|
+
value: address.state,
|
|
8021
|
+
onChange: (e) => handleFieldChange("state", e.target.value),
|
|
8022
|
+
placeholder: labels.statePlaceholder ?? "",
|
|
8023
|
+
disabled,
|
|
8024
|
+
className: cn(inputClassName2, inputClass)
|
|
8025
|
+
}
|
|
8026
|
+
)
|
|
8027
|
+
] })
|
|
8028
|
+
] }),
|
|
8029
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 gap-4 sm:grid-cols-2", children: [
|
|
8030
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", children: [
|
|
8031
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
8032
|
+
"label",
|
|
8033
|
+
{
|
|
8034
|
+
htmlFor: "blocks-usaddress-zip",
|
|
8035
|
+
className: cn("font-medium leading-none", labelClass),
|
|
8036
|
+
children: labels.zip
|
|
8037
|
+
}
|
|
8038
|
+
),
|
|
8039
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
|
|
8040
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
8041
|
+
"input",
|
|
8042
|
+
{
|
|
8043
|
+
id: "blocks-usaddress-zip",
|
|
8044
|
+
value: address.zip,
|
|
8045
|
+
onChange: (e) => handleFieldChange(
|
|
8046
|
+
"zip",
|
|
8047
|
+
e.target.value.replace(/\D/g, "").slice(0, 10)
|
|
8048
|
+
),
|
|
8049
|
+
placeholder: labels.zipPlaceholder ?? "",
|
|
8050
|
+
disabled,
|
|
8051
|
+
className: cn(inputClassName2, inputClass)
|
|
8052
|
+
}
|
|
8053
|
+
),
|
|
8054
|
+
loadingZip && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { className: "absolute right-3 top-1/2 h-4 w-4 -translate-y-1/2 animate-spin text-muted-foreground" })
|
|
8055
|
+
] })
|
|
8056
|
+
] }),
|
|
8057
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", children: [
|
|
8058
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
8059
|
+
"label",
|
|
8060
|
+
{
|
|
8061
|
+
htmlFor: "blocks-usaddress-country",
|
|
8062
|
+
className: cn("font-medium leading-none", labelClass),
|
|
8063
|
+
children: labels.countryLabel ?? "Country"
|
|
8064
|
+
}
|
|
8065
|
+
),
|
|
8066
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
8067
|
+
"input",
|
|
8068
|
+
{
|
|
8069
|
+
id: "blocks-usaddress-country",
|
|
8070
|
+
value: "United States",
|
|
8071
|
+
readOnly: true,
|
|
8072
|
+
disabled,
|
|
8073
|
+
className: cn(inputClassName2, inputClass, "bg-muted/50"),
|
|
8074
|
+
"aria-readonly": "true"
|
|
8075
|
+
}
|
|
8076
|
+
)
|
|
8077
|
+
] })
|
|
8078
|
+
] }),
|
|
8079
|
+
allowUspsValidation && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-2", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
8080
|
+
Button,
|
|
8081
|
+
{
|
|
8082
|
+
type: "button",
|
|
8083
|
+
variant: "secondary",
|
|
8084
|
+
size: "sm",
|
|
8085
|
+
disabled: disabled || loadingValidate,
|
|
8086
|
+
onClick: () => void runUspsValidate(),
|
|
8087
|
+
className: "gap-2",
|
|
8088
|
+
children: loadingValidate ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
8089
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { className: "h-4 w-4 animate-spin" }),
|
|
8090
|
+
labels.uspsValidating
|
|
8091
|
+
] }) : labels.uspsValidate
|
|
8092
|
+
}
|
|
8093
|
+
) })
|
|
8094
|
+
] })
|
|
8095
|
+
] });
|
|
8096
|
+
}
|
|
7353
8097
|
|
|
7354
8098
|
exports.AvatarEditor = AvatarEditor;
|
|
7355
8099
|
exports.AvatarEditorDialog = AvatarEditorDialog;
|
|
@@ -7359,6 +8103,7 @@ exports.CalendarContext = CalendarContext;
|
|
|
7359
8103
|
exports.CalendarSubscribeButton = CalendarSubscribeButton;
|
|
7360
8104
|
exports.CalendarView = CalendarView;
|
|
7361
8105
|
exports.CalendarWidget = CalendarWidget;
|
|
8106
|
+
exports.CardInput = CardInput;
|
|
7362
8107
|
exports.ChatRoomView = ChatRoomView;
|
|
7363
8108
|
exports.ChatSidebar = ChatSidebar;
|
|
7364
8109
|
exports.ChatSidebarContext = ChatSidebarContext;
|
|
@@ -7423,6 +8168,7 @@ exports.Tooltip = Tooltip;
|
|
|
7423
8168
|
exports.TooltipContent = TooltipContent;
|
|
7424
8169
|
exports.TooltipProvider = TooltipProvider;
|
|
7425
8170
|
exports.TooltipTrigger = TooltipTrigger;
|
|
8171
|
+
exports.USAddressInput = USAddressInput;
|
|
7426
8172
|
exports.UpcomingEvents = UpcomingEvents;
|
|
7427
8173
|
exports.buttonVariants = buttonVariants;
|
|
7428
8174
|
exports.cn = cn;
|
|
@@ -7434,6 +8180,7 @@ exports.toggleVariants = toggleVariants;
|
|
|
7434
8180
|
exports.useCalendarContext = useCalendarContext;
|
|
7435
8181
|
exports.useChatRoom = useChatRoom;
|
|
7436
8182
|
exports.useChatSidebar = useChatSidebar;
|
|
8183
|
+
exports.useDebouncedValue = useDebouncedValue;
|
|
7437
8184
|
exports.useEnvironmentContext = useEnvironmentContext;
|
|
7438
8185
|
exports.useLanguageContext = useLanguageContext;
|
|
7439
8186
|
exports.useNotificationsContext = useNotificationsContext;
|