@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 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 relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
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
- "focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
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
- "focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
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
- "focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground [&_svg:not([class*='text-'])]:text-muted-foreground flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
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:border-input dark:hover:bg-input/50",
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,783 @@ 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 useDebouncedValueStrict(value, delayMs) {
7366
+ const [debounced, setDebounced] = React2.useState(void 0);
7367
+ React2.useEffect(() => {
7368
+ setDebounced(void 0);
7369
+ const id = window.setTimeout(() => setDebounced(value), delayMs);
7370
+ return () => window.clearTimeout(id);
7371
+ }, [value, delayMs]);
7372
+ return debounced;
7373
+ }
7374
+ function onlyDigits(s, max) {
7375
+ return s.replace(/\D/g, "").slice(0, max);
7376
+ }
7377
+ function formatPan(digits) {
7378
+ const cardInfo = valid__default.default.number(digits).card;
7379
+ const gaps = cardInfo?.gaps ?? [4, 8, 12];
7380
+ const parts = [];
7381
+ let idx = 0;
7382
+ for (const g of gaps) {
7383
+ parts.push(digits.slice(idx, g));
7384
+ idx = g;
7385
+ }
7386
+ parts.push(digits.slice(idx));
7387
+ return parts.filter((p) => p.length > 0).join(" ");
7388
+ }
7389
+ function parseExpiry(raw) {
7390
+ const d = onlyDigits(raw, 4);
7391
+ if (d.length < 4) return null;
7392
+ const mm = Number.parseInt(d.slice(0, 2), 10);
7393
+ const yy = Number.parseInt(d.slice(2, 4), 10);
7394
+ if (mm < 1 || mm > 12) return null;
7395
+ const year = yy < 100 ? 2e3 + yy : yy;
7396
+ const exp = valid__default.default.expirationDate({ month: String(mm), year: String(year) });
7397
+ if (!exp.isValid) return null;
7398
+ return { month: mm, year };
7399
+ }
7400
+ function normalizeBrand(detected) {
7401
+ if (!detected) return "";
7402
+ if (detected === "american-express") return "amex";
7403
+ return detected;
7404
+ }
7405
+ function brandAllowed(detected, accepted) {
7406
+ if (!accepted?.length) return true;
7407
+ if (!detected) return true;
7408
+ const n = normalizeBrand(detected);
7409
+ return accepted.map((a) => a.toLowerCase()).includes(n.toLowerCase());
7410
+ }
7411
+ 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";
7412
+ function CardInput({
7413
+ tokenize,
7414
+ value,
7415
+ onChange,
7416
+ acceptedBrands,
7417
+ requireHolderName = false,
7418
+ labels,
7419
+ disabled = false,
7420
+ largeText = false,
7421
+ className,
7422
+ onError
7423
+ }) {
7424
+ const baseId = React2.useId();
7425
+ const [panDigits, setPanDigits] = React2.useState("");
7426
+ const [expiryRaw, setExpiryRaw] = React2.useState("");
7427
+ const [cvc, setCvc] = React2.useState("");
7428
+ const [holderName, setHolderName] = React2.useState("");
7429
+ const [panFocused, setPanFocused] = React2.useState(false);
7430
+ const [submitting, setSubmitting] = React2.useState(false);
7431
+ const inputClass = largeText ? "text-base py-3" : "";
7432
+ const labelClass = largeText ? "text-base" : "text-sm";
7433
+ const numberValidation = valid__default.default.number(panDigits);
7434
+ const rawBrand = numberValidation.card?.type;
7435
+ const brand = normalizeBrand(rawBrand) || "unknown";
7436
+ const maxPanLen = numberValidation.card?.lengths?.slice(-1)[0] ?? 19;
7437
+ const minPanLenForType = numberValidation.card?.lengths?.[0];
7438
+ const panPastMinimumLength = minPanLenForType !== void 0 && panDigits.length >= minPanLenForType;
7439
+ const cvcSize = rawBrand === "american-express" || brand === "amex" ? 4 : 3;
7440
+ const expiryParsed = parseExpiry(expiryRaw);
7441
+ const expiryValid = expiryRaw.replace(/\D/g, "").length >= 4 && expiryParsed !== null ? valid__default.default.expirationDate({
7442
+ month: String(expiryParsed.month),
7443
+ year: String(expiryParsed.year)
7444
+ }).isValid : false;
7445
+ const cvvValid = cvc.length >= cvcSize && valid__default.default.cvv(cvc, cvcSize).isValid;
7446
+ const panComplete = numberValidation.isValid && brandAllowed(rawBrand, acceptedBrands);
7447
+ const holderOk = !requireHolderName || holderName.trim().length > 1;
7448
+ const canSubmit = panComplete && expiryValid && cvvValid && holderOk && !disabled && !value;
7449
+ const handlePanChange = (e) => {
7450
+ const d = onlyDigits(e.target.value, maxPanLen);
7451
+ setPanDigits(d);
7452
+ };
7453
+ const handleExpiryChange = (e) => {
7454
+ let d = onlyDigits(e.target.value, 4);
7455
+ if (d.length >= 2) d = `${d.slice(0, 2)}/${d.slice(2)}`;
7456
+ setExpiryRaw(d);
7457
+ };
7458
+ const runTokenize = React2.useCallback(async () => {
7459
+ if (!expiryParsed) return;
7460
+ setSubmitting(true);
7461
+ try {
7462
+ const result = await tokenize({
7463
+ pan: panDigits,
7464
+ expMonth: expiryParsed.month,
7465
+ expYear: expiryParsed.year,
7466
+ cvc,
7467
+ holderName: holderName.trim() || void 0
7468
+ });
7469
+ onChange(result);
7470
+ setPanDigits("");
7471
+ setExpiryRaw("");
7472
+ setCvc("");
7473
+ setHolderName("");
7474
+ } catch (err) {
7475
+ const msg = err instanceof Error ? err.message : labels.tokenizeFailed;
7476
+ onError?.(msg);
7477
+ } finally {
7478
+ setSubmitting(false);
7479
+ }
7480
+ }, [
7481
+ cvc,
7482
+ expiryParsed,
7483
+ holderName,
7484
+ labels.tokenizeFailed,
7485
+ onChange,
7486
+ onError,
7487
+ panDigits,
7488
+ tokenize
7489
+ ]);
7490
+ const displayPan = panFocused || panDigits.length <= 4 ? formatPan(panDigits) : `\u2022\u2022\u2022\u2022 \u2022\u2022\u2022\u2022 \u2022\u2022\u2022\u2022 ${panDigits.slice(-4)}`;
7491
+ if (value?.tokenId) {
7492
+ return /* @__PURE__ */ jsxRuntime.jsxs(
7493
+ "div",
7494
+ {
7495
+ className: cn("space-y-3 rounded-lg border bg-muted/30 p-4", className),
7496
+ children: [
7497
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 text-sm", children: [
7498
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CreditCard, { className: "h-4 w-4 text-muted-foreground" }),
7499
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: value.masked }),
7500
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-muted-foreground", children: [
7501
+ String(value.expMonth).padStart(2, "0"),
7502
+ "/",
7503
+ String(value.expYear).slice(-2)
7504
+ ] })
7505
+ ] }),
7506
+ value.holderName ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground", children: value.holderName }) : null,
7507
+ /* @__PURE__ */ jsxRuntime.jsx(
7508
+ Button,
7509
+ {
7510
+ type: "button",
7511
+ variant: "outline",
7512
+ size: "sm",
7513
+ disabled,
7514
+ onClick: () => onChange(null),
7515
+ children: labels.replace
7516
+ }
7517
+ )
7518
+ ]
7519
+ }
7520
+ );
7521
+ }
7522
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("space-y-4 rounded-lg border bg-card p-4", className), children: [
7523
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", children: [
7524
+ /* @__PURE__ */ jsxRuntime.jsx(
7525
+ "label",
7526
+ {
7527
+ htmlFor: `${baseId}-pan`,
7528
+ className: cn("font-medium leading-none", labelClass),
7529
+ children: labels.number
7530
+ }
7531
+ ),
7532
+ /* @__PURE__ */ jsxRuntime.jsx(
7533
+ "input",
7534
+ {
7535
+ id: `${baseId}-pan`,
7536
+ inputMode: "numeric",
7537
+ autoComplete: "cc-number",
7538
+ value: displayPan,
7539
+ onChange: handlePanChange,
7540
+ onFocus: () => setPanFocused(true),
7541
+ onBlur: () => setPanFocused(false),
7542
+ placeholder: "4242 4242 4242 4242",
7543
+ disabled,
7544
+ className: cn(inputClassName, inputClass)
7545
+ }
7546
+ ),
7547
+ panDigits.length > 0 && (!numberValidation.isPotentiallyValid || panPastMinimumLength && !numberValidation.isValid) && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-destructive", children: labels.invalidNumber }),
7548
+ panDigits.length > 0 && numberValidation.isPotentiallyValid && !brandAllowed(rawBrand, acceptedBrands) && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-destructive", children: labels.invalidNumber })
7549
+ ] }),
7550
+ requireHolderName && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", children: [
7551
+ /* @__PURE__ */ jsxRuntime.jsx(
7552
+ "label",
7553
+ {
7554
+ htmlFor: `${baseId}-holder`,
7555
+ className: cn("font-medium leading-none", labelClass),
7556
+ children: labels.holderName
7557
+ }
7558
+ ),
7559
+ /* @__PURE__ */ jsxRuntime.jsx(
7560
+ "input",
7561
+ {
7562
+ id: `${baseId}-holder`,
7563
+ autoComplete: "cc-name",
7564
+ value: holderName,
7565
+ onChange: (e) => setHolderName(e.target.value),
7566
+ disabled,
7567
+ className: cn(inputClassName, inputClass)
7568
+ }
7569
+ )
7570
+ ] }),
7571
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 gap-4 sm:grid-cols-2", children: [
7572
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", children: [
7573
+ /* @__PURE__ */ jsxRuntime.jsx(
7574
+ "label",
7575
+ {
7576
+ htmlFor: `${baseId}-exp`,
7577
+ className: cn("font-medium leading-none", labelClass),
7578
+ children: labels.expiry
7579
+ }
7580
+ ),
7581
+ /* @__PURE__ */ jsxRuntime.jsx(
7582
+ "input",
7583
+ {
7584
+ id: `${baseId}-exp`,
7585
+ inputMode: "numeric",
7586
+ autoComplete: "cc-exp",
7587
+ value: expiryRaw,
7588
+ onChange: handleExpiryChange,
7589
+ placeholder: "MM/YY",
7590
+ disabled,
7591
+ className: cn(inputClassName, inputClass)
7592
+ }
7593
+ ),
7594
+ expiryRaw.replace(/\D/g, "").length >= 4 && !expiryValid && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-destructive", children: labels.expiredCard })
7595
+ ] }),
7596
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", children: [
7597
+ /* @__PURE__ */ jsxRuntime.jsx(
7598
+ "label",
7599
+ {
7600
+ htmlFor: `${baseId}-cvc`,
7601
+ className: cn("font-medium leading-none", labelClass),
7602
+ children: labels.cvc
7603
+ }
7604
+ ),
7605
+ /* @__PURE__ */ jsxRuntime.jsx(
7606
+ "input",
7607
+ {
7608
+ id: `${baseId}-cvc`,
7609
+ inputMode: "numeric",
7610
+ autoComplete: "cc-csc",
7611
+ value: cvc,
7612
+ onChange: (e) => setCvc(onlyDigits(e.target.value, cvcSize)),
7613
+ placeholder: cvcSize === 4 ? "0000" : "000",
7614
+ disabled,
7615
+ className: cn(inputClassName, inputClass),
7616
+ maxLength: cvcSize
7617
+ }
7618
+ ),
7619
+ cvc.length > 0 && !cvvValid && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-destructive", children: labels.invalidCvc })
7620
+ ] })
7621
+ ] }),
7622
+ /* @__PURE__ */ jsxRuntime.jsxs(
7623
+ Button,
7624
+ {
7625
+ type: "button",
7626
+ disabled: !canSubmit || submitting,
7627
+ onClick: () => void runTokenize(),
7628
+ className: "gap-2",
7629
+ children: [
7630
+ submitting ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { className: "h-4 w-4 animate-spin" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CreditCard, { className: "h-4 w-4" }),
7631
+ labels.tokenize
7632
+ ]
7633
+ }
7634
+ )
7635
+ ] });
7636
+ }
7637
+ function parseInitial(value) {
7638
+ if (!value) {
7639
+ return {
7640
+ street: "",
7641
+ street2: "",
7642
+ city: "",
7643
+ state: "",
7644
+ zip: "",
7645
+ country: "US"
7646
+ };
7647
+ }
7648
+ return {
7649
+ street: value.street ?? "",
7650
+ street2: value.street2 ?? "",
7651
+ city: value.city ?? "",
7652
+ state: value.state ?? "",
7653
+ zip: value.zip ?? "",
7654
+ country: "US"
7655
+ };
7656
+ }
7657
+ function addressSig(a) {
7658
+ return JSON.stringify({
7659
+ street: a.street.trim(),
7660
+ street2: (a.street2 ?? "").trim(),
7661
+ city: a.city.trim(),
7662
+ state: a.state.trim().toUpperCase(),
7663
+ zip: a.zip.replace(/\D/g, "").slice(0, 5)
7664
+ });
7665
+ }
7666
+ function isAddressComplete(a) {
7667
+ const zip5 = a.zip.replace(/\D/g, "").slice(0, 5);
7668
+ const st = a.state.trim();
7669
+ return a.street.trim().length > 0 && a.city.trim().length > 0 && /^[A-Za-z]{2}$/.test(st) && zip5.length === 5;
7670
+ }
7671
+ 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";
7672
+ function USAddressInput({
7673
+ value,
7674
+ onChange,
7675
+ lookupZip,
7676
+ validateAddress,
7677
+ autocomplete,
7678
+ labels,
7679
+ disabled = false,
7680
+ largeText = false,
7681
+ className,
7682
+ onError
7683
+ }) {
7684
+ const [searchQuery, setSearchQuery] = React2.useState("");
7685
+ const [showSuggestions, setShowSuggestions] = React2.useState(false);
7686
+ const [suggestions, setSuggestions] = React2.useState([]);
7687
+ const [address, setAddress] = React2.useState(
7688
+ () => parseInitial(value)
7689
+ );
7690
+ const [sessionToken] = React2.useState(
7691
+ () => typeof crypto !== "undefined" && crypto.randomUUID ? crypto.randomUUID() : `${Date.now()}-${Math.random()}`
7692
+ );
7693
+ const [loadingAutocomplete, setLoadingAutocomplete] = React2.useState(false);
7694
+ const [loadingZip, setLoadingZip] = React2.useState(false);
7695
+ const [loadingValidate, setLoadingValidate] = React2.useState(false);
7696
+ const [uspsSuggestion, setUspsSuggestion] = React2.useState(
7697
+ null
7698
+ );
7699
+ const [uspsVerifiedNoChange, setUspsVerifiedNoChange] = React2.useState(false);
7700
+ const searchRef = React2.useRef(null);
7701
+ const suggestionCache = React2.useRef(/* @__PURE__ */ new Map());
7702
+ const warnedRef = React2.useRef({
7703
+ autocomplete: false,
7704
+ zip: false,
7705
+ validate: false
7706
+ });
7707
+ const lastZipLookup = React2.useRef("");
7708
+ const addressRef = React2.useRef(address);
7709
+ addressRef.current = address;
7710
+ const lastValidatedSigRef = React2.useRef("");
7711
+ const debouncedSearch = useDebouncedValue(searchQuery, 400);
7712
+ const zipDigits = address.zip.replace(/\D/g, "").slice(0, 5);
7713
+ const debouncedZip = useDebouncedValue(zipDigits, 400);
7714
+ const debouncedAddressForValidate = useDebouncedValueStrict(address, 1200);
7715
+ const inputClass = largeText ? "text-base py-3" : "";
7716
+ const labelClass = largeText ? "text-base" : "text-sm";
7717
+ React2.useEffect(() => {
7718
+ const handleClickOutside = (event) => {
7719
+ if (searchRef.current && !searchRef.current.contains(event.target)) {
7720
+ setShowSuggestions(false);
7721
+ }
7722
+ };
7723
+ document.addEventListener("mousedown", handleClickOutside);
7724
+ return () => document.removeEventListener("mousedown", handleClickOutside);
7725
+ }, []);
7726
+ const valueSyncKey = value == null ? "" : `o:${JSON.stringify(value)}`;
7727
+ React2.useEffect(() => {
7728
+ setAddress(parseInitial(value));
7729
+ }, [valueSyncKey]);
7730
+ const handleFieldChange = (field, fieldValue) => {
7731
+ setAddress((prev) => {
7732
+ const next = field === "country" ? { ...prev, country: "US" } : { ...prev, [field]: fieldValue };
7733
+ onChange(next);
7734
+ return next;
7735
+ });
7736
+ };
7737
+ React2.useEffect(() => {
7738
+ const sig = addressSig(addressRef.current);
7739
+ if (sig !== lastValidatedSigRef.current) {
7740
+ setUspsVerifiedNoChange(false);
7741
+ setUspsSuggestion(null);
7742
+ }
7743
+ }, [address]);
7744
+ const allowAutocomplete = Boolean(autocomplete);
7745
+ const allowUspsValidation = Boolean(validateAddress);
7746
+ const allowZipLookup = Boolean(lookupZip);
7747
+ React2.useEffect(() => {
7748
+ if (!allowAutocomplete || !autocomplete) return;
7749
+ const q = debouncedSearch.trim();
7750
+ if (q.length < 3) {
7751
+ setSuggestions([]);
7752
+ setShowSuggestions(false);
7753
+ setLoadingAutocomplete(false);
7754
+ return;
7755
+ }
7756
+ const cacheKey = q.toLowerCase();
7757
+ const cached = suggestionCache.current.get(cacheKey);
7758
+ if (cached) {
7759
+ setSuggestions(cached);
7760
+ setShowSuggestions(true);
7761
+ setLoadingAutocomplete(false);
7762
+ return;
7763
+ }
7764
+ const ctrl = new AbortController();
7765
+ setLoadingAutocomplete(true);
7766
+ autocomplete.search(q, sessionToken, ctrl.signal).then((list) => {
7767
+ if (ctrl.signal.aborted) return;
7768
+ suggestionCache.current.set(cacheKey, list);
7769
+ setSuggestions(list);
7770
+ setShowSuggestions(list.length > 0);
7771
+ }).catch((e) => {
7772
+ if (e.name === "AbortError") return;
7773
+ if (!warnedRef.current.autocomplete) {
7774
+ onError?.(labels.autocompleteUnavailable);
7775
+ warnedRef.current.autocomplete = true;
7776
+ }
7777
+ setSuggestions([]);
7778
+ setShowSuggestions(false);
7779
+ }).finally(() => setLoadingAutocomplete(false));
7780
+ return () => ctrl.abort();
7781
+ }, [
7782
+ debouncedSearch,
7783
+ allowAutocomplete,
7784
+ autocomplete,
7785
+ sessionToken,
7786
+ labels.autocompleteUnavailable,
7787
+ onError
7788
+ ]);
7789
+ React2.useEffect(() => {
7790
+ if (!allowZipLookup || !lookupZip) return;
7791
+ if (debouncedZip.length !== 5) return;
7792
+ if (debouncedZip === lastZipLookup.current) return;
7793
+ const ctrl = new AbortController();
7794
+ setLoadingZip(true);
7795
+ lookupZip(debouncedZip, ctrl.signal).then((data) => {
7796
+ if (ctrl.signal.aborted) return;
7797
+ lastZipLookup.current = debouncedZip;
7798
+ setAddress((prev) => {
7799
+ const cityEmpty = !prev.city.trim();
7800
+ const stateEmpty = !prev.state.trim();
7801
+ const next = { ...prev };
7802
+ if (cityEmpty && data.city) next.city = data.city;
7803
+ if (stateEmpty && data.state) next.state = data.state;
7804
+ next.country = "US";
7805
+ onChange(next);
7806
+ return next;
7807
+ });
7808
+ }).catch(() => {
7809
+ if (!warnedRef.current.zip) {
7810
+ onError?.(labels.zipLookupFailed);
7811
+ warnedRef.current.zip = true;
7812
+ }
7813
+ }).finally(() => setLoadingZip(false));
7814
+ return () => ctrl.abort();
7815
+ }, [
7816
+ debouncedZip,
7817
+ allowZipLookup,
7818
+ lookupZip,
7819
+ onChange,
7820
+ labels.zipLookupFailed,
7821
+ onError
7822
+ ]);
7823
+ React2.useEffect(() => {
7824
+ if (!allowUspsValidation || !validateAddress || disabled) return;
7825
+ if (debouncedAddressForValidate === void 0) return;
7826
+ const addr = debouncedAddressForValidate;
7827
+ if (!isAddressComplete(addr)) return;
7828
+ const requestSig = addressSig(addr);
7829
+ if (requestSig === lastValidatedSigRef.current) return;
7830
+ const ctrl = new AbortController();
7831
+ const timeoutId = window.setTimeout(() => ctrl.abort(), 8e3);
7832
+ setLoadingValidate(true);
7833
+ setUspsVerifiedNoChange(false);
7834
+ setUspsSuggestion(null);
7835
+ validateAddress(addr, ctrl.signal).then((result) => {
7836
+ if (ctrl.signal.aborted) return;
7837
+ if (addressSig(addressRef.current) !== requestSig) return;
7838
+ lastValidatedSigRef.current = requestSig;
7839
+ const std = result.standardized;
7840
+ if (result.changed) {
7841
+ setUspsSuggestion(std);
7842
+ setUspsVerifiedNoChange(false);
7843
+ } else {
7844
+ setUspsSuggestion(null);
7845
+ setUspsVerifiedNoChange(true);
7846
+ }
7847
+ }).catch(() => {
7848
+ if (ctrl.signal.aborted) return;
7849
+ if (!warnedRef.current.validate) {
7850
+ onError?.(labels.uspsUnavailable);
7851
+ warnedRef.current.validate = true;
7852
+ }
7853
+ }).finally(() => {
7854
+ window.clearTimeout(timeoutId);
7855
+ setLoadingValidate(false);
7856
+ });
7857
+ return () => {
7858
+ window.clearTimeout(timeoutId);
7859
+ ctrl.abort();
7860
+ };
7861
+ }, [
7862
+ debouncedAddressForValidate,
7863
+ allowUspsValidation,
7864
+ validateAddress,
7865
+ disabled,
7866
+ labels.uspsUnavailable,
7867
+ onError
7868
+ ]);
7869
+ const handleSelectSuggestion = async (row) => {
7870
+ if (!autocomplete) return;
7871
+ try {
7872
+ const next = await autocomplete.details(
7873
+ row.placeId,
7874
+ AbortSignal.timeout(8e3)
7875
+ );
7876
+ const normalized = {
7877
+ ...next,
7878
+ country: "US"
7879
+ };
7880
+ setAddress(normalized);
7881
+ onChange(normalized);
7882
+ setShowSuggestions(false);
7883
+ setSearchQuery("");
7884
+ setUspsSuggestion(null);
7885
+ lastValidatedSigRef.current = "";
7886
+ setUspsVerifiedNoChange(false);
7887
+ } catch {
7888
+ onError?.(labels.placeLookupFailed);
7889
+ }
7890
+ };
7891
+ const applyUspsSuggestion = () => {
7892
+ if (!uspsSuggestion) return;
7893
+ setAddress(uspsSuggestion);
7894
+ onChange(uspsSuggestion);
7895
+ setUspsSuggestion(null);
7896
+ lastValidatedSigRef.current = addressSig(uspsSuggestion);
7897
+ setUspsVerifiedNoChange(true);
7898
+ };
7899
+ const dismissUspsSuggestion = () => {
7900
+ setUspsSuggestion(null);
7901
+ lastValidatedSigRef.current = addressSig(addressRef.current);
7902
+ setUspsVerifiedNoChange(true);
7903
+ };
7904
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("space-y-4", className), children: [
7905
+ allowAutocomplete && autocomplete && /* @__PURE__ */ jsxRuntime.jsxs("div", { ref: searchRef, className: "relative", children: [
7906
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
7907
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Search, { className: "absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" }),
7908
+ /* @__PURE__ */ jsxRuntime.jsx(
7909
+ "input",
7910
+ {
7911
+ value: searchQuery,
7912
+ onChange: (e) => setSearchQuery(e.target.value),
7913
+ placeholder: labels.searchPlaceholder,
7914
+ disabled,
7915
+ className: cn(inputClassName2, "pl-9 pr-9", inputClass),
7916
+ "aria-label": labels.searchPlaceholder
7917
+ }
7918
+ ),
7919
+ 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" }),
7920
+ searchQuery ? /* @__PURE__ */ jsxRuntime.jsx(
7921
+ "button",
7922
+ {
7923
+ type: "button",
7924
+ onClick: () => setSearchQuery(""),
7925
+ className: "absolute right-3 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground",
7926
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "h-4 w-4" })
7927
+ }
7928
+ ) : null
7929
+ ] }),
7930
+ 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(
7931
+ "button",
7932
+ {
7933
+ type: "button",
7934
+ onClick: () => void handleSelectSuggestion(suggestion),
7935
+ className: "w-full border-b px-4 py-3 text-left transition-colors last:border-b-0 hover:bg-muted",
7936
+ children: [
7937
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm font-medium", children: suggestion.mainText }),
7938
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground", children: suggestion.secondaryText })
7939
+ ]
7940
+ },
7941
+ suggestion.placeId
7942
+ )) })
7943
+ ] }),
7944
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid gap-4", children: [
7945
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", children: [
7946
+ /* @__PURE__ */ jsxRuntime.jsx(
7947
+ "label",
7948
+ {
7949
+ htmlFor: "blocks-usaddress-street",
7950
+ className: cn("font-medium leading-none", labelClass),
7951
+ children: labels.street
7952
+ }
7953
+ ),
7954
+ /* @__PURE__ */ jsxRuntime.jsx(
7955
+ "input",
7956
+ {
7957
+ id: "blocks-usaddress-street",
7958
+ value: address.street,
7959
+ onChange: (e) => handleFieldChange("street", e.target.value),
7960
+ placeholder: labels.streetPlaceholder ?? "",
7961
+ disabled,
7962
+ className: cn(inputClassName2, inputClass)
7963
+ }
7964
+ )
7965
+ ] }),
7966
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", children: [
7967
+ /* @__PURE__ */ jsxRuntime.jsxs(
7968
+ "label",
7969
+ {
7970
+ htmlFor: "blocks-usaddress-street2",
7971
+ className: cn(
7972
+ `${labelClass} text-muted-foreground`,
7973
+ "leading-none"
7974
+ ),
7975
+ children: [
7976
+ labels.street2 ?? "Address line 2",
7977
+ " ",
7978
+ labels.street2OptionalHint ? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xs", children: [
7979
+ "(",
7980
+ labels.street2OptionalHint,
7981
+ ")"
7982
+ ] }) : null
7983
+ ]
7984
+ }
7985
+ ),
7986
+ /* @__PURE__ */ jsxRuntime.jsx(
7987
+ "input",
7988
+ {
7989
+ id: "blocks-usaddress-street2",
7990
+ value: address.street2 || "",
7991
+ onChange: (e) => handleFieldChange("street2", e.target.value),
7992
+ placeholder: labels.street2Placeholder ?? "",
7993
+ disabled,
7994
+ className: cn(inputClassName2, inputClass)
7995
+ }
7996
+ )
7997
+ ] }),
7998
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 gap-4 sm:grid-cols-2", children: [
7999
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", children: [
8000
+ /* @__PURE__ */ jsxRuntime.jsx(
8001
+ "label",
8002
+ {
8003
+ htmlFor: "blocks-usaddress-city",
8004
+ className: cn("font-medium leading-none", labelClass),
8005
+ children: labels.city
8006
+ }
8007
+ ),
8008
+ /* @__PURE__ */ jsxRuntime.jsx(
8009
+ "input",
8010
+ {
8011
+ id: "blocks-usaddress-city",
8012
+ value: address.city,
8013
+ onChange: (e) => handleFieldChange("city", e.target.value),
8014
+ placeholder: labels.cityPlaceholder ?? "",
8015
+ disabled,
8016
+ className: cn(inputClassName2, inputClass)
8017
+ }
8018
+ )
8019
+ ] }),
8020
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", children: [
8021
+ /* @__PURE__ */ jsxRuntime.jsx(
8022
+ "label",
8023
+ {
8024
+ htmlFor: "blocks-usaddress-state",
8025
+ className: cn("font-medium leading-none", labelClass),
8026
+ children: labels.state
8027
+ }
8028
+ ),
8029
+ /* @__PURE__ */ jsxRuntime.jsx(
8030
+ "input",
8031
+ {
8032
+ id: "blocks-usaddress-state",
8033
+ value: address.state,
8034
+ onChange: (e) => handleFieldChange("state", e.target.value),
8035
+ placeholder: labels.statePlaceholder ?? "",
8036
+ disabled,
8037
+ className: cn(inputClassName2, inputClass)
8038
+ }
8039
+ )
8040
+ ] })
8041
+ ] }),
8042
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 gap-4 sm:grid-cols-2", children: [
8043
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", children: [
8044
+ /* @__PURE__ */ jsxRuntime.jsx(
8045
+ "label",
8046
+ {
8047
+ htmlFor: "blocks-usaddress-zip",
8048
+ className: cn("font-medium leading-none", labelClass),
8049
+ children: labels.zip
8050
+ }
8051
+ ),
8052
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
8053
+ /* @__PURE__ */ jsxRuntime.jsx(
8054
+ "input",
8055
+ {
8056
+ id: "blocks-usaddress-zip",
8057
+ value: address.zip,
8058
+ onChange: (e) => handleFieldChange(
8059
+ "zip",
8060
+ e.target.value.replace(/\D/g, "").slice(0, 10)
8061
+ ),
8062
+ placeholder: labels.zipPlaceholder ?? "",
8063
+ disabled,
8064
+ className: cn(inputClassName2, inputClass)
8065
+ }
8066
+ ),
8067
+ 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" })
8068
+ ] })
8069
+ ] }),
8070
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", children: [
8071
+ /* @__PURE__ */ jsxRuntime.jsx(
8072
+ "label",
8073
+ {
8074
+ htmlFor: "blocks-usaddress-country",
8075
+ className: cn("font-medium leading-none", labelClass),
8076
+ children: labels.countryLabel ?? "Country"
8077
+ }
8078
+ ),
8079
+ /* @__PURE__ */ jsxRuntime.jsx(
8080
+ "input",
8081
+ {
8082
+ id: "blocks-usaddress-country",
8083
+ value: "United States",
8084
+ readOnly: true,
8085
+ disabled,
8086
+ className: cn(inputClassName2, inputClass, "bg-muted/50"),
8087
+ "aria-readonly": "true"
8088
+ }
8089
+ )
8090
+ ] })
8091
+ ] })
8092
+ ] }),
8093
+ allowUspsValidation && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
8094
+ /* @__PURE__ */ jsxRuntime.jsx(
8095
+ "div",
8096
+ {
8097
+ className: "flex min-h-7 items-center gap-2 text-xs text-muted-foreground",
8098
+ "aria-live": "polite",
8099
+ children: loadingValidate ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
8100
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { className: "h-3.5 w-3.5 shrink-0 animate-spin" }),
8101
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: labels.uspsValidating })
8102
+ ] }) : uspsVerifiedNoChange && !uspsSuggestion ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
8103
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CheckCircle2, { className: "h-3.5 w-3.5 shrink-0 text-emerald-600 dark:text-emerald-400" }),
8104
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: labels.uspsVerified })
8105
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "select-none opacity-0", "aria-hidden": true, children: "\xA0" })
8106
+ }
8107
+ ),
8108
+ 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: [
8109
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm font-medium text-amber-900 dark:text-amber-100", children: labels.uspsSuggested }),
8110
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground", children: [
8111
+ uspsSuggestion.street,
8112
+ uspsSuggestion.street2,
8113
+ uspsSuggestion.city,
8114
+ uspsSuggestion.state,
8115
+ uspsSuggestion.zip
8116
+ ].filter(Boolean).join(", ") }),
8117
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap gap-2", children: [
8118
+ /* @__PURE__ */ jsxRuntime.jsx(Button, { type: "button", size: "sm", onClick: applyUspsSuggestion, children: labels.uspsUseSuggestion }),
8119
+ /* @__PURE__ */ jsxRuntime.jsx(
8120
+ Button,
8121
+ {
8122
+ type: "button",
8123
+ size: "sm",
8124
+ variant: "outline",
8125
+ onClick: dismissUspsSuggestion,
8126
+ children: labels.uspsKeepMine
8127
+ }
8128
+ )
8129
+ ] })
8130
+ ] }) : null
8131
+ ] })
8132
+ ] });
8133
+ }
7353
8134
 
7354
8135
  exports.AvatarEditor = AvatarEditor;
7355
8136
  exports.AvatarEditorDialog = AvatarEditorDialog;
@@ -7359,6 +8140,7 @@ exports.CalendarContext = CalendarContext;
7359
8140
  exports.CalendarSubscribeButton = CalendarSubscribeButton;
7360
8141
  exports.CalendarView = CalendarView;
7361
8142
  exports.CalendarWidget = CalendarWidget;
8143
+ exports.CardInput = CardInput;
7362
8144
  exports.ChatRoomView = ChatRoomView;
7363
8145
  exports.ChatSidebar = ChatSidebar;
7364
8146
  exports.ChatSidebarContext = ChatSidebarContext;
@@ -7423,6 +8205,7 @@ exports.Tooltip = Tooltip;
7423
8205
  exports.TooltipContent = TooltipContent;
7424
8206
  exports.TooltipProvider = TooltipProvider;
7425
8207
  exports.TooltipTrigger = TooltipTrigger;
8208
+ exports.USAddressInput = USAddressInput;
7426
8209
  exports.UpcomingEvents = UpcomingEvents;
7427
8210
  exports.buttonVariants = buttonVariants;
7428
8211
  exports.cn = cn;
@@ -7434,6 +8217,8 @@ exports.toggleVariants = toggleVariants;
7434
8217
  exports.useCalendarContext = useCalendarContext;
7435
8218
  exports.useChatRoom = useChatRoom;
7436
8219
  exports.useChatSidebar = useChatSidebar;
8220
+ exports.useDebouncedValue = useDebouncedValue;
8221
+ exports.useDebouncedValueStrict = useDebouncedValueStrict;
7437
8222
  exports.useEnvironmentContext = useEnvironmentContext;
7438
8223
  exports.useLanguageContext = useLanguageContext;
7439
8224
  exports.useNotificationsContext = useNotificationsContext;