@algenium/blocks 1.5.0 → 1.7.0-rc.1
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 +794 -9
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +123 -1
- package/dist/index.d.ts +123 -1
- package/dist/index.js +790 -12
- package/dist/index.js.map +1 -1
- package/package.json +5 -1
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as React2 from 'react';
|
|
2
|
-
import { createContext, useContext, useState, useCallback, useEffect, useRef, useMemo } from 'react';
|
|
2
|
+
import { createContext, useContext, useState, useCallback, useEffect, useRef, useMemo, useId } from 'react';
|
|
3
3
|
import { useTheme } from 'next-themes';
|
|
4
|
-
import { CheckIcon, CircleIcon, ChevronRightIcon, Monitor, Sun, Moon, Languages, FlaskConical, X, Upload, Move, ZoomOut, ZoomIn, RotateCcw, RotateCw, Grid3X3, RefreshCw, XIcon, User, Pencil, Check, Loader2, Bell, CheckCheck, XCircle, AlertTriangle, CheckCircle, Info, Trash2, Clock, MapPin, Link, CalendarDays, ExternalLink, ChevronLeft, ChevronRight, Plus, HelpCircle, MessageSquare, Wifi, WifiOff, FileIcon, Download, Paperclip, Send, ArrowLeft } from 'lucide-react';
|
|
4
|
+
import { CheckIcon, CircleIcon, ChevronRightIcon, Monitor, Sun, Moon, Languages, FlaskConical, X, Upload, Move, ZoomOut, ZoomIn, RotateCcw, RotateCw, Grid3X3, RefreshCw, XIcon, User, Pencil, Check, Loader2, Bell, CheckCheck, XCircle, AlertTriangle, CheckCircle, Info, Trash2, Clock, MapPin, Link, CalendarDays, ExternalLink, ChevronLeft, ChevronRight, Plus, HelpCircle, MessageSquare, Wifi, WifiOff, FileIcon, Download, Paperclip, Send, ArrowLeft, CreditCard, Search, CheckCircle2 } from 'lucide-react';
|
|
5
5
|
import { AnimatePresence, motion } from 'framer-motion';
|
|
6
6
|
import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu';
|
|
7
7
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
@@ -15,6 +15,7 @@ import * as PopoverPrimitive from '@radix-ui/react-popover';
|
|
|
15
15
|
import * as ScrollAreaPrimitive from '@radix-ui/react-scroll-area';
|
|
16
16
|
import { startOfMonth, endOfMonth, eachDayOfInterval, endOfWeek, startOfWeek, format, isSameDay, subMonths, addMonths } from 'date-fns';
|
|
17
17
|
import { DayPicker } from 'react-day-picker';
|
|
18
|
+
import valid from 'card-validator';
|
|
18
19
|
|
|
19
20
|
var CalendarContext = createContext(null);
|
|
20
21
|
function useCalendarContext() {
|
|
@@ -3140,7 +3141,7 @@ function DropdownMenuItem({
|
|
|
3140
3141
|
"data-inset": inset,
|
|
3141
3142
|
"data-variant": variant,
|
|
3142
3143
|
className: cn(
|
|
3143
|
-
"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
|
|
3144
|
+
"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",
|
|
3144
3145
|
className
|
|
3145
3146
|
),
|
|
3146
3147
|
...props
|
|
@@ -3158,7 +3159,7 @@ function DropdownMenuCheckboxItem({
|
|
|
3158
3159
|
{
|
|
3159
3160
|
"data-slot": "dropdown-menu-checkbox-item",
|
|
3160
3161
|
className: cn(
|
|
3161
|
-
"
|
|
3162
|
+
"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",
|
|
3162
3163
|
className
|
|
3163
3164
|
),
|
|
3164
3165
|
checked,
|
|
@@ -3191,7 +3192,7 @@ function DropdownMenuRadioItem({
|
|
|
3191
3192
|
{
|
|
3192
3193
|
"data-slot": "dropdown-menu-radio-item",
|
|
3193
3194
|
className: cn(
|
|
3194
|
-
"
|
|
3195
|
+
"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",
|
|
3195
3196
|
className
|
|
3196
3197
|
),
|
|
3197
3198
|
...props,
|
|
@@ -3266,7 +3267,7 @@ function DropdownMenuSubTrigger({
|
|
|
3266
3267
|
"data-slot": "dropdown-menu-sub-trigger",
|
|
3267
3268
|
"data-inset": inset,
|
|
3268
3269
|
className: cn(
|
|
3269
|
-
"
|
|
3270
|
+
"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",
|
|
3270
3271
|
className
|
|
3271
3272
|
),
|
|
3272
3273
|
...props,
|
|
@@ -3342,9 +3343,9 @@ var buttonVariants = cva(
|
|
|
3342
3343
|
variant: {
|
|
3343
3344
|
default: "bg-primary text-primary-foreground hover:bg-primary/90",
|
|
3344
3345
|
destructive: "bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
|
|
3345
|
-
outline: "border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:
|
|
3346
|
+
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",
|
|
3346
3347
|
secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
|
|
3347
|
-
ghost: "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
|
|
3348
|
+
ghost: "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50 dark:hover:text-foreground",
|
|
3348
3349
|
link: "text-primary underline-offset-4 hover:underline"
|
|
3349
3350
|
},
|
|
3350
3351
|
size: {
|
|
@@ -3536,7 +3537,7 @@ function ThemeSwitcher({
|
|
|
3536
3537
|
onClick: () => handleThemeClick(key),
|
|
3537
3538
|
className: cn(
|
|
3538
3539
|
"gap-2 cursor-pointer",
|
|
3539
|
-
currentTheme === key && "bg-accent"
|
|
3540
|
+
currentTheme === key && "bg-accent text-accent-foreground [&_svg]:text-accent-foreground"
|
|
3540
3541
|
),
|
|
3541
3542
|
children: [
|
|
3542
3543
|
/* @__PURE__ */ jsx(Icon, { className: "h-4 w-4" }),
|
|
@@ -3694,7 +3695,7 @@ function LanguageSwitcher({
|
|
|
3694
3695
|
onClick: () => onLanguageChange?.(key),
|
|
3695
3696
|
className: cn(
|
|
3696
3697
|
"justify-center text-xs font-semibold cursor-pointer px-3",
|
|
3697
|
-
currentLanguage === key && "bg-accent"
|
|
3698
|
+
currentLanguage === key && "bg-accent text-accent-foreground"
|
|
3698
3699
|
),
|
|
3699
3700
|
children: nativeName
|
|
3700
3701
|
},
|
|
@@ -3952,7 +3953,7 @@ function EnvironmentSwitcher({
|
|
|
3952
3953
|
onClick: () => handleSelect(env),
|
|
3953
3954
|
className: cn(
|
|
3954
3955
|
"gap-2 cursor-pointer",
|
|
3955
|
-
environment === env && "bg-accent"
|
|
3956
|
+
environment === env && "bg-accent text-accent-foreground [&_svg]:text-accent-foreground"
|
|
3956
3957
|
),
|
|
3957
3958
|
children: [
|
|
3958
3959
|
/* @__PURE__ */ jsx(
|
|
@@ -7322,7 +7323,784 @@ function formatRelativeTime(dateStr) {
|
|
|
7322
7323
|
if (diffD < 7) return `${diffD}d`;
|
|
7323
7324
|
return date.toLocaleDateString([], { month: "short", day: "numeric" });
|
|
7324
7325
|
}
|
|
7326
|
+
function useDebouncedValue(value, delayMs) {
|
|
7327
|
+
const [debounced, setDebounced] = useState(value);
|
|
7328
|
+
useEffect(() => {
|
|
7329
|
+
const id = window.setTimeout(() => setDebounced(value), delayMs);
|
|
7330
|
+
return () => window.clearTimeout(id);
|
|
7331
|
+
}, [value, delayMs]);
|
|
7332
|
+
return debounced;
|
|
7333
|
+
}
|
|
7334
|
+
function useDebouncedValueStrict(value, delayMs) {
|
|
7335
|
+
const [debounced, setDebounced] = useState(void 0);
|
|
7336
|
+
useEffect(() => {
|
|
7337
|
+
setDebounced(void 0);
|
|
7338
|
+
const id = window.setTimeout(() => setDebounced(value), delayMs);
|
|
7339
|
+
return () => window.clearTimeout(id);
|
|
7340
|
+
}, [value, delayMs]);
|
|
7341
|
+
return debounced;
|
|
7342
|
+
}
|
|
7343
|
+
function onlyDigits(s, max) {
|
|
7344
|
+
return s.replace(/\D/g, "").slice(0, max);
|
|
7345
|
+
}
|
|
7346
|
+
function formatPan(digits) {
|
|
7347
|
+
const cardInfo = valid.number(digits).card;
|
|
7348
|
+
const gaps = cardInfo?.gaps ?? [4, 8, 12];
|
|
7349
|
+
const parts = [];
|
|
7350
|
+
let idx = 0;
|
|
7351
|
+
for (const g of gaps) {
|
|
7352
|
+
parts.push(digits.slice(idx, g));
|
|
7353
|
+
idx = g;
|
|
7354
|
+
}
|
|
7355
|
+
parts.push(digits.slice(idx));
|
|
7356
|
+
return parts.filter((p) => p.length > 0).join(" ");
|
|
7357
|
+
}
|
|
7358
|
+
function parseExpiry(raw) {
|
|
7359
|
+
const d = onlyDigits(raw, 4);
|
|
7360
|
+
if (d.length < 4) return null;
|
|
7361
|
+
const mm = Number.parseInt(d.slice(0, 2), 10);
|
|
7362
|
+
const yy = Number.parseInt(d.slice(2, 4), 10);
|
|
7363
|
+
if (mm < 1 || mm > 12) return null;
|
|
7364
|
+
const year = yy < 100 ? 2e3 + yy : yy;
|
|
7365
|
+
const exp = valid.expirationDate({ month: String(mm), year: String(year) });
|
|
7366
|
+
if (!exp.isValid) return null;
|
|
7367
|
+
return { month: mm, year };
|
|
7368
|
+
}
|
|
7369
|
+
function normalizeBrand(detected) {
|
|
7370
|
+
if (!detected) return "";
|
|
7371
|
+
if (detected === "american-express") return "amex";
|
|
7372
|
+
return detected;
|
|
7373
|
+
}
|
|
7374
|
+
function brandAllowed(detected, accepted) {
|
|
7375
|
+
if (!accepted?.length) return true;
|
|
7376
|
+
if (!detected) return true;
|
|
7377
|
+
const n = normalizeBrand(detected);
|
|
7378
|
+
return accepted.map((a) => a.toLowerCase()).includes(n.toLowerCase());
|
|
7379
|
+
}
|
|
7380
|
+
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";
|
|
7381
|
+
function CardInput({
|
|
7382
|
+
tokenize,
|
|
7383
|
+
value,
|
|
7384
|
+
onChange,
|
|
7385
|
+
acceptedBrands,
|
|
7386
|
+
requireHolderName = false,
|
|
7387
|
+
labels,
|
|
7388
|
+
disabled = false,
|
|
7389
|
+
largeText = false,
|
|
7390
|
+
className,
|
|
7391
|
+
onError
|
|
7392
|
+
}) {
|
|
7393
|
+
const baseId = useId();
|
|
7394
|
+
const [panDigits, setPanDigits] = useState("");
|
|
7395
|
+
const [expiryRaw, setExpiryRaw] = useState("");
|
|
7396
|
+
const [cvc, setCvc] = useState("");
|
|
7397
|
+
const [holderName, setHolderName] = useState("");
|
|
7398
|
+
const [panFocused, setPanFocused] = useState(false);
|
|
7399
|
+
const [submitting, setSubmitting] = useState(false);
|
|
7400
|
+
const inputClass = largeText ? "text-base py-3" : "";
|
|
7401
|
+
const labelClass = largeText ? "text-base" : "text-sm";
|
|
7402
|
+
const numberValidation = valid.number(panDigits);
|
|
7403
|
+
const rawBrand = numberValidation.card?.type;
|
|
7404
|
+
const brand = normalizeBrand(rawBrand) || "unknown";
|
|
7405
|
+
const maxPanLen = numberValidation.card?.lengths?.slice(-1)[0] ?? 19;
|
|
7406
|
+
const minPanLenForType = numberValidation.card?.lengths?.[0];
|
|
7407
|
+
const panPastMinimumLength = minPanLenForType !== void 0 && panDigits.length >= minPanLenForType;
|
|
7408
|
+
const cvcSize = rawBrand === "american-express" || brand === "amex" ? 4 : 3;
|
|
7409
|
+
const expiryParsed = parseExpiry(expiryRaw);
|
|
7410
|
+
const expiryValid = expiryRaw.replace(/\D/g, "").length >= 4 && expiryParsed !== null ? valid.expirationDate({
|
|
7411
|
+
month: String(expiryParsed.month),
|
|
7412
|
+
year: String(expiryParsed.year)
|
|
7413
|
+
}).isValid : false;
|
|
7414
|
+
const cvvValid = cvc.length >= cvcSize && valid.cvv(cvc, cvcSize).isValid;
|
|
7415
|
+
const panComplete = numberValidation.isValid && brandAllowed(rawBrand, acceptedBrands);
|
|
7416
|
+
const holderOk = !requireHolderName || holderName.trim().length > 1;
|
|
7417
|
+
const canSubmit = panComplete && expiryValid && cvvValid && holderOk && !disabled && !value;
|
|
7418
|
+
const handlePanChange = (e) => {
|
|
7419
|
+
const d = onlyDigits(e.target.value, maxPanLen);
|
|
7420
|
+
setPanDigits(d);
|
|
7421
|
+
};
|
|
7422
|
+
const handleExpiryChange = (e) => {
|
|
7423
|
+
let d = onlyDigits(e.target.value, 4);
|
|
7424
|
+
if (d.length >= 2) d = `${d.slice(0, 2)}/${d.slice(2)}`;
|
|
7425
|
+
setExpiryRaw(d);
|
|
7426
|
+
};
|
|
7427
|
+
const runTokenize = useCallback(async () => {
|
|
7428
|
+
if (!expiryParsed) return;
|
|
7429
|
+
setSubmitting(true);
|
|
7430
|
+
try {
|
|
7431
|
+
const result = await tokenize({
|
|
7432
|
+
pan: panDigits,
|
|
7433
|
+
expMonth: expiryParsed.month,
|
|
7434
|
+
expYear: expiryParsed.year,
|
|
7435
|
+
cvc,
|
|
7436
|
+
holderName: holderName.trim() || void 0
|
|
7437
|
+
});
|
|
7438
|
+
onChange(result);
|
|
7439
|
+
setPanDigits("");
|
|
7440
|
+
setExpiryRaw("");
|
|
7441
|
+
setCvc("");
|
|
7442
|
+
setHolderName("");
|
|
7443
|
+
} catch (err) {
|
|
7444
|
+
const msg = err instanceof Error ? err.message : labels.tokenizeFailed;
|
|
7445
|
+
onError?.(msg);
|
|
7446
|
+
} finally {
|
|
7447
|
+
setSubmitting(false);
|
|
7448
|
+
}
|
|
7449
|
+
}, [
|
|
7450
|
+
cvc,
|
|
7451
|
+
expiryParsed,
|
|
7452
|
+
holderName,
|
|
7453
|
+
labels.tokenizeFailed,
|
|
7454
|
+
onChange,
|
|
7455
|
+
onError,
|
|
7456
|
+
panDigits,
|
|
7457
|
+
tokenize
|
|
7458
|
+
]);
|
|
7459
|
+
const displayPan = panFocused || panDigits.length <= 4 ? formatPan(panDigits) : `\u2022\u2022\u2022\u2022 \u2022\u2022\u2022\u2022 \u2022\u2022\u2022\u2022 ${panDigits.slice(-4)}`;
|
|
7460
|
+
if (value?.tokenId) {
|
|
7461
|
+
return /* @__PURE__ */ jsxs(
|
|
7462
|
+
"div",
|
|
7463
|
+
{
|
|
7464
|
+
className: cn("space-y-3 rounded-lg border bg-muted/30 p-4", className),
|
|
7465
|
+
children: [
|
|
7466
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-sm", children: [
|
|
7467
|
+
/* @__PURE__ */ jsx(CreditCard, { className: "h-4 w-4 text-muted-foreground" }),
|
|
7468
|
+
/* @__PURE__ */ jsx("span", { className: "font-medium", children: value.masked }),
|
|
7469
|
+
/* @__PURE__ */ jsxs("span", { className: "text-muted-foreground", children: [
|
|
7470
|
+
String(value.expMonth).padStart(2, "0"),
|
|
7471
|
+
"/",
|
|
7472
|
+
String(value.expYear).slice(-2)
|
|
7473
|
+
] })
|
|
7474
|
+
] }),
|
|
7475
|
+
value.holderName ? /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: value.holderName }) : null,
|
|
7476
|
+
/* @__PURE__ */ jsx(
|
|
7477
|
+
Button,
|
|
7478
|
+
{
|
|
7479
|
+
type: "button",
|
|
7480
|
+
variant: "outline",
|
|
7481
|
+
size: "sm",
|
|
7482
|
+
disabled,
|
|
7483
|
+
onClick: () => onChange(null),
|
|
7484
|
+
children: labels.replace
|
|
7485
|
+
}
|
|
7486
|
+
)
|
|
7487
|
+
]
|
|
7488
|
+
}
|
|
7489
|
+
);
|
|
7490
|
+
}
|
|
7491
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("space-y-4 rounded-lg border bg-card p-4", className), children: [
|
|
7492
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-1.5", children: [
|
|
7493
|
+
/* @__PURE__ */ jsx(
|
|
7494
|
+
"label",
|
|
7495
|
+
{
|
|
7496
|
+
htmlFor: `${baseId}-pan`,
|
|
7497
|
+
className: cn("font-medium leading-none", labelClass),
|
|
7498
|
+
children: labels.number
|
|
7499
|
+
}
|
|
7500
|
+
),
|
|
7501
|
+
/* @__PURE__ */ jsx(
|
|
7502
|
+
"input",
|
|
7503
|
+
{
|
|
7504
|
+
id: `${baseId}-pan`,
|
|
7505
|
+
inputMode: "numeric",
|
|
7506
|
+
autoComplete: "cc-number",
|
|
7507
|
+
value: displayPan,
|
|
7508
|
+
onChange: handlePanChange,
|
|
7509
|
+
onFocus: () => setPanFocused(true),
|
|
7510
|
+
onBlur: () => setPanFocused(false),
|
|
7511
|
+
placeholder: "4242 4242 4242 4242",
|
|
7512
|
+
disabled,
|
|
7513
|
+
className: cn(inputClassName, inputClass)
|
|
7514
|
+
}
|
|
7515
|
+
),
|
|
7516
|
+
panDigits.length > 0 && (!numberValidation.isPotentiallyValid || panPastMinimumLength && !numberValidation.isValid) && /* @__PURE__ */ jsx("p", { className: "text-xs text-destructive", children: labels.invalidNumber }),
|
|
7517
|
+
panDigits.length > 0 && numberValidation.isPotentiallyValid && !brandAllowed(rawBrand, acceptedBrands) && /* @__PURE__ */ jsx("p", { className: "text-xs text-destructive", children: labels.invalidNumber })
|
|
7518
|
+
] }),
|
|
7519
|
+
requireHolderName && /* @__PURE__ */ jsxs("div", { className: "space-y-1.5", children: [
|
|
7520
|
+
/* @__PURE__ */ jsx(
|
|
7521
|
+
"label",
|
|
7522
|
+
{
|
|
7523
|
+
htmlFor: `${baseId}-holder`,
|
|
7524
|
+
className: cn("font-medium leading-none", labelClass),
|
|
7525
|
+
children: labels.holderName
|
|
7526
|
+
}
|
|
7527
|
+
),
|
|
7528
|
+
/* @__PURE__ */ jsx(
|
|
7529
|
+
"input",
|
|
7530
|
+
{
|
|
7531
|
+
id: `${baseId}-holder`,
|
|
7532
|
+
autoComplete: "cc-name",
|
|
7533
|
+
value: holderName,
|
|
7534
|
+
onChange: (e) => setHolderName(e.target.value),
|
|
7535
|
+
disabled,
|
|
7536
|
+
className: cn(inputClassName, inputClass)
|
|
7537
|
+
}
|
|
7538
|
+
)
|
|
7539
|
+
] }),
|
|
7540
|
+
/* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 gap-4 sm:grid-cols-2", children: [
|
|
7541
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-1.5", children: [
|
|
7542
|
+
/* @__PURE__ */ jsx(
|
|
7543
|
+
"label",
|
|
7544
|
+
{
|
|
7545
|
+
htmlFor: `${baseId}-exp`,
|
|
7546
|
+
className: cn("font-medium leading-none", labelClass),
|
|
7547
|
+
children: labels.expiry
|
|
7548
|
+
}
|
|
7549
|
+
),
|
|
7550
|
+
/* @__PURE__ */ jsx(
|
|
7551
|
+
"input",
|
|
7552
|
+
{
|
|
7553
|
+
id: `${baseId}-exp`,
|
|
7554
|
+
inputMode: "numeric",
|
|
7555
|
+
autoComplete: "cc-exp",
|
|
7556
|
+
value: expiryRaw,
|
|
7557
|
+
onChange: handleExpiryChange,
|
|
7558
|
+
placeholder: "MM/YY",
|
|
7559
|
+
disabled,
|
|
7560
|
+
className: cn(inputClassName, inputClass)
|
|
7561
|
+
}
|
|
7562
|
+
),
|
|
7563
|
+
expiryRaw.replace(/\D/g, "").length >= 4 && !expiryValid && /* @__PURE__ */ jsx("p", { className: "text-xs text-destructive", children: labels.expiredCard })
|
|
7564
|
+
] }),
|
|
7565
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-1.5", children: [
|
|
7566
|
+
/* @__PURE__ */ jsx(
|
|
7567
|
+
"label",
|
|
7568
|
+
{
|
|
7569
|
+
htmlFor: `${baseId}-cvc`,
|
|
7570
|
+
className: cn("font-medium leading-none", labelClass),
|
|
7571
|
+
children: labels.cvc
|
|
7572
|
+
}
|
|
7573
|
+
),
|
|
7574
|
+
/* @__PURE__ */ jsx(
|
|
7575
|
+
"input",
|
|
7576
|
+
{
|
|
7577
|
+
id: `${baseId}-cvc`,
|
|
7578
|
+
inputMode: "numeric",
|
|
7579
|
+
autoComplete: "cc-csc",
|
|
7580
|
+
value: cvc,
|
|
7581
|
+
onChange: (e) => setCvc(onlyDigits(e.target.value, cvcSize)),
|
|
7582
|
+
placeholder: cvcSize === 4 ? "0000" : "000",
|
|
7583
|
+
disabled,
|
|
7584
|
+
className: cn(inputClassName, inputClass),
|
|
7585
|
+
maxLength: cvcSize
|
|
7586
|
+
}
|
|
7587
|
+
),
|
|
7588
|
+
cvc.length > 0 && !cvvValid && /* @__PURE__ */ jsx("p", { className: "text-xs text-destructive", children: labels.invalidCvc })
|
|
7589
|
+
] })
|
|
7590
|
+
] }),
|
|
7591
|
+
/* @__PURE__ */ jsxs(
|
|
7592
|
+
Button,
|
|
7593
|
+
{
|
|
7594
|
+
type: "button",
|
|
7595
|
+
disabled: !canSubmit || submitting,
|
|
7596
|
+
onClick: () => void runTokenize(),
|
|
7597
|
+
className: "gap-2",
|
|
7598
|
+
children: [
|
|
7599
|
+
submitting ? /* @__PURE__ */ jsx(Loader2, { className: "h-4 w-4 animate-spin" }) : /* @__PURE__ */ jsx(CreditCard, { className: "h-4 w-4" }),
|
|
7600
|
+
labels.tokenize
|
|
7601
|
+
]
|
|
7602
|
+
}
|
|
7603
|
+
)
|
|
7604
|
+
] });
|
|
7605
|
+
}
|
|
7606
|
+
function parseInitial(value) {
|
|
7607
|
+
if (!value) {
|
|
7608
|
+
return {
|
|
7609
|
+
street: "",
|
|
7610
|
+
street2: "",
|
|
7611
|
+
city: "",
|
|
7612
|
+
state: "",
|
|
7613
|
+
zip: "",
|
|
7614
|
+
country: "US"
|
|
7615
|
+
};
|
|
7616
|
+
}
|
|
7617
|
+
return {
|
|
7618
|
+
street: value.street ?? "",
|
|
7619
|
+
street2: value.street2 ?? "",
|
|
7620
|
+
city: value.city ?? "",
|
|
7621
|
+
state: value.state ?? "",
|
|
7622
|
+
zip: value.zip ?? "",
|
|
7623
|
+
country: "US"
|
|
7624
|
+
};
|
|
7625
|
+
}
|
|
7626
|
+
function addressSig(a) {
|
|
7627
|
+
return JSON.stringify({
|
|
7628
|
+
street: a.street.trim(),
|
|
7629
|
+
street2: (a.street2 ?? "").trim(),
|
|
7630
|
+
city: a.city.trim(),
|
|
7631
|
+
state: a.state.trim().toUpperCase(),
|
|
7632
|
+
zip: a.zip.replace(/\D/g, "").slice(0, 5)
|
|
7633
|
+
});
|
|
7634
|
+
}
|
|
7635
|
+
function isAddressComplete(a) {
|
|
7636
|
+
const zip5 = a.zip.replace(/\D/g, "").slice(0, 5);
|
|
7637
|
+
const st = a.state.trim();
|
|
7638
|
+
return a.street.trim().length > 0 && a.city.trim().length > 0 && /^[A-Za-z]{2}$/.test(st) && zip5.length === 5;
|
|
7639
|
+
}
|
|
7640
|
+
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";
|
|
7641
|
+
function USAddressInput({
|
|
7642
|
+
value,
|
|
7643
|
+
onChange,
|
|
7644
|
+
lookupZip,
|
|
7645
|
+
validateAddress,
|
|
7646
|
+
autocomplete,
|
|
7647
|
+
labels,
|
|
7648
|
+
disabled = false,
|
|
7649
|
+
largeText = false,
|
|
7650
|
+
className,
|
|
7651
|
+
onError
|
|
7652
|
+
}) {
|
|
7653
|
+
const [searchQuery, setSearchQuery] = useState("");
|
|
7654
|
+
const [showSuggestions, setShowSuggestions] = useState(false);
|
|
7655
|
+
const [suggestions, setSuggestions] = useState([]);
|
|
7656
|
+
const [address, setAddress] = useState(
|
|
7657
|
+
() => parseInitial(value)
|
|
7658
|
+
);
|
|
7659
|
+
const [sessionToken] = useState(
|
|
7660
|
+
() => typeof crypto !== "undefined" && crypto.randomUUID ? crypto.randomUUID() : `${Date.now()}-${Math.random()}`
|
|
7661
|
+
);
|
|
7662
|
+
const [loadingAutocomplete, setLoadingAutocomplete] = useState(false);
|
|
7663
|
+
const [loadingZip, setLoadingZip] = useState(false);
|
|
7664
|
+
const [loadingValidate, setLoadingValidate] = useState(false);
|
|
7665
|
+
const [uspsSuggestion, setUspsSuggestion] = useState(
|
|
7666
|
+
null
|
|
7667
|
+
);
|
|
7668
|
+
const [uspsVerifiedNoChange, setUspsVerifiedNoChange] = useState(false);
|
|
7669
|
+
const searchRef = useRef(null);
|
|
7670
|
+
const suggestionCache = useRef(/* @__PURE__ */ new Map());
|
|
7671
|
+
const warnedRef = useRef({
|
|
7672
|
+
autocomplete: false,
|
|
7673
|
+
zip: false,
|
|
7674
|
+
validate: false
|
|
7675
|
+
});
|
|
7676
|
+
const lastZipLookup = useRef("");
|
|
7677
|
+
const addressRef = useRef(address);
|
|
7678
|
+
addressRef.current = address;
|
|
7679
|
+
const lastValidatedSigRef = useRef("");
|
|
7680
|
+
const debouncedSearch = useDebouncedValue(searchQuery, 400);
|
|
7681
|
+
const zipDigits = address.zip.replace(/\D/g, "").slice(0, 5);
|
|
7682
|
+
const debouncedZip = useDebouncedValue(zipDigits, 400);
|
|
7683
|
+
const debouncedAddressForValidate = useDebouncedValueStrict(address, 1200);
|
|
7684
|
+
const inputClass = largeText ? "text-base py-3" : "";
|
|
7685
|
+
const labelClass = largeText ? "text-base" : "text-sm";
|
|
7686
|
+
useEffect(() => {
|
|
7687
|
+
const handleClickOutside = (event) => {
|
|
7688
|
+
if (searchRef.current && !searchRef.current.contains(event.target)) {
|
|
7689
|
+
setShowSuggestions(false);
|
|
7690
|
+
}
|
|
7691
|
+
};
|
|
7692
|
+
document.addEventListener("mousedown", handleClickOutside);
|
|
7693
|
+
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
7694
|
+
}, []);
|
|
7695
|
+
const valueSyncKey = value == null ? "" : `o:${JSON.stringify(value)}`;
|
|
7696
|
+
useEffect(() => {
|
|
7697
|
+
setAddress(parseInitial(value));
|
|
7698
|
+
}, [valueSyncKey]);
|
|
7699
|
+
const handleFieldChange = (field, fieldValue) => {
|
|
7700
|
+
setAddress((prev) => {
|
|
7701
|
+
const next = field === "country" ? { ...prev, country: "US" } : { ...prev, [field]: fieldValue };
|
|
7702
|
+
onChange(next);
|
|
7703
|
+
return next;
|
|
7704
|
+
});
|
|
7705
|
+
};
|
|
7706
|
+
useEffect(() => {
|
|
7707
|
+
const sig = addressSig(addressRef.current);
|
|
7708
|
+
if (sig !== lastValidatedSigRef.current) {
|
|
7709
|
+
setUspsVerifiedNoChange(false);
|
|
7710
|
+
setUspsSuggestion(null);
|
|
7711
|
+
}
|
|
7712
|
+
}, [address]);
|
|
7713
|
+
const allowAutocomplete = Boolean(autocomplete);
|
|
7714
|
+
const allowUspsValidation = Boolean(validateAddress);
|
|
7715
|
+
const allowZipLookup = Boolean(lookupZip);
|
|
7716
|
+
useEffect(() => {
|
|
7717
|
+
if (!allowAutocomplete || !autocomplete) return;
|
|
7718
|
+
const q = debouncedSearch.trim();
|
|
7719
|
+
if (q.length < 3) {
|
|
7720
|
+
setSuggestions([]);
|
|
7721
|
+
setShowSuggestions(false);
|
|
7722
|
+
setLoadingAutocomplete(false);
|
|
7723
|
+
return;
|
|
7724
|
+
}
|
|
7725
|
+
const cacheKey = q.toLowerCase();
|
|
7726
|
+
const cached = suggestionCache.current.get(cacheKey);
|
|
7727
|
+
if (cached) {
|
|
7728
|
+
setSuggestions(cached);
|
|
7729
|
+
setShowSuggestions(true);
|
|
7730
|
+
setLoadingAutocomplete(false);
|
|
7731
|
+
return;
|
|
7732
|
+
}
|
|
7733
|
+
const ctrl = new AbortController();
|
|
7734
|
+
setLoadingAutocomplete(true);
|
|
7735
|
+
autocomplete.search(q, sessionToken, ctrl.signal).then((list) => {
|
|
7736
|
+
if (ctrl.signal.aborted) return;
|
|
7737
|
+
suggestionCache.current.set(cacheKey, list);
|
|
7738
|
+
setSuggestions(list);
|
|
7739
|
+
setShowSuggestions(list.length > 0);
|
|
7740
|
+
}).catch((e) => {
|
|
7741
|
+
if (e.name === "AbortError") return;
|
|
7742
|
+
if (!warnedRef.current.autocomplete) {
|
|
7743
|
+
onError?.(labels.autocompleteUnavailable);
|
|
7744
|
+
warnedRef.current.autocomplete = true;
|
|
7745
|
+
}
|
|
7746
|
+
setSuggestions([]);
|
|
7747
|
+
setShowSuggestions(false);
|
|
7748
|
+
}).finally(() => setLoadingAutocomplete(false));
|
|
7749
|
+
return () => ctrl.abort();
|
|
7750
|
+
}, [
|
|
7751
|
+
debouncedSearch,
|
|
7752
|
+
allowAutocomplete,
|
|
7753
|
+
autocomplete,
|
|
7754
|
+
sessionToken,
|
|
7755
|
+
labels.autocompleteUnavailable,
|
|
7756
|
+
onError
|
|
7757
|
+
]);
|
|
7758
|
+
useEffect(() => {
|
|
7759
|
+
if (!allowZipLookup || !lookupZip) return;
|
|
7760
|
+
if (debouncedZip.length !== 5) return;
|
|
7761
|
+
if (debouncedZip === lastZipLookup.current) return;
|
|
7762
|
+
const ctrl = new AbortController();
|
|
7763
|
+
setLoadingZip(true);
|
|
7764
|
+
lookupZip(debouncedZip, ctrl.signal).then((data) => {
|
|
7765
|
+
if (ctrl.signal.aborted) return;
|
|
7766
|
+
lastZipLookup.current = debouncedZip;
|
|
7767
|
+
setAddress((prev) => {
|
|
7768
|
+
const cityEmpty = !prev.city.trim();
|
|
7769
|
+
const stateEmpty = !prev.state.trim();
|
|
7770
|
+
const next = { ...prev };
|
|
7771
|
+
if (cityEmpty && data.city) next.city = data.city;
|
|
7772
|
+
if (stateEmpty && data.state) next.state = data.state;
|
|
7773
|
+
next.country = "US";
|
|
7774
|
+
onChange(next);
|
|
7775
|
+
return next;
|
|
7776
|
+
});
|
|
7777
|
+
}).catch(() => {
|
|
7778
|
+
if (!warnedRef.current.zip) {
|
|
7779
|
+
onError?.(labels.zipLookupFailed);
|
|
7780
|
+
warnedRef.current.zip = true;
|
|
7781
|
+
}
|
|
7782
|
+
}).finally(() => setLoadingZip(false));
|
|
7783
|
+
return () => ctrl.abort();
|
|
7784
|
+
}, [
|
|
7785
|
+
debouncedZip,
|
|
7786
|
+
allowZipLookup,
|
|
7787
|
+
lookupZip,
|
|
7788
|
+
onChange,
|
|
7789
|
+
labels.zipLookupFailed,
|
|
7790
|
+
onError
|
|
7791
|
+
]);
|
|
7792
|
+
useEffect(() => {
|
|
7793
|
+
if (!allowUspsValidation || !validateAddress || disabled) return;
|
|
7794
|
+
if (debouncedAddressForValidate === void 0) return;
|
|
7795
|
+
const addr = debouncedAddressForValidate;
|
|
7796
|
+
if (!isAddressComplete(addr)) return;
|
|
7797
|
+
const requestSig = addressSig(addr);
|
|
7798
|
+
if (requestSig === lastValidatedSigRef.current) return;
|
|
7799
|
+
const ctrl = new AbortController();
|
|
7800
|
+
const timeoutId = window.setTimeout(() => ctrl.abort(), 8e3);
|
|
7801
|
+
setLoadingValidate(true);
|
|
7802
|
+
setUspsVerifiedNoChange(false);
|
|
7803
|
+
setUspsSuggestion(null);
|
|
7804
|
+
validateAddress(addr, ctrl.signal).then((result) => {
|
|
7805
|
+
if (ctrl.signal.aborted) return;
|
|
7806
|
+
if (addressSig(addressRef.current) !== requestSig) return;
|
|
7807
|
+
lastValidatedSigRef.current = requestSig;
|
|
7808
|
+
const std = result.standardized;
|
|
7809
|
+
if (result.changed) {
|
|
7810
|
+
setUspsSuggestion(std);
|
|
7811
|
+
setUspsVerifiedNoChange(false);
|
|
7812
|
+
} else {
|
|
7813
|
+
setUspsSuggestion(null);
|
|
7814
|
+
setUspsVerifiedNoChange(true);
|
|
7815
|
+
}
|
|
7816
|
+
}).catch(() => {
|
|
7817
|
+
if (ctrl.signal.aborted) return;
|
|
7818
|
+
if (!warnedRef.current.validate) {
|
|
7819
|
+
onError?.(labels.uspsUnavailable);
|
|
7820
|
+
warnedRef.current.validate = true;
|
|
7821
|
+
}
|
|
7822
|
+
}).finally(() => {
|
|
7823
|
+
window.clearTimeout(timeoutId);
|
|
7824
|
+
setLoadingValidate(false);
|
|
7825
|
+
});
|
|
7826
|
+
return () => {
|
|
7827
|
+
window.clearTimeout(timeoutId);
|
|
7828
|
+
ctrl.abort();
|
|
7829
|
+
};
|
|
7830
|
+
}, [
|
|
7831
|
+
debouncedAddressForValidate,
|
|
7832
|
+
allowUspsValidation,
|
|
7833
|
+
validateAddress,
|
|
7834
|
+
disabled,
|
|
7835
|
+
labels.uspsUnavailable,
|
|
7836
|
+
onError
|
|
7837
|
+
]);
|
|
7838
|
+
const handleSelectSuggestion = async (row) => {
|
|
7839
|
+
if (!autocomplete) return;
|
|
7840
|
+
try {
|
|
7841
|
+
const next = await autocomplete.details(
|
|
7842
|
+
row.placeId,
|
|
7843
|
+
AbortSignal.timeout(8e3)
|
|
7844
|
+
);
|
|
7845
|
+
const normalized = {
|
|
7846
|
+
...next,
|
|
7847
|
+
country: "US"
|
|
7848
|
+
};
|
|
7849
|
+
setAddress(normalized);
|
|
7850
|
+
onChange(normalized);
|
|
7851
|
+
setShowSuggestions(false);
|
|
7852
|
+
setSearchQuery("");
|
|
7853
|
+
setUspsSuggestion(null);
|
|
7854
|
+
lastValidatedSigRef.current = "";
|
|
7855
|
+
setUspsVerifiedNoChange(false);
|
|
7856
|
+
} catch {
|
|
7857
|
+
onError?.(labels.placeLookupFailed);
|
|
7858
|
+
}
|
|
7859
|
+
};
|
|
7860
|
+
const applyUspsSuggestion = () => {
|
|
7861
|
+
if (!uspsSuggestion) return;
|
|
7862
|
+
setAddress(uspsSuggestion);
|
|
7863
|
+
onChange(uspsSuggestion);
|
|
7864
|
+
setUspsSuggestion(null);
|
|
7865
|
+
lastValidatedSigRef.current = addressSig(uspsSuggestion);
|
|
7866
|
+
setUspsVerifiedNoChange(true);
|
|
7867
|
+
};
|
|
7868
|
+
const dismissUspsSuggestion = () => {
|
|
7869
|
+
setUspsSuggestion(null);
|
|
7870
|
+
lastValidatedSigRef.current = addressSig(addressRef.current);
|
|
7871
|
+
setUspsVerifiedNoChange(true);
|
|
7872
|
+
};
|
|
7873
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("space-y-4", className), children: [
|
|
7874
|
+
allowAutocomplete && autocomplete && /* @__PURE__ */ jsxs("div", { ref: searchRef, className: "relative", children: [
|
|
7875
|
+
/* @__PURE__ */ jsxs("div", { className: "relative", children: [
|
|
7876
|
+
/* @__PURE__ */ jsx(Search, { className: "absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" }),
|
|
7877
|
+
/* @__PURE__ */ jsx(
|
|
7878
|
+
"input",
|
|
7879
|
+
{
|
|
7880
|
+
value: searchQuery,
|
|
7881
|
+
onChange: (e) => setSearchQuery(e.target.value),
|
|
7882
|
+
placeholder: labels.searchPlaceholder,
|
|
7883
|
+
disabled,
|
|
7884
|
+
className: cn(inputClassName2, "pl-9 pr-9", inputClass),
|
|
7885
|
+
"aria-label": labels.searchPlaceholder
|
|
7886
|
+
}
|
|
7887
|
+
),
|
|
7888
|
+
loadingAutocomplete && /* @__PURE__ */ jsx(Loader2, { className: "absolute right-10 top-1/2 h-4 w-4 -translate-y-1/2 animate-spin text-muted-foreground" }),
|
|
7889
|
+
searchQuery ? /* @__PURE__ */ jsx(
|
|
7890
|
+
"button",
|
|
7891
|
+
{
|
|
7892
|
+
type: "button",
|
|
7893
|
+
onClick: () => setSearchQuery(""),
|
|
7894
|
+
className: "absolute right-3 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground",
|
|
7895
|
+
children: /* @__PURE__ */ jsx(X, { className: "h-4 w-4" })
|
|
7896
|
+
}
|
|
7897
|
+
) : null
|
|
7898
|
+
] }),
|
|
7899
|
+
showSuggestions && suggestions.length > 0 && /* @__PURE__ */ 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__ */ jsxs(
|
|
7900
|
+
"button",
|
|
7901
|
+
{
|
|
7902
|
+
type: "button",
|
|
7903
|
+
onClick: () => void handleSelectSuggestion(suggestion),
|
|
7904
|
+
className: "w-full border-b px-4 py-3 text-left transition-colors last:border-b-0 hover:bg-muted",
|
|
7905
|
+
children: [
|
|
7906
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm font-medium", children: suggestion.mainText }),
|
|
7907
|
+
/* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: suggestion.secondaryText })
|
|
7908
|
+
]
|
|
7909
|
+
},
|
|
7910
|
+
suggestion.placeId
|
|
7911
|
+
)) })
|
|
7912
|
+
] }),
|
|
7913
|
+
/* @__PURE__ */ jsxs("div", { className: "grid gap-4", children: [
|
|
7914
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-1.5", children: [
|
|
7915
|
+
/* @__PURE__ */ jsx(
|
|
7916
|
+
"label",
|
|
7917
|
+
{
|
|
7918
|
+
htmlFor: "blocks-usaddress-street",
|
|
7919
|
+
className: cn("font-medium leading-none", labelClass),
|
|
7920
|
+
children: labels.street
|
|
7921
|
+
}
|
|
7922
|
+
),
|
|
7923
|
+
/* @__PURE__ */ jsx(
|
|
7924
|
+
"input",
|
|
7925
|
+
{
|
|
7926
|
+
id: "blocks-usaddress-street",
|
|
7927
|
+
value: address.street,
|
|
7928
|
+
onChange: (e) => handleFieldChange("street", e.target.value),
|
|
7929
|
+
placeholder: labels.streetPlaceholder ?? "",
|
|
7930
|
+
disabled,
|
|
7931
|
+
className: cn(inputClassName2, inputClass)
|
|
7932
|
+
}
|
|
7933
|
+
)
|
|
7934
|
+
] }),
|
|
7935
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-1.5", children: [
|
|
7936
|
+
/* @__PURE__ */ jsxs(
|
|
7937
|
+
"label",
|
|
7938
|
+
{
|
|
7939
|
+
htmlFor: "blocks-usaddress-street2",
|
|
7940
|
+
className: cn(
|
|
7941
|
+
`${labelClass} text-muted-foreground`,
|
|
7942
|
+
"leading-none"
|
|
7943
|
+
),
|
|
7944
|
+
children: [
|
|
7945
|
+
labels.street2 ?? "Address line 2",
|
|
7946
|
+
" ",
|
|
7947
|
+
labels.street2OptionalHint ? /* @__PURE__ */ jsxs("span", { className: "text-xs", children: [
|
|
7948
|
+
"(",
|
|
7949
|
+
labels.street2OptionalHint,
|
|
7950
|
+
")"
|
|
7951
|
+
] }) : null
|
|
7952
|
+
]
|
|
7953
|
+
}
|
|
7954
|
+
),
|
|
7955
|
+
/* @__PURE__ */ jsx(
|
|
7956
|
+
"input",
|
|
7957
|
+
{
|
|
7958
|
+
id: "blocks-usaddress-street2",
|
|
7959
|
+
value: address.street2 || "",
|
|
7960
|
+
onChange: (e) => handleFieldChange("street2", e.target.value),
|
|
7961
|
+
placeholder: labels.street2Placeholder ?? "",
|
|
7962
|
+
disabled,
|
|
7963
|
+
className: cn(inputClassName2, inputClass)
|
|
7964
|
+
}
|
|
7965
|
+
)
|
|
7966
|
+
] }),
|
|
7967
|
+
/* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 gap-4 sm:grid-cols-2", children: [
|
|
7968
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-1.5", children: [
|
|
7969
|
+
/* @__PURE__ */ jsx(
|
|
7970
|
+
"label",
|
|
7971
|
+
{
|
|
7972
|
+
htmlFor: "blocks-usaddress-city",
|
|
7973
|
+
className: cn("font-medium leading-none", labelClass),
|
|
7974
|
+
children: labels.city
|
|
7975
|
+
}
|
|
7976
|
+
),
|
|
7977
|
+
/* @__PURE__ */ jsx(
|
|
7978
|
+
"input",
|
|
7979
|
+
{
|
|
7980
|
+
id: "blocks-usaddress-city",
|
|
7981
|
+
value: address.city,
|
|
7982
|
+
onChange: (e) => handleFieldChange("city", e.target.value),
|
|
7983
|
+
placeholder: labels.cityPlaceholder ?? "",
|
|
7984
|
+
disabled,
|
|
7985
|
+
className: cn(inputClassName2, inputClass)
|
|
7986
|
+
}
|
|
7987
|
+
)
|
|
7988
|
+
] }),
|
|
7989
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-1.5", children: [
|
|
7990
|
+
/* @__PURE__ */ jsx(
|
|
7991
|
+
"label",
|
|
7992
|
+
{
|
|
7993
|
+
htmlFor: "blocks-usaddress-state",
|
|
7994
|
+
className: cn("font-medium leading-none", labelClass),
|
|
7995
|
+
children: labels.state
|
|
7996
|
+
}
|
|
7997
|
+
),
|
|
7998
|
+
/* @__PURE__ */ jsx(
|
|
7999
|
+
"input",
|
|
8000
|
+
{
|
|
8001
|
+
id: "blocks-usaddress-state",
|
|
8002
|
+
value: address.state,
|
|
8003
|
+
onChange: (e) => handleFieldChange("state", e.target.value),
|
|
8004
|
+
placeholder: labels.statePlaceholder ?? "",
|
|
8005
|
+
disabled,
|
|
8006
|
+
className: cn(inputClassName2, inputClass)
|
|
8007
|
+
}
|
|
8008
|
+
)
|
|
8009
|
+
] })
|
|
8010
|
+
] }),
|
|
8011
|
+
/* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 gap-4 sm:grid-cols-2", children: [
|
|
8012
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-1.5", children: [
|
|
8013
|
+
/* @__PURE__ */ jsx(
|
|
8014
|
+
"label",
|
|
8015
|
+
{
|
|
8016
|
+
htmlFor: "blocks-usaddress-zip",
|
|
8017
|
+
className: cn("font-medium leading-none", labelClass),
|
|
8018
|
+
children: labels.zip
|
|
8019
|
+
}
|
|
8020
|
+
),
|
|
8021
|
+
/* @__PURE__ */ jsxs("div", { className: "relative", children: [
|
|
8022
|
+
/* @__PURE__ */ jsx(
|
|
8023
|
+
"input",
|
|
8024
|
+
{
|
|
8025
|
+
id: "blocks-usaddress-zip",
|
|
8026
|
+
value: address.zip,
|
|
8027
|
+
onChange: (e) => handleFieldChange(
|
|
8028
|
+
"zip",
|
|
8029
|
+
e.target.value.replace(/\D/g, "").slice(0, 10)
|
|
8030
|
+
),
|
|
8031
|
+
placeholder: labels.zipPlaceholder ?? "",
|
|
8032
|
+
disabled,
|
|
8033
|
+
className: cn(inputClassName2, inputClass)
|
|
8034
|
+
}
|
|
8035
|
+
),
|
|
8036
|
+
loadingZip && /* @__PURE__ */ jsx(Loader2, { className: "absolute right-3 top-1/2 h-4 w-4 -translate-y-1/2 animate-spin text-muted-foreground" })
|
|
8037
|
+
] })
|
|
8038
|
+
] }),
|
|
8039
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-1.5", children: [
|
|
8040
|
+
/* @__PURE__ */ jsx(
|
|
8041
|
+
"label",
|
|
8042
|
+
{
|
|
8043
|
+
htmlFor: "blocks-usaddress-country",
|
|
8044
|
+
className: cn("font-medium leading-none", labelClass),
|
|
8045
|
+
children: labels.countryLabel ?? "Country"
|
|
8046
|
+
}
|
|
8047
|
+
),
|
|
8048
|
+
/* @__PURE__ */ jsx(
|
|
8049
|
+
"input",
|
|
8050
|
+
{
|
|
8051
|
+
id: "blocks-usaddress-country",
|
|
8052
|
+
value: "United States",
|
|
8053
|
+
readOnly: true,
|
|
8054
|
+
disabled,
|
|
8055
|
+
className: cn(inputClassName2, inputClass, "bg-muted/50"),
|
|
8056
|
+
"aria-readonly": "true"
|
|
8057
|
+
}
|
|
8058
|
+
)
|
|
8059
|
+
] })
|
|
8060
|
+
] })
|
|
8061
|
+
] }),
|
|
8062
|
+
allowUspsValidation && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
8063
|
+
/* @__PURE__ */ jsx(
|
|
8064
|
+
"div",
|
|
8065
|
+
{
|
|
8066
|
+
className: "flex min-h-7 items-center gap-2 text-xs text-muted-foreground",
|
|
8067
|
+
"aria-live": "polite",
|
|
8068
|
+
children: loadingValidate ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
8069
|
+
/* @__PURE__ */ jsx(Loader2, { className: "h-3.5 w-3.5 shrink-0 animate-spin" }),
|
|
8070
|
+
/* @__PURE__ */ jsx("span", { children: labels.uspsValidating })
|
|
8071
|
+
] }) : uspsVerifiedNoChange && !uspsSuggestion ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
8072
|
+
/* @__PURE__ */ jsx(CheckCircle2, { className: "h-3.5 w-3.5 shrink-0 text-emerald-600 dark:text-emerald-400" }),
|
|
8073
|
+
/* @__PURE__ */ jsx("span", { children: labels.uspsVerified })
|
|
8074
|
+
] }) : /* @__PURE__ */ jsx("span", { className: "select-none opacity-0", "aria-hidden": true, children: "\xA0" })
|
|
8075
|
+
}
|
|
8076
|
+
),
|
|
8077
|
+
uspsSuggestion ? /* @__PURE__ */ 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: [
|
|
8078
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-amber-900 dark:text-amber-100", children: labels.uspsSuggested }),
|
|
8079
|
+
/* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: [
|
|
8080
|
+
uspsSuggestion.street,
|
|
8081
|
+
uspsSuggestion.street2,
|
|
8082
|
+
uspsSuggestion.city,
|
|
8083
|
+
uspsSuggestion.state,
|
|
8084
|
+
uspsSuggestion.zip
|
|
8085
|
+
].filter(Boolean).join(", ") }),
|
|
8086
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap gap-2", children: [
|
|
8087
|
+
/* @__PURE__ */ jsx(Button, { type: "button", size: "sm", onClick: applyUspsSuggestion, children: labels.uspsUseSuggestion }),
|
|
8088
|
+
/* @__PURE__ */ jsx(
|
|
8089
|
+
Button,
|
|
8090
|
+
{
|
|
8091
|
+
type: "button",
|
|
8092
|
+
size: "sm",
|
|
8093
|
+
variant: "outline",
|
|
8094
|
+
onClick: dismissUspsSuggestion,
|
|
8095
|
+
children: labels.uspsKeepMine
|
|
8096
|
+
}
|
|
8097
|
+
)
|
|
8098
|
+
] })
|
|
8099
|
+
] }) : null
|
|
8100
|
+
] })
|
|
8101
|
+
] });
|
|
8102
|
+
}
|
|
7325
8103
|
|
|
7326
|
-
export { AvatarEditor, AvatarEditorDialog, BLOCKS_DATA_ENVIRONMENTS, Button, CalendarContext, CalendarSubscribeButton, CalendarView, CalendarWidget, ChatRoomView, ChatSidebar, ChatSidebarContext, ChatSidebarProvider, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, Drawer, DrawerClose, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerOverlay, DrawerPortal, DrawerTitle, DrawerTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, EnvironmentBanner, EnvironmentContext, EnvironmentDot, EnvironmentMiniBadge, EnvironmentSwitcher, EventDialog, EventRsvpBadge, LanguageContext, LanguageSwitcher, MiniCalendar, NotificationsContext, NotificationsWidget, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, ScrollArea, ScrollBar, Slider, ThemeSwitcher, Toggle, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, UpcomingEvents, buttonVariants, cn, defaultLanguages, getEnvironmentDotClass, getEnvironmentLabel, isBlocksDataEnvironment, toggleVariants, useCalendarContext, useChatRoom, useChatSidebar, useEnvironmentContext, useLanguageContext, useNotificationsContext };
|
|
8104
|
+
export { AvatarEditor, AvatarEditorDialog, BLOCKS_DATA_ENVIRONMENTS, Button, CalendarContext, CalendarSubscribeButton, CalendarView, CalendarWidget, CardInput, ChatRoomView, ChatSidebar, ChatSidebarContext, ChatSidebarProvider, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, Drawer, DrawerClose, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerOverlay, DrawerPortal, DrawerTitle, DrawerTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, EnvironmentBanner, EnvironmentContext, EnvironmentDot, EnvironmentMiniBadge, EnvironmentSwitcher, EventDialog, EventRsvpBadge, LanguageContext, LanguageSwitcher, MiniCalendar, NotificationsContext, NotificationsWidget, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, ScrollArea, ScrollBar, Slider, ThemeSwitcher, Toggle, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, USAddressInput, UpcomingEvents, buttonVariants, cn, defaultLanguages, getEnvironmentDotClass, getEnvironmentLabel, isBlocksDataEnvironment, toggleVariants, useCalendarContext, useChatRoom, useChatSidebar, useDebouncedValue, useDebouncedValueStrict, useEnvironmentContext, useLanguageContext, useNotificationsContext };
|
|
7327
8105
|
//# sourceMappingURL=index.js.map
|
|
7328
8106
|
//# sourceMappingURL=index.js.map
|