@algenium/blocks 1.7.0-rc.7 → 1.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -7,13 +7,13 @@ var framerMotion = require('framer-motion');
7
7
  var DropdownMenuPrimitive = require('@radix-ui/react-dropdown-menu');
8
8
  var jsxRuntime = require('react/jsx-runtime');
9
9
  var reactSlot = require('@radix-ui/react-slot');
10
- var TooltipPrimitive = require('@radix-ui/react-tooltip');
11
10
  var SliderPrimitive = require('@radix-ui/react-slider');
12
11
  var TogglePrimitive = require('@radix-ui/react-toggle');
13
12
  var DialogPrimitive = require('@radix-ui/react-dialog');
14
13
  var vaul = require('vaul');
15
14
  var PopoverPrimitive = require('@radix-ui/react-popover');
16
15
  var ScrollAreaPrimitive = require('@radix-ui/react-scroll-area');
16
+ var TooltipPrimitive = require('@radix-ui/react-tooltip');
17
17
  var dateFns = require('date-fns');
18
18
  var reactDayPicker = require('react-day-picker');
19
19
  var valid = require('card-validator');
@@ -40,12 +40,12 @@ function _interopNamespace(e) {
40
40
 
41
41
  var React2__namespace = /*#__PURE__*/_interopNamespace(React2);
42
42
  var DropdownMenuPrimitive__namespace = /*#__PURE__*/_interopNamespace(DropdownMenuPrimitive);
43
- var TooltipPrimitive__namespace = /*#__PURE__*/_interopNamespace(TooltipPrimitive);
44
43
  var SliderPrimitive__namespace = /*#__PURE__*/_interopNamespace(SliderPrimitive);
45
44
  var TogglePrimitive__namespace = /*#__PURE__*/_interopNamespace(TogglePrimitive);
46
45
  var DialogPrimitive__namespace = /*#__PURE__*/_interopNamespace(DialogPrimitive);
47
46
  var PopoverPrimitive__namespace = /*#__PURE__*/_interopNamespace(PopoverPrimitive);
48
47
  var ScrollAreaPrimitive__namespace = /*#__PURE__*/_interopNamespace(ScrollAreaPrimitive);
48
+ var TooltipPrimitive__namespace = /*#__PURE__*/_interopNamespace(TooltipPrimitive);
49
49
  var valid__default = /*#__PURE__*/_interopDefault(valid);
50
50
 
51
51
  var CalendarContext = React2.createContext(null);
@@ -3115,6 +3115,11 @@ var twMerge = /* @__PURE__ */ createTailwindMerge(getDefaultConfig);
3115
3115
  function cn(...inputs) {
3116
3116
  return twMerge(clsx(inputs));
3117
3117
  }
3118
+ var miniMenuContentClassName = "max-h-none overflow-x-visible overflow-y-visible";
3119
+ var miniMenuContentDefaults = {
3120
+ sideOffset: 8,
3121
+ collisionPadding: 12
3122
+ };
3118
3123
  function DropdownMenu({
3119
3124
  ...props
3120
3125
  }) {
@@ -3413,52 +3418,6 @@ function Button({
3413
3418
  }
3414
3419
  );
3415
3420
  }
3416
- function TooltipProvider({
3417
- delayDuration = 0,
3418
- ...props
3419
- }) {
3420
- return /* @__PURE__ */ jsxRuntime.jsx(
3421
- TooltipPrimitive__namespace.Provider,
3422
- {
3423
- "data-slot": "tooltip-provider",
3424
- delayDuration,
3425
- ...props
3426
- }
3427
- );
3428
- }
3429
- function Tooltip({
3430
- ...props
3431
- }) {
3432
- return /* @__PURE__ */ jsxRuntime.jsx(TooltipProvider, { children: /* @__PURE__ */ jsxRuntime.jsx(TooltipPrimitive__namespace.Root, { "data-slot": "tooltip", ...props }) });
3433
- }
3434
- function TooltipTrigger({
3435
- ...props
3436
- }) {
3437
- return /* @__PURE__ */ jsxRuntime.jsx(TooltipPrimitive__namespace.Trigger, { "data-slot": "tooltip-trigger", ...props });
3438
- }
3439
- function TooltipContent({
3440
- className,
3441
- sideOffset = 0,
3442
- children,
3443
- ...props
3444
- }) {
3445
- return /* @__PURE__ */ jsxRuntime.jsx(TooltipPrimitive__namespace.Portal, { children: /* @__PURE__ */ jsxRuntime.jsxs(
3446
- TooltipPrimitive__namespace.Content,
3447
- {
3448
- "data-slot": "tooltip-content",
3449
- sideOffset,
3450
- className: cn(
3451
- "bg-foreground text-background animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-fit origin-(--radix-tooltip-content-transform-origin) rounded-md px-3 py-1.5 text-xs text-balance",
3452
- className
3453
- ),
3454
- ...props,
3455
- children: [
3456
- children,
3457
- /* @__PURE__ */ jsxRuntime.jsx(TooltipPrimitive__namespace.Arrow, { className: "bg-foreground fill-foreground z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px]" })
3458
- ]
3459
- }
3460
- ) });
3461
- }
3462
3421
  var defaultLabels = {
3463
3422
  theme: "Theme",
3464
3423
  system: "System",
@@ -3502,11 +3461,8 @@ function ThemeSwitcher({
3502
3461
  size = "sm",
3503
3462
  shape = "rounded",
3504
3463
  variant = "default",
3505
- align = "center",
3506
- side = "top",
3507
- tooltipSide = "bottom",
3508
- tooltipAlign = "center",
3509
- tooltipSideOffset = 8,
3464
+ align = "end",
3465
+ side = "bottom",
3510
3466
  labels: userLabels
3511
3467
  }) {
3512
3468
  const { theme, setTheme } = nextThemes.useTheme();
@@ -3540,43 +3496,42 @@ function ThemeSwitcher({
3540
3496
  const CurrentIcon = themes.find((t) => t.key === currentTheme)?.icon || lucideReact.Monitor;
3541
3497
  if (variant === "mini") {
3542
3498
  return /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenu, { modal: false, children: [
3543
- /* @__PURE__ */ jsxRuntime.jsxs(Tooltip, { children: [
3544
- /* @__PURE__ */ jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
3545
- Button,
3546
- {
3547
- "data-testid": "theme-switcher",
3548
- variant: "ghost",
3549
- size: "icon",
3550
- "aria-label": labels.theme,
3551
- className: cn(sizes.buttonMini, shapeClass, className),
3552
- children: /* @__PURE__ */ jsxRuntime.jsx(CurrentIcon, { className: sizes.iconMini })
3553
- }
3554
- ) }) }),
3555
- /* @__PURE__ */ jsxRuntime.jsx(
3556
- TooltipContent,
3557
- {
3558
- side: tooltipSide,
3559
- align: tooltipAlign,
3560
- sideOffset: tooltipSideOffset,
3561
- children: labels.theme
3562
- }
3563
- )
3564
- ] }),
3565
- /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuContent, { side, align, sideOffset: 8, children: themes.map(({ key, icon: Icon }) => /* @__PURE__ */ jsxRuntime.jsxs(
3566
- DropdownMenuItem,
3499
+ /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
3500
+ Button,
3567
3501
  {
3568
- onClick: () => handleThemeClick(key),
3569
- className: cn(
3570
- "gap-2 cursor-pointer",
3571
- currentTheme === key && "bg-accent text-accent-foreground [&_svg]:text-accent-foreground"
3572
- ),
3573
- children: [
3574
- /* @__PURE__ */ jsxRuntime.jsx(Icon, { className: "h-4 w-4" }),
3575
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: labels[key] })
3576
- ]
3577
- },
3578
- key
3579
- )) })
3502
+ "data-testid": "theme-switcher",
3503
+ variant: "ghost",
3504
+ size: "icon",
3505
+ "aria-label": labels.theme,
3506
+ className: cn(sizes.buttonMini, shapeClass, className),
3507
+ children: /* @__PURE__ */ jsxRuntime.jsx(CurrentIcon, { className: sizes.iconMini })
3508
+ }
3509
+ ) }),
3510
+ /* @__PURE__ */ jsxRuntime.jsx(
3511
+ DropdownMenuContent,
3512
+ {
3513
+ side,
3514
+ align,
3515
+ sideOffset: miniMenuContentDefaults.sideOffset,
3516
+ collisionPadding: miniMenuContentDefaults.collisionPadding,
3517
+ className: miniMenuContentClassName,
3518
+ children: themes.map(({ key, icon: Icon }) => /* @__PURE__ */ jsxRuntime.jsxs(
3519
+ DropdownMenuItem,
3520
+ {
3521
+ onClick: () => handleThemeClick(key),
3522
+ className: cn(
3523
+ "gap-2 cursor-pointer",
3524
+ currentTheme === key && "bg-accent text-accent-foreground [&_svg]:text-accent-foreground"
3525
+ ),
3526
+ children: [
3527
+ /* @__PURE__ */ jsxRuntime.jsx(Icon, { className: "h-4 w-4" }),
3528
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: labels[key] })
3529
+ ]
3530
+ },
3531
+ key
3532
+ ))
3533
+ }
3534
+ )
3580
3535
  ] });
3581
3536
  }
3582
3537
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -3670,11 +3625,8 @@ function LanguageSwitcher({
3670
3625
  shape = "rounded",
3671
3626
  variant = "default",
3672
3627
  showIcon = true,
3673
- align = "center",
3674
- side = "top",
3675
- tooltipSide = "bottom",
3676
- tooltipAlign = "center",
3677
- tooltipSideOffset = 8
3628
+ align = "end",
3629
+ side = "bottom"
3678
3630
  }) {
3679
3631
  const context = useLanguageContext();
3680
3632
  const contextLanguages = context?.languages?.map((lang) => ({
@@ -3692,34 +3644,24 @@ function LanguageSwitcher({
3692
3644
  };
3693
3645
  if (variant === "mini") {
3694
3646
  return /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenu, { modal: false, children: [
3695
- /* @__PURE__ */ jsxRuntime.jsxs(Tooltip, { children: [
3696
- /* @__PURE__ */ jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
3697
- Button,
3698
- {
3699
- variant: "ghost",
3700
- size: "icon",
3701
- "aria-label": defaultLabels4.language,
3702
- className: cn(sizes.buttonMini, shapeClass, className),
3703
- children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Languages, { className: sizes.iconMini })
3704
- }
3705
- ) }) }),
3706
- /* @__PURE__ */ jsxRuntime.jsx(
3707
- TooltipContent,
3708
- {
3709
- side: tooltipSide,
3710
- align: tooltipAlign,
3711
- sideOffset: tooltipSideOffset,
3712
- children: defaultLabels4.language
3713
- }
3714
- )
3715
- ] }),
3647
+ /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
3648
+ Button,
3649
+ {
3650
+ variant: "ghost",
3651
+ size: "icon",
3652
+ "aria-label": defaultLabels4.language,
3653
+ className: cn(sizes.buttonMini, shapeClass, className),
3654
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Languages, { className: sizes.iconMini })
3655
+ }
3656
+ ) }),
3716
3657
  /* @__PURE__ */ jsxRuntime.jsx(
3717
3658
  DropdownMenuContent,
3718
3659
  {
3719
3660
  side,
3720
3661
  align,
3721
- sideOffset: 8,
3722
- className: "min-w-0 w-auto",
3662
+ sideOffset: miniMenuContentDefaults.sideOffset,
3663
+ collisionPadding: miniMenuContentDefaults.collisionPadding,
3664
+ className: cn(miniMenuContentClassName, "min-w-0 w-auto"),
3723
3665
  children: languages.map(({ key, nativeName }) => /* @__PURE__ */ jsxRuntime.jsx(
3724
3666
  DropdownMenuItem,
3725
3667
  {
@@ -3919,10 +3861,7 @@ function EnvironmentSwitcher({
3919
3861
  shape = "rounded",
3920
3862
  variant = "mini",
3921
3863
  align = "end",
3922
- side = "bottom",
3923
- tooltipSide = "bottom",
3924
- tooltipAlign = "center",
3925
- tooltipSideOffset = 8
3864
+ side = "bottom"
3926
3865
  }) {
3927
3866
  const ctx = useEnvironmentContext();
3928
3867
  const labels = { ...defaultLabels2, ...userLabels };
@@ -3938,53 +3877,18 @@ function EnvironmentSwitcher({
3938
3877
  };
3939
3878
  if (variant === "mini") {
3940
3879
  return /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenu, { modal: false, children: [
3941
- /* @__PURE__ */ jsxRuntime.jsxs(Tooltip, { children: [
3942
- /* @__PURE__ */ jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
3943
- Button,
3944
- {
3945
- "data-testid": "environment-switcher",
3946
- variant: "outline",
3947
- size: "sm",
3948
- "aria-label": labels.environment,
3949
- className: cn(
3950
- sizes.buttonMini,
3951
- shapeClass,
3952
- "font-medium tabular-nums border-border bg-background",
3953
- className
3954
- ),
3955
- children: [
3956
- /* @__PURE__ */ jsxRuntime.jsx(
3957
- "span",
3958
- {
3959
- className: cn(
3960
- "rounded-full shrink-0 ring-1 ring-background",
3961
- sizes.dot,
3962
- getEnvironmentDotClass(environment)
3963
- ),
3964
- "aria-hidden": true
3965
- }
3966
- ),
3967
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "max-w-[5.5rem] truncate", children: getEnvironmentLabel(environment, labels) })
3968
- ]
3969
- }
3970
- ) }) }),
3971
- /* @__PURE__ */ jsxRuntime.jsx(
3972
- TooltipContent,
3973
- {
3974
- side: tooltipSide,
3975
- align: tooltipAlign,
3976
- sideOffset: tooltipSideOffset,
3977
- children: labels.environment
3978
- }
3979
- )
3980
- ] }),
3981
- /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuContent, { side, align, sideOffset: 8, children: environments.map((env) => /* @__PURE__ */ jsxRuntime.jsxs(
3982
- DropdownMenuItem,
3880
+ /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
3881
+ Button,
3983
3882
  {
3984
- onClick: () => handleSelect(env),
3883
+ "data-testid": "environment-switcher",
3884
+ variant: "outline",
3885
+ size: "sm",
3886
+ "aria-label": labels.environment,
3985
3887
  className: cn(
3986
- "gap-2 cursor-pointer",
3987
- environment === env && "bg-accent text-accent-foreground [&_svg]:text-accent-foreground"
3888
+ sizes.buttonMini,
3889
+ shapeClass,
3890
+ "font-medium tabular-nums border-border bg-background",
3891
+ className
3988
3892
  ),
3989
3893
  children: [
3990
3894
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -3993,16 +3897,50 @@ function EnvironmentSwitcher({
3993
3897
  className: cn(
3994
3898
  "rounded-full shrink-0 ring-1 ring-background",
3995
3899
  sizes.dot,
3996
- getEnvironmentDotClass(env)
3900
+ getEnvironmentDotClass(environment)
3997
3901
  ),
3998
3902
  "aria-hidden": true
3999
3903
  }
4000
3904
  ),
4001
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: getEnvironmentLabel(env, labels) })
3905
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "max-w-[5.5rem] truncate", children: getEnvironmentLabel(environment, labels) })
4002
3906
  ]
4003
- },
4004
- env
4005
- )) })
3907
+ }
3908
+ ) }),
3909
+ /* @__PURE__ */ jsxRuntime.jsx(
3910
+ DropdownMenuContent,
3911
+ {
3912
+ side,
3913
+ align,
3914
+ sideOffset: miniMenuContentDefaults.sideOffset,
3915
+ collisionPadding: miniMenuContentDefaults.collisionPadding,
3916
+ className: miniMenuContentClassName,
3917
+ children: environments.map((env) => /* @__PURE__ */ jsxRuntime.jsxs(
3918
+ DropdownMenuItem,
3919
+ {
3920
+ onClick: () => handleSelect(env),
3921
+ className: cn(
3922
+ "gap-2 cursor-pointer",
3923
+ environment === env && "bg-accent text-accent-foreground [&_svg]:text-accent-foreground"
3924
+ ),
3925
+ children: [
3926
+ /* @__PURE__ */ jsxRuntime.jsx(
3927
+ "span",
3928
+ {
3929
+ className: cn(
3930
+ "rounded-full shrink-0 ring-1 ring-background",
3931
+ sizes.dot,
3932
+ getEnvironmentDotClass(env)
3933
+ ),
3934
+ "aria-hidden": true
3935
+ }
3936
+ ),
3937
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: getEnvironmentLabel(env, labels) })
3938
+ ]
3939
+ },
3940
+ env
3941
+ ))
3942
+ }
3943
+ )
4006
3944
  ] });
4007
3945
  }
4008
3946
  return /* @__PURE__ */ jsxRuntime.jsxs(
@@ -5860,6 +5798,52 @@ function UpcomingEvents({
5860
5798
  );
5861
5799
  }) });
5862
5800
  }
5801
+ function TooltipProvider({
5802
+ delayDuration = 0,
5803
+ ...props
5804
+ }) {
5805
+ return /* @__PURE__ */ jsxRuntime.jsx(
5806
+ TooltipPrimitive__namespace.Provider,
5807
+ {
5808
+ "data-slot": "tooltip-provider",
5809
+ delayDuration,
5810
+ ...props
5811
+ }
5812
+ );
5813
+ }
5814
+ function Tooltip({
5815
+ ...props
5816
+ }) {
5817
+ return /* @__PURE__ */ jsxRuntime.jsx(TooltipProvider, { children: /* @__PURE__ */ jsxRuntime.jsx(TooltipPrimitive__namespace.Root, { "data-slot": "tooltip", ...props }) });
5818
+ }
5819
+ function TooltipTrigger({
5820
+ ...props
5821
+ }) {
5822
+ return /* @__PURE__ */ jsxRuntime.jsx(TooltipPrimitive__namespace.Trigger, { "data-slot": "tooltip-trigger", ...props });
5823
+ }
5824
+ function TooltipContent({
5825
+ className,
5826
+ sideOffset = 0,
5827
+ children,
5828
+ ...props
5829
+ }) {
5830
+ return /* @__PURE__ */ jsxRuntime.jsx(TooltipPrimitive__namespace.Portal, { children: /* @__PURE__ */ jsxRuntime.jsxs(
5831
+ TooltipPrimitive__namespace.Content,
5832
+ {
5833
+ "data-slot": "tooltip-content",
5834
+ sideOffset,
5835
+ className: cn(
5836
+ "bg-foreground text-background animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-fit origin-(--radix-tooltip-content-transform-origin) rounded-md px-3 py-1.5 text-xs text-balance",
5837
+ className
5838
+ ),
5839
+ ...props,
5840
+ children: [
5841
+ children,
5842
+ /* @__PURE__ */ jsxRuntime.jsx(TooltipPrimitive__namespace.Arrow, { className: "bg-foreground fill-foreground z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px]" })
5843
+ ]
5844
+ }
5845
+ ) });
5846
+ }
5863
5847
  function CalendarSubscribeButton({
5864
5848
  feedUrl,
5865
5849
  label
@@ -7634,26 +7618,6 @@ function CardInput({
7634
7618
  )
7635
7619
  ] });
7636
7620
  }
7637
-
7638
- // src/lib/usAddress.ts
7639
- function splitStreet(street) {
7640
- const trimmed = street.trim();
7641
- const m = trimmed.match(/^(\S+)\s+(.+)$/);
7642
- if (m && /^\d/.test(m[1])) {
7643
- return { number: m[1], name: m[2].trim() };
7644
- }
7645
- return { number: "", name: trimmed };
7646
- }
7647
- function joinStreet(streetNumber, streetName) {
7648
- return [streetNumber, streetName].map((s) => s.trim()).filter((s) => s.length > 0).join(" ");
7649
- }
7650
- function sanitizeForNls(input) {
7651
- return input.replace(/[^A-Za-z0-9 .,'#\-/]/g, " ").replace(/\s+/g, " ").trim();
7652
- }
7653
- function composeAddressLine1ForNls(v) {
7654
- const line = [v.streetNumber, v.streetName, v.apt].filter((s) => typeof s === "string" && s.trim().length > 0).join(" ");
7655
- return sanitizeForNls(line).slice(0, 40);
7656
- }
7657
7621
  function parseInitial(value) {
7658
7622
  if (!value) {
7659
7623
  return {
@@ -7674,28 +7638,6 @@ function parseInitial(value) {
7674
7638
  country: "US"
7675
7639
  };
7676
7640
  }
7677
- function legacyToModern(legacy) {
7678
- return {
7679
- street: joinStreet(legacy.streetNumber, legacy.streetName),
7680
- street2: legacy.apt ?? "",
7681
- city: legacy.city,
7682
- state: legacy.state,
7683
- zip: legacy.zipCode,
7684
- country: "US"
7685
- };
7686
- }
7687
- function toLegacy(modern) {
7688
- const parts = splitStreet(modern.street);
7689
- return {
7690
- streetNumber: sanitizeForNls(parts.number),
7691
- streetName: sanitizeForNls(parts.name),
7692
- apt: modern.street2 ? sanitizeForNls(modern.street2) : void 0,
7693
- city: modern.city.trim(),
7694
- state: modern.state.trim().toUpperCase(),
7695
- zipCode: modern.zip.replace(/\D/g, "").slice(0, 5),
7696
- country: "US"
7697
- };
7698
- }
7699
7641
  function addressSig(a) {
7700
7642
  return JSON.stringify({
7701
7643
  street: a.street.trim(),
@@ -7721,19 +7663,14 @@ function USAddressInput({
7721
7663
  disabled = false,
7722
7664
  largeText = false,
7723
7665
  className,
7724
- onError,
7725
- legacyMode = false,
7726
- valueLegacy,
7727
- onChangeLegacy
7666
+ onError
7728
7667
  }) {
7729
7668
  const [searchQuery, setSearchQuery] = React2.useState("");
7730
7669
  const [showSuggestions, setShowSuggestions] = React2.useState(false);
7731
7670
  const [suggestions, setSuggestions] = React2.useState([]);
7732
- const [address, setAddress] = React2.useState(() => {
7733
- if (value != null) return parseInitial(value);
7734
- if (valueLegacy != null) return legacyToModern(valueLegacy);
7735
- return parseInitial(void 0);
7736
- });
7671
+ const [address, setAddress] = React2.useState(
7672
+ () => parseInitial(value)
7673
+ );
7737
7674
  const [sessionToken] = React2.useState(
7738
7675
  () => typeof crypto !== "undefined" && crypto.randomUUID ? crypto.randomUUID() : `${Date.now()}-${Math.random()}`
7739
7676
  );
@@ -7755,22 +7692,6 @@ function USAddressInput({
7755
7692
  const addressRef = React2.useRef(address);
7756
7693
  addressRef.current = address;
7757
7694
  const lastValidatedSigRef = React2.useRef("");
7758
- const onChangeLegacyRef = React2.useRef(onChangeLegacy);
7759
- onChangeLegacyRef.current = onChangeLegacy;
7760
- const legacyModeRef = React2.useRef(legacyMode);
7761
- legacyModeRef.current = legacyMode;
7762
- const emitChange = React2.useRef((next) => {
7763
- onChange(next);
7764
- if (legacyModeRef.current && onChangeLegacyRef.current) {
7765
- onChangeLegacyRef.current(toLegacy(next));
7766
- }
7767
- });
7768
- emitChange.current = (next) => {
7769
- onChange(next);
7770
- if (legacyModeRef.current && onChangeLegacyRef.current) {
7771
- onChangeLegacyRef.current(toLegacy(next));
7772
- }
7773
- };
7774
7695
  const debouncedSearch = useDebouncedValue(searchQuery, 400);
7775
7696
  const zipDigits = address.zip.replace(/\D/g, "").slice(0, 5);
7776
7697
  const debouncedZip = useDebouncedValue(zipDigits, 400);
@@ -7787,18 +7708,13 @@ function USAddressInput({
7787
7708
  return () => document.removeEventListener("mousedown", handleClickOutside);
7788
7709
  }, []);
7789
7710
  const valueSyncKey = value == null ? "" : `o:${JSON.stringify(value)}`;
7790
- const valueLegacySyncKey = value != null || valueLegacy == null ? null : `l:${JSON.stringify(valueLegacy)}`;
7791
7711
  React2.useEffect(() => {
7792
7712
  setAddress(parseInitial(value));
7793
7713
  }, [valueSyncKey]);
7794
- React2.useEffect(() => {
7795
- if (valueLegacySyncKey == null) return;
7796
- setAddress(legacyToModern(valueLegacy));
7797
- }, [valueLegacySyncKey]);
7798
7714
  const handleFieldChange = (field, fieldValue) => {
7799
7715
  setAddress((prev) => {
7800
7716
  const next = field === "country" ? { ...prev, country: "US" } : { ...prev, [field]: fieldValue };
7801
- emitChange.current(next);
7717
+ onChange(next);
7802
7718
  return next;
7803
7719
  });
7804
7720
  };
@@ -7870,7 +7786,7 @@ function USAddressInput({
7870
7786
  if (cityEmpty && data.city) next.city = data.city;
7871
7787
  if (stateEmpty && data.state) next.state = data.state;
7872
7788
  next.country = "US";
7873
- emitChange.current(next);
7789
+ onChange(next);
7874
7790
  return next;
7875
7791
  });
7876
7792
  }).catch(() => {
@@ -7884,6 +7800,7 @@ function USAddressInput({
7884
7800
  debouncedZip,
7885
7801
  allowZipLookup,
7886
7802
  lookupZip,
7803
+ onChange,
7887
7804
  labels.zipLookupFailed,
7888
7805
  onError
7889
7806
  ]);
@@ -7945,7 +7862,7 @@ function USAddressInput({
7945
7862
  country: "US"
7946
7863
  };
7947
7864
  setAddress(normalized);
7948
- emitChange.current(normalized);
7865
+ onChange(normalized);
7949
7866
  setShowSuggestions(false);
7950
7867
  setSearchQuery("");
7951
7868
  setUspsSuggestion(null);
@@ -7958,7 +7875,7 @@ function USAddressInput({
7958
7875
  const applyUspsSuggestion = () => {
7959
7876
  if (!uspsSuggestion) return;
7960
7877
  setAddress(uspsSuggestion);
7961
- emitChange.current(uspsSuggestion);
7878
+ onChange(uspsSuggestion);
7962
7879
  setUspsSuggestion(null);
7963
7880
  lastValidatedSigRef.current = addressSig(uspsSuggestion);
7964
7881
  setUspsVerifiedNoChange(true);
@@ -8198,808 +8115,6 @@ function USAddressInput({
8198
8115
  ] })
8199
8116
  ] });
8200
8117
  }
8201
- function defaultPageOf(page, total) {
8202
- return `${page} / ${total}`;
8203
- }
8204
- var DEFAULT_WORKER_MSG = "PdfViewer requires a non-empty workerSrc pointing at pdf.worker matching your project's pdfjs-dist version. Example: `new URL('pdfjs-dist/build/pdf.worker.min.mjs', import.meta.url)`.";
8205
- function buildGetDocumentArgs(src, documentOptions) {
8206
- const rest = documentOptions ?? {};
8207
- if (typeof src === "string") {
8208
- return { url: src, ...rest };
8209
- }
8210
- return { data: src, ...rest };
8211
- }
8212
- function PdfPageCanvas({
8213
- page,
8214
- layout,
8215
- scale,
8216
- visible,
8217
- pageClassName
8218
- }) {
8219
- const canvasRef = React2.useRef(null);
8220
- const taskRef = React2.useRef(null);
8221
- React2.useEffect(() => {
8222
- if (!visible || !canvasRef.current) {
8223
- taskRef.current?.cancel();
8224
- taskRef.current = null;
8225
- const c = canvasRef.current;
8226
- if (c) {
8227
- const ctx2 = c.getContext("2d");
8228
- if (ctx2) {
8229
- ctx2.setTransform(1, 0, 0, 1, 0, 0);
8230
- ctx2.clearRect(0, 0, c.width, c.height);
8231
- }
8232
- }
8233
- return;
8234
- }
8235
- const canvas = canvasRef.current;
8236
- const ctx = canvas.getContext("2d");
8237
- if (!ctx) return;
8238
- const viewport = page.getViewport({ scale });
8239
- canvas.width = viewport.width;
8240
- canvas.height = viewport.height;
8241
- const task = page.render({
8242
- canvasContext: ctx,
8243
- viewport,
8244
- canvas
8245
- });
8246
- taskRef.current = task;
8247
- task.promise.catch(() => {
8248
- });
8249
- return () => {
8250
- task.cancel();
8251
- if (taskRef.current === task) {
8252
- taskRef.current = null;
8253
- }
8254
- };
8255
- }, [page, visible, scale]);
8256
- const w = layout.widthPt * scale;
8257
- const h = layout.heightPt * scale;
8258
- return /* @__PURE__ */ jsxRuntime.jsx(
8259
- "div",
8260
- {
8261
- className: cn("relative flex justify-center bg-muted/40", pageClassName),
8262
- style: { width: w, height: h },
8263
- "data-page": layout.pageNumber,
8264
- children: visible ? /* @__PURE__ */ jsxRuntime.jsx(
8265
- "canvas",
8266
- {
8267
- ref: canvasRef,
8268
- className: "block max-h-full shadow-sm",
8269
- "aria-hidden": "true"
8270
- }
8271
- ) : null
8272
- }
8273
- );
8274
- }
8275
- var PAGE_INPUT_CLASS = "h-8 w-14 rounded-md border px-2 text-sm tabular-nums shadow-sm border-neutral-300 bg-white text-neutral-950 caret-neutral-950 selection:bg-neutral-200 selection:text-neutral-950 dark:border-neutral-600 dark:bg-neutral-950 dark:text-neutral-50 dark:caret-neutral-50 dark:selection:bg-neutral-700 dark:selection:text-neutral-50";
8276
- function touchPairDistance(touches) {
8277
- if (touches.length < 2) return 0;
8278
- const a = touches.item(0);
8279
- const b = touches.item(1);
8280
- return Math.hypot(a.clientX - b.clientX, a.clientY - b.clientY);
8281
- }
8282
- function PdfThumbnailStrip({
8283
- page,
8284
- pageNumber,
8285
- active,
8286
- onPick,
8287
- label
8288
- }) {
8289
- const canvasRef = React2.useRef(null);
8290
- React2.useEffect(() => {
8291
- const canvas = canvasRef.current;
8292
- if (!canvas) return;
8293
- const viewport = page.getViewport({ scale: 1 });
8294
- const thumbMax = 176;
8295
- const s = thumbMax / Math.max(viewport.width, viewport.height);
8296
- const vp = page.getViewport({ scale: s });
8297
- const ctx = canvas.getContext("2d");
8298
- if (!ctx) return;
8299
- canvas.width = vp.width;
8300
- canvas.height = vp.height;
8301
- const task = page.render({
8302
- canvasContext: ctx,
8303
- viewport: vp,
8304
- canvas
8305
- });
8306
- task.promise.catch(() => {
8307
- });
8308
- return () => {
8309
- task.cancel();
8310
- };
8311
- }, [page]);
8312
- return /* @__PURE__ */ jsxRuntime.jsxs(
8313
- "button",
8314
- {
8315
- type: "button",
8316
- onClick: () => onPick(pageNumber),
8317
- className: cn(
8318
- "flex w-full flex-col items-center gap-1 rounded-md p-2 transition-colors hover:bg-white/5",
8319
- active ? "bg-white/10" : ""
8320
- ),
8321
- "aria-label": label,
8322
- "aria-current": active ? "page" : void 0,
8323
- children: [
8324
- /* @__PURE__ */ jsxRuntime.jsx(
8325
- "canvas",
8326
- {
8327
- ref: canvasRef,
8328
- className: "block max-w-full overflow-hidden rounded-sm bg-black",
8329
- "aria-hidden": true
8330
- }
8331
- ),
8332
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] tabular-nums text-neutral-400", children: pageNumber })
8333
- ]
8334
- }
8335
- );
8336
- }
8337
- function PdfViewer({
8338
- src,
8339
- workerSrc,
8340
- documentOptions,
8341
- initialPage = 1,
8342
- initialScale = 1,
8343
- minScale = 0.5,
8344
- maxScale = 4,
8345
- scaleStep = 0.2,
8346
- enableKeyboardShortcuts = true,
8347
- enablePinchZoom = true,
8348
- enableThumbnailSidebar = true,
8349
- thumbnailSidebarDefaultOpen = true,
8350
- labels,
8351
- onLoad,
8352
- onError,
8353
- onPageChange,
8354
- onScaleChange,
8355
- className,
8356
- toolbarClassName,
8357
- pageClassName,
8358
- toolbarEndSlot
8359
- }) {
8360
- const mergedLabels = labels ?? {};
8361
- const toolbarLabel = mergedLabels.toolbar ?? "PDF controls";
8362
- const loadingLabel = mergedLabels.loading ?? "Loading PDF\u2026";
8363
- const workerErrorMessage = mergedLabels.workerMissing ?? DEFAULT_WORKER_MSG;
8364
- const errorLabelFallback = mergedLabels.error ?? "Failed to load PDF";
8365
- const toolbarId = React2.useId();
8366
- const pageInputId = `${toolbarId}-page`;
8367
- const thumbnailNavId = `${toolbarId}-thumbnails`;
8368
- const scrollRef = React2.useRef(null);
8369
- const observerRef = React2.useRef(null);
8370
- const lastReportedPage = React2.useRef(0);
8371
- const loadedPdfRef = React2.useRef(null);
8372
- const [loadError, setLoadError] = React2.useState(null);
8373
- const [busy, setBusy] = React2.useState(false);
8374
- const [layouts, setLayouts] = React2.useState([]);
8375
- const [pagesMap, setPagesMap] = React2.useState(
8376
- null
8377
- );
8378
- const [scale, setScale] = React2.useState(initialScale);
8379
- const [ratios, setRatios] = React2.useState({});
8380
- const [pageInput, setPageInput] = React2.useState(String(initialPage));
8381
- const [thumbnailSidebarOpen, setThumbnailSidebarOpen] = React2.useState(
8382
- thumbnailSidebarDefaultOpen
8383
- );
8384
- const baselineScaleRef = React2.useRef(initialScale);
8385
- React2.useEffect(() => {
8386
- baselineScaleRef.current = initialScale;
8387
- }, [initialScale]);
8388
- const pageOfFormatter = mergedLabels.pageOf ?? defaultPageOf;
8389
- const resolvedGoToLabel = mergedLabels.goToPage ?? "Go to page";
8390
- const zoomInLabel = mergedLabels.zoomIn ?? "Zoom in";
8391
- const zoomOutLabel = mergedLabels.zoomOut ?? "Zoom out";
8392
- const resetZoomLabel = mergedLabels.resetZoom ?? "Reset zoom";
8393
- const fitWidthLabel = mergedLabels.fitToWidth ?? "Fit to width";
8394
- const thumbnailSidebarLabel = mergedLabels.thumbnailSidebar ?? "Page thumbnails";
8395
- const toggleThumbLabel = mergedLabels.toggleThumbnailSidebar ?? "Toggle page thumbnails";
8396
- const pageThumbLabel = mergedLabels.pageThumbnail ?? ((n) => `Page ${n}, show in document`);
8397
- const pageCount = layouts.length;
8398
- const currentVisiblePage = React2.useMemo(() => {
8399
- let bestPage = 1;
8400
- let bestRatio = -1;
8401
- for (const layout of layouts) {
8402
- const r2 = ratios[layout.pageNumber] ?? 0;
8403
- if (r2 > bestRatio) {
8404
- bestRatio = r2;
8405
- bestPage = layout.pageNumber;
8406
- }
8407
- }
8408
- return bestRatio >= 0.01 ? bestPage : 1;
8409
- }, [layouts, ratios]);
8410
- const clampScaleValue = React2.useCallback(
8411
- (v) => Math.min(maxScale, Math.max(minScale, v)),
8412
- [minScale, maxScale]
8413
- );
8414
- const zoomInAct = React2.useCallback(() => {
8415
- setScale((prev) => {
8416
- const c = clampScaleValue(prev + scaleStep);
8417
- onScaleChange?.(c);
8418
- return c;
8419
- });
8420
- }, [clampScaleValue, onScaleChange, scaleStep]);
8421
- const zoomOutAct = React2.useCallback(() => {
8422
- setScale((prev) => {
8423
- const c = clampScaleValue(prev - scaleStep);
8424
- onScaleChange?.(c);
8425
- return c;
8426
- });
8427
- }, [clampScaleValue, onScaleChange, scaleStep]);
8428
- const resetZoomAct = React2.useCallback(() => {
8429
- const c = clampScaleValue(baselineScaleRef.current);
8430
- setScale(c);
8431
- onScaleChange?.(c);
8432
- }, [clampScaleValue, onScaleChange]);
8433
- const fitToWidthAct = React2.useCallback(() => {
8434
- const root = scrollRef.current;
8435
- if (!root || layouts.length === 0) return;
8436
- const avail = Math.max(root.clientWidth - 32, 120);
8437
- const maxW = Math.max(...layouts.map((l) => l.widthPt), 1);
8438
- const next = clampScaleValue(avail / maxW);
8439
- setScale(next);
8440
- onScaleChange?.(next);
8441
- }, [clampScaleValue, layouts, onScaleChange]);
8442
- React2.useEffect(() => {
8443
- setPageInput(String(currentVisiblePage));
8444
- if (lastReportedPage.current !== currentVisiblePage) {
8445
- lastReportedPage.current = currentVisiblePage;
8446
- onPageChange?.(currentVisiblePage);
8447
- }
8448
- }, [currentVisiblePage, onPageChange]);
8449
- const scrollToPage = React2.useCallback((pageNum) => {
8450
- const root = scrollRef.current;
8451
- if (!root || pageNum < 1) return;
8452
- const el = root.querySelector(`[data-page="${pageNum}"]`);
8453
- if (el instanceof HTMLElement) {
8454
- el.scrollIntoView({ behavior: "smooth", block: "start" });
8455
- }
8456
- }, []);
8457
- React2.useEffect(() => {
8458
- if (!busy && pagesMap && pageCount > 0) {
8459
- const p = Math.min(Math.max(1, initialPage), pageCount);
8460
- requestAnimationFrame(() => scrollToPage(p));
8461
- }
8462
- }, [busy, pagesMap, pageCount, initialPage, scrollToPage]);
8463
- const loadKey = React2.useMemo(() => {
8464
- if (typeof src === "string") return src;
8465
- if (src instanceof ArrayBuffer) return `ab:${src.byteLength}`;
8466
- return `ua:${src.byteLength}:${src.byteOffset}:${src.buffer.byteLength}`;
8467
- }, [src]);
8468
- React2.useEffect(() => {
8469
- let cancelled = false;
8470
- let activeDoc = null;
8471
- setLoadError(null);
8472
- if (loadedPdfRef.current) {
8473
- void loadedPdfRef.current.destroy();
8474
- loadedPdfRef.current = null;
8475
- }
8476
- setLayouts([]);
8477
- setPagesMap(null);
8478
- setRatios({});
8479
- const trimmedWorker = workerSrc?.trim?.() ?? "";
8480
- if (!trimmedWorker) {
8481
- setLoadError(workerErrorMessage);
8482
- onError?.(new Error(workerErrorMessage));
8483
- return () => {
8484
- cancelled = true;
8485
- };
8486
- }
8487
- void (async () => {
8488
- try {
8489
- setBusy(true);
8490
- const pdfjs = await import('pdfjs-dist');
8491
- if (cancelled) return;
8492
- pdfjs.GlobalWorkerOptions.workerSrc = trimmedWorker;
8493
- const loadingTask = pdfjs.getDocument(
8494
- buildGetDocumentArgs(src, documentOptions)
8495
- );
8496
- activeDoc = await loadingTask.promise;
8497
- if (cancelled) {
8498
- void activeDoc.destroy();
8499
- activeDoc = null;
8500
- return;
8501
- }
8502
- const layoutsLocal = [];
8503
- const mapLocal = /* @__PURE__ */ new Map();
8504
- for (let p = 1; p <= activeDoc.numPages; p++) {
8505
- const page = await activeDoc.getPage(p);
8506
- mapLocal.set(p, page);
8507
- const viewport = page.getViewport({ scale: 1 });
8508
- layoutsLocal.push({
8509
- pageNumber: p,
8510
- widthPt: viewport.width,
8511
- heightPt: viewport.height
8512
- });
8513
- }
8514
- if (cancelled) {
8515
- void activeDoc.destroy();
8516
- activeDoc = null;
8517
- return;
8518
- }
8519
- onLoad?.(activeDoc);
8520
- loadedPdfRef.current = activeDoc;
8521
- setLayouts(layoutsLocal);
8522
- setPagesMap(mapLocal);
8523
- activeDoc = null;
8524
- } catch (e) {
8525
- const err = e instanceof Error ? e : new Error(String(e));
8526
- if (!cancelled) {
8527
- setLoadError(errorLabelFallback);
8528
- onError?.(err);
8529
- }
8530
- if (activeDoc) {
8531
- void activeDoc.destroy();
8532
- activeDoc = null;
8533
- }
8534
- } finally {
8535
- if (!cancelled) setBusy(false);
8536
- }
8537
- })();
8538
- return () => {
8539
- cancelled = true;
8540
- if (observerRef.current) {
8541
- observerRef.current.disconnect();
8542
- observerRef.current = null;
8543
- }
8544
- if (activeDoc) {
8545
- void activeDoc.destroy();
8546
- }
8547
- if (loadedPdfRef.current) {
8548
- void loadedPdfRef.current.destroy();
8549
- loadedPdfRef.current = null;
8550
- }
8551
- };
8552
- }, [workerSrc, loadKey, documentOptions]);
8553
- React2.useEffect(() => {
8554
- setScale(clampScaleValue(initialScale));
8555
- }, [initialScale, clampScaleValue]);
8556
- React2.useEffect(() => {
8557
- const el = scrollRef.current;
8558
- if (!el || !enablePinchZoom) return;
8559
- let pinchDist = 0;
8560
- const onWheel = (e) => {
8561
- if (!e.ctrlKey) return;
8562
- e.preventDefault();
8563
- const delta = -e.deltaY;
8564
- const factor = Math.exp(delta * 2e-3);
8565
- setScale((prev) => {
8566
- const c = clampScaleValue(prev * factor);
8567
- onScaleChange?.(c);
8568
- return c;
8569
- });
8570
- };
8571
- const onTouchStart = (e) => {
8572
- if (e.touches.length === 2) {
8573
- pinchDist = touchPairDistance(e.touches);
8574
- }
8575
- };
8576
- const onTouchMove = (e) => {
8577
- if (e.touches.length !== 2 || pinchDist <= 0) return;
8578
- e.preventDefault();
8579
- const d = touchPairDistance(e.touches);
8580
- const ratio = d / pinchDist;
8581
- pinchDist = d;
8582
- setScale((prev) => {
8583
- const c = clampScaleValue(prev * ratio);
8584
- onScaleChange?.(c);
8585
- return c;
8586
- });
8587
- };
8588
- const endPinch = (e) => {
8589
- if (e.touches.length < 2) pinchDist = 0;
8590
- };
8591
- el.addEventListener("wheel", onWheel, { passive: false });
8592
- el.addEventListener("touchstart", onTouchStart, { passive: true });
8593
- el.addEventListener("touchmove", onTouchMove, { passive: false });
8594
- el.addEventListener("touchend", endPinch);
8595
- el.addEventListener("touchcancel", endPinch);
8596
- return () => {
8597
- el.removeEventListener("wheel", onWheel);
8598
- el.removeEventListener("touchstart", onTouchStart);
8599
- el.removeEventListener("touchmove", onTouchMove);
8600
- el.removeEventListener("touchend", endPinch);
8601
- el.removeEventListener("touchcancel", endPinch);
8602
- };
8603
- }, [enablePinchZoom, clampScaleValue, onScaleChange]);
8604
- React2.useEffect(() => {
8605
- if (layouts.length === 0) return;
8606
- const frame = requestAnimationFrame(() => {
8607
- const root = scrollRef.current;
8608
- if (!root) return;
8609
- if (observerRef.current) {
8610
- observerRef.current.disconnect();
8611
- }
8612
- const io = new IntersectionObserver(
8613
- (entries) => {
8614
- setRatios((prev) => {
8615
- const next = { ...prev };
8616
- for (const e of entries) {
8617
- const tgt = e.target;
8618
- const p = Number(tgt.dataset.page);
8619
- if (Number.isFinite(p)) next[p] = e.intersectionRatio;
8620
- }
8621
- return next;
8622
- });
8623
- },
8624
- {
8625
- root,
8626
- rootMargin: "200px 0px",
8627
- threshold: [0, 0.05, 0.25, 0.5, 0.75, 1]
8628
- }
8629
- );
8630
- observerRef.current = io;
8631
- root.querySelectorAll("[data-page]").forEach((el) => io.observe(el));
8632
- });
8633
- return () => {
8634
- cancelAnimationFrame(frame);
8635
- if (observerRef.current) {
8636
- observerRef.current.disconnect();
8637
- observerRef.current = null;
8638
- }
8639
- };
8640
- }, [layouts]);
8641
- const handleSubmitPage = React2.useCallback(() => {
8642
- const n = Number.parseInt(pageInput, 10);
8643
- if (!Number.isFinite(n) || pageCount === 0) return;
8644
- const clamped = Math.min(Math.max(1, n), pageCount);
8645
- scrollToPage(clamped);
8646
- setPageInput(String(clamped));
8647
- }, [pageInput, pageCount, scrollToPage]);
8648
- const handleKeyDown = React2.useCallback(
8649
- (e) => {
8650
- if (!enableKeyboardShortcuts) return;
8651
- if (e.target !== e.currentTarget && e.target instanceof HTMLInputElement) {
8652
- return;
8653
- }
8654
- let handled = false;
8655
- switch (e.key) {
8656
- case "PageDown": {
8657
- scrollToPage(Math.min(pageCount || 1, currentVisiblePage + 1));
8658
- handled = true;
8659
- break;
8660
- }
8661
- case "PageUp": {
8662
- scrollToPage(Math.max(1, currentVisiblePage - 1));
8663
- handled = true;
8664
- break;
8665
- }
8666
- case "Home": {
8667
- scrollToPage(1);
8668
- handled = true;
8669
- break;
8670
- }
8671
- case "End": {
8672
- if (pageCount) scrollToPage(pageCount);
8673
- handled = true;
8674
- break;
8675
- }
8676
- case "+":
8677
- case "=": {
8678
- zoomInAct();
8679
- handled = true;
8680
- break;
8681
- }
8682
- case "-":
8683
- case "_": {
8684
- zoomOutAct();
8685
- handled = true;
8686
- break;
8687
- }
8688
- case "0": {
8689
- resetZoomAct();
8690
- handled = true;
8691
- break;
8692
- }
8693
- }
8694
- if (handled) {
8695
- e.preventDefault();
8696
- e.stopPropagation();
8697
- }
8698
- },
8699
- [
8700
- enableKeyboardShortcuts,
8701
- pageCount,
8702
- currentVisiblePage,
8703
- scrollToPage,
8704
- zoomInAct,
8705
- zoomOutAct,
8706
- resetZoomAct
8707
- ]
8708
- );
8709
- const thumbnailsRailEligible = enableThumbnailSidebar && !busy && pagesMap !== null && pageCount > 0;
8710
- if (loadError) {
8711
- return /* @__PURE__ */ jsxRuntime.jsx(
8712
- "div",
8713
- {
8714
- className: cn("rounded-md border border-destructive/50 p-4", className),
8715
- role: "alert",
8716
- children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-destructive text-sm", children: loadError })
8717
- }
8718
- );
8719
- }
8720
- return /* @__PURE__ */ jsxRuntime.jsxs(
8721
- "div",
8722
- {
8723
- className: cn(
8724
- "flex min-h-0 flex-col overflow-hidden rounded-md border",
8725
- className
8726
- ),
8727
- children: [
8728
- /* @__PURE__ */ jsxRuntime.jsxs(
8729
- "div",
8730
- {
8731
- id: toolbarId,
8732
- role: "toolbar",
8733
- "aria-label": toolbarLabel,
8734
- className: cn(
8735
- "sticky top-0 z-10 flex shrink-0 flex-wrap items-center gap-2 border-b bg-background/95 px-2 py-2 backdrop-blur supports-[backdrop-filter]:bg-background/80",
8736
- toolbarClassName
8737
- ),
8738
- children: [
8739
- thumbnailsRailEligible ? /* @__PURE__ */ jsxRuntime.jsx(
8740
- Button,
8741
- {
8742
- type: "button",
8743
- variant: "outline",
8744
- size: "icon-sm",
8745
- className: "hidden md:inline-flex",
8746
- onClick: () => setThumbnailSidebarOpen((v) => !v),
8747
- "aria-label": toggleThumbLabel,
8748
- "aria-expanded": thumbnailSidebarOpen,
8749
- "aria-controls": thumbnailNavId,
8750
- children: thumbnailSidebarOpen ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.PanelLeftOpen, { className: "size-4", "aria-hidden": true }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.PanelRightOpen, { className: "size-4", "aria-hidden": true })
8751
- }
8752
- ) : null,
8753
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground text-xs tabular-nums sm:text-sm", children: busy || pagesMap === null ? "\u2014" : pageOfFormatter(currentVisiblePage, pageCount) }),
8754
- /* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: pageInputId, className: "sr-only", children: resolvedGoToLabel }),
8755
- /* @__PURE__ */ jsxRuntime.jsx(
8756
- "input",
8757
- {
8758
- id: pageInputId,
8759
- type: "number",
8760
- min: 1,
8761
- max: Math.max(pageCount, 1),
8762
- disabled: busy || pageCount === 0,
8763
- className: PAGE_INPUT_CLASS,
8764
- "aria-label": resolvedGoToLabel,
8765
- value: pageInput,
8766
- onChange: (ev) => setPageInput(ev.target.value),
8767
- onKeyDown: (ev) => {
8768
- if (ev.key === "Enter") {
8769
- ev.preventDefault();
8770
- handleSubmitPage();
8771
- }
8772
- }
8773
- }
8774
- ),
8775
- /* @__PURE__ */ jsxRuntime.jsx(
8776
- Button,
8777
- {
8778
- type: "button",
8779
- variant: "outline",
8780
- size: "icon-sm",
8781
- onClick: zoomOutAct,
8782
- disabled: busy || scale <= minScale,
8783
- "aria-label": zoomOutLabel,
8784
- children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ZoomOut, { "aria-hidden": true })
8785
- }
8786
- ),
8787
- /* @__PURE__ */ jsxRuntime.jsx(
8788
- Button,
8789
- {
8790
- type: "button",
8791
- variant: "outline",
8792
- size: "icon-sm",
8793
- onClick: zoomInAct,
8794
- disabled: busy || scale >= maxScale,
8795
- "aria-label": zoomInLabel,
8796
- children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ZoomIn, { "aria-hidden": true })
8797
- }
8798
- ),
8799
- /* @__PURE__ */ jsxRuntime.jsx(
8800
- Button,
8801
- {
8802
- type: "button",
8803
- variant: "outline",
8804
- size: "icon-sm",
8805
- onClick: resetZoomAct,
8806
- disabled: busy,
8807
- "aria-label": resetZoomLabel,
8808
- children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.RotateCcw, { "aria-hidden": true })
8809
- }
8810
- ),
8811
- /* @__PURE__ */ jsxRuntime.jsx(
8812
- Button,
8813
- {
8814
- type: "button",
8815
- variant: "outline",
8816
- size: "icon-sm",
8817
- onClick: fitToWidthAct,
8818
- disabled: busy || pageCount === 0,
8819
- "aria-label": fitWidthLabel,
8820
- children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Maximize2, { "aria-hidden": true })
8821
- }
8822
- ),
8823
- toolbarEndSlot
8824
- ]
8825
- }
8826
- ),
8827
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-h-0 flex-1 overflow-hidden", children: [
8828
- thumbnailsRailEligible && thumbnailSidebarOpen ? /* @__PURE__ */ jsxRuntime.jsx(
8829
- "nav",
8830
- {
8831
- id: thumbnailNavId,
8832
- className: "hidden w-[220px] shrink-0 flex-col overflow-y-auto border-r border-neutral-900 bg-black py-3 pl-3 pr-2 md:flex",
8833
- "aria-label": thumbnailSidebarLabel,
8834
- children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-2", children: layouts.map((layout) => {
8835
- const pg = pagesMap.get(layout.pageNumber);
8836
- return pg ? /* @__PURE__ */ jsxRuntime.jsx(
8837
- PdfThumbnailStrip,
8838
- {
8839
- page: pg,
8840
- pageNumber: layout.pageNumber,
8841
- active: layout.pageNumber === currentVisiblePage,
8842
- onPick: scrollToPage,
8843
- label: pageThumbLabel(layout.pageNumber)
8844
- },
8845
- `thumb-${layout.pageNumber}`
8846
- ) : null;
8847
- }) })
8848
- }
8849
- ) : null,
8850
- /* @__PURE__ */ jsxRuntime.jsx(
8851
- "div",
8852
- {
8853
- ref: scrollRef,
8854
- tabIndex: 0,
8855
- onKeyDown: handleKeyDown,
8856
- className: "relative min-h-[240px] min-w-0 flex-1 overflow-auto outline-none focus-visible:ring-2 focus-visible:ring-ring",
8857
- "aria-busy": busy,
8858
- "aria-label": busy ? loadingLabel : "PDF pages",
8859
- children: busy || pagesMap === null ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground p-6 text-sm", children: loadingLabel }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col items-center gap-4 pb-8 pt-2", children: layouts.map((layout) => {
8860
- const pg = pagesMap.get(layout.pageNumber);
8861
- const visible = (ratios[layout.pageNumber] ?? 0) >= 1e-3;
8862
- return pg ? /* @__PURE__ */ jsxRuntime.jsx(
8863
- PdfPageCanvas,
8864
- {
8865
- page: pg,
8866
- layout,
8867
- scale,
8868
- visible,
8869
- pageClassName
8870
- },
8871
- layout.pageNumber
8872
- ) : null;
8873
- }) })
8874
- }
8875
- )
8876
- ] })
8877
- ]
8878
- }
8879
- );
8880
- }
8881
- function usePdfViewerDialogScrollLock(active) {
8882
- React2.useLayoutEffect(() => {
8883
- if (!active || typeof document === "undefined") return;
8884
- const html = document.documentElement;
8885
- const body = document.body;
8886
- const scrollRoots = [
8887
- ...document.querySelectorAll("[data-scroll-lock-root]")
8888
- ];
8889
- const scrollTopSnapshot = scrollRoots.map((el) => ({
8890
- el,
8891
- scrollTop: el.scrollTop
8892
- }));
8893
- const targets = /* @__PURE__ */ new Set([html, body, ...scrollRoots]);
8894
- const snapshot = [...targets].map((el) => ({
8895
- el,
8896
- overflow: el.style.overflow,
8897
- overscrollBehavior: el.style.overscrollBehavior
8898
- }));
8899
- const windowScrollY = window.scrollY;
8900
- for (const el of targets) {
8901
- el.style.overflow = "hidden";
8902
- el.style.overscrollBehavior = "none";
8903
- }
8904
- const dialogSurfaceSelector = '[data-slot="dialog-content"]';
8905
- const shouldAllowEventTarget = (target) => target instanceof Element && Boolean(target.closest(dialogSurfaceSelector));
8906
- const onWheel = (e) => {
8907
- if (shouldAllowEventTarget(e.target)) return;
8908
- e.preventDefault();
8909
- };
8910
- const onTouchMove = (e) => {
8911
- if (shouldAllowEventTarget(e.target)) return;
8912
- e.preventDefault();
8913
- };
8914
- window.addEventListener("wheel", onWheel, {
8915
- capture: true,
8916
- passive: false
8917
- });
8918
- window.addEventListener("touchmove", onTouchMove, {
8919
- capture: true,
8920
- passive: false
8921
- });
8922
- return () => {
8923
- window.removeEventListener("wheel", onWheel, { capture: true });
8924
- window.removeEventListener("touchmove", onTouchMove, {
8925
- capture: true
8926
- });
8927
- for (const { el, overflow, overscrollBehavior } of snapshot) {
8928
- el.style.overflow = overflow;
8929
- el.style.overscrollBehavior = overscrollBehavior;
8930
- }
8931
- for (const { el, scrollTop } of scrollTopSnapshot) {
8932
- el.scrollTop = scrollTop;
8933
- }
8934
- window.scrollTo(0, windowScrollY);
8935
- };
8936
- }, [active]);
8937
- }
8938
- var fullscreenDialogContentClass = "!max-w-none !w-screen !h-screen !p-0 !border-0 !bg-black/95 !rounded-none !top-0 !left-0 !translate-x-0 !translate-y-0 !gap-0 !shadow-none !flex !flex-col data-[state=open]:!zoom-in-100 data-[state=closed]:!zoom-out-100";
8939
- function PdfViewerDialog({
8940
- open,
8941
- onOpenChange,
8942
- src,
8943
- workerSrc,
8944
- documentOptions,
8945
- trigger,
8946
- title,
8947
- labels,
8948
- forwardedProps
8949
- }) {
8950
- const closeLabel = labels?.close ?? "Close";
8951
- const dialogTitle = labels?.dialogTitle ?? title ?? "PDF document";
8952
- const dialogDescription = labels?.dialogDescription ?? "Document viewer with zoom and page navigation.";
8953
- usePdfViewerDialogScrollLock(open);
8954
- const {
8955
- className: forwardedClassName,
8956
- toolbarClassName: forwardedToolbarClassName,
8957
- ...restForwarded
8958
- } = forwardedProps ?? {};
8959
- return /* @__PURE__ */ jsxRuntime.jsxs(Dialog, { open, onOpenChange, children: [
8960
- trigger ? /* @__PURE__ */ jsxRuntime.jsx(DialogTrigger, { asChild: true, children: trigger }) : null,
8961
- /* @__PURE__ */ jsxRuntime.jsxs(
8962
- DialogContent,
8963
- {
8964
- className: fullscreenDialogContentClass,
8965
- showCloseButton: false,
8966
- children: [
8967
- /* @__PURE__ */ jsxRuntime.jsx(DialogTitle, { className: "sr-only", children: dialogTitle }),
8968
- /* @__PURE__ */ jsxRuntime.jsx(DialogDescription, { className: "sr-only", children: dialogDescription }),
8969
- /* @__PURE__ */ jsxRuntime.jsx(
8970
- PdfViewer,
8971
- {
8972
- ...restForwarded,
8973
- src,
8974
- workerSrc,
8975
- documentOptions,
8976
- className: cn(
8977
- "min-h-0 flex-1 rounded-none border-0 bg-transparent text-white",
8978
- forwardedClassName
8979
- ),
8980
- toolbarClassName: cn(
8981
- "border-white/10 bg-black/80 text-white backdrop-blur",
8982
- forwardedToolbarClassName
8983
- ),
8984
- toolbarEndSlot: /* @__PURE__ */ jsxRuntime.jsx(
8985
- Button,
8986
- {
8987
- type: "button",
8988
- variant: "ghost",
8989
- size: "icon-sm",
8990
- className: "ml-auto text-white hover:bg-white/10 hover:text-white",
8991
- onClick: () => onOpenChange(false),
8992
- "aria-label": closeLabel,
8993
- children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "size-5", "aria-hidden": true })
8994
- }
8995
- )
8996
- }
8997
- )
8998
- ]
8999
- }
9000
- )
9001
- ] });
9002
- }
9003
8118
 
9004
8119
  exports.AvatarEditor = AvatarEditor;
9005
8120
  exports.AvatarEditorDialog = AvatarEditorDialog;
@@ -9061,8 +8176,6 @@ exports.LanguageSwitcher = LanguageSwitcher;
9061
8176
  exports.MiniCalendar = MiniCalendar;
9062
8177
  exports.NotificationsContext = NotificationsContext;
9063
8178
  exports.NotificationsWidget = NotificationsWidget;
9064
- exports.PdfViewer = PdfViewer;
9065
- exports.PdfViewerDialog = PdfViewerDialog;
9066
8179
  exports.Popover = Popover;
9067
8180
  exports.PopoverAnchor = PopoverAnchor;
9068
8181
  exports.PopoverContent = PopoverContent;
@@ -9080,14 +8193,10 @@ exports.USAddressInput = USAddressInput;
9080
8193
  exports.UpcomingEvents = UpcomingEvents;
9081
8194
  exports.buttonVariants = buttonVariants;
9082
8195
  exports.cn = cn;
9083
- exports.composeAddressLine1ForNls = composeAddressLine1ForNls;
9084
8196
  exports.defaultLanguages = defaultLanguages;
9085
8197
  exports.getEnvironmentDotClass = getEnvironmentDotClass;
9086
8198
  exports.getEnvironmentLabel = getEnvironmentLabel;
9087
8199
  exports.isBlocksDataEnvironment = isBlocksDataEnvironment;
9088
- exports.joinStreet = joinStreet;
9089
- exports.sanitizeForNls = sanitizeForNls;
9090
- exports.splitStreet = splitStreet;
9091
8200
  exports.toggleVariants = toggleVariants;
9092
8201
  exports.useCalendarContext = useCalendarContext;
9093
8202
  exports.useChatRoom = useChatRoom;