@ohhwells/bridge 0.1.48-next.113 → 0.1.49-next.114

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
@@ -36,6 +36,12 @@ __export(index_exports, {
36
36
  CustomToolbarDivider: () => CustomToolbarDivider,
37
37
  DragHandle: () => DragHandle,
38
38
  DropIndicator: () => DropIndicator,
39
+ DropdownMenu: () => DropdownMenu,
40
+ DropdownMenuContent: () => DropdownMenuContent,
41
+ DropdownMenuGroup: () => DropdownMenuGroup,
42
+ DropdownMenuItem: () => DropdownMenuItem,
43
+ DropdownMenuSeparator: () => DropdownMenuSeparator,
44
+ DropdownMenuTrigger: () => DropdownMenuTrigger,
39
45
  ItemActionToolbar: () => ItemActionToolbar,
40
46
  ItemInteractionLayer: () => ItemInteractionLayer,
41
47
  LinkEditorPanel: () => LinkEditorPanel,
@@ -63,7 +69,7 @@ __export(index_exports, {
63
69
  module.exports = __toCommonJS(index_exports);
64
70
 
65
71
  // src/OhhwellsBridge.tsx
66
- var import_react10 = __toESM(require("react"), 1);
72
+ var import_react11 = __toESM(require("react"), 1);
67
73
  var import_client = require("react-dom/client");
68
74
  var import_react_dom2 = require("react-dom");
69
75
 
@@ -4400,22 +4406,116 @@ var CustomToolbarButton = React4.forwardRef(
4400
4406
  CustomToolbarButton.displayName = "CustomToolbarButton";
4401
4407
 
4402
4408
  // src/ui/item-action-toolbar.tsx
4409
+ var import_react4 = require("react");
4403
4410
  var import_lucide_react2 = require("lucide-react");
4404
4411
 
4405
- // src/ui/tooltip.tsx
4412
+ // src/ui/dropdown-menu.tsx
4406
4413
  var import_radix_ui3 = require("radix-ui");
4407
4414
  var import_jsx_runtime7 = require("react/jsx-runtime");
4415
+ function DropdownMenu({ ...props }) {
4416
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_radix_ui3.DropdownMenu.Root, { "data-slot": "dropdown-menu", ...props });
4417
+ }
4418
+ function DropdownMenuTrigger({
4419
+ ...props
4420
+ }) {
4421
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_radix_ui3.DropdownMenu.Trigger, { "data-slot": "dropdown-menu-trigger", ...props });
4422
+ }
4423
+ function DropdownMenuGroup({
4424
+ className,
4425
+ ...props
4426
+ }) {
4427
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4428
+ import_radix_ui3.DropdownMenu.Group,
4429
+ {
4430
+ "data-slot": "dropdown-menu-group",
4431
+ className: cn("flex w-full flex-col items-start p-1", className),
4432
+ ...props
4433
+ }
4434
+ );
4435
+ }
4436
+ function DropdownMenuContent({
4437
+ className,
4438
+ sideOffset = 6,
4439
+ ...props
4440
+ }) {
4441
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_radix_ui3.DropdownMenu.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4442
+ import_radix_ui3.DropdownMenu.Content,
4443
+ {
4444
+ "data-slot": "dropdown-menu-content",
4445
+ "data-ohw-more-menu": "",
4446
+ sideOffset,
4447
+ className: cn(
4448
+ "z-[2147483647] flex w-56 min-w-32 flex-col items-center overflow-hidden rounded-[6px] border border-border bg-popover p-0 text-popover-foreground outline-none",
4449
+ "shadow-[0px_4px_6px_0px_rgba(0,0,0,0.1),0px_2px_4px_0px_rgba(0,0,0,0.1)]",
4450
+ "origin-[var(--radix-dropdown-menu-content-transform-origin)]",
4451
+ "data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95",
4452
+ "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",
4453
+ className
4454
+ ),
4455
+ ...props
4456
+ }
4457
+ ) });
4458
+ }
4459
+ function DropdownMenuItem({
4460
+ className,
4461
+ inset,
4462
+ variant = "default",
4463
+ ...props
4464
+ }) {
4465
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4466
+ import_radix_ui3.DropdownMenu.Item,
4467
+ {
4468
+ "data-slot": "dropdown-menu-item",
4469
+ "data-inset": inset ? "" : void 0,
4470
+ "data-variant": variant,
4471
+ className: cn(
4472
+ "relative flex w-full min-w-32 cursor-pointer select-none items-center gap-2 rounded-[calc(var(--radius,0.5rem)-4px)] py-1.5 pl-8 pr-2 text-sm leading-5 outline-none",
4473
+ "text-popover-foreground",
4474
+ "focus:bg-muted data-[highlighted]:bg-muted",
4475
+ "data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
4476
+ "[&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
4477
+ "[&_svg:not([class*=absolute])]:relative",
4478
+ // Leading icon — Figma absolute left-2 / top-1/2
4479
+ "[&>svg:first-child]:absolute [&>svg:first-child]:left-2 [&>svg:first-child]:top-1/2 [&>svg:first-child]:-translate-y-1/2",
4480
+ "data-[variant=destructive]:text-destructive",
4481
+ "data-[variant=destructive]:focus:bg-bg-destructive-10 data-[variant=destructive]:focus:text-destructive",
4482
+ "data-[variant=destructive]:data-[highlighted]:bg-bg-destructive-10 data-[variant=destructive]:data-[highlighted]:text-destructive",
4483
+ "data-[variant=destructive]:[&_svg]:text-destructive",
4484
+ inset && "pl-8",
4485
+ className
4486
+ ),
4487
+ ...props
4488
+ }
4489
+ );
4490
+ }
4491
+ function DropdownMenuSeparator({
4492
+ className,
4493
+ ...props
4494
+ }) {
4495
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4496
+ import_radix_ui3.DropdownMenu.Separator,
4497
+ {
4498
+ "data-slot": "dropdown-menu-separator",
4499
+ className: cn("h-px w-full bg-border", className),
4500
+ ...props
4501
+ }
4502
+ );
4503
+ }
4504
+
4505
+ // src/ui/tooltip.tsx
4506
+ var import_radix_ui4 = require("radix-ui");
4507
+ var import_jsx_runtime8 = require("react/jsx-runtime");
4408
4508
  function TooltipProvider({
4409
4509
  delayDuration = 0,
4410
4510
  ...props
4411
4511
  }) {
4412
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_radix_ui3.Tooltip.Provider, { "data-slot": "tooltip-provider", delayDuration, ...props });
4512
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_radix_ui4.Tooltip.Provider, { "data-slot": "tooltip-provider", delayDuration, ...props });
4413
4513
  }
4414
4514
  function Tooltip({ ...props }) {
4415
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_radix_ui3.Tooltip.Root, { "data-slot": "tooltip", ...props });
4515
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_radix_ui4.Tooltip.Root, { "data-slot": "tooltip", ...props });
4416
4516
  }
4417
4517
  function TooltipTrigger({ ...props }) {
4418
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_radix_ui3.Tooltip.Trigger, { "data-slot": "tooltip-trigger", ...props });
4518
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_radix_ui4.Tooltip.Trigger, { "data-slot": "tooltip-trigger", ...props });
4419
4519
  }
4420
4520
  var arrowClassBySide = {
4421
4521
  top: "before:bottom-0 before:left-1/2 before:-translate-x-1/2 before:translate-y-1/2",
@@ -4432,8 +4532,8 @@ function TooltipContent({
4432
4532
  ...props
4433
4533
  }) {
4434
4534
  const resolvedSide = side ?? "bottom";
4435
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_radix_ui3.Tooltip.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
4436
- import_radix_ui3.Tooltip.Content,
4535
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_radix_ui4.Tooltip.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
4536
+ import_radix_ui4.Tooltip.Content,
4437
4537
  {
4438
4538
  "data-slot": "tooltip-content",
4439
4539
  side,
@@ -4455,7 +4555,7 @@ function TooltipContent({
4455
4555
  }
4456
4556
 
4457
4557
  // src/ui/item-action-toolbar.tsx
4458
- var import_jsx_runtime8 = require("react/jsx-runtime");
4558
+ var import_jsx_runtime9 = require("react/jsx-runtime");
4459
4559
  function ToolbarActionTooltip({
4460
4560
  label,
4461
4561
  side = "bottom",
@@ -4463,25 +4563,31 @@ function ToolbarActionTooltip({
4463
4563
  buttonProps,
4464
4564
  children
4465
4565
  }) {
4466
- const button = /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(CustomToolbarButton, { type: "button", "aria-label": label, disabled, ...buttonProps, children });
4467
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(Tooltip, { children: [
4468
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(TooltipTrigger, { asChild: true, children: disabled ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "inline-flex", children: button }) : button }),
4469
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(TooltipContent, { side, sideOffset: 9, children: label })
4566
+ const button = /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(CustomToolbarButton, { type: "button", "aria-label": label, disabled, ...buttonProps, children });
4567
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Tooltip, { children: [
4568
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(TooltipTrigger, { asChild: true, children: disabled ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "inline-flex", children: button }) : button }),
4569
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(TooltipContent, { side, sideOffset: 9, children: label })
4470
4570
  ] });
4471
4571
  }
4472
4572
  function ItemActionToolbar({
4473
4573
  onEditLink,
4474
4574
  onAddItem,
4475
- onMore,
4575
+ onSelectParent,
4576
+ onDuplicate,
4577
+ onDelete,
4476
4578
  editLinkDisabled = false,
4477
4579
  addItemDisabled = true,
4478
- moreDisabled = true,
4580
+ moreDisabled = false,
4581
+ selectParentDisabled = false,
4582
+ duplicateDisabled = false,
4583
+ deleteDisabled = false,
4479
4584
  showAddItem = true,
4480
4585
  showMore = true,
4481
4586
  tooltipSide = "bottom"
4482
4587
  }) {
4483
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(TooltipProvider, { delayDuration: 0, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(CustomToolbar, { children: [
4484
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
4588
+ const [moreOpen, setMoreOpen] = (0, import_react4.useState)(false);
4589
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(TooltipProvider, { delayDuration: 0, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(CustomToolbar, { children: [
4590
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
4485
4591
  ToolbarActionTooltip,
4486
4592
  {
4487
4593
  label: "Edit link",
@@ -4499,10 +4605,10 @@ function ItemActionToolbar({
4499
4605
  e.stopPropagation();
4500
4606
  }
4501
4607
  },
4502
- children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_lucide_react2.Link, { className: "size-4 shrink-0", "aria-hidden": true })
4608
+ children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react2.Link, { className: "size-4 shrink-0", "aria-hidden": true })
4503
4609
  }
4504
4610
  ),
4505
- showAddItem ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
4611
+ showAddItem ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
4506
4612
  ToolbarActionTooltip,
4507
4613
  {
4508
4614
  label: "Add item",
@@ -4516,32 +4622,84 @@ function ItemActionToolbar({
4516
4622
  onAddItem?.();
4517
4623
  }
4518
4624
  },
4519
- children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_lucide_react2.Plus, { className: "size-4 shrink-0", "aria-hidden": true })
4625
+ children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react2.Plus, { className: "size-4 shrink-0", "aria-hidden": true })
4520
4626
  }
4521
4627
  ) : null,
4522
- showMore ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
4523
- ToolbarActionTooltip,
4524
- {
4525
- label: "More",
4526
- side: tooltipSide,
4527
- disabled: moreDisabled,
4528
- buttonProps: {
4628
+ showMore ? /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(DropdownMenu, { open: moreOpen, onOpenChange: setMoreOpen, children: [
4629
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Tooltip, { open: moreOpen ? false : void 0, children: [
4630
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(DropdownMenuTrigger, { asChild: true, disabled: moreDisabled, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
4631
+ CustomToolbarButton,
4632
+ {
4633
+ type: "button",
4634
+ "aria-label": "More",
4635
+ disabled: moreDisabled,
4636
+ onMouseDown: (e) => {
4637
+ e.preventDefault();
4638
+ e.stopPropagation();
4639
+ },
4640
+ children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react2.MoreHorizontal, { className: "size-4 shrink-0", "aria-hidden": true })
4641
+ }
4642
+ ) }) }),
4643
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(TooltipContent, { side: tooltipSide, sideOffset: 9, children: "More" })
4644
+ ] }),
4645
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
4646
+ DropdownMenuContent,
4647
+ {
4648
+ align: "end",
4649
+ side: "bottom",
4650
+ onCloseAutoFocus: (e) => e.preventDefault(),
4529
4651
  onMouseDown: (e) => {
4530
- if (moreDisabled) return;
4531
4652
  e.preventDefault();
4532
4653
  e.stopPropagation();
4533
- onMore?.();
4534
- }
4535
- },
4536
- children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_lucide_react2.MoreHorizontal, { className: "size-4 shrink-0", "aria-hidden": true })
4537
- }
4538
- ) : null
4654
+ },
4655
+ children: [
4656
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(DropdownMenuGroup, { children: [
4657
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
4658
+ DropdownMenuItem,
4659
+ {
4660
+ disabled: selectParentDisabled,
4661
+ onSelect: () => onSelectParent?.(),
4662
+ children: [
4663
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react2.CornerLeftUp, { size: 12, "aria-hidden": true }),
4664
+ "Select parent"
4665
+ ]
4666
+ }
4667
+ ),
4668
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
4669
+ DropdownMenuItem,
4670
+ {
4671
+ disabled: duplicateDisabled,
4672
+ onSelect: () => onDuplicate?.(),
4673
+ children: [
4674
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react2.Copy, { size: 12, "aria-hidden": true }),
4675
+ "Duplicate"
4676
+ ]
4677
+ }
4678
+ )
4679
+ ] }),
4680
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(DropdownMenuSeparator, {}),
4681
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(DropdownMenuGroup, { children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
4682
+ DropdownMenuItem,
4683
+ {
4684
+ variant: "destructive",
4685
+ disabled: deleteDisabled,
4686
+ onSelect: () => onDelete?.(),
4687
+ children: [
4688
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react2.Trash2, { size: 15, "aria-hidden": true }),
4689
+ "Delete"
4690
+ ]
4691
+ }
4692
+ ) })
4693
+ ]
4694
+ }
4695
+ )
4696
+ ] }) : null
4539
4697
  ] }) });
4540
4698
  }
4541
4699
 
4542
4700
  // src/ui/item-interaction-layer.tsx
4543
4701
  var React5 = __toESM(require("react"), 1);
4544
- var import_jsx_runtime9 = require("react/jsx-runtime");
4702
+ var import_jsx_runtime10 = require("react/jsx-runtime");
4545
4703
  var PRIMARY = "var(--ohw-primary, #0885FE)";
4546
4704
  var FOCUS_RING = `0 0 0 4px color-mix(in srgb, ${PRIMARY} 12%, transparent)`;
4547
4705
  var DRAG_SHADOW = "0px 4px 6px -1px rgba(0, 0, 0, 0.1), 0px 2px 4px -2px rgba(0, 0, 0, 0.1)";
@@ -4623,7 +4781,7 @@ function ClampedToolbarSlot({
4623
4781
  window.removeEventListener("resize", clamp);
4624
4782
  };
4625
4783
  }, [placement, children]);
4626
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
4784
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
4627
4785
  "div",
4628
4786
  {
4629
4787
  ref: slotRef,
@@ -4663,7 +4821,7 @@ function ItemInteractionLayer({
4663
4821
  const showToolbar = isActive && toolbar;
4664
4822
  const showDragHandle = (isActive || isDragging) && showHandle;
4665
4823
  const itemDragEnabled = itemDragSurface && isActive && showHandle && !isDragging && !dragDisabled;
4666
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
4824
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
4667
4825
  "div",
4668
4826
  {
4669
4827
  ref: elRef,
@@ -4679,7 +4837,7 @@ function ItemInteractionLayer({
4679
4837
  zIndex: getChromeZIndex(state)
4680
4838
  },
4681
4839
  children: [
4682
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
4840
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
4683
4841
  "div",
4684
4842
  {
4685
4843
  "aria-hidden": true,
@@ -4687,7 +4845,7 @@ function ItemInteractionLayer({
4687
4845
  style: getChromeStyle(state)
4688
4846
  }
4689
4847
  ),
4690
- itemDragEnabled && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
4848
+ itemDragEnabled && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
4691
4849
  "div",
4692
4850
  {
4693
4851
  "data-ohw-item-drag-surface": "",
@@ -4703,14 +4861,14 @@ function ItemInteractionLayer({
4703
4861
  }
4704
4862
  }
4705
4863
  ),
4706
- showDragHandle && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
4864
+ showDragHandle && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
4707
4865
  "div",
4708
4866
  {
4709
4867
  "data-ohw-drag-handle-container": "",
4710
4868
  className: "pointer-events-auto absolute left-0 top-1/2 z-10 -translate-x-[calc(100%+7px)] -translate-y-1/2",
4711
4869
  style: isDragging ? { opacity: 0 } : void 0,
4712
4870
  "aria-hidden": isDragging || void 0,
4713
- children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
4871
+ children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
4714
4872
  DragHandle,
4715
4873
  {
4716
4874
  draggable: !dragDisabled,
@@ -4740,8 +4898,8 @@ function ItemInteractionLayer({
4740
4898
  )
4741
4899
  }
4742
4900
  ),
4743
- showToolbar && state === "active-top" && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ClampedToolbarSlot, { placement: "top", children: toolbar }),
4744
- showToolbar && state === "active-bottom" && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ClampedToolbarSlot, { placement: "bottom", children: toolbar })
4901
+ showToolbar && state === "active-top" && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ClampedToolbarSlot, { placement: "top", children: toolbar }),
4902
+ showToolbar && state === "active-bottom" && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ClampedToolbarSlot, { placement: "bottom", children: toolbar })
4745
4903
  ]
4746
4904
  }
4747
4905
  );
@@ -4753,8 +4911,8 @@ var import_lucide_react3 = require("lucide-react");
4753
4911
 
4754
4912
  // src/ui/button.tsx
4755
4913
  var React6 = __toESM(require("react"), 1);
4756
- var import_radix_ui4 = require("radix-ui");
4757
- var import_jsx_runtime10 = require("react/jsx-runtime");
4914
+ var import_radix_ui5 = require("radix-ui");
4915
+ var import_jsx_runtime11 = require("react/jsx-runtime");
4758
4916
  var buttonVariants = cva(
4759
4917
  "inline-flex items-center justify-center gap-1 whitespace-nowrap rounded-md text-sm font-medium transition-colors outline-none disabled:pointer-events-none disabled:opacity-50 min-w-[80px] px-3 py-2",
4760
4918
  {
@@ -4777,8 +4935,8 @@ var buttonVariants = cva(
4777
4935
  );
4778
4936
  var Button = React6.forwardRef(
4779
4937
  ({ className, variant, size, asChild = false, ...props }, ref) => {
4780
- const Comp = asChild ? import_radix_ui4.Slot.Root : "button";
4781
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
4938
+ const Comp = asChild ? import_radix_ui5.Slot.Root : "button";
4939
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
4782
4940
  Comp,
4783
4941
  {
4784
4942
  ref,
@@ -4792,7 +4950,7 @@ var Button = React6.forwardRef(
4792
4950
  Button.displayName = "Button";
4793
4951
 
4794
4952
  // src/ui/MediaOverlay.tsx
4795
- var import_jsx_runtime11 = require("react/jsx-runtime");
4953
+ var import_jsx_runtime12 = require("react/jsx-runtime");
4796
4954
  var MEDIA_UPLOAD_FADE_MS = 300;
4797
4955
  var VIDEO_SETTINGS_BAR_INSET = 8;
4798
4956
  var OVERLAY_BUTTON_STYLE = {
@@ -4850,7 +5008,7 @@ function MediaOverlay({
4850
5008
  return () => anim.cancel();
4851
5009
  }, [isUploading, fadingOut, onFadeOutComplete, hover.key]);
4852
5010
  if (isUploading) {
4853
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
5011
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
4854
5012
  "div",
4855
5013
  {
4856
5014
  ref: skeletonRef,
@@ -4859,11 +5017,11 @@ function MediaOverlay({
4859
5017
  "data-ohw-media-skeleton": "",
4860
5018
  "aria-hidden": true,
4861
5019
  style: { ...box, pointerEvents: "none" },
4862
- children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("style", { children: SKELETON_CSS })
5020
+ children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("style", { children: SKELETON_CSS })
4863
5021
  }
4864
5022
  );
4865
5023
  }
4866
- const settingsBar = isVideo && !hover.isDragOver ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
5024
+ const settingsBar = isVideo && !hover.isDragOver ? /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
4867
5025
  "div",
4868
5026
  {
4869
5027
  "data-ohw-bridge": "",
@@ -4879,7 +5037,7 @@ function MediaOverlay({
4879
5037
  },
4880
5038
  onClick: (e) => e.stopPropagation(),
4881
5039
  children: [
4882
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
5040
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
4883
5041
  Button,
4884
5042
  {
4885
5043
  "data-ohw-media-overlay": "",
@@ -4894,10 +5052,10 @@ function MediaOverlay({
4894
5052
  e.stopPropagation();
4895
5053
  onVideoSettingsChange?.(hover.key, { autoplay: !autoplay });
4896
5054
  },
4897
- children: autoplay ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react3.Pause, { size: 14 }) : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react3.Play, { size: 14 })
5055
+ children: autoplay ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react3.Pause, { size: 14 }) : /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react3.Play, { size: 14 })
4898
5056
  }
4899
5057
  ),
4900
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
5058
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
4901
5059
  Button,
4902
5060
  {
4903
5061
  "data-ohw-media-overlay": "",
@@ -4912,15 +5070,15 @@ function MediaOverlay({
4912
5070
  e.stopPropagation();
4913
5071
  onVideoSettingsChange?.(hover.key, { muted: !muted });
4914
5072
  },
4915
- children: muted ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react3.VolumeX, { size: 14 }) : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react3.Volume2, { size: 14 })
5073
+ children: muted ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react3.VolumeX, { size: 14 }) : /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react3.Volume2, { size: 14 })
4916
5074
  }
4917
5075
  )
4918
5076
  ]
4919
5077
  }
4920
5078
  ) : null;
4921
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
5079
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
4922
5080
  settingsBar,
4923
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
5081
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
4924
5082
  "div",
4925
5083
  {
4926
5084
  "data-ohw-bridge": "",
@@ -4937,7 +5095,7 @@ function MediaOverlay({
4937
5095
  background: "color-mix(in srgb, var(--color-primary) 20%, transparent)"
4938
5096
  },
4939
5097
  onClick: () => onReplace(hover.key),
4940
- children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
5098
+ children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
4941
5099
  Button,
4942
5100
  {
4943
5101
  "data-ohw-media-overlay": "",
@@ -4955,7 +5113,7 @@ function MediaOverlay({
4955
5113
  onReplace(hover.key);
4956
5114
  },
4957
5115
  children: [
4958
- isVideo ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react3.Film, { size: 14 }) : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react3.ImageIcon, { size: 14 }),
5116
+ isVideo ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react3.Film, { size: 14 }) : /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react3.ImageIcon, { size: 14 }),
4959
5117
  isVideo ? "Replace video" : "Replace image"
4960
5118
  ]
4961
5119
  }
@@ -4967,7 +5125,7 @@ function MediaOverlay({
4967
5125
 
4968
5126
  // src/ui/CarouselOverlay.tsx
4969
5127
  var import_lucide_react4 = require("lucide-react");
4970
- var import_jsx_runtime12 = require("react/jsx-runtime");
5128
+ var import_jsx_runtime13 = require("react/jsx-runtime");
4971
5129
  var OVERLAY_BUTTON_STYLE2 = {
4972
5130
  pointerEvents: "auto",
4973
5131
  fontFamily: "Inter, sans-serif",
@@ -4979,7 +5137,7 @@ function CarouselOverlay({
4979
5137
  onEdit
4980
5138
  }) {
4981
5139
  const { rect } = hover;
4982
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
5140
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
4983
5141
  "div",
4984
5142
  {
4985
5143
  "data-ohw-bridge": "",
@@ -4997,7 +5155,7 @@ function CarouselOverlay({
4997
5155
  background: "color-mix(in srgb, var(--color-primary) 20%, transparent)"
4998
5156
  },
4999
5157
  onClick: () => onEdit(hover.key),
5000
- children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
5158
+ children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
5001
5159
  Button,
5002
5160
  {
5003
5161
  "data-ohw-carousel-overlay": "",
@@ -5011,7 +5169,7 @@ function CarouselOverlay({
5011
5169
  onEdit(hover.key);
5012
5170
  },
5013
5171
  children: [
5014
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react4.GalleryHorizontal, { size: 14 }),
5172
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react4.GalleryHorizontal, { size: 14 }),
5015
5173
  "Edit gallery"
5016
5174
  ]
5017
5175
  }
@@ -5300,29 +5458,29 @@ function scrollToHashSectionWhenReady(behavior = "smooth") {
5300
5458
  }
5301
5459
 
5302
5460
  // src/ui/link-modal/LinkPopover.tsx
5303
- var import_react7 = require("react");
5461
+ var import_react8 = require("react");
5304
5462
 
5305
5463
  // src/ui/dialog.tsx
5306
5464
  var React8 = __toESM(require("react"), 1);
5307
- var import_radix_ui5 = require("radix-ui");
5465
+ var import_radix_ui6 = require("radix-ui");
5308
5466
  var import_lucide_react5 = require("lucide-react");
5309
- var import_jsx_runtime13 = require("react/jsx-runtime");
5467
+ var import_jsx_runtime14 = require("react/jsx-runtime");
5310
5468
  function Dialog2({
5311
5469
  ...props
5312
5470
  }) {
5313
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_radix_ui5.Dialog.Root, { "data-slot": "dialog", ...props });
5471
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_radix_ui6.Dialog.Root, { "data-slot": "dialog", ...props });
5314
5472
  }
5315
5473
  function DialogPortal({
5316
5474
  ...props
5317
5475
  }) {
5318
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_radix_ui5.Dialog.Portal, { ...props });
5476
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_radix_ui6.Dialog.Portal, { ...props });
5319
5477
  }
5320
5478
  function DialogOverlay({
5321
5479
  className,
5322
5480
  ...props
5323
5481
  }) {
5324
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
5325
- import_radix_ui5.Dialog.Overlay,
5482
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
5483
+ import_radix_ui6.Dialog.Overlay,
5326
5484
  {
5327
5485
  "data-slot": "dialog-overlay",
5328
5486
  "data-ohw-link-modal-root": "",
@@ -5334,10 +5492,10 @@ function DialogOverlay({
5334
5492
  var DialogContent = React8.forwardRef(
5335
5493
  ({ className, children, showCloseButton = true, container, ...props }, ref) => {
5336
5494
  const positionMode = container ? "absolute" : "fixed";
5337
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(DialogPortal, { container: container ?? void 0, children: [
5338
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(DialogOverlay, { className: cn(positionMode, "inset-0") }),
5339
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
5340
- import_radix_ui5.Dialog.Content,
5495
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(DialogPortal, { container: container ?? void 0, children: [
5496
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(DialogOverlay, { className: cn(positionMode, "inset-0") }),
5497
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
5498
+ import_radix_ui6.Dialog.Content,
5341
5499
  {
5342
5500
  ref,
5343
5501
  "data-slot": "dialog-content",
@@ -5352,13 +5510,13 @@ var DialogContent = React8.forwardRef(
5352
5510
  ...props,
5353
5511
  children: [
5354
5512
  children,
5355
- showCloseButton ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
5356
- import_radix_ui5.Dialog.Close,
5513
+ showCloseButton ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
5514
+ import_radix_ui6.Dialog.Close,
5357
5515
  {
5358
5516
  type: "button",
5359
5517
  className: "absolute right-[9px] top-[9px] rounded-sm p-1.5 text-foreground hover:bg-muted/50",
5360
5518
  "aria-label": "Close",
5361
- children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react5.X, { size: 16, "aria-hidden": true })
5519
+ children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_lucide_react5.X, { size: 16, "aria-hidden": true })
5362
5520
  }
5363
5521
  ) : null
5364
5522
  ]
@@ -5367,18 +5525,18 @@ var DialogContent = React8.forwardRef(
5367
5525
  ] });
5368
5526
  }
5369
5527
  );
5370
- DialogContent.displayName = import_radix_ui5.Dialog.Content.displayName;
5528
+ DialogContent.displayName = import_radix_ui6.Dialog.Content.displayName;
5371
5529
  function DialogHeader({
5372
5530
  className,
5373
5531
  ...props
5374
5532
  }) {
5375
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: cn("flex flex-col gap-1.5", className), ...props });
5533
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: cn("flex flex-col gap-1.5", className), ...props });
5376
5534
  }
5377
5535
  function DialogFooter({
5378
5536
  className,
5379
5537
  ...props
5380
5538
  }) {
5381
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
5539
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
5382
5540
  "div",
5383
5541
  {
5384
5542
  className: cn("flex items-center justify-end gap-2", className),
@@ -5386,8 +5544,8 @@ function DialogFooter({
5386
5544
  }
5387
5545
  );
5388
5546
  }
5389
- var DialogTitle = React8.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
5390
- import_radix_ui5.Dialog.Title,
5547
+ var DialogTitle = React8.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
5548
+ import_radix_ui6.Dialog.Title,
5391
5549
  {
5392
5550
  ref,
5393
5551
  className: cn(
@@ -5397,36 +5555,36 @@ var DialogTitle = React8.forwardRef(({ className, ...props }, ref) => /* @__PURE
5397
5555
  ...props
5398
5556
  }
5399
5557
  ));
5400
- DialogTitle.displayName = import_radix_ui5.Dialog.Title.displayName;
5401
- var DialogDescription = React8.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
5402
- import_radix_ui5.Dialog.Description,
5558
+ DialogTitle.displayName = import_radix_ui6.Dialog.Title.displayName;
5559
+ var DialogDescription = React8.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
5560
+ import_radix_ui6.Dialog.Description,
5403
5561
  {
5404
5562
  ref,
5405
5563
  className: cn("text-sm text-muted-foreground", className),
5406
5564
  ...props
5407
5565
  }
5408
5566
  ));
5409
- DialogDescription.displayName = import_radix_ui5.Dialog.Description.displayName;
5410
- var DialogClose = import_radix_ui5.Dialog.Close;
5567
+ DialogDescription.displayName = import_radix_ui6.Dialog.Description.displayName;
5568
+ var DialogClose = import_radix_ui6.Dialog.Close;
5411
5569
 
5412
5570
  // src/ui/link-modal/LinkEditorPanel.tsx
5413
5571
  var import_lucide_react9 = require("lucide-react");
5414
5572
 
5415
5573
  // src/ui/link-modal/DestinationBreadcrumb.tsx
5416
5574
  var import_lucide_react6 = require("lucide-react");
5417
- var import_jsx_runtime14 = require("react/jsx-runtime");
5575
+ var import_jsx_runtime15 = require("react/jsx-runtime");
5418
5576
  function DestinationBreadcrumb({
5419
5577
  pageTitle,
5420
5578
  sectionLabel
5421
5579
  }) {
5422
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex w-full flex-col gap-2", children: [
5423
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("p", { className: "text-sm font-medium! text-foreground m-0", children: "Destination" }),
5424
- /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex items-center gap-3", children: [
5425
- /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex items-center gap-2", children: [
5426
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_lucide_react6.File, { size: 16, className: "shrink-0 text-foreground", "aria-hidden": true }),
5427
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "text-sm font-medium leading-none text-foreground!", children: pageTitle })
5580
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "flex w-full flex-col gap-2", children: [
5581
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("p", { className: "text-sm font-medium! text-foreground m-0", children: "Destination" }),
5582
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "flex items-center gap-3", children: [
5583
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "flex items-center gap-2", children: [
5584
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_lucide_react6.File, { size: 16, className: "shrink-0 text-foreground", "aria-hidden": true }),
5585
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "text-sm font-medium leading-none text-foreground!", children: pageTitle })
5428
5586
  ] }),
5429
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
5587
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
5430
5588
  import_lucide_react6.ArrowRight,
5431
5589
  {
5432
5590
  size: 16,
@@ -5434,8 +5592,8 @@ function DestinationBreadcrumb({
5434
5592
  "aria-hidden": true
5435
5593
  }
5436
5594
  ),
5437
- /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex min-w-0 flex-1 items-center gap-2", children: [
5438
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
5595
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "flex min-w-0 flex-1 items-center gap-2", children: [
5596
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
5439
5597
  import_lucide_react6.GalleryVertical,
5440
5598
  {
5441
5599
  size: 16,
@@ -5443,7 +5601,7 @@ function DestinationBreadcrumb({
5443
5601
  "aria-hidden": true
5444
5602
  }
5445
5603
  ),
5446
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "truncate text-sm font-medium leading-none text-foreground", children: sectionLabel })
5604
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "truncate text-sm font-medium leading-none text-foreground", children: sectionLabel })
5447
5605
  ] })
5448
5606
  ] })
5449
5607
  ] });
@@ -5451,22 +5609,22 @@ function DestinationBreadcrumb({
5451
5609
 
5452
5610
  // src/ui/link-modal/SectionTreeItem.tsx
5453
5611
  var import_lucide_react7 = require("lucide-react");
5454
- var import_jsx_runtime15 = require("react/jsx-runtime");
5612
+ var import_jsx_runtime16 = require("react/jsx-runtime");
5455
5613
  function SectionTreeItem({
5456
5614
  section,
5457
5615
  onSelect,
5458
5616
  selected
5459
5617
  }) {
5460
5618
  const interactive = Boolean(onSelect);
5461
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "flex h-9 w-full items-end pl-3", children: [
5462
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
5619
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex h-9 w-full items-end pl-3", children: [
5620
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
5463
5621
  "div",
5464
5622
  {
5465
5623
  className: "mr-[-1px] h-9 w-2 shrink-0 rounded-bl-sm border-b border-l border-border mb-4",
5466
5624
  "aria-hidden": true
5467
5625
  }
5468
5626
  ),
5469
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
5627
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
5470
5628
  "div",
5471
5629
  {
5472
5630
  role: interactive ? "button" : void 0,
@@ -5484,7 +5642,7 @@ function SectionTreeItem({
5484
5642
  interactive && selected && "border-primary"
5485
5643
  ),
5486
5644
  children: [
5487
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
5645
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
5488
5646
  import_lucide_react7.GalleryVertical,
5489
5647
  {
5490
5648
  size: 16,
@@ -5492,7 +5650,7 @@ function SectionTreeItem({
5492
5650
  "aria-hidden": true
5493
5651
  }
5494
5652
  ),
5495
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "truncate text-sm font-normal leading-5 text-foreground", children: section.label })
5653
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "truncate text-sm font-normal leading-5 text-foreground", children: section.label })
5496
5654
  ]
5497
5655
  }
5498
5656
  )
@@ -5500,14 +5658,14 @@ function SectionTreeItem({
5500
5658
  }
5501
5659
 
5502
5660
  // src/ui/link-modal/UrlOrPageInput.tsx
5503
- var import_react4 = require("react");
5661
+ var import_react5 = require("react");
5504
5662
 
5505
5663
  // src/ui/input.tsx
5506
5664
  var React9 = __toESM(require("react"), 1);
5507
- var import_jsx_runtime16 = require("react/jsx-runtime");
5665
+ var import_jsx_runtime17 = require("react/jsx-runtime");
5508
5666
  var Input = React9.forwardRef(
5509
5667
  ({ className, type, ...props }, ref) => {
5510
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
5668
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
5511
5669
  "input",
5512
5670
  {
5513
5671
  type,
@@ -5525,11 +5683,11 @@ var Input = React9.forwardRef(
5525
5683
  Input.displayName = "Input";
5526
5684
 
5527
5685
  // src/ui/label.tsx
5528
- var import_radix_ui6 = require("radix-ui");
5529
- var import_jsx_runtime17 = require("react/jsx-runtime");
5686
+ var import_radix_ui7 = require("radix-ui");
5687
+ var import_jsx_runtime18 = require("react/jsx-runtime");
5530
5688
  function Label({ className, ...props }) {
5531
- return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
5532
- import_radix_ui6.Label.Root,
5689
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
5690
+ import_radix_ui7.Label.Root,
5533
5691
  {
5534
5692
  "data-slot": "label",
5535
5693
  className: cn("text-sm font-medium leading-5 text-foreground", className),
@@ -5540,11 +5698,11 @@ function Label({ className, ...props }) {
5540
5698
 
5541
5699
  // src/ui/link-modal/UrlOrPageInput.tsx
5542
5700
  var import_lucide_react8 = require("lucide-react");
5543
- var import_jsx_runtime18 = require("react/jsx-runtime");
5701
+ var import_jsx_runtime19 = require("react/jsx-runtime");
5544
5702
  function FieldChevron({
5545
5703
  onClick
5546
5704
  }) {
5547
- return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
5705
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
5548
5706
  "button",
5549
5707
  {
5550
5708
  type: "button",
@@ -5552,7 +5710,7 @@ function FieldChevron({
5552
5710
  onClick,
5553
5711
  "aria-label": "Open page list",
5554
5712
  tabIndex: -1,
5555
- children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_lucide_react8.ChevronDown, { size: 16 })
5713
+ children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_lucide_react8.ChevronDown, { size: 16 })
5556
5714
  }
5557
5715
  );
5558
5716
  }
@@ -5568,11 +5726,11 @@ function UrlOrPageInput({
5568
5726
  readOnly = false,
5569
5727
  urlError
5570
5728
  }) {
5571
- const inputId = (0, import_react4.useId)();
5572
- const inputRef = (0, import_react4.useRef)(null);
5573
- const rootRef = (0, import_react4.useRef)(null);
5574
- const [isFocused, setIsFocused] = (0, import_react4.useState)(false);
5575
- (0, import_react4.useEffect)(() => {
5729
+ const inputId = (0, import_react5.useId)();
5730
+ const inputRef = (0, import_react5.useRef)(null);
5731
+ const rootRef = (0, import_react5.useRef)(null);
5732
+ const [isFocused, setIsFocused] = (0, import_react5.useState)(false);
5733
+ (0, import_react5.useEffect)(() => {
5576
5734
  if (!dropdownOpen) return;
5577
5735
  const isOutside = (e) => {
5578
5736
  const root = rootRef.current;
@@ -5613,11 +5771,11 @@ function UrlOrPageInput({
5613
5771
  "data-ohw-link-field flex h-[36px] w-full items-center overflow-hidden rounded-md border bg-background pl-3 pr-3 py-2 outline-none transition-[border-color,box-shadow]",
5614
5772
  urlError ? "border-destructive shadow-[0_0_0_1px_var(--ohw-destructive)]" : isFocused ? "border-primary shadow-[0_0_0_1px_var(--ohw-primary)]" : "border-input"
5615
5773
  );
5616
- return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "flex w-full flex-col gap-2 p-0", children: [
5617
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Label, { htmlFor: inputId, className: cn(urlError && "text-destructive"), children: "Destination" }),
5618
- /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { ref: rootRef, className: "relative w-full", children: [
5619
- /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { "data-ohw-link-field": true, className: fieldClassName, children: [
5620
- selectedPage ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "flex shrink-0 items-center pr-2", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
5774
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex w-full flex-col gap-2 p-0", children: [
5775
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Label, { htmlFor: inputId, className: cn(urlError && "text-destructive"), children: "Destination" }),
5776
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { ref: rootRef, className: "relative w-full", children: [
5777
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { "data-ohw-link-field": true, className: fieldClassName, children: [
5778
+ selectedPage ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "flex shrink-0 items-center pr-2", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
5621
5779
  import_lucide_react8.File,
5622
5780
  {
5623
5781
  size: 16,
@@ -5625,7 +5783,7 @@ function UrlOrPageInput({
5625
5783
  "aria-hidden": true
5626
5784
  }
5627
5785
  ) }) : null,
5628
- readOnly ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "min-w-0 flex-1 truncate text-sm leading-5 text-foreground", children: selectedPage?.title ?? value }) : /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
5786
+ readOnly ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "min-w-0 flex-1 truncate text-sm leading-5 text-foreground", children: selectedPage?.title ?? value }) : /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
5629
5787
  Input,
5630
5788
  {
5631
5789
  ref: inputRef,
@@ -5651,7 +5809,7 @@ function UrlOrPageInput({
5651
5809
  )
5652
5810
  }
5653
5811
  ),
5654
- selectedPage && !readOnly ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
5812
+ selectedPage && !readOnly ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
5655
5813
  "button",
5656
5814
  {
5657
5815
  type: "button",
@@ -5659,26 +5817,26 @@ function UrlOrPageInput({
5659
5817
  onMouseDown: clearSelection,
5660
5818
  "aria-label": "Clear selected page",
5661
5819
  tabIndex: -1,
5662
- children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_lucide_react8.X, { size: 16, "aria-hidden": true })
5820
+ children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_lucide_react8.X, { size: 16, "aria-hidden": true })
5663
5821
  }
5664
5822
  ) : null,
5665
- !readOnly ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(FieldChevron, { onClick: toggleDropdown }) : null
5823
+ !readOnly ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(FieldChevron, { onClick: toggleDropdown }) : null
5666
5824
  ] }),
5667
- dropdownOpen && !readOnly && filteredPages.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
5825
+ dropdownOpen && !readOnly && filteredPages.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
5668
5826
  "div",
5669
5827
  {
5670
5828
  "data-ohw-link-page-dropdown": "",
5671
5829
  className: "absolute left-0 right-0 top-[calc(100%+4px)] z-50 max-h-48 overflow-auto rounded-lg border border-border bg-popover py-1 shadow-lg",
5672
5830
  onMouseDown: (e) => e.preventDefault(),
5673
- children: filteredPages.map((page) => /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
5831
+ children: filteredPages.map((page) => /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
5674
5832
  "button",
5675
5833
  {
5676
5834
  type: "button",
5677
5835
  className: "flex h-9 w-full items-center gap-2 border-0 bg-transparent px-3 text-left text-sm leading-5 text-foreground outline-none hover:bg-muted",
5678
5836
  onClick: () => onPageSelect(page),
5679
5837
  children: [
5680
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_lucide_react8.File, { size: 16, className: "shrink-0", "aria-hidden": true }),
5681
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "truncate", children: page.title })
5838
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_lucide_react8.File, { size: 16, className: "shrink-0", "aria-hidden": true }),
5839
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "truncate", children: page.title })
5682
5840
  ]
5683
5841
  },
5684
5842
  page.path
@@ -5686,34 +5844,34 @@ function UrlOrPageInput({
5686
5844
  }
5687
5845
  ) : null
5688
5846
  ] }),
5689
- urlError ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("p", { className: "text-sm font-medium text-destructive", children: urlError }) : null
5847
+ urlError ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { className: "text-sm font-medium text-destructive", children: urlError }) : null
5690
5848
  ] });
5691
5849
  }
5692
5850
 
5693
5851
  // src/ui/link-modal/LinkEditorPanel.tsx
5694
- var import_jsx_runtime19 = require("react/jsx-runtime");
5852
+ var import_jsx_runtime20 = require("react/jsx-runtime");
5695
5853
  function LinkEditorPanel({ state, onClose }) {
5696
5854
  const isCancel = state.secondaryLabel === "Cancel" || state.secondaryLabel === "Back to sections";
5697
- return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_jsx_runtime19.Fragment, { children: [
5698
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(DialogClose, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
5855
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_jsx_runtime20.Fragment, { children: [
5856
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(DialogClose, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
5699
5857
  "button",
5700
5858
  {
5701
5859
  type: "button",
5702
5860
  className: "absolute right-[9px] top-[9px] rounded-sm p-1.5 text-foreground hover:bg-muted/50 h-7",
5703
5861
  "aria-label": "Close",
5704
5862
  onClick: onClose,
5705
- children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_lucide_react9.X, { size: 16, "aria-hidden": true })
5863
+ children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react9.X, { size: 16, "aria-hidden": true })
5706
5864
  }
5707
5865
  ) }),
5708
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(DialogHeader, { className: "w-full gap-1.5 p-6 pr-12", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(DialogTitle, { className: "m-0 w-full break-words", children: state.title }) }),
5709
- /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex w-full flex-col gap-3 px-6 pb-8 pt-1", children: [
5710
- state.showBreadcrumb && state.selectedPage && state.selectedSection ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
5866
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(DialogHeader, { className: "w-full gap-1.5 p-6 pr-12", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(DialogTitle, { className: "m-0 w-full break-words", children: state.title }) }),
5867
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex w-full flex-col gap-3 px-6 pb-8 pt-1", children: [
5868
+ state.showBreadcrumb && state.selectedPage && state.selectedSection ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
5711
5869
  DestinationBreadcrumb,
5712
5870
  {
5713
5871
  pageTitle: state.selectedPage.title,
5714
5872
  sectionLabel: state.selectedSection.label
5715
5873
  }
5716
- ) : /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
5874
+ ) : /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
5717
5875
  UrlOrPageInput,
5718
5876
  {
5719
5877
  value: state.searchValue,
@@ -5726,8 +5884,8 @@ function LinkEditorPanel({ state, onClose }) {
5726
5884
  urlError: state.urlError
5727
5885
  }
5728
5886
  ),
5729
- state.showChooseSection ? /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex flex-col justify-center gap-2", children: [
5730
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
5887
+ state.showChooseSection ? /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex flex-col justify-center gap-2", children: [
5888
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
5731
5889
  Button,
5732
5890
  {
5733
5891
  type: "button",
@@ -5738,15 +5896,15 @@ function LinkEditorPanel({ state, onClose }) {
5738
5896
  children: "Choose a section"
5739
5897
  }
5740
5898
  ),
5741
- /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex items-center gap-1 text-sm text-muted-foreground", children: [
5742
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_lucide_react9.Info, { size: 16, className: "shrink-0", "aria-hidden": true }),
5743
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { children: "Pick a section this link should scroll to." })
5899
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex items-center gap-1 text-sm text-muted-foreground", children: [
5900
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react9.Info, { size: 16, className: "shrink-0", "aria-hidden": true }),
5901
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { children: "Pick a section this link should scroll to." })
5744
5902
  ] })
5745
5903
  ] }) : null,
5746
- state.showSectionRow && state.selectedSection ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(SectionTreeItem, { section: state.selectedSection, selected: true }) : null
5904
+ state.showSectionRow && state.selectedSection ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(SectionTreeItem, { section: state.selectedSection, selected: true }) : null
5747
5905
  ] }),
5748
- /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(DialogFooter, { className: "w-full px-6 pb-6", children: [
5749
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
5906
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(DialogFooter, { className: "w-full px-6 pb-6", children: [
5907
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
5750
5908
  Button,
5751
5909
  {
5752
5910
  type: "button",
@@ -5761,7 +5919,7 @@ function LinkEditorPanel({ state, onClose }) {
5761
5919
  children: state.secondaryLabel
5762
5920
  }
5763
5921
  ),
5764
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
5922
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
5765
5923
  Button,
5766
5924
  {
5767
5925
  type: "button",
@@ -5780,11 +5938,11 @@ function LinkEditorPanel({ state, onClose }) {
5780
5938
  }
5781
5939
 
5782
5940
  // src/ui/link-modal/SectionPickerOverlay.tsx
5783
- var import_react5 = require("react");
5941
+ var import_react6 = require("react");
5784
5942
  var import_react_dom = require("react-dom");
5785
5943
  var import_lucide_react10 = require("lucide-react");
5786
5944
  var import_navigation = require("next/navigation");
5787
- var import_jsx_runtime20 = require("react/jsx-runtime");
5945
+ var import_jsx_runtime21 = require("react/jsx-runtime");
5788
5946
  var DIM_OVERLAY = "rgba(0, 0, 0, 0.45)";
5789
5947
  function rectsEqual(a, b) {
5790
5948
  if (a.size !== b.size) return false;
@@ -5817,12 +5975,12 @@ function hitTestSectionId(x, y, sectionIds, rects) {
5817
5975
  return null;
5818
5976
  }
5819
5977
  function useSectionRects(sectionIdsKey, enabled) {
5820
- const [rects, setRects] = (0, import_react5.useState)(/* @__PURE__ */ new Map());
5821
- const sectionIds = (0, import_react5.useMemo)(
5978
+ const [rects, setRects] = (0, import_react6.useState)(/* @__PURE__ */ new Map());
5979
+ const sectionIds = (0, import_react6.useMemo)(
5822
5980
  () => sectionIdsKey ? sectionIdsKey.split("\0") : [],
5823
5981
  [sectionIdsKey]
5824
5982
  );
5825
- (0, import_react5.useEffect)(() => {
5983
+ (0, import_react6.useEffect)(() => {
5826
5984
  if (!enabled || sectionIds.length === 0) {
5827
5985
  setRects((prev) => prev.size === 0 ? prev : /* @__PURE__ */ new Map());
5828
5986
  return;
@@ -5863,13 +6021,13 @@ function SectionPickerOverlay({
5863
6021
  }) {
5864
6022
  const router = (0, import_navigation.useRouter)();
5865
6023
  const pathname = (0, import_navigation.usePathname)();
5866
- const [selectedId, setSelectedId] = (0, import_react5.useState)(null);
5867
- const [hoveredId, setHoveredId] = (0, import_react5.useState)(null);
5868
- const pointerRef = (0, import_react5.useRef)(null);
5869
- const pointerScreenRef = (0, import_react5.useRef)(null);
5870
- const iframeOffsetTopRef = (0, import_react5.useRef)(null);
5871
- const sectionIdsRef = (0, import_react5.useRef)([]);
5872
- const [chromeClip, setChromeClip] = (0, import_react5.useState)(
6024
+ const [selectedId, setSelectedId] = (0, import_react6.useState)(null);
6025
+ const [hoveredId, setHoveredId] = (0, import_react6.useState)(null);
6026
+ const pointerRef = (0, import_react6.useRef)(null);
6027
+ const pointerScreenRef = (0, import_react6.useRef)(null);
6028
+ const iframeOffsetTopRef = (0, import_react6.useRef)(null);
6029
+ const sectionIdsRef = (0, import_react6.useRef)([]);
6030
+ const [chromeClip, setChromeClip] = (0, import_react6.useState)(
5873
6031
  () => ({
5874
6032
  top: 0,
5875
6033
  bottom: typeof window !== "undefined" ? window.innerHeight : 0
@@ -5877,12 +6035,12 @@ function SectionPickerOverlay({
5877
6035
  );
5878
6036
  const normalizedTarget = normalizePath(pagePath);
5879
6037
  const isOnTargetPage = normalizePath(pathname) === normalizedTarget;
5880
- (0, import_react5.useEffect)(() => {
6038
+ (0, import_react6.useEffect)(() => {
5881
6039
  if (isOnTargetPage) return;
5882
6040
  const search = readPreservedSearch();
5883
6041
  router.push(`${normalizedTarget}${search}`);
5884
6042
  }, [isOnTargetPage, normalizedTarget, router]);
5885
- (0, import_react5.useEffect)(() => {
6043
+ (0, import_react6.useEffect)(() => {
5886
6044
  document.documentElement.setAttribute("data-ohw-section-picking", "");
5887
6045
  document.querySelectorAll("[data-ohw-hovered]").forEach((el) => {
5888
6046
  el.removeAttribute("data-ohw-hovered");
@@ -5894,24 +6052,24 @@ function SectionPickerOverlay({
5894
6052
  document.documentElement.removeAttribute("data-ohw-section-picking");
5895
6053
  };
5896
6054
  }, []);
5897
- const liveSections = (0, import_react5.useMemo)(() => {
6055
+ const liveSections = (0, import_react6.useMemo)(() => {
5898
6056
  if (!isOnTargetPage) return sections;
5899
6057
  const live = collectSectionsFromDom();
5900
6058
  if (live.length === 0) return sections;
5901
6059
  const labels = new Map(sections.map((s) => [s.id, s.label]));
5902
6060
  return live.map((s) => ({ id: s.id, label: labels.get(s.id) ?? s.label }));
5903
6061
  }, [isOnTargetPage, sections, pathname]);
5904
- const sectionIdsKey = (0, import_react5.useMemo)(
6062
+ const sectionIdsKey = (0, import_react6.useMemo)(
5905
6063
  () => liveSections.map((s) => s.id).join("\0"),
5906
6064
  [liveSections]
5907
6065
  );
5908
- const sectionIds = (0, import_react5.useMemo)(
6066
+ const sectionIds = (0, import_react6.useMemo)(
5909
6067
  () => liveSections.map((s) => s.id),
5910
6068
  [liveSections]
5911
6069
  );
5912
6070
  sectionIdsRef.current = sectionIds;
5913
6071
  const rects = useSectionRects(sectionIdsKey, isOnTargetPage);
5914
- const applyHoverAt = (0, import_react5.useCallback)(
6072
+ const applyHoverAt = (0, import_react6.useCallback)(
5915
6073
  (x, y, liveRects) => {
5916
6074
  const ids = sectionIdsRef.current;
5917
6075
  const map = liveRects ?? readSectionRects(ids);
@@ -5920,7 +6078,7 @@ function SectionPickerOverlay({
5920
6078
  },
5921
6079
  []
5922
6080
  );
5923
- (0, import_react5.useEffect)(() => {
6081
+ (0, import_react6.useEffect)(() => {
5924
6082
  const applyClip = (iframeOffsetTop, visibleCanvasTop, canvasH) => {
5925
6083
  const top = Math.max(0, visibleCanvasTop - iframeOffsetTop);
5926
6084
  const bottom = Math.min(
@@ -5962,12 +6120,12 @@ function SectionPickerOverlay({
5962
6120
  window.removeEventListener("resize", onResize);
5963
6121
  };
5964
6122
  }, [applyHoverAt]);
5965
- (0, import_react5.useEffect)(() => {
6123
+ (0, import_react6.useEffect)(() => {
5966
6124
  const ptr = pointerRef.current;
5967
6125
  if (!ptr) return;
5968
6126
  applyHoverAt(ptr.x, ptr.y, rects);
5969
6127
  }, [rects, applyHoverAt]);
5970
- (0, import_react5.useEffect)(() => {
6128
+ (0, import_react6.useEffect)(() => {
5971
6129
  const rememberPointer = (clientX, clientY) => {
5972
6130
  pointerRef.current = { x: clientX, y: clientY };
5973
6131
  const top = iframeOffsetTopRef.current;
@@ -5991,7 +6149,7 @@ function SectionPickerOverlay({
5991
6149
  window.removeEventListener("message", onPointerSync);
5992
6150
  };
5993
6151
  }, [rects, applyHoverAt]);
5994
- const handleSelect = (0, import_react5.useCallback)(
6152
+ const handleSelect = (0, import_react6.useCallback)(
5995
6153
  (section) => {
5996
6154
  if (selectedId) return;
5997
6155
  setSelectedId(section.id);
@@ -5999,7 +6157,7 @@ function SectionPickerOverlay({
5999
6157
  },
6000
6158
  [selectedId, onSelect]
6001
6159
  );
6002
- (0, import_react5.useEffect)(() => {
6160
+ (0, import_react6.useEffect)(() => {
6003
6161
  const onKeyDown = (e) => {
6004
6162
  if (e.key === "Escape") {
6005
6163
  e.preventDefault();
@@ -6013,7 +6171,7 @@ function SectionPickerOverlay({
6013
6171
  const portalRoot = typeof document !== "undefined" ? document.querySelector("[data-ohw-bridge-root]") ?? document.body : null;
6014
6172
  if (!portalRoot) return null;
6015
6173
  return (0, import_react_dom.createPortal)(
6016
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
6174
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
6017
6175
  "div",
6018
6176
  {
6019
6177
  "data-ohw-section-picker": "",
@@ -6023,12 +6181,12 @@ function SectionPickerOverlay({
6023
6181
  role: "dialog",
6024
6182
  "aria-label": "Choose a section",
6025
6183
  children: [
6026
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
6184
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
6027
6185
  "div",
6028
6186
  {
6029
6187
  className: "pointer-events-auto fixed left-5 z-[2]",
6030
6188
  style: { top: chromeClip.top + 20 },
6031
- children: /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
6189
+ children: /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
6032
6190
  Button,
6033
6191
  {
6034
6192
  type: "button",
@@ -6037,14 +6195,14 @@ function SectionPickerOverlay({
6037
6195
  className: "h-8 min-w-0 gap-1 border-border bg-background px-2 py-1.5 shadow-sm hover:bg-muted cursor-pointer",
6038
6196
  onClick: onBack,
6039
6197
  children: [
6040
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react10.ArrowLeft, { className: "size-4 shrink-0", "aria-hidden": true }),
6198
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react10.ArrowLeft, { className: "size-4 shrink-0", "aria-hidden": true }),
6041
6199
  "Back"
6042
6200
  ]
6043
6201
  }
6044
6202
  )
6045
6203
  }
6046
6204
  ),
6047
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
6205
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
6048
6206
  "div",
6049
6207
  {
6050
6208
  className: "pointer-events-none fixed left-1/2 z-[2] rounded-lg px-4 py-3 text-xs leading-4 tracking-[0.18px] text-white shadow-md",
@@ -6057,7 +6215,7 @@ function SectionPickerOverlay({
6057
6215
  children: "Click on section to select"
6058
6216
  }
6059
6217
  ),
6060
- !isOnTargetPage ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
6218
+ !isOnTargetPage ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
6061
6219
  "div",
6062
6220
  {
6063
6221
  className: "pointer-events-none fixed left-1/2 z-[1] -translate-x-1/2 rounded-md px-3 py-2 text-sm text-muted-foreground shadow-sm",
@@ -6065,14 +6223,14 @@ function SectionPickerOverlay({
6065
6223
  children: "Loading page preview\u2026"
6066
6224
  }
6067
6225
  ) : null,
6068
- isOnTargetPage && liveSections.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "pointer-events-auto fixed inset-0 z-[1] flex items-center justify-center bg-muted/40", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("p", { className: "text-sm text-muted-foreground", children: "No sections found on this page." }) }) : null,
6226
+ isOnTargetPage && liveSections.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "pointer-events-auto fixed inset-0 z-[1] flex items-center justify-center bg-muted/40", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("p", { className: "text-sm text-muted-foreground", children: "No sections found on this page." }) }) : null,
6069
6227
  isOnTargetPage ? liveSections.map((section) => {
6070
6228
  const rect = rects.get(section.id);
6071
6229
  if (!rect || rect.width <= 0 || rect.height <= 0) return null;
6072
6230
  const isSelected = selectedId === section.id;
6073
6231
  const isHovered = hoveredId === section.id;
6074
6232
  const isLit = isSelected || isHovered;
6075
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
6233
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
6076
6234
  "button",
6077
6235
  {
6078
6236
  type: "button",
@@ -6087,7 +6245,7 @@ function SectionPickerOverlay({
6087
6245
  "aria-label": `Select section ${section.label}`,
6088
6246
  onClick: () => handleSelect(section),
6089
6247
  children: [
6090
- isLit ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
6248
+ isLit ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
6091
6249
  "span",
6092
6250
  {
6093
6251
  className: "pointer-events-none absolute",
@@ -6100,13 +6258,13 @@ function SectionPickerOverlay({
6100
6258
  "aria-hidden": true
6101
6259
  }
6102
6260
  ) : null,
6103
- isSelected ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
6261
+ isSelected ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
6104
6262
  "span",
6105
6263
  {
6106
6264
  className: "absolute right-3 top-3 flex size-8 items-center justify-center rounded-full text-white",
6107
6265
  style: { backgroundColor: "var(--ohw-primary, #0885fe)" },
6108
6266
  "aria-hidden": true,
6109
- children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react10.Check, { className: "size-5" })
6267
+ children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react10.Check, { className: "size-5" })
6110
6268
  }
6111
6269
  ) : null
6112
6270
  ]
@@ -6122,7 +6280,7 @@ function SectionPickerOverlay({
6122
6280
  }
6123
6281
 
6124
6282
  // src/ui/link-modal/useLinkModalState.ts
6125
- var import_react6 = require("react");
6283
+ var import_react7 = require("react");
6126
6284
  function useLinkModalState({
6127
6285
  open,
6128
6286
  mode,
@@ -6134,14 +6292,14 @@ function useLinkModalState({
6134
6292
  onClose,
6135
6293
  onSubmit
6136
6294
  }) {
6137
- const availablePages = (0, import_react6.useMemo)(() => pages, [pages]);
6138
- const [searchValue, setSearchValue] = (0, import_react6.useState)("");
6139
- const [selectedPage, setSelectedPage] = (0, import_react6.useState)(null);
6140
- const [selectedSection, setSelectedSection] = (0, import_react6.useState)(null);
6141
- const [step, setStep] = (0, import_react6.useState)("input");
6142
- const [dropdownOpen, setDropdownOpen] = (0, import_react6.useState)(false);
6143
- const [urlError, setUrlError] = (0, import_react6.useState)("");
6144
- const reset = (0, import_react6.useCallback)(() => {
6295
+ const availablePages = (0, import_react7.useMemo)(() => pages, [pages]);
6296
+ const [searchValue, setSearchValue] = (0, import_react7.useState)("");
6297
+ const [selectedPage, setSelectedPage] = (0, import_react7.useState)(null);
6298
+ const [selectedSection, setSelectedSection] = (0, import_react7.useState)(null);
6299
+ const [step, setStep] = (0, import_react7.useState)("input");
6300
+ const [dropdownOpen, setDropdownOpen] = (0, import_react7.useState)(false);
6301
+ const [urlError, setUrlError] = (0, import_react7.useState)("");
6302
+ const reset = (0, import_react7.useCallback)(() => {
6145
6303
  setSearchValue("");
6146
6304
  setSelectedPage(null);
6147
6305
  setSelectedSection(null);
@@ -6149,7 +6307,7 @@ function useLinkModalState({
6149
6307
  setDropdownOpen(false);
6150
6308
  setUrlError("");
6151
6309
  }, []);
6152
- (0, import_react6.useEffect)(() => {
6310
+ (0, import_react7.useEffect)(() => {
6153
6311
  if (!open) return;
6154
6312
  if (mode === "edit" && initialTarget) {
6155
6313
  const { pageRoute } = parseTarget(initialTarget);
@@ -6165,11 +6323,11 @@ function useLinkModalState({
6165
6323
  setDropdownOpen(false);
6166
6324
  setUrlError("");
6167
6325
  }, [open, mode, initialTarget, reset]);
6168
- const filteredPages = (0, import_react6.useMemo)(() => {
6326
+ const filteredPages = (0, import_react7.useMemo)(() => {
6169
6327
  if (!searchValue.trim()) return availablePages;
6170
6328
  return availablePages.filter((p) => p.title.toLowerCase().startsWith(searchValue.toLowerCase()));
6171
6329
  }, [availablePages, searchValue]);
6172
- const activeSections = (0, import_react6.useMemo)(() => {
6330
+ const activeSections = (0, import_react7.useMemo)(() => {
6173
6331
  if (!selectedPage) return [];
6174
6332
  return getSectionsForPath(sectionsByPath, selectedPage.path);
6175
6333
  }, [selectedPage, sectionsByPath]);
@@ -6218,7 +6376,7 @@ function useLinkModalState({
6218
6376
  reset();
6219
6377
  onClose();
6220
6378
  };
6221
- const isValid = (0, import_react6.useMemo)(() => {
6379
+ const isValid = (0, import_react7.useMemo)(() => {
6222
6380
  if (urlError) return false;
6223
6381
  if (showBreadcrumb) return true;
6224
6382
  if (selectedPage) return true;
@@ -6286,7 +6444,7 @@ function useLinkModalState({
6286
6444
  }
6287
6445
 
6288
6446
  // src/ui/link-modal/LinkPopover.tsx
6289
- var import_jsx_runtime21 = require("react/jsx-runtime");
6447
+ var import_jsx_runtime22 = require("react/jsx-runtime");
6290
6448
  function postToParent(data) {
6291
6449
  window.parent?.postMessage(data, "*");
6292
6450
  }
@@ -6315,7 +6473,7 @@ function LinkPopover({
6315
6473
  onSubmit
6316
6474
  });
6317
6475
  const sectionPickerActive = state.showSectionPicker && Boolean(state.selectedPage);
6318
- (0, import_react7.useEffect)(() => {
6476
+ (0, import_react8.useEffect)(() => {
6319
6477
  if (!open) return;
6320
6478
  if (sectionPickerActive) {
6321
6479
  postToParent({ type: "ui:unlock" });
@@ -6382,15 +6540,15 @@ function LinkPopover({
6382
6540
  );
6383
6541
  };
6384
6542
  }, [open, sectionPickerActive]);
6385
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_jsx_runtime21.Fragment, { children: [
6386
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
6543
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_jsx_runtime22.Fragment, { children: [
6544
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
6387
6545
  Dialog2,
6388
6546
  {
6389
6547
  open: open && !sectionPickerActive,
6390
6548
  onOpenChange: (next) => {
6391
6549
  if (!next) onClose?.();
6392
6550
  },
6393
- children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
6551
+ children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
6394
6552
  DialogContent,
6395
6553
  {
6396
6554
  ref: panelRef,
@@ -6400,12 +6558,12 @@ function LinkPopover({
6400
6558
  "data-ohw-bridge": "",
6401
6559
  showCloseButton: false,
6402
6560
  className: "gap-0 p-0 w-full max-w-[448px] pointer-events-auto z-[2147483646] overflow-visible",
6403
- children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(LinkEditorPanel, { state, onClose })
6561
+ children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(LinkEditorPanel, { state, onClose })
6404
6562
  }
6405
6563
  )
6406
6564
  }
6407
6565
  ),
6408
- sectionPickerActive && state.selectedPage ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
6566
+ sectionPickerActive && state.selectedPage ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
6409
6567
  SectionPickerOverlay,
6410
6568
  {
6411
6569
  pagePath: state.selectedPage.path,
@@ -6944,6 +7102,53 @@ function insertNavbarItem(href, label, afterAnchor = null) {
6944
7102
  order
6945
7103
  };
6946
7104
  }
7105
+ function duplicateNavbarItem(sourceAnchor) {
7106
+ if (!isNavbarLinkItem(sourceAnchor)) return null;
7107
+ const sourceHrefKey = sourceAnchor.getAttribute("data-ohw-href-key");
7108
+ if (!sourceHrefKey || !isNavbarHrefKey(sourceHrefKey)) return null;
7109
+ const href = getLinkHref(sourceAnchor);
7110
+ const labelEl = sourceAnchor.querySelector('[data-ohw-editable="text"]');
7111
+ const label = (labelEl?.textContent ?? "").trim() || "Untitled";
7112
+ const forest = getNavForestFromDom();
7113
+ const sourceNode = forest.find((n) => n.id === sourceHrefKey);
7114
+ const childIds = sourceNode?.children.map((c) => c.id) ?? [];
7115
+ const primary = insertNavbarItem(href, label, sourceAnchor);
7116
+ const childResults = [];
7117
+ let after = primary.anchor;
7118
+ for (const childId of childIds) {
7119
+ const childEl = findCounterpartByHrefKey(childId, document) ?? document.querySelector(`[data-ohw-href-key="${CSS.escape(childId)}"]`);
7120
+ if (!childEl || !isNavbarLinkItem(childEl)) continue;
7121
+ const childHref = getLinkHref(childEl);
7122
+ const childLabelEl = childEl.querySelector('[data-ohw-editable="text"]');
7123
+ const childLabel = (childLabelEl?.textContent ?? "").trim() || "Untitled";
7124
+ const inserted = insertNavbarItem(childHref, childLabel, after);
7125
+ childResults.push(inserted);
7126
+ after = inserted.anchor;
7127
+ }
7128
+ let orderJson;
7129
+ if (childResults.length > 0) {
7130
+ const nextForest = getNavForestFromDom();
7131
+ const withoutNew = nextForest.filter(
7132
+ (n) => n.id !== primary.hrefKey && !childResults.some((c) => c.hrefKey === n.id)
7133
+ );
7134
+ const sourceIdx = withoutNew.findIndex((n) => n.id === sourceHrefKey);
7135
+ const insertAt = sourceIdx >= 0 ? sourceIdx + 1 : withoutNew.length;
7136
+ withoutNew.splice(insertAt, 0, {
7137
+ id: primary.hrefKey,
7138
+ children: childResults.map((c) => ({ id: c.hrefKey, children: [] }))
7139
+ });
7140
+ applyNavForest(withoutNew);
7141
+ orderJson = serializeNavOrder(withoutNew);
7142
+ } else {
7143
+ orderJson = serializeNavOrder(getNavForestFromDom());
7144
+ }
7145
+ return {
7146
+ ...primary,
7147
+ order: flattenNavOrder(parseNavOrderJson(orderJson) ?? getNavForestFromDom()),
7148
+ childResults,
7149
+ orderJson
7150
+ };
7151
+ }
6947
7152
 
6948
7153
  // src/lib/footer-items.ts
6949
7154
  var FOOTER_ORDER_KEY = "__ohw_footer_order";
@@ -7161,16 +7366,6 @@ function getNextFooterColumnIndex() {
7161
7366
  if (indices.length === 0) return 0;
7162
7367
  return Math.max(...indices) + 1;
7163
7368
  }
7164
- function cloneFooterLinkShell(template) {
7165
- const anchor = document.createElement("a");
7166
- if (template) {
7167
- anchor.style.cssText = template.style.cssText;
7168
- if (template.className) anchor.className = template.className;
7169
- }
7170
- anchor.style.cursor = "pointer";
7171
- anchor.style.textDecoration = "none";
7172
- return anchor;
7173
- }
7174
7369
  function buildFooterHeading(colIndex, text) {
7175
7370
  const heading = document.createElement("p");
7176
7371
  heading.setAttribute("data-ohw-editable", "text");
@@ -7499,6 +7694,76 @@ function hitTestColumnDropSlot(clientX, _clientY) {
7499
7694
  }
7500
7695
  return best?.slot ?? null;
7501
7696
  }
7697
+ function getLinkHref2(el) {
7698
+ const key = el.getAttribute("data-ohw-href-key");
7699
+ if (key) {
7700
+ const stored = getStoredLinkHref(key);
7701
+ if (stored !== void 0) return stored;
7702
+ }
7703
+ return el.getAttribute("href") ?? "";
7704
+ }
7705
+ function getNextFooterItemIndex(col) {
7706
+ let max = -1;
7707
+ for (const el of document.querySelectorAll("footer [data-ohw-href-key]")) {
7708
+ const parsed = parseFooterHrefKey(el.getAttribute("data-ohw-href-key"));
7709
+ if (!parsed || parsed.col !== col) continue;
7710
+ if (parsed.item > max) max = parsed.item;
7711
+ }
7712
+ return max + 1;
7713
+ }
7714
+ function cloneFooterLinkShell(template) {
7715
+ const anchor = document.createElement("a");
7716
+ if (template) {
7717
+ anchor.style.cssText = template.style.cssText;
7718
+ if (template.className) anchor.className = template.className;
7719
+ }
7720
+ anchor.style.cursor = "pointer";
7721
+ anchor.style.textDecoration = "none";
7722
+ return anchor;
7723
+ }
7724
+ function insertFooterItem(column, href, label, afterAnchor = null) {
7725
+ const columns = listFooterColumns();
7726
+ const colIndex = columns.indexOf(column);
7727
+ if (colIndex < 0) throw new Error("Footer column not found");
7728
+ const item = getNextFooterItemIndex(colIndex);
7729
+ const hrefKey = `footer-${colIndex}-${item}-href`;
7730
+ const labelKey = `footer-${colIndex}-${item}-label`;
7731
+ const template = listFooterLinksInColumn(column)[0] ?? null;
7732
+ const anchor = cloneFooterLinkShell(template);
7733
+ anchor.href = href;
7734
+ anchor.setAttribute("data-ohw-href-key", hrefKey);
7735
+ const span = document.createElement("span");
7736
+ span.setAttribute("data-ohw-editable", "text");
7737
+ span.setAttribute("data-ohw-key", labelKey);
7738
+ span.textContent = label;
7739
+ anchor.appendChild(span);
7740
+ if (afterAnchor && afterAnchor.parentElement === column) {
7741
+ afterAnchor.insertAdjacentElement("afterend", anchor);
7742
+ } else {
7743
+ column.appendChild(anchor);
7744
+ }
7745
+ const order = getFooterOrderFromDom();
7746
+ applyFooterOrder(order);
7747
+ return {
7748
+ anchor,
7749
+ col: colIndex,
7750
+ item,
7751
+ hrefKey,
7752
+ labelKey,
7753
+ href,
7754
+ label,
7755
+ order
7756
+ };
7757
+ }
7758
+ function duplicateFooterItem(sourceAnchor) {
7759
+ if (!isFooterLinkAnchor(sourceAnchor)) return null;
7760
+ const column = findFooterColumnForLink(sourceAnchor);
7761
+ if (!column) return null;
7762
+ const href = getLinkHref2(sourceAnchor);
7763
+ const labelEl = sourceAnchor.querySelector('[data-ohw-editable="text"]');
7764
+ const label = (labelEl?.textContent ?? "").trim() || "Untitled";
7765
+ return insertFooterItem(column, href || "/", label, sourceAnchor);
7766
+ }
7502
7767
 
7503
7768
  // src/lib/add-footer-column.ts
7504
7769
  function buildFooterColumnEditContentPatch(result) {
@@ -7721,7 +7986,7 @@ function hitTestNavDropSlot(clientX, clientY, draggedHrefKey) {
7721
7986
  }
7722
7987
 
7723
7988
  // src/useNavItemDrag.ts
7724
- var import_react8 = require("react");
7989
+ var import_react9 = require("react");
7725
7990
  function useNavItemDrag({
7726
7991
  isEditMode,
7727
7992
  editContentRef,
@@ -7746,11 +8011,11 @@ function useNavItemDrag({
7746
8011
  isDragHandleDisabled: isDragHandleDisabled2,
7747
8012
  isNavbarButton: isNavbarButton3
7748
8013
  }) {
7749
- const navDragRef = (0, import_react8.useRef)(null);
7750
- const [navDropSlots, setNavDropSlots] = (0, import_react8.useState)([]);
7751
- const [activeNavDropIndex, setActiveNavDropIndex] = (0, import_react8.useState)(null);
7752
- const navPointerDragRef = (0, import_react8.useRef)(null);
7753
- const clearNavDragVisuals = (0, import_react8.useCallback)(() => {
8014
+ const navDragRef = (0, import_react9.useRef)(null);
8015
+ const [navDropSlots, setNavDropSlots] = (0, import_react9.useState)([]);
8016
+ const [activeNavDropIndex, setActiveNavDropIndex] = (0, import_react9.useState)(null);
8017
+ const navPointerDragRef = (0, import_react9.useRef)(null);
8018
+ const clearNavDragVisuals = (0, import_react9.useCallback)(() => {
7754
8019
  navDragRef.current = null;
7755
8020
  setNavDropSlots([]);
7756
8021
  setActiveNavDropIndex(null);
@@ -7759,7 +8024,7 @@ function useNavItemDrag({
7759
8024
  setIsItemDragging(false);
7760
8025
  unlockItemDragInteraction();
7761
8026
  }, [setDraggedItemRect, setIsItemDragging, setSiblingHintRects]);
7762
- const refreshNavDragVisuals = (0, import_react8.useCallback)(
8027
+ const refreshNavDragVisuals = (0, import_react9.useCallback)(
7763
8028
  (session, activeSlot, clientX, clientY) => {
7764
8029
  setDraggedItemRect(session.draggedEl.getBoundingClientRect());
7765
8030
  if (typeof clientX === "number" && typeof clientY === "number") {
@@ -7777,13 +8042,13 @@ function useNavItemDrag({
7777
8042
  },
7778
8043
  [setDraggedItemRect, setSiblingHintRects]
7779
8044
  );
7780
- const refreshNavDragVisualsRef = (0, import_react8.useRef)(refreshNavDragVisuals);
8045
+ const refreshNavDragVisualsRef = (0, import_react9.useRef)(refreshNavDragVisuals);
7781
8046
  refreshNavDragVisualsRef.current = refreshNavDragVisuals;
7782
- const commitNavDragRef = (0, import_react8.useRef)(() => {
8047
+ const commitNavDragRef = (0, import_react9.useRef)(() => {
7783
8048
  });
7784
- const beginNavDragRef = (0, import_react8.useRef)(() => {
8049
+ const beginNavDragRef = (0, import_react9.useRef)(() => {
7785
8050
  });
7786
- const beginNavDrag = (0, import_react8.useCallback)(
8051
+ const beginNavDrag = (0, import_react9.useCallback)(
7787
8052
  (session) => {
7788
8053
  const rect = session.draggedEl.getBoundingClientRect();
7789
8054
  session.lastClientX = session.lastClientX || rect.left + rect.width / 2;
@@ -7810,7 +8075,7 @@ function useNavItemDrag({
7810
8075
  ]
7811
8076
  );
7812
8077
  beginNavDragRef.current = beginNavDrag;
7813
- const commitNavDrag = (0, import_react8.useCallback)(
8078
+ const commitNavDrag = (0, import_react9.useCallback)(
7814
8079
  (clientX, clientY) => {
7815
8080
  const session = navDragRef.current;
7816
8081
  if (!session) {
@@ -7871,7 +8136,7 @@ function useNavItemDrag({
7871
8136
  [clearNavDragVisuals, deselectRef, editContentRef, postToParentRef, selectRef]
7872
8137
  );
7873
8138
  commitNavDragRef.current = commitNavDrag;
7874
- const startNavLinkDrag = (0, import_react8.useCallback)(
8139
+ const startNavLinkDrag = (0, import_react9.useCallback)(
7875
8140
  (anchor, clientX, clientY, wasSelected) => {
7876
8141
  if (footerDragRef.current) return false;
7877
8142
  const hrefKey = anchor.getAttribute("data-ohw-href-key");
@@ -7889,7 +8154,7 @@ function useNavItemDrag({
7889
8154
  },
7890
8155
  [beginNavDrag, footerDragRef, isDragHandleDisabled2, isNavbarButton3]
7891
8156
  );
7892
- const onNavDragOver = (0, import_react8.useCallback)(
8157
+ const onNavDragOver = (0, import_react9.useCallback)(
7893
8158
  (e) => {
7894
8159
  const session = navDragRef.current;
7895
8160
  if (!session) return false;
@@ -7901,7 +8166,7 @@ function useNavItemDrag({
7901
8166
  },
7902
8167
  []
7903
8168
  );
7904
- (0, import_react8.useEffect)(() => {
8169
+ (0, import_react9.useEffect)(() => {
7905
8170
  if (!isEditMode) return;
7906
8171
  const THRESHOLD = 10;
7907
8172
  const resolveWasSelected = (el) => {
@@ -8026,7 +8291,7 @@ function useNavItemDrag({
8026
8291
  setLinkPopover,
8027
8292
  suppressNextClickRef
8028
8293
  ]);
8029
- const armNavPressFromChrome = (0, import_react8.useCallback)(
8294
+ const armNavPressFromChrome = (0, import_react9.useCallback)(
8030
8295
  (selected, clientX, clientY, pointerId) => {
8031
8296
  const hrefKey = selected.getAttribute("data-ohw-href-key");
8032
8297
  if (!hrefKey || !isNavbarHrefKey(hrefKey)) return false;
@@ -8058,11 +8323,11 @@ function useNavItemDrag({
8058
8323
 
8059
8324
  // src/ui/footer-container-chrome.tsx
8060
8325
  var import_lucide_react11 = require("lucide-react");
8061
- var import_jsx_runtime22 = require("react/jsx-runtime");
8326
+ var import_jsx_runtime23 = require("react/jsx-runtime");
8062
8327
  function FooterContainerChrome({ rect, onAdd }) {
8063
8328
  const chromeGap = 6;
8064
8329
  const buttonMargin = 7;
8065
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(TooltipProvider, { delayDuration: 0, children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
8330
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(TooltipProvider, { delayDuration: 0, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
8066
8331
  "div",
8067
8332
  {
8068
8333
  "data-ohw-footer-container-chrome": "",
@@ -8074,8 +8339,8 @@ function FooterContainerChrome({ rect, onAdd }) {
8074
8339
  width: rect.width + chromeGap * 2,
8075
8340
  height: rect.height + chromeGap * 2
8076
8341
  },
8077
- children: /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(Tooltip, { children: [
8078
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
8342
+ children: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(Tooltip, { children: [
8343
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
8079
8344
  "button",
8080
8345
  {
8081
8346
  type: "button",
@@ -8092,17 +8357,17 @@ function FooterContainerChrome({ rect, onAdd }) {
8092
8357
  e.stopPropagation();
8093
8358
  onAdd();
8094
8359
  },
8095
- children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react11.Plus, { className: "size-4 shrink-0 text-foreground", "aria-hidden": true })
8360
+ children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react11.Plus, { className: "size-4 shrink-0 text-foreground", "aria-hidden": true })
8096
8361
  }
8097
8362
  ) }),
8098
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(TooltipContent, { side: "bottom", sideOffset: 9, children: "Add item" })
8363
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(TooltipContent, { side: "bottom", sideOffset: 9, children: "Add item" })
8099
8364
  ] })
8100
8365
  }
8101
8366
  ) });
8102
8367
  }
8103
8368
 
8104
8369
  // src/lib/carousel.ts
8105
- var import_react9 = require("react");
8370
+ var import_react10 = require("react");
8106
8371
  var CAROUSEL_ATTR = "data-ohw-carousel";
8107
8372
  var CAROUSEL_VALUE_ATTR = "data-ohw-carousel-value";
8108
8373
  var CAROUSEL_SLIDE_ATTR = "data-ohw-carousel-slide";
@@ -8164,8 +8429,8 @@ function applyCarouselNode(key, val) {
8164
8429
  return true;
8165
8430
  }
8166
8431
  function useOhwCarousel(key, initial) {
8167
- const [images, setImages] = (0, import_react9.useState)(initial);
8168
- (0, import_react9.useEffect)(() => {
8432
+ const [images, setImages] = (0, import_react10.useState)(initial);
8433
+ (0, import_react10.useEffect)(() => {
8169
8434
  const el = document.querySelector(
8170
8435
  `[${CAROUSEL_ATTR}][data-ohw-key="${CSS.escape(key)}"]`
8171
8436
  );
@@ -8187,13 +8452,13 @@ function useOhwCarousel(key, initial) {
8187
8452
 
8188
8453
  // src/ui/navbar-container-chrome.tsx
8189
8454
  var import_lucide_react12 = require("lucide-react");
8190
- var import_jsx_runtime23 = require("react/jsx-runtime");
8455
+ var import_jsx_runtime24 = require("react/jsx-runtime");
8191
8456
  function NavbarContainerChrome({
8192
8457
  rect,
8193
8458
  onAdd
8194
8459
  }) {
8195
8460
  const chromeGap = 6;
8196
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
8461
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
8197
8462
  "div",
8198
8463
  {
8199
8464
  "data-ohw-navbar-container-chrome": "",
@@ -8205,7 +8470,7 @@ function NavbarContainerChrome({
8205
8470
  width: rect.width + chromeGap * 2,
8206
8471
  height: rect.height + chromeGap * 2
8207
8472
  },
8208
- children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
8473
+ children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
8209
8474
  "button",
8210
8475
  {
8211
8476
  type: "button",
@@ -8222,7 +8487,7 @@ function NavbarContainerChrome({
8222
8487
  e.stopPropagation();
8223
8488
  onAdd();
8224
8489
  },
8225
- children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react12.Plus, { className: "size-4 shrink-0 text-foreground", "aria-hidden": true })
8490
+ children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react12.Plus, { className: "size-4 shrink-0 text-foreground", "aria-hidden": true })
8226
8491
  }
8227
8492
  )
8228
8493
  }
@@ -8231,7 +8496,7 @@ function NavbarContainerChrome({
8231
8496
 
8232
8497
  // src/ui/drop-indicator.tsx
8233
8498
  var React10 = __toESM(require("react"), 1);
8234
- var import_jsx_runtime24 = require("react/jsx-runtime");
8499
+ var import_jsx_runtime25 = require("react/jsx-runtime");
8235
8500
  var dropIndicatorVariants = cva(
8236
8501
  "ov-gap-line pointer-events-none shrink-0 transition-opacity duration-150",
8237
8502
  {
@@ -8255,7 +8520,7 @@ var dropIndicatorVariants = cva(
8255
8520
  );
8256
8521
  var DropIndicator = React10.forwardRef(
8257
8522
  ({ className, direction, state, ...props }, ref) => {
8258
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
8523
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
8259
8524
  "div",
8260
8525
  {
8261
8526
  ref,
@@ -8272,7 +8537,7 @@ var DropIndicator = React10.forwardRef(
8272
8537
  DropIndicator.displayName = "DropIndicator";
8273
8538
 
8274
8539
  // src/ui/badge.tsx
8275
- var import_jsx_runtime25 = require("react/jsx-runtime");
8540
+ var import_jsx_runtime26 = require("react/jsx-runtime");
8276
8541
  var badgeVariants = cva(
8277
8542
  "inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
8278
8543
  {
@@ -8290,12 +8555,12 @@ var badgeVariants = cva(
8290
8555
  }
8291
8556
  );
8292
8557
  function Badge({ className, variant, ...props }) {
8293
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: cn(badgeVariants({ variant }), className), ...props });
8558
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: cn(badgeVariants({ variant }), className), ...props });
8294
8559
  }
8295
8560
 
8296
8561
  // src/OhhwellsBridge.tsx
8297
8562
  var import_lucide_react13 = require("lucide-react");
8298
- var import_jsx_runtime26 = require("react/jsx-runtime");
8563
+ var import_jsx_runtime27 = require("react/jsx-runtime");
8299
8564
  var PRIMARY2 = "#0885FE";
8300
8565
  var IMAGE_FADE_MS = 300;
8301
8566
  function runOpacityFade(el, onDone) {
@@ -8474,7 +8739,7 @@ function mountSchedulingWidget(insertAfter, notifyOnConnect = false, scheduleId,
8474
8739
  const root = (0, import_client.createRoot)(container);
8475
8740
  (0, import_react_dom2.flushSync)(() => {
8476
8741
  root.render(
8477
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
8742
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
8478
8743
  SchedulingWidget,
8479
8744
  {
8480
8745
  notifyOnConnect,
@@ -8514,7 +8779,7 @@ function mountSchedulingEntries(entries, notifyOnConnect = false) {
8514
8779
  }
8515
8780
  }
8516
8781
  }
8517
- function getLinkHref2(el) {
8782
+ function getLinkHref3(el) {
8518
8783
  const anchor = el instanceof HTMLAnchorElement ? el : el.querySelector("a");
8519
8784
  return anchor?.getAttribute("href") ?? "";
8520
8785
  }
@@ -8564,7 +8829,7 @@ function collectEditableNodes(extraContent) {
8564
8829
  return { key: el.dataset.ohwKey ?? "", type: "video", text: getVideoEl(el)?.src ?? "" };
8565
8830
  }
8566
8831
  if (el.dataset.ohwEditable === "link") {
8567
- return { key: el.dataset.ohwKey ?? "", type: "link", text: getLinkHref2(el) };
8832
+ return { key: el.dataset.ohwKey ?? "", type: "link", text: getLinkHref3(el) };
8568
8833
  }
8569
8834
  return {
8570
8835
  key: el.dataset.ohwKey ?? "",
@@ -8575,7 +8840,7 @@ function collectEditableNodes(extraContent) {
8575
8840
  document.querySelectorAll("[data-ohw-href-key]").forEach((el) => {
8576
8841
  const key = el.getAttribute("data-ohw-href-key") ?? "";
8577
8842
  if (!key) return;
8578
- nodes.push({ key, type: "link", text: getLinkHref2(el) });
8843
+ nodes.push({ key, type: "link", text: getLinkHref3(el) });
8579
8844
  });
8580
8845
  if (extraContent) {
8581
8846
  for (const key of [NAV_ORDER_KEY, FOOTER_ORDER_KEY, NAV_COUNT_KEY]) {
@@ -8678,7 +8943,7 @@ function applyLinkByKey(key, val) {
8678
8943
  }
8679
8944
  function isInsideLinkEditor(target) {
8680
8945
  return Boolean(
8681
- target.closest("[data-ohw-link-popover-root]") || target.closest("[data-ohw-link-modal-root]") || target.closest("[data-ohw-link-page-dropdown]") || target.closest("[data-ohw-section-picker]") || target.closest("[data-ohw-navbar-container-chrome]") || target.closest("[data-ohw-navbar-add-button]") || target.closest("[data-ohw-footer-container-chrome]") || target.closest("[data-ohw-footer-add-button]") || target.closest('[data-slot="popover-content"]') || target.closest('[data-slot="dialog-content"]') || target.closest('[data-slot="dialog-overlay"]')
8946
+ target.closest("[data-ohw-link-popover-root]") || target.closest("[data-ohw-link-modal-root]") || target.closest("[data-ohw-link-page-dropdown]") || target.closest("[data-ohw-section-picker]") || target.closest("[data-ohw-navbar-container-chrome]") || target.closest("[data-ohw-navbar-add-button]") || target.closest("[data-ohw-footer-container-chrome]") || target.closest("[data-ohw-footer-add-button]") || target.closest("[data-ohw-more-menu]") || target.closest('[data-slot="dropdown-menu-content"]') || target.closest('[data-slot="popover-content"]') || target.closest('[data-slot="dialog-content"]') || target.closest('[data-slot="dialog-overlay"]')
8682
8947
  );
8683
8948
  }
8684
8949
  function getHrefKeyFromElement(el) {
@@ -9075,7 +9340,7 @@ function EditGlowChrome({
9075
9340
  hideHandle = false
9076
9341
  }) {
9077
9342
  const GAP = SELECTION_CHROME_GAP2;
9078
- return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
9343
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
9079
9344
  "div",
9080
9345
  {
9081
9346
  ref: elRef,
@@ -9090,7 +9355,7 @@ function EditGlowChrome({
9090
9355
  zIndex: 2147483646
9091
9356
  },
9092
9357
  children: [
9093
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
9358
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
9094
9359
  "div",
9095
9360
  {
9096
9361
  style: {
@@ -9103,7 +9368,7 @@ function EditGlowChrome({
9103
9368
  }
9104
9369
  }
9105
9370
  ),
9106
- reorderHrefKey && !hideHandle && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
9371
+ reorderHrefKey && !hideHandle && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
9107
9372
  "div",
9108
9373
  {
9109
9374
  "data-ohw-drag-handle-container": "",
@@ -9115,7 +9380,7 @@ function EditGlowChrome({
9115
9380
  transform: "translate(calc(-100% - 7px), -50%)",
9116
9381
  pointerEvents: dragDisabled ? "none" : "auto"
9117
9382
  },
9118
- children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
9383
+ children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
9119
9384
  DragHandle,
9120
9385
  {
9121
9386
  "aria-label": `Reorder ${reorderHrefKey}`,
@@ -9298,9 +9563,9 @@ function FloatingToolbar({
9298
9563
  showEditLink,
9299
9564
  onEditLink
9300
9565
  }) {
9301
- const localRef = import_react10.default.useRef(null);
9302
- const [measuredW, setMeasuredW] = import_react10.default.useState(330);
9303
- const setRefs = import_react10.default.useCallback(
9566
+ const localRef = import_react11.default.useRef(null);
9567
+ const [measuredW, setMeasuredW] = import_react11.default.useState(330);
9568
+ const setRefs = import_react11.default.useCallback(
9304
9569
  (node) => {
9305
9570
  localRef.current = node;
9306
9571
  if (typeof elRef === "function") elRef(node);
@@ -9312,7 +9577,7 @@ function FloatingToolbar({
9312
9577
  },
9313
9578
  [elRef]
9314
9579
  );
9315
- import_react10.default.useLayoutEffect(() => {
9580
+ import_react11.default.useLayoutEffect(() => {
9316
9581
  const node = localRef.current;
9317
9582
  if (!node) return;
9318
9583
  const update = () => {
@@ -9325,7 +9590,7 @@ function FloatingToolbar({
9325
9590
  return () => ro.disconnect();
9326
9591
  }, [showEditLink, activeCommands]);
9327
9592
  const { top, left, transform } = calcToolbarPos(rect, parentScroll, measuredW);
9328
- return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
9593
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
9329
9594
  "div",
9330
9595
  {
9331
9596
  ref: setRefs,
@@ -9337,12 +9602,12 @@ function FloatingToolbar({
9337
9602
  zIndex: 2147483647,
9338
9603
  pointerEvents: "auto"
9339
9604
  },
9340
- children: /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(CustomToolbar, { children: [
9341
- TOOLBAR_GROUPS.map((btns, gi) => /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_react10.default.Fragment, { children: [
9342
- gi > 0 && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(CustomToolbarDivider, {}),
9605
+ children: /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(CustomToolbar, { children: [
9606
+ TOOLBAR_GROUPS.map((btns, gi) => /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(import_react11.default.Fragment, { children: [
9607
+ gi > 0 && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(CustomToolbarDivider, {}),
9343
9608
  btns.map((btn) => {
9344
9609
  const isActive = activeCommands.has(btn.cmd);
9345
- return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
9610
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
9346
9611
  CustomToolbarButton,
9347
9612
  {
9348
9613
  title: btn.title,
@@ -9351,7 +9616,7 @@ function FloatingToolbar({
9351
9616
  e.preventDefault();
9352
9617
  onCommand(btn.cmd);
9353
9618
  },
9354
- children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
9619
+ children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
9355
9620
  "svg",
9356
9621
  {
9357
9622
  width: "16",
@@ -9372,7 +9637,7 @@ function FloatingToolbar({
9372
9637
  );
9373
9638
  })
9374
9639
  ] }, gi)),
9375
- showEditLink ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
9640
+ showEditLink ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
9376
9641
  CustomToolbarButton,
9377
9642
  {
9378
9643
  type: "button",
@@ -9386,7 +9651,7 @@ function FloatingToolbar({
9386
9651
  e.preventDefault();
9387
9652
  e.stopPropagation();
9388
9653
  },
9389
- children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_lucide_react13.Link, { className: "size-4 shrink-0", "aria-hidden": true })
9654
+ children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_lucide_react13.Link, { className: "size-4 shrink-0", "aria-hidden": true })
9390
9655
  }
9391
9656
  ) : null
9392
9657
  ] })
@@ -9403,7 +9668,7 @@ function StateToggle({
9403
9668
  states,
9404
9669
  onStateChange
9405
9670
  }) {
9406
- return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
9671
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
9407
9672
  ToggleGroup,
9408
9673
  {
9409
9674
  "data-ohw-state-toggle": "",
@@ -9417,7 +9682,7 @@ function StateToggle({
9417
9682
  left: rect.right - 8,
9418
9683
  transform: "translateX(-100%)"
9419
9684
  },
9420
- children: states.map((state) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(ToggleGroupItem, { value: state, size: "sm", children: state }, state))
9685
+ children: states.map((state) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(ToggleGroupItem, { value: state, size: "sm", children: state }, state))
9421
9686
  }
9422
9687
  );
9423
9688
  }
@@ -9444,8 +9709,8 @@ function OhhwellsBridge() {
9444
9709
  const router = (0, import_navigation2.useRouter)();
9445
9710
  const searchParams = (0, import_navigation2.useSearchParams)();
9446
9711
  const isEditMode = isEditSessionActive();
9447
- const [bridgeRoot, setBridgeRoot] = (0, import_react10.useState)(null);
9448
- (0, import_react10.useEffect)(() => {
9712
+ const [bridgeRoot, setBridgeRoot] = (0, import_react11.useState)(null);
9713
+ (0, import_react11.useEffect)(() => {
9449
9714
  const figtreeFontId = "ohw-figtree-font";
9450
9715
  if (!document.getElementById(figtreeFontId)) {
9451
9716
  const preconnect1 = Object.assign(document.createElement("link"), { rel: "preconnect", href: "https://fonts.googleapis.com" });
@@ -9473,99 +9738,99 @@ function OhhwellsBridge() {
9473
9738
  const subdomainFromQuery = searchParams.get("subdomain");
9474
9739
  const subdomain = resolveSubdomain(subdomainFromQuery);
9475
9740
  useLinkHrefGuardian(pathname, subdomain, isEditMode);
9476
- const postToParent2 = (0, import_react10.useCallback)((data) => {
9741
+ const postToParent2 = (0, import_react11.useCallback)((data) => {
9477
9742
  if (typeof window !== "undefined" && window.parent !== window) {
9478
9743
  window.parent.postMessage(data, "*");
9479
9744
  }
9480
9745
  }, []);
9481
- const [fetchState, setFetchState] = (0, import_react10.useState)("idle");
9482
- const autoSaveTimers = (0, import_react10.useRef)(/* @__PURE__ */ new Map());
9483
- const activeElRef = (0, import_react10.useRef)(null);
9484
- const pointerHeldRef = (0, import_react10.useRef)(false);
9485
- const selectedElRef = (0, import_react10.useRef)(null);
9486
- const selectedHrefKeyRef = (0, import_react10.useRef)(null);
9487
- const selectedFooterColAttrRef = (0, import_react10.useRef)(null);
9488
- const originalContentRef = (0, import_react10.useRef)(null);
9489
- const activeStateElRef = (0, import_react10.useRef)(null);
9490
- const parentScrollRef = (0, import_react10.useRef)(null);
9491
- const visibleViewportRef = (0, import_react10.useRef)(null);
9492
- const [dialogPortalContainer, setDialogPortalContainer] = (0, import_react10.useState)(null);
9493
- const attachVisibleViewport = (0, import_react10.useCallback)((node) => {
9746
+ const [fetchState, setFetchState] = (0, import_react11.useState)("idle");
9747
+ const autoSaveTimers = (0, import_react11.useRef)(/* @__PURE__ */ new Map());
9748
+ const activeElRef = (0, import_react11.useRef)(null);
9749
+ const pointerHeldRef = (0, import_react11.useRef)(false);
9750
+ const selectedElRef = (0, import_react11.useRef)(null);
9751
+ const selectedHrefKeyRef = (0, import_react11.useRef)(null);
9752
+ const selectedFooterColAttrRef = (0, import_react11.useRef)(null);
9753
+ const originalContentRef = (0, import_react11.useRef)(null);
9754
+ const activeStateElRef = (0, import_react11.useRef)(null);
9755
+ const parentScrollRef = (0, import_react11.useRef)(null);
9756
+ const visibleViewportRef = (0, import_react11.useRef)(null);
9757
+ const [dialogPortalContainer, setDialogPortalContainer] = (0, import_react11.useState)(null);
9758
+ const attachVisibleViewport = (0, import_react11.useCallback)((node) => {
9494
9759
  visibleViewportRef.current = node;
9495
9760
  setDialogPortalContainer(node);
9496
9761
  if (node) applyVisibleViewport(node, parentScrollRef.current);
9497
9762
  }, []);
9498
- const toolbarElRef = (0, import_react10.useRef)(null);
9499
- const glowElRef = (0, import_react10.useRef)(null);
9500
- const hoveredImageRef = (0, import_react10.useRef)(null);
9501
- const hoveredImageHasTextOverlapRef = (0, import_react10.useRef)(false);
9502
- const dragOverElRef = (0, import_react10.useRef)(null);
9503
- const [mediaHover, setMediaHover] = (0, import_react10.useState)(null);
9504
- const [carouselHover, setCarouselHover] = (0, import_react10.useState)(null);
9505
- const [uploadingRects, setUploadingRects] = (0, import_react10.useState)({});
9506
- const hoveredGapRef = (0, import_react10.useRef)(null);
9507
- const imageUnhoverTimerRef = (0, import_react10.useRef)(null);
9508
- const imageShowTimerRef = (0, import_react10.useRef)(null);
9509
- const editStylesRef = (0, import_react10.useRef)(null);
9510
- const activateRef = (0, import_react10.useRef)(() => {
9763
+ const toolbarElRef = (0, import_react11.useRef)(null);
9764
+ const glowElRef = (0, import_react11.useRef)(null);
9765
+ const hoveredImageRef = (0, import_react11.useRef)(null);
9766
+ const hoveredImageHasTextOverlapRef = (0, import_react11.useRef)(false);
9767
+ const dragOverElRef = (0, import_react11.useRef)(null);
9768
+ const [mediaHover, setMediaHover] = (0, import_react11.useState)(null);
9769
+ const [carouselHover, setCarouselHover] = (0, import_react11.useState)(null);
9770
+ const [uploadingRects, setUploadingRects] = (0, import_react11.useState)({});
9771
+ const hoveredGapRef = (0, import_react11.useRef)(null);
9772
+ const imageUnhoverTimerRef = (0, import_react11.useRef)(null);
9773
+ const imageShowTimerRef = (0, import_react11.useRef)(null);
9774
+ const editStylesRef = (0, import_react11.useRef)(null);
9775
+ const activateRef = (0, import_react11.useRef)(() => {
9511
9776
  });
9512
- const deactivateRef = (0, import_react10.useRef)(() => {
9777
+ const deactivateRef = (0, import_react11.useRef)(() => {
9513
9778
  });
9514
- const selectRef = (0, import_react10.useRef)(() => {
9779
+ const selectRef = (0, import_react11.useRef)(() => {
9515
9780
  });
9516
- const selectFrameRef = (0, import_react10.useRef)(() => {
9781
+ const selectFrameRef = (0, import_react11.useRef)(() => {
9517
9782
  });
9518
- const deselectRef = (0, import_react10.useRef)(() => {
9783
+ const deselectRef = (0, import_react11.useRef)(() => {
9519
9784
  });
9520
- const reselectNavigationItemRef = (0, import_react10.useRef)(() => {
9785
+ const reselectNavigationItemRef = (0, import_react11.useRef)(() => {
9521
9786
  });
9522
- const commitNavigationTextEditRef = (0, import_react10.useRef)(() => {
9787
+ const commitNavigationTextEditRef = (0, import_react11.useRef)(() => {
9523
9788
  });
9524
- const refreshActiveCommandsRef = (0, import_react10.useRef)(() => {
9789
+ const refreshActiveCommandsRef = (0, import_react11.useRef)(() => {
9525
9790
  });
9526
- const postToParentRef = (0, import_react10.useRef)(postToParent2);
9791
+ const postToParentRef = (0, import_react11.useRef)(postToParent2);
9527
9792
  postToParentRef.current = postToParent2;
9528
- const sectionsLoadedRef = (0, import_react10.useRef)(false);
9529
- const pendingScheduleConfigRequests = (0, import_react10.useRef)([]);
9530
- const [toolbarRect, setToolbarRect] = (0, import_react10.useState)(null);
9531
- const [toolbarVariant, setToolbarVariant] = (0, import_react10.useState)("none");
9532
- const toolbarVariantRef = (0, import_react10.useRef)("none");
9793
+ const sectionsLoadedRef = (0, import_react11.useRef)(false);
9794
+ const pendingScheduleConfigRequests = (0, import_react11.useRef)([]);
9795
+ const [toolbarRect, setToolbarRect] = (0, import_react11.useState)(null);
9796
+ const [toolbarVariant, setToolbarVariant] = (0, import_react11.useState)("none");
9797
+ const toolbarVariantRef = (0, import_react11.useRef)("none");
9533
9798
  toolbarVariantRef.current = toolbarVariant;
9534
- const [selectedIsCta, setSelectedIsCta] = (0, import_react10.useState)(false);
9535
- const [reorderHrefKey, setReorderHrefKey] = (0, import_react10.useState)(null);
9536
- const [reorderDragDisabled, setReorderDragDisabled] = (0, import_react10.useState)(false);
9537
- const [toggleState, setToggleState] = (0, import_react10.useState)(null);
9538
- const [maxBadge, setMaxBadge] = (0, import_react10.useState)(null);
9539
- const [activeCommands, setActiveCommands] = (0, import_react10.useState)(/* @__PURE__ */ new Set());
9540
- const [sectionGap, setSectionGap] = (0, import_react10.useState)(null);
9541
- const [toolbarShowEditLink, setToolbarShowEditLink] = (0, import_react10.useState)(false);
9542
- const hoveredNavContainerRef = (0, import_react10.useRef)(null);
9543
- const [hoveredNavContainerRect, setHoveredNavContainerRect] = (0, import_react10.useState)(null);
9544
- const hoveredItemElRef = (0, import_react10.useRef)(null);
9545
- const [hoveredItemRect, setHoveredItemRect] = (0, import_react10.useState)(null);
9546
- const siblingHintElRef = (0, import_react10.useRef)(null);
9547
- const [siblingHintRect, setSiblingHintRect] = (0, import_react10.useState)(null);
9548
- const [siblingHintRects, setSiblingHintRects] = (0, import_react10.useState)([]);
9549
- const [isItemDragging, setIsItemDragging] = (0, import_react10.useState)(false);
9550
- const [isFooterFrameSelection, setIsFooterFrameSelection] = (0, import_react10.useState)(false);
9551
- const footerDragRef = (0, import_react10.useRef)(null);
9552
- const [footerDropSlots, setFooterDropSlots] = (0, import_react10.useState)([]);
9553
- const [activeFooterDropIndex, setActiveFooterDropIndex] = (0, import_react10.useState)(null);
9554
- const [draggedItemRect, setDraggedItemRect] = (0, import_react10.useState)(null);
9555
- const footerPointerDragRef = (0, import_react10.useRef)(null);
9556
- const suppressNextClickRef = (0, import_react10.useRef)(false);
9557
- const suppressClickUntilRef = (0, import_react10.useRef)(0);
9558
- const [linkPopover, setLinkPopover] = (0, import_react10.useState)(null);
9559
- const linkPopoverSessionRef = (0, import_react10.useRef)(null);
9560
- const addNavAfterAnchorRef = (0, import_react10.useRef)(null);
9561
- const editContentRef = (0, import_react10.useRef)({});
9562
- const [sitePages, setSitePages] = (0, import_react10.useState)([]);
9563
- const [sectionsByPath, setSectionsByPath] = (0, import_react10.useState)({});
9564
- const sectionsPrefetchGenRef = (0, import_react10.useRef)(0);
9565
- const setLinkPopoverRef = (0, import_react10.useRef)(setLinkPopover);
9566
- const linkPopoverPanelRef = (0, import_react10.useRef)(null);
9567
- const linkPopoverOpenRef = (0, import_react10.useRef)(false);
9568
- const linkPopoverGraceUntilRef = (0, import_react10.useRef)(0);
9799
+ const [selectedIsCta, setSelectedIsCta] = (0, import_react11.useState)(false);
9800
+ const [reorderHrefKey, setReorderHrefKey] = (0, import_react11.useState)(null);
9801
+ const [reorderDragDisabled, setReorderDragDisabled] = (0, import_react11.useState)(false);
9802
+ const [toggleState, setToggleState] = (0, import_react11.useState)(null);
9803
+ const [maxBadge, setMaxBadge] = (0, import_react11.useState)(null);
9804
+ const [activeCommands, setActiveCommands] = (0, import_react11.useState)(/* @__PURE__ */ new Set());
9805
+ const [sectionGap, setSectionGap] = (0, import_react11.useState)(null);
9806
+ const [toolbarShowEditLink, setToolbarShowEditLink] = (0, import_react11.useState)(false);
9807
+ const hoveredNavContainerRef = (0, import_react11.useRef)(null);
9808
+ const [hoveredNavContainerRect, setHoveredNavContainerRect] = (0, import_react11.useState)(null);
9809
+ const hoveredItemElRef = (0, import_react11.useRef)(null);
9810
+ const [hoveredItemRect, setHoveredItemRect] = (0, import_react11.useState)(null);
9811
+ const siblingHintElRef = (0, import_react11.useRef)(null);
9812
+ const [siblingHintRect, setSiblingHintRect] = (0, import_react11.useState)(null);
9813
+ const [siblingHintRects, setSiblingHintRects] = (0, import_react11.useState)([]);
9814
+ const [isItemDragging, setIsItemDragging] = (0, import_react11.useState)(false);
9815
+ const [isFooterFrameSelection, setIsFooterFrameSelection] = (0, import_react11.useState)(false);
9816
+ const footerDragRef = (0, import_react11.useRef)(null);
9817
+ const [footerDropSlots, setFooterDropSlots] = (0, import_react11.useState)([]);
9818
+ const [activeFooterDropIndex, setActiveFooterDropIndex] = (0, import_react11.useState)(null);
9819
+ const [draggedItemRect, setDraggedItemRect] = (0, import_react11.useState)(null);
9820
+ const footerPointerDragRef = (0, import_react11.useRef)(null);
9821
+ const suppressNextClickRef = (0, import_react11.useRef)(false);
9822
+ const suppressClickUntilRef = (0, import_react11.useRef)(0);
9823
+ const [linkPopover, setLinkPopover] = (0, import_react11.useState)(null);
9824
+ const linkPopoverSessionRef = (0, import_react11.useRef)(null);
9825
+ const addNavAfterAnchorRef = (0, import_react11.useRef)(null);
9826
+ const editContentRef = (0, import_react11.useRef)({});
9827
+ const [sitePages, setSitePages] = (0, import_react11.useState)([]);
9828
+ const [sectionsByPath, setSectionsByPath] = (0, import_react11.useState)({});
9829
+ const sectionsPrefetchGenRef = (0, import_react11.useRef)(0);
9830
+ const setLinkPopoverRef = (0, import_react11.useRef)(setLinkPopover);
9831
+ const linkPopoverPanelRef = (0, import_react11.useRef)(null);
9832
+ const linkPopoverOpenRef = (0, import_react11.useRef)(false);
9833
+ const linkPopoverGraceUntilRef = (0, import_react11.useRef)(0);
9569
9834
  setLinkPopoverRef.current = setLinkPopover;
9570
9835
  linkPopoverSessionRef.current = linkPopover;
9571
9836
  const {
@@ -9604,7 +9869,7 @@ function OhhwellsBridge() {
9604
9869
  const bumpLinkPopoverGrace = () => {
9605
9870
  linkPopoverGraceUntilRef.current = Date.now() + 350;
9606
9871
  };
9607
- const runSectionsPrefetch = (0, import_react10.useCallback)((pages) => {
9872
+ const runSectionsPrefetch = (0, import_react11.useCallback)((pages) => {
9608
9873
  if (!isEditMode || shouldUseDevFixtures() || pages.length === 0) return;
9609
9874
  const gen = ++sectionsPrefetchGenRef.current;
9610
9875
  const paths = pages.map((p) => p.path);
@@ -9623,9 +9888,9 @@ function OhhwellsBridge() {
9623
9888
  );
9624
9889
  });
9625
9890
  }, [isEditMode, pathname]);
9626
- const runSectionsPrefetchRef = (0, import_react10.useRef)(runSectionsPrefetch);
9891
+ const runSectionsPrefetchRef = (0, import_react11.useRef)(runSectionsPrefetch);
9627
9892
  runSectionsPrefetchRef.current = runSectionsPrefetch;
9628
- (0, import_react10.useEffect)(() => {
9893
+ (0, import_react11.useEffect)(() => {
9629
9894
  if (!linkPopover) {
9630
9895
  document.documentElement.removeAttribute("data-ohw-link-popover-open");
9631
9896
  return;
@@ -9675,7 +9940,7 @@ function OhhwellsBridge() {
9675
9940
  document.removeEventListener("touchmove", preventBackgroundScroll, scrollOpts);
9676
9941
  };
9677
9942
  }, [linkPopover, postToParent2]);
9678
- (0, import_react10.useEffect)(() => {
9943
+ (0, import_react11.useEffect)(() => {
9679
9944
  if (!isEditMode) return;
9680
9945
  const useFixtures = shouldUseDevFixtures();
9681
9946
  if (useFixtures) {
@@ -9699,14 +9964,14 @@ function OhhwellsBridge() {
9699
9964
  if (!useFixtures) postToParent2({ type: "ow:request-site-pages" });
9700
9965
  return () => window.removeEventListener("message", onSitePages);
9701
9966
  }, [isEditMode, postToParent2]);
9702
- (0, import_react10.useEffect)(() => {
9967
+ (0, import_react11.useEffect)(() => {
9703
9968
  if (!isEditMode || shouldUseDevFixtures()) return;
9704
9969
  void loadAllSectionsManifest().then((manifest) => {
9705
9970
  if (Object.keys(manifest).length === 0) return;
9706
9971
  setSectionsByPath((prev) => ({ ...manifest, ...prev }));
9707
9972
  });
9708
9973
  }, [isEditMode]);
9709
- (0, import_react10.useEffect)(() => {
9974
+ (0, import_react11.useEffect)(() => {
9710
9975
  const update = () => {
9711
9976
  const el = activeElRef.current ?? selectedElRef.current;
9712
9977
  if (el) setToolbarRect(getEditMeasureEl(el).getBoundingClientRect());
@@ -9730,10 +9995,10 @@ function OhhwellsBridge() {
9730
9995
  vvp.removeEventListener("resize", update);
9731
9996
  };
9732
9997
  }, []);
9733
- const refreshStateRules = (0, import_react10.useCallback)(() => {
9998
+ const refreshStateRules = (0, import_react11.useCallback)(() => {
9734
9999
  editStylesRef.current?.forceHover && (editStylesRef.current.forceHover.textContent = collectStateRules());
9735
10000
  }, []);
9736
- const processConfigRequest = (0, import_react10.useCallback)((insertAfterVal) => {
10001
+ const processConfigRequest = (0, import_react11.useCallback)((insertAfterVal) => {
9737
10002
  const tracker = getSectionsTracker();
9738
10003
  let entries = [];
9739
10004
  try {
@@ -9756,7 +10021,7 @@ function OhhwellsBridge() {
9756
10021
  }
9757
10022
  window.postMessage({ type: "ow:schedule-config", insertAfter: insertAfterVal, scheduleId: null }, "*");
9758
10023
  }, [isEditMode]);
9759
- const deactivate = (0, import_react10.useCallback)(() => {
10024
+ const deactivate = (0, import_react11.useCallback)(() => {
9760
10025
  const el = activeElRef.current;
9761
10026
  if (!el) return;
9762
10027
  const key = el.dataset.ohwKey;
@@ -9788,12 +10053,12 @@ function OhhwellsBridge() {
9788
10053
  setToolbarShowEditLink(false);
9789
10054
  postToParent2({ type: "ow:exit-edit" });
9790
10055
  }, [postToParent2]);
9791
- const clearSelectedAttr = (0, import_react10.useCallback)(() => {
10056
+ const clearSelectedAttr = (0, import_react11.useCallback)(() => {
9792
10057
  document.querySelectorAll("[data-ohw-selected]").forEach((el) => {
9793
10058
  el.removeAttribute("data-ohw-selected");
9794
10059
  });
9795
10060
  }, []);
9796
- const deselect = (0, import_react10.useCallback)(() => {
10061
+ const deselect = (0, import_react11.useCallback)(() => {
9797
10062
  clearSelectedAttr();
9798
10063
  selectedElRef.current = null;
9799
10064
  selectedHrefKeyRef.current = null;
@@ -9813,11 +10078,11 @@ function OhhwellsBridge() {
9813
10078
  setToolbarVariant("none");
9814
10079
  }
9815
10080
  }, [clearSelectedAttr]);
9816
- const markSelected = (0, import_react10.useCallback)((el) => {
10081
+ const markSelected = (0, import_react11.useCallback)((el) => {
9817
10082
  clearSelectedAttr();
9818
10083
  el.setAttribute("data-ohw-selected", "");
9819
10084
  }, [clearSelectedAttr]);
9820
- const resolveHrefKeyElement = (0, import_react10.useCallback)((hrefKey) => {
10085
+ const resolveHrefKeyElement = (0, import_react11.useCallback)((hrefKey) => {
9821
10086
  if (isFooterHrefKey(hrefKey)) {
9822
10087
  return document.querySelector(
9823
10088
  `footer [data-ohw-href-key="${CSS.escape(hrefKey)}"]`
@@ -9832,7 +10097,7 @@ function OhhwellsBridge() {
9832
10097
  `[data-ohw-href-key="${CSS.escape(hrefKey)}"]`
9833
10098
  );
9834
10099
  }, []);
9835
- const resyncSelectedNavigationItem = (0, import_react10.useCallback)(() => {
10100
+ const resyncSelectedNavigationItem = (0, import_react11.useCallback)(() => {
9836
10101
  const hrefKey = selectedHrefKeyRef.current;
9837
10102
  if (hrefKey) {
9838
10103
  const link = resolveHrefKeyElement(hrefKey);
@@ -9860,7 +10125,7 @@ function OhhwellsBridge() {
9860
10125
  );
9861
10126
  }
9862
10127
  }, [resolveHrefKeyElement]);
9863
- const reselectNavigationItem = (0, import_react10.useCallback)((navAnchor) => {
10128
+ const reselectNavigationItem = (0, import_react11.useCallback)((navAnchor) => {
9864
10129
  selectedElRef.current = navAnchor;
9865
10130
  selectedHrefKeyRef.current = navAnchor.getAttribute("data-ohw-href-key");
9866
10131
  selectedFooterColAttrRef.current = null;
@@ -9875,7 +10140,7 @@ function OhhwellsBridge() {
9875
10140
  setToolbarShowEditLink(false);
9876
10141
  setActiveCommands(/* @__PURE__ */ new Set());
9877
10142
  }, [markSelected]);
9878
- const commitNavigationTextEdit = (0, import_react10.useCallback)((navAnchor) => {
10143
+ const commitNavigationTextEdit = (0, import_react11.useCallback)((navAnchor) => {
9879
10144
  const el = activeElRef.current;
9880
10145
  if (!el) return;
9881
10146
  const key = el.dataset.ohwKey;
@@ -9902,7 +10167,7 @@ function OhhwellsBridge() {
9902
10167
  postToParent2({ type: "ow:exit-edit" });
9903
10168
  reselectNavigationItem(navAnchor);
9904
10169
  }, [postToParent2, reselectNavigationItem]);
9905
- const handleAddTopLevelNavItem = (0, import_react10.useCallback)(() => {
10170
+ const handleAddTopLevelNavItem = (0, import_react11.useCallback)(() => {
9906
10171
  const items = listNavbarItems();
9907
10172
  addNavAfterAnchorRef.current = items[items.length - 1] ?? null;
9908
10173
  deselectRef.current();
@@ -9914,7 +10179,7 @@ function OhhwellsBridge() {
9914
10179
  intent: "add-nav"
9915
10180
  });
9916
10181
  }, []);
9917
- const handleAddFooterColumn = (0, import_react10.useCallback)(() => {
10182
+ const handleAddFooterColumn = (0, import_react11.useCallback)(() => {
9918
10183
  deselectRef.current();
9919
10184
  deactivateRef.current();
9920
10185
  const result = addFooterColumnWithPersist({ postToParent: postToParent2 });
@@ -9926,7 +10191,7 @@ function OhhwellsBridge() {
9926
10191
  selectRef.current(result.firstLink);
9927
10192
  });
9928
10193
  }, [postToParent2]);
9929
- const clearFooterDragVisuals = (0, import_react10.useCallback)(() => {
10194
+ const clearFooterDragVisuals = (0, import_react11.useCallback)(() => {
9930
10195
  footerDragRef.current = null;
9931
10196
  setSiblingHintRects([]);
9932
10197
  setFooterDropSlots([]);
@@ -9935,7 +10200,7 @@ function OhhwellsBridge() {
9935
10200
  setIsItemDragging(false);
9936
10201
  unlockFooterDragInteraction();
9937
10202
  }, []);
9938
- const refreshFooterDragVisuals = (0, import_react10.useCallback)((session, activeSlot, clientX, clientY) => {
10203
+ const refreshFooterDragVisuals = (0, import_react11.useCallback)((session, activeSlot, clientX, clientY) => {
9939
10204
  const dragged = session.draggedEl;
9940
10205
  setDraggedItemRect(dragged.getBoundingClientRect());
9941
10206
  if (typeof clientX === "number" && typeof clientY === "number") {
@@ -9960,13 +10225,13 @@ function OhhwellsBridge() {
9960
10225
  const activeIdx = activeSlot ? slots.findIndex((s) => s.insertIndex === activeSlot.insertIndex) : -1;
9961
10226
  setActiveFooterDropIndex(activeIdx >= 0 ? activeIdx : null);
9962
10227
  }, []);
9963
- const refreshFooterDragVisualsRef = (0, import_react10.useRef)(refreshFooterDragVisuals);
10228
+ const refreshFooterDragVisualsRef = (0, import_react11.useRef)(refreshFooterDragVisuals);
9964
10229
  refreshFooterDragVisualsRef.current = refreshFooterDragVisuals;
9965
- const commitFooterDragRef = (0, import_react10.useRef)(() => {
10230
+ const commitFooterDragRef = (0, import_react11.useRef)(() => {
9966
10231
  });
9967
- const beginFooterDragRef = (0, import_react10.useRef)(() => {
10232
+ const beginFooterDragRef = (0, import_react11.useRef)(() => {
9968
10233
  });
9969
- const beginFooterDrag = (0, import_react10.useCallback)(
10234
+ const beginFooterDrag = (0, import_react11.useCallback)(
9970
10235
  (session) => {
9971
10236
  const rect = session.draggedEl.getBoundingClientRect();
9972
10237
  session.lastClientX = session.lastClientX || rect.left + rect.width / 2;
@@ -9986,7 +10251,7 @@ function OhhwellsBridge() {
9986
10251
  [refreshFooterDragVisuals]
9987
10252
  );
9988
10253
  beginFooterDragRef.current = beginFooterDrag;
9989
- const commitFooterDrag = (0, import_react10.useCallback)(
10254
+ const commitFooterDrag = (0, import_react11.useCallback)(
9990
10255
  (clientX, clientY) => {
9991
10256
  const session = footerDragRef.current;
9992
10257
  if (!session) {
@@ -10090,7 +10355,7 @@ function OhhwellsBridge() {
10090
10355
  [clearFooterDragVisuals, resolveHrefKeyElement, resyncSelectedNavigationItem]
10091
10356
  );
10092
10357
  commitFooterDragRef.current = commitFooterDrag;
10093
- const startFooterLinkDrag = (0, import_react10.useCallback)(
10358
+ const startFooterLinkDrag = (0, import_react11.useCallback)(
10094
10359
  (anchor, clientX, clientY, wasSelected) => {
10095
10360
  const hrefKey = anchor.getAttribute("data-ohw-href-key");
10096
10361
  if (!hrefKey || !isFooterHrefKey(hrefKey)) return false;
@@ -10111,7 +10376,7 @@ function OhhwellsBridge() {
10111
10376
  },
10112
10377
  [beginFooterDrag]
10113
10378
  );
10114
- const startFooterColumnDrag = (0, import_react10.useCallback)(
10379
+ const startFooterColumnDrag = (0, import_react11.useCallback)(
10115
10380
  (columnEl, clientX, clientY, wasSelected) => {
10116
10381
  const columns = listFooterColumns();
10117
10382
  const idx = columns.indexOf(columnEl);
@@ -10131,7 +10396,7 @@ function OhhwellsBridge() {
10131
10396
  },
10132
10397
  [beginFooterDrag]
10133
10398
  );
10134
- const handleItemDragStart = (0, import_react10.useCallback)(
10399
+ const handleItemDragStart = (0, import_react11.useCallback)(
10135
10400
  (e) => {
10136
10401
  const selected = selectedElRef.current;
10137
10402
  if (!selected) {
@@ -10151,7 +10416,7 @@ function OhhwellsBridge() {
10151
10416
  },
10152
10417
  [startFooterColumnDrag, startFooterLinkDrag, startNavLinkDrag]
10153
10418
  );
10154
- const handleItemDragEnd = (0, import_react10.useCallback)(
10419
+ const handleItemDragEnd = (0, import_react11.useCallback)(
10155
10420
  (e) => {
10156
10421
  if (footerDragRef.current) {
10157
10422
  const x = e?.clientX;
@@ -10177,7 +10442,7 @@ function OhhwellsBridge() {
10177
10442
  },
10178
10443
  [commitFooterDrag, commitNavDrag, navDragRef]
10179
10444
  );
10180
- const handleItemChromePointerDown = (0, import_react10.useCallback)((e) => {
10445
+ const handleItemChromePointerDown = (0, import_react11.useCallback)((e) => {
10181
10446
  if (e.button !== 0) return;
10182
10447
  const selected = selectedElRef.current;
10183
10448
  if (!selected) return;
@@ -10208,7 +10473,7 @@ function OhhwellsBridge() {
10208
10473
  }
10209
10474
  if (armNavPressFromChrome(selected, e.clientX, e.clientY, e.pointerId)) return;
10210
10475
  }, [armNavPressFromChrome]);
10211
- const handleItemChromeClick = (0, import_react10.useCallback)((clientX, clientY) => {
10476
+ const handleItemChromeClick = (0, import_react11.useCallback)((clientX, clientY) => {
10212
10477
  if (suppressNextClickRef.current || Date.now() < suppressClickUntilRef.current) {
10213
10478
  suppressNextClickRef.current = false;
10214
10479
  return;
@@ -10221,7 +10486,7 @@ function OhhwellsBridge() {
10221
10486
  }, []);
10222
10487
  reselectNavigationItemRef.current = reselectNavigationItem;
10223
10488
  commitNavigationTextEditRef.current = commitNavigationTextEdit;
10224
- const select = (0, import_react10.useCallback)((anchor) => {
10489
+ const select = (0, import_react11.useCallback)((anchor) => {
10225
10490
  if (!isNavigationItem(anchor)) return;
10226
10491
  if (activeElRef.current) deactivate();
10227
10492
  selectedElRef.current = anchor;
@@ -10247,7 +10512,7 @@ function OhhwellsBridge() {
10247
10512
  setToolbarShowEditLink(false);
10248
10513
  setActiveCommands(/* @__PURE__ */ new Set());
10249
10514
  }, [deactivate, markSelected]);
10250
- const selectFrame = (0, import_react10.useCallback)((el) => {
10515
+ const selectFrame = (0, import_react11.useCallback)((el) => {
10251
10516
  if (!isNavigationContainer(el)) return;
10252
10517
  if (activeElRef.current) deactivate();
10253
10518
  const isFooterColumn = !isFooterLinksContainer(el) && (el.hasAttribute("data-ohw-footer-col") || Boolean(el.closest("footer") && isInferredFooterGroup(el)));
@@ -10275,7 +10540,7 @@ function OhhwellsBridge() {
10275
10540
  setToolbarShowEditLink(false);
10276
10541
  setActiveCommands(/* @__PURE__ */ new Set());
10277
10542
  }, [deactivate, markSelected]);
10278
- const activate = (0, import_react10.useCallback)((el, options) => {
10543
+ const activate = (0, import_react11.useCallback)((el, options) => {
10279
10544
  if (activeElRef.current === el) return;
10280
10545
  clearSelectedAttr();
10281
10546
  selectedElRef.current = null;
@@ -10340,7 +10605,7 @@ function OhhwellsBridge() {
10340
10605
  selectRef.current = select;
10341
10606
  selectFrameRef.current = selectFrame;
10342
10607
  deselectRef.current = deselect;
10343
- (0, import_react10.useLayoutEffect)(() => {
10608
+ (0, import_react11.useLayoutEffect)(() => {
10344
10609
  if (!subdomain || isEditMode) {
10345
10610
  setFetchState("done");
10346
10611
  return;
@@ -10411,7 +10676,7 @@ function OhhwellsBridge() {
10411
10676
  cancelled = true;
10412
10677
  };
10413
10678
  }, [subdomain, isEditMode]);
10414
- (0, import_react10.useEffect)(() => {
10679
+ (0, import_react11.useEffect)(() => {
10415
10680
  if (!subdomain || isEditMode) return;
10416
10681
  let debounceTimer = null;
10417
10682
  let observer = null;
@@ -10462,16 +10727,16 @@ function OhhwellsBridge() {
10462
10727
  if (debounceTimer) clearTimeout(debounceTimer);
10463
10728
  };
10464
10729
  }, [subdomain, isEditMode, pathname]);
10465
- (0, import_react10.useLayoutEffect)(() => {
10730
+ (0, import_react11.useLayoutEffect)(() => {
10466
10731
  const el = document.getElementById("ohw-loader");
10467
10732
  if (!el) return;
10468
10733
  const visible = Boolean(subdomain) && fetchState !== "done";
10469
10734
  el.style.display = visible ? "flex" : "none";
10470
10735
  }, [subdomain, fetchState]);
10471
- (0, import_react10.useEffect)(() => {
10736
+ (0, import_react11.useEffect)(() => {
10472
10737
  postToParent2({ type: "ow:navigation", path: pathname });
10473
10738
  }, [pathname, postToParent2]);
10474
- (0, import_react10.useEffect)(() => {
10739
+ (0, import_react11.useEffect)(() => {
10475
10740
  if (!isEditMode) return;
10476
10741
  if (linkPopoverSessionRef.current?.intent === "add-nav") return;
10477
10742
  if (document.querySelector("[data-ohw-section-picker]")) return;
@@ -10479,7 +10744,7 @@ function OhhwellsBridge() {
10479
10744
  deselectRef.current();
10480
10745
  deactivateRef.current();
10481
10746
  }, [pathname, isEditMode]);
10482
- (0, import_react10.useEffect)(() => {
10747
+ (0, import_react11.useEffect)(() => {
10483
10748
  const contentForNav = () => {
10484
10749
  if (isEditMode) return editContentRef.current;
10485
10750
  if (!subdomain) return {};
@@ -10544,7 +10809,7 @@ function OhhwellsBridge() {
10544
10809
  observer?.disconnect();
10545
10810
  };
10546
10811
  }, [isEditMode, pathname, subdomain, fetchState, resyncSelectedNavigationItem]);
10547
- (0, import_react10.useEffect)(() => {
10812
+ (0, import_react11.useEffect)(() => {
10548
10813
  if (!isEditMode) return;
10549
10814
  const measure = () => {
10550
10815
  const h = document.body.scrollHeight;
@@ -10568,7 +10833,7 @@ function OhhwellsBridge() {
10568
10833
  window.removeEventListener("resize", handleResize);
10569
10834
  };
10570
10835
  }, [pathname, isEditMode, postToParent2]);
10571
- (0, import_react10.useEffect)(() => {
10836
+ (0, import_react11.useEffect)(() => {
10572
10837
  if (!subdomainFromQuery || isEditMode) return;
10573
10838
  const handleClick = (e) => {
10574
10839
  const anchor = e.target.closest("a");
@@ -10584,7 +10849,7 @@ function OhhwellsBridge() {
10584
10849
  document.addEventListener("click", handleClick, true);
10585
10850
  return () => document.removeEventListener("click", handleClick, true);
10586
10851
  }, [subdomainFromQuery, isEditMode, router]);
10587
- (0, import_react10.useEffect)(() => {
10852
+ (0, import_react11.useEffect)(() => {
10588
10853
  if (!isEditMode) {
10589
10854
  editStylesRef.current?.base.remove();
10590
10855
  editStylesRef.current?.forceHover.remove();
@@ -10783,7 +11048,7 @@ function OhhwellsBridge() {
10783
11048
  setLinkPopoverRef.current({
10784
11049
  key: editable.dataset.ohwKey ?? "",
10785
11050
  mode: "edit",
10786
- target: getLinkHref2(editable)
11051
+ target: getLinkHref3(editable)
10787
11052
  });
10788
11053
  return;
10789
11054
  }
@@ -11255,6 +11520,13 @@ function OhhwellsBridge() {
11255
11520
  probeNavigationHoverAt(x, y);
11256
11521
  return;
11257
11522
  }
11523
+ const overMoreMenu = document.elementFromPoint(x, y)?.closest?.(
11524
+ '[data-ohw-more-menu], [data-slot="dropdown-menu-content"], [data-slot="dropdown-menu-item"]'
11525
+ );
11526
+ if (overMoreMenu) {
11527
+ dismissImageHover();
11528
+ return;
11529
+ }
11258
11530
  hoveredNavContainerRef.current = null;
11259
11531
  setHoveredNavContainerRect(null);
11260
11532
  if (hoveredItemElRef.current?.hasAttribute("data-ohw-footer-col") || hoveredItemElRef.current?.hasAttribute("data-ohw-footer-column")) {
@@ -11301,7 +11573,7 @@ function OhhwellsBridge() {
11301
11573
  return;
11302
11574
  }
11303
11575
  const topEl = document.elementFromPoint(x2, y2);
11304
- if (topEl?.closest('[data-ohw-toolbar], [data-ohw-edit-chrome], [data-ohw-item-interaction], [data-ohw-drag-handle-container], [data-slot="drag-handle"]')) {
11576
+ if (topEl?.closest('[data-ohw-toolbar], [data-ohw-edit-chrome], [data-ohw-item-interaction], [data-ohw-drag-handle-container], [data-slot="drag-handle"], [data-ohw-more-menu], [data-slot="dropdown-menu-content"], [data-slot="dropdown-menu-item"]')) {
11305
11577
  if (hoveredImageRef.current) {
11306
11578
  hoveredImageRef.current = null;
11307
11579
  resumeAnimTracks();
@@ -11745,6 +12017,7 @@ function OhhwellsBridge() {
11745
12017
  window.addEventListener("message", handleDeactivate);
11746
12018
  const handleUiEscape = (e) => {
11747
12019
  if (e.data?.type !== "ui:escape") return;
12020
+ if (document.querySelector("[data-ohw-more-menu]")) return;
11748
12021
  if (linkPopoverOpenRef.current) {
11749
12022
  setLinkPopoverRef.current(null);
11750
12023
  return;
@@ -11799,6 +12072,7 @@ function OhhwellsBridge() {
11799
12072
  window.addEventListener("message", handleUiEscape);
11800
12073
  const handleKeyDown = (e) => {
11801
12074
  if (e.key === "Escape" && document.querySelector("[data-ohw-section-picker]")) return;
12075
+ if (e.key === "Escape" && document.querySelector("[data-ohw-more-menu]")) return;
11802
12076
  if ((e.ctrlKey || e.metaKey) && e.key.toLowerCase() === "a" && activeElRef.current) {
11803
12077
  e.preventDefault();
11804
12078
  selectAllTextInEditable(activeElRef.current);
@@ -12266,7 +12540,7 @@ function OhhwellsBridge() {
12266
12540
  if (imageShowTimerRef.current) clearTimeout(imageShowTimerRef.current);
12267
12541
  };
12268
12542
  }, [isEditMode, refreshStateRules]);
12269
- (0, import_react10.useEffect)(() => {
12543
+ (0, import_react11.useEffect)(() => {
12270
12544
  if (!isEditMode) return;
12271
12545
  const THRESHOLD = 10;
12272
12546
  const resolveWasSelected = (el) => {
@@ -12420,7 +12694,7 @@ function OhhwellsBridge() {
12420
12694
  unlockFooterDragInteraction();
12421
12695
  };
12422
12696
  }, [isEditMode]);
12423
- (0, import_react10.useEffect)(() => {
12697
+ (0, import_react11.useEffect)(() => {
12424
12698
  const handler = (e) => {
12425
12699
  if (e.data?.type !== "ow:request-schedule-config") return;
12426
12700
  const insertAfterVal = e.data.insertAfter;
@@ -12436,7 +12710,7 @@ function OhhwellsBridge() {
12436
12710
  window.addEventListener("message", handler);
12437
12711
  return () => window.removeEventListener("message", handler);
12438
12712
  }, [processConfigRequest]);
12439
- (0, import_react10.useEffect)(() => {
12713
+ (0, import_react11.useEffect)(() => {
12440
12714
  if (!isEditMode) return;
12441
12715
  document.querySelectorAll("[data-ohw-active-state]").forEach((el) => {
12442
12716
  el.removeAttribute("data-ohw-active-state");
@@ -12471,13 +12745,13 @@ function OhhwellsBridge() {
12471
12745
  clearTimeout(timer);
12472
12746
  };
12473
12747
  }, [pathname, isEditMode, refreshStateRules, postToParent2]);
12474
- (0, import_react10.useEffect)(() => {
12748
+ (0, import_react11.useEffect)(() => {
12475
12749
  scrollToHashSectionWhenReady();
12476
12750
  const onHashChange = () => scrollToHashSectionWhenReady();
12477
12751
  window.addEventListener("hashchange", onHashChange);
12478
12752
  return () => window.removeEventListener("hashchange", onHashChange);
12479
12753
  }, [pathname]);
12480
- const handleCommand = (0, import_react10.useCallback)((cmd) => {
12754
+ const handleCommand = (0, import_react11.useCallback)((cmd) => {
12481
12755
  const el = activeElRef.current;
12482
12756
  const selBefore = window.getSelection();
12483
12757
  let savedOffsets = null;
@@ -12513,7 +12787,7 @@ function OhhwellsBridge() {
12513
12787
  if (el) setToolbarRect(getEditMeasureEl(el).getBoundingClientRect());
12514
12788
  refreshActiveCommandsRef.current();
12515
12789
  }, []);
12516
- const handleStateChange = (0, import_react10.useCallback)((state) => {
12790
+ const handleStateChange = (0, import_react11.useCallback)((state) => {
12517
12791
  if (!activeStateElRef.current) return;
12518
12792
  const el = activeStateElRef.current;
12519
12793
  if (state === "Default") {
@@ -12526,22 +12800,22 @@ function OhhwellsBridge() {
12526
12800
  }
12527
12801
  setToggleState((prev) => prev ? { ...prev, activeState: state } : null);
12528
12802
  }, [deactivate]);
12529
- const closeLinkPopover = (0, import_react10.useCallback)(() => {
12803
+ const closeLinkPopover = (0, import_react11.useCallback)(() => {
12530
12804
  addNavAfterAnchorRef.current = null;
12531
12805
  setLinkPopover(null);
12532
12806
  }, []);
12533
- const openLinkPopoverForActive = (0, import_react10.useCallback)(() => {
12807
+ const openLinkPopoverForActive = (0, import_react11.useCallback)(() => {
12534
12808
  const hrefCtx = getHrefKeyFromElement(activeElRef.current);
12535
12809
  if (!hrefCtx) return;
12536
12810
  bumpLinkPopoverGrace();
12537
12811
  setLinkPopover({
12538
12812
  key: hrefCtx.key,
12539
12813
  mode: "edit",
12540
- target: getLinkHref2(hrefCtx.anchor)
12814
+ target: getLinkHref3(hrefCtx.anchor)
12541
12815
  });
12542
12816
  deactivate();
12543
12817
  }, [deactivate]);
12544
- const openLinkPopoverForSelected = (0, import_react10.useCallback)(() => {
12818
+ const openLinkPopoverForSelected = (0, import_react11.useCallback)(() => {
12545
12819
  const anchor = selectedElRef.current;
12546
12820
  if (!anchor) return;
12547
12821
  const key = anchor.getAttribute("data-ohw-href-key");
@@ -12550,11 +12824,108 @@ function OhhwellsBridge() {
12550
12824
  setLinkPopover({
12551
12825
  key,
12552
12826
  mode: "edit",
12553
- target: getLinkHref2(anchor)
12827
+ target: getLinkHref3(anchor)
12554
12828
  });
12555
12829
  deselect();
12556
12830
  }, [deselect]);
12557
- const handleLinkPopoverSubmit = (0, import_react10.useCallback)(
12831
+ const handleSelectParent = (0, import_react11.useCallback)(() => {
12832
+ const selected = selectedElRef.current;
12833
+ if (!selected) return;
12834
+ if (toolbarVariantRef.current === "select-frame") {
12835
+ deselectRef.current();
12836
+ return;
12837
+ }
12838
+ const parent = getNavigationSelectionParent(selected);
12839
+ if (parent && isNavigationContainer(parent)) {
12840
+ selectFrameRef.current(parent);
12841
+ } else {
12842
+ deselectRef.current();
12843
+ }
12844
+ }, []);
12845
+ const handleDuplicateSelected = (0, import_react11.useCallback)(() => {
12846
+ const selected = selectedElRef.current;
12847
+ if (!selected || !isNavigationItem(selected)) return;
12848
+ const hrefKey = selected.getAttribute("data-ohw-href-key");
12849
+ if (!hrefKey) return;
12850
+ if (isNavbarHrefKey(hrefKey)) {
12851
+ const result = duplicateNavbarItem(selected);
12852
+ if (!result) return;
12853
+ applyLinkByKey(result.hrefKey, result.href);
12854
+ document.querySelectorAll(`[data-ohw-key="${result.labelKey}"]`).forEach((el) => {
12855
+ el.textContent = result.label;
12856
+ });
12857
+ const nodes = [
12858
+ { key: result.hrefKey, text: result.href },
12859
+ { key: result.labelKey, text: result.label }
12860
+ ];
12861
+ for (const child of result.childResults) {
12862
+ applyLinkByKey(child.hrefKey, child.href);
12863
+ document.querySelectorAll(`[data-ohw-key="${child.labelKey}"]`).forEach((el) => {
12864
+ el.textContent = child.label;
12865
+ });
12866
+ nodes.push(
12867
+ { key: child.hrefKey, text: child.href },
12868
+ { key: child.labelKey, text: child.label }
12869
+ );
12870
+ }
12871
+ const maxIndex = Math.max(
12872
+ result.index,
12873
+ ...result.childResults.map((c) => c.index)
12874
+ );
12875
+ const navCount = String(maxIndex + 1);
12876
+ nodes.push(
12877
+ { key: NAV_COUNT_KEY, text: navCount },
12878
+ { key: NAV_ORDER_KEY, text: result.orderJson }
12879
+ );
12880
+ editContentRef.current = {
12881
+ ...editContentRef.current,
12882
+ [result.hrefKey]: result.href,
12883
+ [result.labelKey]: result.label,
12884
+ ...Object.fromEntries(
12885
+ result.childResults.flatMap((c) => [
12886
+ [c.hrefKey, c.href],
12887
+ [c.labelKey, c.label]
12888
+ ])
12889
+ ),
12890
+ [NAV_COUNT_KEY]: navCount,
12891
+ [NAV_ORDER_KEY]: result.orderJson
12892
+ };
12893
+ postToParent2({ type: "ow:change", nodes });
12894
+ enforceLinkHrefs();
12895
+ requestAnimationFrame(() => {
12896
+ selectRef.current(result.anchor);
12897
+ });
12898
+ return;
12899
+ }
12900
+ if (isFooterHrefKey(hrefKey)) {
12901
+ const result = duplicateFooterItem(selected);
12902
+ if (!result) return;
12903
+ applyLinkByKey(result.hrefKey, result.href);
12904
+ document.querySelectorAll(`[data-ohw-key="${result.labelKey}"]`).forEach((el) => {
12905
+ el.textContent = result.label;
12906
+ });
12907
+ const orderJson = JSON.stringify(result.order);
12908
+ editContentRef.current = {
12909
+ ...editContentRef.current,
12910
+ [result.hrefKey]: result.href,
12911
+ [result.labelKey]: result.label,
12912
+ [FOOTER_ORDER_KEY]: orderJson
12913
+ };
12914
+ postToParent2({
12915
+ type: "ow:change",
12916
+ nodes: [
12917
+ { key: result.hrefKey, text: result.href },
12918
+ { key: result.labelKey, text: result.label },
12919
+ { key: FOOTER_ORDER_KEY, text: orderJson }
12920
+ ]
12921
+ });
12922
+ enforceLinkHrefs();
12923
+ requestAnimationFrame(() => {
12924
+ selectRef.current(result.anchor);
12925
+ });
12926
+ }
12927
+ }, [postToParent2]);
12928
+ const handleLinkPopoverSubmit = (0, import_react11.useCallback)(
12558
12929
  (target) => {
12559
12930
  const session = linkPopoverSessionRef.current;
12560
12931
  if (!session) return;
@@ -12613,19 +12984,19 @@ function OhhwellsBridge() {
12613
12984
  const showEditLink = toolbarShowEditLink;
12614
12985
  const currentSections = sectionsByPath[pathname] ?? [];
12615
12986
  linkPopoverOpenRef.current = linkPopover !== null;
12616
- const handleMediaReplace = (0, import_react10.useCallback)(
12987
+ const handleMediaReplace = (0, import_react11.useCallback)(
12617
12988
  (key) => {
12618
12989
  postToParent2({ type: "ow:image-pick", key, elementType: mediaHover?.elementType ?? "image" });
12619
12990
  },
12620
12991
  [postToParent2, mediaHover?.elementType]
12621
12992
  );
12622
- const handleEditCarousel = (0, import_react10.useCallback)(
12993
+ const handleEditCarousel = (0, import_react11.useCallback)(
12623
12994
  (key) => {
12624
12995
  postToParent2({ type: "ow:carousel-open", key, images: readCarouselValue(key) });
12625
12996
  },
12626
12997
  [postToParent2]
12627
12998
  );
12628
- const handleMediaFadeOutComplete = (0, import_react10.useCallback)((key) => {
12999
+ const handleMediaFadeOutComplete = (0, import_react11.useCallback)((key) => {
12629
13000
  setUploadingRects((prev) => {
12630
13001
  if (!(key in prev)) return prev;
12631
13002
  const next = { ...prev };
@@ -12633,7 +13004,7 @@ function OhhwellsBridge() {
12633
13004
  return next;
12634
13005
  });
12635
13006
  }, []);
12636
- const handleVideoSettingsChange = (0, import_react10.useCallback)(
13007
+ const handleVideoSettingsChange = (0, import_react11.useCallback)(
12637
13008
  (key, settings) => {
12638
13009
  document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
12639
13010
  const video = getVideoEl(el);
@@ -12656,9 +13027,9 @@ function OhhwellsBridge() {
12656
13027
  [postToParent2]
12657
13028
  );
12658
13029
  return bridgeRoot ? (0, import_react_dom3.createPortal)(
12659
- /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_jsx_runtime26.Fragment, { children: [
12660
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { ref: attachVisibleViewport, "data-ohw-visible-viewport": "", "aria-hidden": true }),
12661
- Object.entries(uploadingRects).map(([key, { rect, fadingOut }]) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
13030
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(import_jsx_runtime27.Fragment, { children: [
13031
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { ref: attachVisibleViewport, "data-ohw-visible-viewport": "", "aria-hidden": true }),
13032
+ Object.entries(uploadingRects).map(([key, { rect, fadingOut }]) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
12662
13033
  MediaOverlay,
12663
13034
  {
12664
13035
  hover: { key, rect, elementType: "image", isDragOver: false, hasTextOverlap: false },
@@ -12669,7 +13040,7 @@ function OhhwellsBridge() {
12669
13040
  },
12670
13041
  `uploading-${key}`
12671
13042
  )),
12672
- mediaHover && !(mediaHover.key in uploadingRects) && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
13043
+ mediaHover && !(mediaHover.key in uploadingRects) && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
12673
13044
  MediaOverlay,
12674
13045
  {
12675
13046
  hover: mediaHover,
@@ -12678,11 +13049,11 @@ function OhhwellsBridge() {
12678
13049
  onVideoSettingsChange: handleVideoSettingsChange
12679
13050
  }
12680
13051
  ),
12681
- carouselHover && !linkPopover && !isItemDragging && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(CarouselOverlay, { hover: carouselHover, onEdit: handleEditCarousel }),
12682
- siblingHintRect && !linkPopover && !isItemDragging && siblingHintRects.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(ItemInteractionLayer, { rect: siblingHintRect, state: "sibling-hint" }),
12683
- siblingHintRects.length > 0 && !linkPopover && !isItemDragging && siblingHintRects.map((rect, i) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(ItemInteractionLayer, { rect, state: "sibling-hint" }, `sibling-hint-${i}`)),
12684
- isItemDragging && draggedItemRect && selectedElRef.current !== footerDragRef.current?.draggedEl && selectedElRef.current !== navDragRef.current?.draggedEl && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(ItemInteractionLayer, { rect: draggedItemRect, state: "dragging" }),
12685
- isItemDragging && footerDropSlots.map((slot, i) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
13052
+ carouselHover && !linkPopover && !isItemDragging && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(CarouselOverlay, { hover: carouselHover, onEdit: handleEditCarousel }),
13053
+ siblingHintRect && !linkPopover && !isItemDragging && siblingHintRects.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(ItemInteractionLayer, { rect: siblingHintRect, state: "sibling-hint" }),
13054
+ siblingHintRects.length > 0 && !linkPopover && !isItemDragging && siblingHintRects.map((rect, i) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(ItemInteractionLayer, { rect, state: "sibling-hint" }, `sibling-hint-${i}`)),
13055
+ isItemDragging && draggedItemRect && selectedElRef.current !== footerDragRef.current?.draggedEl && selectedElRef.current !== navDragRef.current?.draggedEl && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(ItemInteractionLayer, { rect: draggedItemRect, state: "dragging" }),
13056
+ isItemDragging && footerDropSlots.map((slot, i) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
12686
13057
  "div",
12687
13058
  {
12688
13059
  className: "pointer-events-none fixed z-2147483646",
@@ -12692,7 +13063,7 @@ function OhhwellsBridge() {
12692
13063
  width: slot.width,
12693
13064
  height: slot.height
12694
13065
  },
12695
- children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
13066
+ children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
12696
13067
  DropIndicator,
12697
13068
  {
12698
13069
  direction: slot.direction,
@@ -12703,7 +13074,7 @@ function OhhwellsBridge() {
12703
13074
  },
12704
13075
  `footer-drop-${slot.direction}-${slot.columnIndex}-${slot.insertIndex}-${i}`
12705
13076
  )),
12706
- isItemDragging && navDropSlots.map((slot, i) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
13077
+ isItemDragging && navDropSlots.map((slot, i) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
12707
13078
  "div",
12708
13079
  {
12709
13080
  className: "pointer-events-none fixed z-2147483646",
@@ -12713,7 +13084,7 @@ function OhhwellsBridge() {
12713
13084
  width: slot.width,
12714
13085
  height: slot.height
12715
13086
  },
12716
- children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
13087
+ children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
12717
13088
  DropIndicator,
12718
13089
  {
12719
13090
  direction: slot.direction,
@@ -12724,11 +13095,11 @@ function OhhwellsBridge() {
12724
13095
  },
12725
13096
  `nav-drop-${slot.direction}-${slot.parentId ?? "root"}-${slot.insertIndex}-${i}`
12726
13097
  )),
12727
- hoveredNavContainerRect && (toolbarVariant !== "select-frame" || isFooterFrameSelection) && !linkPopover && !isItemDragging && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(ItemInteractionLayer, { rect: hoveredNavContainerRect, state: "hover" }),
12728
- hoveredItemRect && !linkPopover && !hoveredNavContainerRect && !isItemDragging && hoveredItemElRef.current !== selectedElRef.current && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(ItemInteractionLayer, { rect: hoveredItemRect, state: "hover" }),
12729
- toolbarVariant === "select-frame" && toolbarRect && !linkPopover && !isItemDragging && !isFooterFrameSelection && selectedElRef.current && isNavbarLinksContainer(selectedElRef.current) && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(NavbarContainerChrome, { rect: toolbarRect, onAdd: handleAddTopLevelNavItem }),
12730
- toolbarVariant === "select-frame" && toolbarRect && !linkPopover && !isItemDragging && !isFooterFrameSelection && selectedElRef.current && isFooterLinksContainer(selectedElRef.current) && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(FooterContainerChrome, { rect: toolbarRect, onAdd: handleAddFooterColumn }),
12731
- toolbarRect && !linkPopover && (toolbarVariant === "link-action" || toolbarVariant === "select-frame") && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
13098
+ hoveredNavContainerRect && (toolbarVariant !== "select-frame" || isFooterFrameSelection) && !linkPopover && !isItemDragging && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(ItemInteractionLayer, { rect: hoveredNavContainerRect, state: "hover" }),
13099
+ hoveredItemRect && !linkPopover && !hoveredNavContainerRect && !isItemDragging && hoveredItemElRef.current !== selectedElRef.current && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(ItemInteractionLayer, { rect: hoveredItemRect, state: "hover" }),
13100
+ toolbarVariant === "select-frame" && toolbarRect && !linkPopover && !isItemDragging && !isFooterFrameSelection && selectedElRef.current && isNavbarLinksContainer(selectedElRef.current) && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(NavbarContainerChrome, { rect: toolbarRect, onAdd: handleAddTopLevelNavItem }),
13101
+ toolbarVariant === "select-frame" && toolbarRect && !linkPopover && !isItemDragging && !isFooterFrameSelection && selectedElRef.current && isFooterLinksContainer(selectedElRef.current) && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(FooterContainerChrome, { rect: toolbarRect, onAdd: handleAddFooterColumn }),
13102
+ toolbarRect && !linkPopover && (toolbarVariant === "link-action" || toolbarVariant === "select-frame") && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
12732
13103
  ItemInteractionLayer,
12733
13104
  {
12734
13105
  rect: isItemDragging && draggedItemRect && (footerDragRef.current?.wasSelected || navDragRef.current?.wasSelected) ? draggedItemRect : toolbarRect,
@@ -12742,21 +13113,23 @@ function OhhwellsBridge() {
12742
13113
  onItemPointerDown: handleItemChromePointerDown,
12743
13114
  onItemClick: handleItemChromeClick,
12744
13115
  itemDragSurface: !isFooterFrameSelection,
12745
- toolbar: toolbarVariant === "link-action" && !isItemDragging ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
13116
+ toolbar: toolbarVariant === "link-action" && !isItemDragging ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
12746
13117
  ItemActionToolbar,
12747
13118
  {
12748
13119
  onEditLink: openLinkPopoverForSelected,
13120
+ onSelectParent: handleSelectParent,
13121
+ onDuplicate: handleDuplicateSelected,
12749
13122
  addItemDisabled: true,
12750
13123
  editLinkDisabled: false,
12751
- moreDisabled: true,
13124
+ moreDisabled: false,
12752
13125
  showAddItem: !selectedIsCta,
12753
13126
  showMore: !selectedIsCta
12754
13127
  }
12755
13128
  ) : void 0
12756
13129
  }
12757
13130
  ),
12758
- toolbarRect && toolbarVariant === "rich-text" && !linkPopover && /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_jsx_runtime26.Fragment, { children: [
12759
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
13131
+ toolbarRect && toolbarVariant === "rich-text" && !linkPopover && /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(import_jsx_runtime27.Fragment, { children: [
13132
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
12760
13133
  EditGlowChrome,
12761
13134
  {
12762
13135
  rect: toolbarRect,
@@ -12766,7 +13139,7 @@ function OhhwellsBridge() {
12766
13139
  hideHandle: isItemDragging
12767
13140
  }
12768
13141
  ),
12769
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
13142
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
12770
13143
  FloatingToolbar,
12771
13144
  {
12772
13145
  rect: toolbarRect,
@@ -12779,7 +13152,7 @@ function OhhwellsBridge() {
12779
13152
  }
12780
13153
  )
12781
13154
  ] }),
12782
- maxBadge && /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
13155
+ maxBadge && /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
12783
13156
  "div",
12784
13157
  {
12785
13158
  "data-ohw-max-badge": "",
@@ -12805,7 +13178,7 @@ function OhhwellsBridge() {
12805
13178
  ]
12806
13179
  }
12807
13180
  ),
12808
- toggleState && !linkPopover && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
13181
+ toggleState && !linkPopover && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
12809
13182
  StateToggle,
12810
13183
  {
12811
13184
  rect: toggleState.rect,
@@ -12814,15 +13187,15 @@ function OhhwellsBridge() {
12814
13187
  onStateChange: handleStateChange
12815
13188
  }
12816
13189
  ),
12817
- sectionGap && !linkPopover && /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
13190
+ sectionGap && !linkPopover && /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
12818
13191
  "div",
12819
13192
  {
12820
13193
  "data-ohw-section-insert-line": "",
12821
13194
  className: "fixed left-0 w-full z-2147483646 flex items-center pointer-events-none",
12822
13195
  style: { top: sectionGap.y, transform: "translateY(-50%)" },
12823
13196
  children: [
12824
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } }),
12825
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
13197
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } }),
13198
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
12826
13199
  Badge,
12827
13200
  {
12828
13201
  className: "px-8 py-1 bg-primary hover:bg-primary text-primary-foreground text-xs font-medium shrink-0 rounded-full cursor-pointer pointer-events-auto",
@@ -12839,11 +13212,11 @@ function OhhwellsBridge() {
12839
13212
  children: "Add Section"
12840
13213
  }
12841
13214
  ),
12842
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } })
13215
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } })
12843
13216
  ]
12844
13217
  }
12845
13218
  ),
12846
- linkPopover && dialogPortalContainer ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
13219
+ linkPopover && dialogPortalContainer ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
12847
13220
  LinkPopover,
12848
13221
  {
12849
13222
  panelRef: linkPopoverPanelRef,
@@ -12871,6 +13244,12 @@ function OhhwellsBridge() {
12871
13244
  CustomToolbarDivider,
12872
13245
  DragHandle,
12873
13246
  DropIndicator,
13247
+ DropdownMenu,
13248
+ DropdownMenuContent,
13249
+ DropdownMenuGroup,
13250
+ DropdownMenuItem,
13251
+ DropdownMenuSeparator,
13252
+ DropdownMenuTrigger,
12874
13253
  ItemActionToolbar,
12875
13254
  ItemInteractionLayer,
12876
13255
  LinkEditorPanel,