@ohhwells/bridge 0.1.51-next.121 → 0.1.51-next.123

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
@@ -69,7 +69,7 @@ __export(index_exports, {
69
69
  module.exports = __toCommonJS(index_exports);
70
70
 
71
71
  // src/OhhwellsBridge.tsx
72
- var import_react11 = __toESM(require("react"), 1);
72
+ var import_react12 = __toESM(require("react"), 1);
73
73
  var import_client = require("react-dom/client");
74
74
  var import_react_dom2 = require("react-dom");
75
75
 
@@ -4587,10 +4587,57 @@ function ItemActionToolbar({
4587
4587
  showEditLink = true,
4588
4588
  showAddItem = true,
4589
4589
  showMore = true,
4590
- tooltipSide = "bottom"
4590
+ tooltipSide = "bottom",
4591
+ dropdownOpen = null,
4592
+ onDropdownOpenChange,
4593
+ headingVisible = null,
4594
+ onHeadingVisibleChange
4591
4595
  }) {
4592
4596
  const [moreOpen, setMoreOpen] = (0, import_react4.useState)(false);
4597
+ const showDropdownToggle = dropdownOpen !== null && dropdownOpen !== void 0;
4598
+ const showHeadingToggle = headingVisible !== null && headingVisible !== void 0;
4599
+ const headingTooltip = headingVisible ? "Hide heading" : "Show heading";
4593
4600
  return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(TooltipProvider, { delayDuration: 0, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(CustomToolbar, { children: [
4601
+ showDropdownToggle ? /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
4602
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
4603
+ ToggleGroup,
4604
+ {
4605
+ value: dropdownOpen ? "open" : "closed",
4606
+ onValueChange: (value) => {
4607
+ if (value !== "open" && value !== "closed") return;
4608
+ onDropdownOpenChange?.(value === "open");
4609
+ },
4610
+ className: "h-7 gap-0.5 rounded-[calc(var(--radius,0.5rem)-2px)] bg-muted p-0.5",
4611
+ onMouseDown: (e) => {
4612
+ e.preventDefault();
4613
+ e.stopPropagation();
4614
+ },
4615
+ children: [
4616
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
4617
+ ToggleGroupItem,
4618
+ {
4619
+ value: "closed",
4620
+ size: "sm",
4621
+ "aria-label": "Closed",
4622
+ className: "h-6 min-w-0 px-2 text-xs font-medium",
4623
+ children: "Closed"
4624
+ }
4625
+ ),
4626
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
4627
+ ToggleGroupItem,
4628
+ {
4629
+ value: "open",
4630
+ size: "sm",
4631
+ "aria-label": "Open",
4632
+ className: "h-6 min-w-0 px-2 text-xs font-medium",
4633
+ children: "Open"
4634
+ }
4635
+ )
4636
+ ]
4637
+ }
4638
+ ),
4639
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(CustomToolbarDivider, {})
4640
+ ] }) : null,
4594
4641
  showEditLink ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
4595
4642
  ToolbarActionTooltip,
4596
4643
  {
@@ -4629,6 +4676,26 @@ function ItemActionToolbar({
4629
4676
  children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react2.Plus, { className: "size-4 shrink-0", "aria-hidden": true })
4630
4677
  }
4631
4678
  ) : null,
4679
+ showHeadingToggle ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
4680
+ ToolbarActionTooltip,
4681
+ {
4682
+ label: headingTooltip,
4683
+ side: tooltipSide,
4684
+ buttonProps: {
4685
+ active: Boolean(headingVisible),
4686
+ style: headingVisible ? {
4687
+ backgroundColor: "var(--ohw-primary, #0885FE)",
4688
+ color: "var(--ohw-primary-foreground, #FAFAF9)"
4689
+ } : void 0,
4690
+ onMouseDown: (e) => {
4691
+ e.preventDefault();
4692
+ e.stopPropagation();
4693
+ onHeadingVisibleChange?.(!headingVisible);
4694
+ }
4695
+ },
4696
+ children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react2.Heading, { className: "size-4 shrink-0", "aria-hidden": true })
4697
+ }
4698
+ ) : null,
4632
4699
  showMore ? /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(DropdownMenu, { open: moreOpen, onOpenChange: setMoreOpen, children: [
4633
4700
  /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Tooltip, { open: moreOpen ? false : void 0, children: [
4634
4701
  /* @__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)(
@@ -4702,7 +4769,7 @@ function ItemActionToolbar({
4702
4769
  }
4703
4770
 
4704
4771
  // src/ui/item-interaction-layer.tsx
4705
- var React5 = __toESM(require("react"), 1);
4772
+ var import_react5 = require("react");
4706
4773
  var import_jsx_runtime10 = require("react/jsx-runtime");
4707
4774
  var PRIMARY = "var(--ohw-primary, #0885FE)";
4708
4775
  var FOCUS_RING = `0 0 0 4px color-mix(in srgb, ${PRIMARY} 12%, transparent)`;
@@ -4754,8 +4821,8 @@ function ClampedToolbarSlot({
4754
4821
  placement,
4755
4822
  children
4756
4823
  }) {
4757
- const slotRef = React5.useRef(null);
4758
- React5.useLayoutEffect(() => {
4824
+ const slotRef = (0, import_react5.useRef)(null);
4825
+ (0, import_react5.useLayoutEffect)(() => {
4759
4826
  const slot = slotRef.current;
4760
4827
  if (!slot) return;
4761
4828
  const clamp = () => {
@@ -4803,11 +4870,59 @@ function ClampedToolbarSlot({
4803
4870
  }
4804
4871
  );
4805
4872
  }
4873
+ function DetachedBelowToolbarSlot({
4874
+ centerX,
4875
+ belowRect,
4876
+ children
4877
+ }) {
4878
+ const slotRef = (0, import_react5.useRef)(null);
4879
+ (0, import_react5.useLayoutEffect)(() => {
4880
+ const slot = slotRef.current;
4881
+ if (!slot) return;
4882
+ const clamp = () => {
4883
+ const toolbar = slot.firstElementChild;
4884
+ if (!toolbar) return;
4885
+ const w = toolbar.offsetWidth;
4886
+ if (w <= 0) return;
4887
+ const half = w / 2;
4888
+ const clampedCenter = Math.max(
4889
+ TOOLBAR_EDGE_MARGIN + half,
4890
+ Math.min(centerX, window.innerWidth - TOOLBAR_EDGE_MARGIN - half)
4891
+ );
4892
+ slot.style.left = `${clampedCenter}px`;
4893
+ };
4894
+ clamp();
4895
+ const ro = new ResizeObserver(clamp);
4896
+ ro.observe(slot);
4897
+ if (slot.firstElementChild) ro.observe(slot.firstElementChild);
4898
+ window.addEventListener("resize", clamp);
4899
+ return () => {
4900
+ ro.disconnect();
4901
+ window.removeEventListener("resize", clamp);
4902
+ };
4903
+ }, [centerX, belowRect, children]);
4904
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
4905
+ "div",
4906
+ {
4907
+ ref: slotRef,
4908
+ className: "pointer-events-auto fixed",
4909
+ style: {
4910
+ top: belowRect.bottom + TOOLBAR_STROKE_GAP,
4911
+ left: centerX,
4912
+ transform: "translateX(-50%)",
4913
+ zIndex: getChromeZIndex("active-bottom")
4914
+ },
4915
+ "data-ohw-item-toolbar-anchor": "below-external",
4916
+ children
4917
+ }
4918
+ );
4919
+ }
4806
4920
  function ItemInteractionLayer({
4807
4921
  rect,
4808
4922
  state,
4809
4923
  elRef,
4810
4924
  toolbar,
4925
+ toolbarBelowRect = null,
4811
4926
  showHandle = false,
4812
4927
  dragDisabled = false,
4813
4928
  dragHandleLabel = "Reorder item",
@@ -4825,6 +4940,7 @@ function ItemInteractionLayer({
4825
4940
  const showToolbar = isActive && toolbar;
4826
4941
  const showDragHandle = (isActive || isDragging) && showHandle;
4827
4942
  const itemDragEnabled = itemDragSurface && isActive && showHandle && !isDragging && !dragDisabled;
4943
+ const useDetachedBelowToolbar = Boolean(showToolbar && state === "active-bottom" && toolbarBelowRect);
4828
4944
  return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
4829
4945
  "div",
4830
4946
  {
@@ -4903,18 +5019,26 @@ function ItemInteractionLayer({
4903
5019
  }
4904
5020
  ),
4905
5021
  showToolbar && state === "active-top" && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ClampedToolbarSlot, { placement: "top", children: toolbar }),
4906
- showToolbar && state === "active-bottom" && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ClampedToolbarSlot, { placement: "bottom", children: toolbar })
5022
+ showToolbar && state === "active-bottom" && !useDetachedBelowToolbar && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(ClampedToolbarSlot, { placement: "bottom", children: toolbar }),
5023
+ useDetachedBelowToolbar && toolbarBelowRect ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
5024
+ DetachedBelowToolbarSlot,
5025
+ {
5026
+ centerX: rect.left + rect.width / 2,
5027
+ belowRect: toolbarBelowRect,
5028
+ children: toolbar
5029
+ }
5030
+ ) : null
4907
5031
  ]
4908
5032
  }
4909
5033
  );
4910
5034
  }
4911
5035
 
4912
5036
  // src/ui/MediaOverlay.tsx
4913
- var React7 = __toESM(require("react"), 1);
5037
+ var React6 = __toESM(require("react"), 1);
4914
5038
  var import_lucide_react3 = require("lucide-react");
4915
5039
 
4916
5040
  // src/ui/button.tsx
4917
- var React6 = __toESM(require("react"), 1);
5041
+ var React5 = __toESM(require("react"), 1);
4918
5042
  var import_radix_ui5 = require("radix-ui");
4919
5043
  var import_jsx_runtime11 = require("react/jsx-runtime");
4920
5044
  var buttonVariants = cva(
@@ -4937,7 +5061,7 @@ var buttonVariants = cva(
4937
5061
  }
4938
5062
  }
4939
5063
  );
4940
- var Button = React6.forwardRef(
5064
+ var Button = React5.forwardRef(
4941
5065
  ({ className, variant, size, asChild = false, ...props }, ref) => {
4942
5066
  const Comp = asChild ? import_radix_ui5.Slot.Root : "button";
4943
5067
  return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
@@ -4989,7 +5113,7 @@ function MediaOverlay({
4989
5113
  onVideoSettingsChange
4990
5114
  }) {
4991
5115
  const { rect } = hover;
4992
- const skeletonRef = React7.useRef(null);
5116
+ const skeletonRef = React6.useRef(null);
4993
5117
  const isVideo = hover.elementType === "video";
4994
5118
  const autoplay = hover.videoAutoplay ?? true;
4995
5119
  const muted = hover.videoMuted ?? true;
@@ -5001,7 +5125,7 @@ function MediaOverlay({
5001
5125
  height: rect.height,
5002
5126
  zIndex: 2147483646
5003
5127
  };
5004
- React7.useEffect(() => {
5128
+ React6.useEffect(() => {
5005
5129
  if (!isUploading || !fadingOut || !skeletonRef.current) return;
5006
5130
  const anim = skeletonRef.current.animate([{ opacity: 1 }, { opacity: 0 }], {
5007
5131
  duration: MEDIA_UPLOAD_FADE_MS,
@@ -5462,10 +5586,10 @@ function scrollToHashSectionWhenReady(behavior = "smooth") {
5462
5586
  }
5463
5587
 
5464
5588
  // src/ui/link-modal/LinkPopover.tsx
5465
- var import_react8 = require("react");
5589
+ var import_react9 = require("react");
5466
5590
 
5467
5591
  // src/ui/dialog.tsx
5468
- var React8 = __toESM(require("react"), 1);
5592
+ var React7 = __toESM(require("react"), 1);
5469
5593
  var import_radix_ui6 = require("radix-ui");
5470
5594
  var import_lucide_react5 = require("lucide-react");
5471
5595
  var import_jsx_runtime14 = require("react/jsx-runtime");
@@ -5493,7 +5617,7 @@ function DialogOverlay({
5493
5617
  }
5494
5618
  );
5495
5619
  }
5496
- var DialogContent = React8.forwardRef(
5620
+ var DialogContent = React7.forwardRef(
5497
5621
  ({ className, children, showCloseButton = true, container, ...props }, ref) => {
5498
5622
  const positionMode = container ? "absolute" : "fixed";
5499
5623
  return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(DialogPortal, { container: container ?? void 0, children: [
@@ -5548,7 +5672,7 @@ function DialogFooter({
5548
5672
  }
5549
5673
  );
5550
5674
  }
5551
- var DialogTitle = React8.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
5675
+ var DialogTitle = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
5552
5676
  import_radix_ui6.Dialog.Title,
5553
5677
  {
5554
5678
  ref,
@@ -5560,7 +5684,7 @@ var DialogTitle = React8.forwardRef(({ className, ...props }, ref) => /* @__PURE
5560
5684
  }
5561
5685
  ));
5562
5686
  DialogTitle.displayName = import_radix_ui6.Dialog.Title.displayName;
5563
- var DialogDescription = React8.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
5687
+ var DialogDescription = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
5564
5688
  import_radix_ui6.Dialog.Description,
5565
5689
  {
5566
5690
  ref,
@@ -5662,12 +5786,12 @@ function SectionTreeItem({
5662
5786
  }
5663
5787
 
5664
5788
  // src/ui/link-modal/UrlOrPageInput.tsx
5665
- var import_react5 = require("react");
5789
+ var import_react6 = require("react");
5666
5790
 
5667
5791
  // src/ui/input.tsx
5668
- var React9 = __toESM(require("react"), 1);
5792
+ var React8 = __toESM(require("react"), 1);
5669
5793
  var import_jsx_runtime17 = require("react/jsx-runtime");
5670
- var Input = React9.forwardRef(
5794
+ var Input = React8.forwardRef(
5671
5795
  ({ className, type, ...props }, ref) => {
5672
5796
  return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
5673
5797
  "input",
@@ -5730,11 +5854,11 @@ function UrlOrPageInput({
5730
5854
  readOnly = false,
5731
5855
  urlError
5732
5856
  }) {
5733
- const inputId = (0, import_react5.useId)();
5734
- const inputRef = (0, import_react5.useRef)(null);
5735
- const rootRef = (0, import_react5.useRef)(null);
5736
- const [isFocused, setIsFocused] = (0, import_react5.useState)(false);
5737
- (0, import_react5.useEffect)(() => {
5857
+ const inputId = (0, import_react6.useId)();
5858
+ const inputRef = (0, import_react6.useRef)(null);
5859
+ const rootRef = (0, import_react6.useRef)(null);
5860
+ const [isFocused, setIsFocused] = (0, import_react6.useState)(false);
5861
+ (0, import_react6.useEffect)(() => {
5738
5862
  if (!dropdownOpen) return;
5739
5863
  const isOutside = (e) => {
5740
5864
  const root = rootRef.current;
@@ -5942,7 +6066,7 @@ function LinkEditorPanel({ state, onClose }) {
5942
6066
  }
5943
6067
 
5944
6068
  // src/ui/link-modal/SectionPickerOverlay.tsx
5945
- var import_react6 = require("react");
6069
+ var import_react7 = require("react");
5946
6070
  var import_react_dom = require("react-dom");
5947
6071
  var import_lucide_react10 = require("lucide-react");
5948
6072
  var import_navigation = require("next/navigation");
@@ -5979,12 +6103,12 @@ function hitTestSectionId(x, y, sectionIds, rects) {
5979
6103
  return null;
5980
6104
  }
5981
6105
  function useSectionRects(sectionIdsKey, enabled) {
5982
- const [rects, setRects] = (0, import_react6.useState)(/* @__PURE__ */ new Map());
5983
- const sectionIds = (0, import_react6.useMemo)(
6106
+ const [rects, setRects] = (0, import_react7.useState)(/* @__PURE__ */ new Map());
6107
+ const sectionIds = (0, import_react7.useMemo)(
5984
6108
  () => sectionIdsKey ? sectionIdsKey.split("\0") : [],
5985
6109
  [sectionIdsKey]
5986
6110
  );
5987
- (0, import_react6.useEffect)(() => {
6111
+ (0, import_react7.useEffect)(() => {
5988
6112
  if (!enabled || sectionIds.length === 0) {
5989
6113
  setRects((prev) => prev.size === 0 ? prev : /* @__PURE__ */ new Map());
5990
6114
  return;
@@ -6025,13 +6149,13 @@ function SectionPickerOverlay({
6025
6149
  }) {
6026
6150
  const router = (0, import_navigation.useRouter)();
6027
6151
  const pathname = (0, import_navigation.usePathname)();
6028
- const [selectedId, setSelectedId] = (0, import_react6.useState)(null);
6029
- const [hoveredId, setHoveredId] = (0, import_react6.useState)(null);
6030
- const pointerRef = (0, import_react6.useRef)(null);
6031
- const pointerScreenRef = (0, import_react6.useRef)(null);
6032
- const iframeOffsetTopRef = (0, import_react6.useRef)(null);
6033
- const sectionIdsRef = (0, import_react6.useRef)([]);
6034
- const [chromeClip, setChromeClip] = (0, import_react6.useState)(
6152
+ const [selectedId, setSelectedId] = (0, import_react7.useState)(null);
6153
+ const [hoveredId, setHoveredId] = (0, import_react7.useState)(null);
6154
+ const pointerRef = (0, import_react7.useRef)(null);
6155
+ const pointerScreenRef = (0, import_react7.useRef)(null);
6156
+ const iframeOffsetTopRef = (0, import_react7.useRef)(null);
6157
+ const sectionIdsRef = (0, import_react7.useRef)([]);
6158
+ const [chromeClip, setChromeClip] = (0, import_react7.useState)(
6035
6159
  () => ({
6036
6160
  top: 0,
6037
6161
  bottom: typeof window !== "undefined" ? window.innerHeight : 0
@@ -6039,12 +6163,12 @@ function SectionPickerOverlay({
6039
6163
  );
6040
6164
  const normalizedTarget = normalizePath(pagePath);
6041
6165
  const isOnTargetPage = normalizePath(pathname) === normalizedTarget;
6042
- (0, import_react6.useEffect)(() => {
6166
+ (0, import_react7.useEffect)(() => {
6043
6167
  if (isOnTargetPage) return;
6044
6168
  const search = readPreservedSearch();
6045
6169
  router.push(`${normalizedTarget}${search}`);
6046
6170
  }, [isOnTargetPage, normalizedTarget, router]);
6047
- (0, import_react6.useEffect)(() => {
6171
+ (0, import_react7.useEffect)(() => {
6048
6172
  document.documentElement.setAttribute("data-ohw-section-picking", "");
6049
6173
  document.querySelectorAll("[data-ohw-hovered]").forEach((el) => {
6050
6174
  el.removeAttribute("data-ohw-hovered");
@@ -6056,24 +6180,24 @@ function SectionPickerOverlay({
6056
6180
  document.documentElement.removeAttribute("data-ohw-section-picking");
6057
6181
  };
6058
6182
  }, []);
6059
- const liveSections = (0, import_react6.useMemo)(() => {
6183
+ const liveSections = (0, import_react7.useMemo)(() => {
6060
6184
  if (!isOnTargetPage) return sections;
6061
6185
  const live = collectSectionsFromDom();
6062
6186
  if (live.length === 0) return sections;
6063
6187
  const labels = new Map(sections.map((s) => [s.id, s.label]));
6064
6188
  return live.map((s) => ({ id: s.id, label: labels.get(s.id) ?? s.label }));
6065
6189
  }, [isOnTargetPage, sections, pathname]);
6066
- const sectionIdsKey = (0, import_react6.useMemo)(
6190
+ const sectionIdsKey = (0, import_react7.useMemo)(
6067
6191
  () => liveSections.map((s) => s.id).join("\0"),
6068
6192
  [liveSections]
6069
6193
  );
6070
- const sectionIds = (0, import_react6.useMemo)(
6194
+ const sectionIds = (0, import_react7.useMemo)(
6071
6195
  () => liveSections.map((s) => s.id),
6072
6196
  [liveSections]
6073
6197
  );
6074
6198
  sectionIdsRef.current = sectionIds;
6075
6199
  const rects = useSectionRects(sectionIdsKey, isOnTargetPage);
6076
- const applyHoverAt = (0, import_react6.useCallback)(
6200
+ const applyHoverAt = (0, import_react7.useCallback)(
6077
6201
  (x, y, liveRects) => {
6078
6202
  const ids = sectionIdsRef.current;
6079
6203
  const map = liveRects ?? readSectionRects(ids);
@@ -6082,7 +6206,7 @@ function SectionPickerOverlay({
6082
6206
  },
6083
6207
  []
6084
6208
  );
6085
- (0, import_react6.useEffect)(() => {
6209
+ (0, import_react7.useEffect)(() => {
6086
6210
  const applyClip = (iframeOffsetTop, visibleCanvasTop, canvasH) => {
6087
6211
  const top = Math.max(0, visibleCanvasTop - iframeOffsetTop);
6088
6212
  const bottom = Math.min(
@@ -6124,12 +6248,12 @@ function SectionPickerOverlay({
6124
6248
  window.removeEventListener("resize", onResize);
6125
6249
  };
6126
6250
  }, [applyHoverAt]);
6127
- (0, import_react6.useEffect)(() => {
6251
+ (0, import_react7.useEffect)(() => {
6128
6252
  const ptr = pointerRef.current;
6129
6253
  if (!ptr) return;
6130
6254
  applyHoverAt(ptr.x, ptr.y, rects);
6131
6255
  }, [rects, applyHoverAt]);
6132
- (0, import_react6.useEffect)(() => {
6256
+ (0, import_react7.useEffect)(() => {
6133
6257
  const rememberPointer = (clientX, clientY) => {
6134
6258
  pointerRef.current = { x: clientX, y: clientY };
6135
6259
  const top = iframeOffsetTopRef.current;
@@ -6153,7 +6277,7 @@ function SectionPickerOverlay({
6153
6277
  window.removeEventListener("message", onPointerSync);
6154
6278
  };
6155
6279
  }, [rects, applyHoverAt]);
6156
- const handleSelect = (0, import_react6.useCallback)(
6280
+ const handleSelect = (0, import_react7.useCallback)(
6157
6281
  (section) => {
6158
6282
  if (selectedId) return;
6159
6283
  setSelectedId(section.id);
@@ -6161,7 +6285,7 @@ function SectionPickerOverlay({
6161
6285
  },
6162
6286
  [selectedId, onSelect]
6163
6287
  );
6164
- (0, import_react6.useEffect)(() => {
6288
+ (0, import_react7.useEffect)(() => {
6165
6289
  const onKeyDown = (e) => {
6166
6290
  if (e.key === "Escape") {
6167
6291
  e.preventDefault();
@@ -6284,7 +6408,7 @@ function SectionPickerOverlay({
6284
6408
  }
6285
6409
 
6286
6410
  // src/ui/link-modal/useLinkModalState.ts
6287
- var import_react7 = require("react");
6411
+ var import_react8 = require("react");
6288
6412
  function useLinkModalState({
6289
6413
  open,
6290
6414
  mode,
@@ -6296,14 +6420,14 @@ function useLinkModalState({
6296
6420
  onClose,
6297
6421
  onSubmit
6298
6422
  }) {
6299
- const availablePages = (0, import_react7.useMemo)(() => pages, [pages]);
6300
- const [searchValue, setSearchValue] = (0, import_react7.useState)("");
6301
- const [selectedPage, setSelectedPage] = (0, import_react7.useState)(null);
6302
- const [selectedSection, setSelectedSection] = (0, import_react7.useState)(null);
6303
- const [step, setStep] = (0, import_react7.useState)("input");
6304
- const [dropdownOpen, setDropdownOpen] = (0, import_react7.useState)(false);
6305
- const [urlError, setUrlError] = (0, import_react7.useState)("");
6306
- const reset = (0, import_react7.useCallback)(() => {
6423
+ const availablePages = (0, import_react8.useMemo)(() => pages, [pages]);
6424
+ const [searchValue, setSearchValue] = (0, import_react8.useState)("");
6425
+ const [selectedPage, setSelectedPage] = (0, import_react8.useState)(null);
6426
+ const [selectedSection, setSelectedSection] = (0, import_react8.useState)(null);
6427
+ const [step, setStep] = (0, import_react8.useState)("input");
6428
+ const [dropdownOpen, setDropdownOpen] = (0, import_react8.useState)(false);
6429
+ const [urlError, setUrlError] = (0, import_react8.useState)("");
6430
+ const reset = (0, import_react8.useCallback)(() => {
6307
6431
  setSearchValue("");
6308
6432
  setSelectedPage(null);
6309
6433
  setSelectedSection(null);
@@ -6311,7 +6435,7 @@ function useLinkModalState({
6311
6435
  setDropdownOpen(false);
6312
6436
  setUrlError("");
6313
6437
  }, []);
6314
- (0, import_react7.useEffect)(() => {
6438
+ (0, import_react8.useEffect)(() => {
6315
6439
  if (!open) return;
6316
6440
  if (mode === "edit" && initialTarget) {
6317
6441
  const { pageRoute } = parseTarget(initialTarget);
@@ -6327,11 +6451,11 @@ function useLinkModalState({
6327
6451
  setDropdownOpen(false);
6328
6452
  setUrlError("");
6329
6453
  }, [open, mode, initialTarget, reset]);
6330
- const filteredPages = (0, import_react7.useMemo)(() => {
6454
+ const filteredPages = (0, import_react8.useMemo)(() => {
6331
6455
  if (!searchValue.trim()) return availablePages;
6332
6456
  return availablePages.filter((p) => p.title.toLowerCase().startsWith(searchValue.toLowerCase()));
6333
6457
  }, [availablePages, searchValue]);
6334
- const activeSections = (0, import_react7.useMemo)(() => {
6458
+ const activeSections = (0, import_react8.useMemo)(() => {
6335
6459
  if (!selectedPage) return [];
6336
6460
  return getSectionsForPath(sectionsByPath, selectedPage.path);
6337
6461
  }, [selectedPage, sectionsByPath]);
@@ -6380,7 +6504,7 @@ function useLinkModalState({
6380
6504
  reset();
6381
6505
  onClose();
6382
6506
  };
6383
- const isValid = (0, import_react7.useMemo)(() => {
6507
+ const isValid = (0, import_react8.useMemo)(() => {
6384
6508
  if (urlError) return false;
6385
6509
  if (showBreadcrumb) return true;
6386
6510
  if (selectedPage) return true;
@@ -6477,7 +6601,7 @@ function LinkPopover({
6477
6601
  onSubmit
6478
6602
  });
6479
6603
  const sectionPickerActive = state.showSectionPicker && Boolean(state.selectedPage);
6480
- (0, import_react8.useEffect)(() => {
6604
+ (0, import_react9.useEffect)(() => {
6481
6605
  if (!open) return;
6482
6606
  if (sectionPickerActive) {
6483
6607
  postToParent({ type: "ui:unlock" });
@@ -7934,6 +8058,90 @@ function buildFooterHeading(colIndex, text) {
7934
8058
  ].join(";");
7935
8059
  return heading;
7936
8060
  }
8061
+ var FOOTER_HEADING_CACHE_ATTR = "data-ohw-heading-cache";
8062
+ function getFooterColumnHeadingEl(column) {
8063
+ return column.querySelector('[data-ohw-key^="footer-"][data-ohw-key$="-heading"]') ?? null;
8064
+ }
8065
+ function getFooterColumnHeadingKey(column) {
8066
+ const attr = column.getAttribute("data-ohw-footer-col");
8067
+ if (attr != null) {
8068
+ const n = parseInt(attr, 10);
8069
+ if (Number.isFinite(n)) return `footer-${n}-heading`;
8070
+ }
8071
+ const existing = getFooterColumnHeadingEl(column)?.getAttribute("data-ohw-key");
8072
+ if (existing) return existing;
8073
+ const index = listFooterColumns().indexOf(column);
8074
+ if (index >= 0) return `footer-${index}-heading`;
8075
+ return null;
8076
+ }
8077
+ function isFooterColumnHeadingVisible(column) {
8078
+ return getFooterColumnHeadingEl(column) !== null;
8079
+ }
8080
+ function setFooterColumnHeadingVisible(column, visible) {
8081
+ const headingKey = getFooterColumnHeadingKey(column);
8082
+ if (!headingKey) return null;
8083
+ const colMatch = headingKey.match(FOOTER_HEADING_RE);
8084
+ const colIndex = colMatch ? parseInt(colMatch[1], 10) : NaN;
8085
+ if (!Number.isFinite(colIndex)) return null;
8086
+ const existing = getFooterColumnHeadingEl(column);
8087
+ if (!visible) {
8088
+ const text2 = (existing?.textContent ?? "").trim() || column.getAttribute(FOOTER_HEADING_CACHE_ATTR) || DEFAULT_FOOTER_COLUMN_HEADING;
8089
+ column.setAttribute(FOOTER_HEADING_CACHE_ATTR, text2);
8090
+ existing?.remove();
8091
+ return { headingKey, text: "", visible: false };
8092
+ }
8093
+ if (existing) {
8094
+ return {
8095
+ headingKey,
8096
+ text: (existing.textContent ?? "").trim() || DEFAULT_FOOTER_COLUMN_HEADING,
8097
+ visible: true
8098
+ };
8099
+ }
8100
+ const text = column.getAttribute(FOOTER_HEADING_CACHE_ATTR) || DEFAULT_FOOTER_COLUMN_HEADING;
8101
+ const heading = buildFooterHeading(colIndex, text);
8102
+ const firstLink = listFooterLinksInColumn(column)[0];
8103
+ if (firstLink) column.insertBefore(heading, firstLink);
8104
+ else column.prepend(heading);
8105
+ return { headingKey, text, visible: true };
8106
+ }
8107
+ function ensureFooterColumnDefaultHeading(column, content) {
8108
+ if (isFooterColumnHeadingVisible(column)) return null;
8109
+ const headingKey = getFooterColumnHeadingKey(column);
8110
+ if (!headingKey) return null;
8111
+ if (content && content[headingKey] === "") return null;
8112
+ const result = setFooterColumnHeadingVisible(column, true);
8113
+ if (!result?.visible) return null;
8114
+ return { headingKey: result.headingKey, text: result.text };
8115
+ }
8116
+ function reconcileFooterHeadingVisibility(content) {
8117
+ for (const column of listFooterColumns()) {
8118
+ const headingKey = getFooterColumnHeadingKey(column);
8119
+ if (!headingKey) continue;
8120
+ const raw = content[headingKey];
8121
+ if (raw === void 0) continue;
8122
+ if (raw === "") {
8123
+ const existing2 = getFooterColumnHeadingEl(column);
8124
+ if (existing2) {
8125
+ const cached = (existing2.textContent ?? "").trim();
8126
+ if (cached) column.setAttribute(FOOTER_HEADING_CACHE_ATTR, cached);
8127
+ existing2.remove();
8128
+ }
8129
+ continue;
8130
+ }
8131
+ const existing = getFooterColumnHeadingEl(column);
8132
+ if (existing) {
8133
+ if (existing.textContent !== raw) existing.textContent = raw;
8134
+ continue;
8135
+ }
8136
+ const colMatch = headingKey.match(FOOTER_HEADING_RE);
8137
+ const colIndex = colMatch ? parseInt(colMatch[1], 10) : NaN;
8138
+ if (!Number.isFinite(colIndex)) continue;
8139
+ const heading = buildFooterHeading(colIndex, raw);
8140
+ const firstLink = listFooterLinksInColumn(column)[0];
8141
+ if (firstLink) column.insertBefore(heading, firstLink);
8142
+ else column.prepend(heading);
8143
+ }
8144
+ }
7937
8145
  function buildFooterLink(colIndex, itemIndex, href, label, template) {
7938
8146
  const anchor = cloneFooterLinkShell(template);
7939
8147
  anchor.setAttribute("href", href);
@@ -7973,7 +8181,11 @@ function insertFooterColumnDom(colIndex, heading, items) {
7973
8181
  column.style.display = getComputedStyle(colTemplate).display || "flex";
7974
8182
  column.style.flexDirection = "column";
7975
8183
  }
7976
- column.appendChild(buildFooterHeading(colIndex, heading));
8184
+ if (heading != null && heading !== "") {
8185
+ column.appendChild(buildFooterHeading(colIndex, heading));
8186
+ } else if (heading === "") {
8187
+ column.setAttribute(FOOTER_HEADING_CACHE_ATTR, DEFAULT_FOOTER_COLUMN_HEADING);
8188
+ }
7977
8189
  let firstLink = null;
7978
8190
  items.forEach((item, itemIndex) => {
7979
8191
  const link = buildFooterLink(colIndex, itemIndex, item.href, item.label, linkTemplate);
@@ -8060,9 +8272,10 @@ function reconcileFooterColumnsFromContent(content) {
8060
8272
  for (const colIndex of indices) {
8061
8273
  if (allowedCols && !allowedCols.has(colIndex)) continue;
8062
8274
  if (footerColumnExistsInDom(colIndex)) continue;
8063
- const heading = content[`footer-${colIndex}-heading`] ?? DEFAULT_FOOTER_COLUMN_HEADING;
8275
+ const headingRaw = content[`footer-${colIndex}-heading`];
8276
+ const heading = headingRaw === "" ? "" : headingRaw ?? DEFAULT_FOOTER_COLUMN_HEADING;
8064
8277
  const items = collectFooterItemsForColumn(content, colIndex);
8065
- const hasPayload = Boolean(content[`footer-${colIndex}-heading`]) || items.some(
8278
+ const hasPayload = content[`footer-${colIndex}-heading`] !== void 0 || items.some(
8066
8279
  (_, i) => content[`footer-${colIndex}-${i}-href`] !== void 0 || content[`footer-${colIndex}-${i}-label`] !== void 0
8067
8280
  ) || (order?.some((col) => col.some((k) => parseFooterHrefKey(k)?.col === colIndex)) ?? false);
8068
8281
  if (!hasPayload) continue;
@@ -8072,7 +8285,10 @@ function reconcileFooterColumnsFromContent(content) {
8072
8285
  function reconcileFooterOrderFromContent(content) {
8073
8286
  reconcileFooterColumnsFromContent(content);
8074
8287
  const order = parseFooterOrder(content);
8075
- if (!order?.length) return;
8288
+ if (!order?.length) {
8289
+ reconcileFooterHeadingVisibility(content);
8290
+ return;
8291
+ }
8076
8292
  const linkTemplate = getFooterLinkTemplate();
8077
8293
  for (let c = 0; c < order.length; c++) {
8078
8294
  const colOrder = order[c];
@@ -8092,6 +8308,7 @@ function reconcileFooterOrderFromContent(content) {
8092
8308
  }
8093
8309
  pruneFooterToOrder(order);
8094
8310
  applyFooterOrder(order);
8311
+ reconcileFooterHeadingVisibility(content);
8095
8312
  }
8096
8313
  function pruneFooterToOrder(order) {
8097
8314
  const allowedKeys = new Set(order.flat());
@@ -8679,7 +8896,7 @@ function hitTestNavDropSlot(clientX, clientY, draggedHrefKey) {
8679
8896
  }
8680
8897
 
8681
8898
  // src/useNavItemDrag.ts
8682
- var import_react9 = require("react");
8899
+ var import_react10 = require("react");
8683
8900
  function useNavItemDrag({
8684
8901
  isEditMode,
8685
8902
  editContentRef,
@@ -8704,22 +8921,28 @@ function useNavItemDrag({
8704
8921
  isDragHandleDisabled: isDragHandleDisabled2,
8705
8922
  isNavbarButton: isNavbarButton3
8706
8923
  }) {
8707
- const navDragRef = (0, import_react9.useRef)(null);
8708
- const [navDropSlots, setNavDropSlots] = (0, import_react9.useState)([]);
8709
- const [activeNavDropIndex, setActiveNavDropIndex] = (0, import_react9.useState)(null);
8710
- const navPointerDragRef = (0, import_react9.useRef)(null);
8711
- const clearNavDragVisuals = (0, import_react9.useCallback)(() => {
8924
+ const navDragRef = (0, import_react10.useRef)(null);
8925
+ const [navDropSlots, setNavDropSlots] = (0, import_react10.useState)([]);
8926
+ const [activeNavDropIndex, setActiveNavDropIndex] = (0, import_react10.useState)(null);
8927
+ const navPointerDragRef = (0, import_react10.useRef)(null);
8928
+ const clearNavDragVisuals = (0, import_react10.useCallback)(() => {
8929
+ const session = navDragRef.current;
8930
+ const keepOpenEl = session?.draggedEl?.closest("[data-ohw-nav-children]") != null ? session.draggedEl : null;
8712
8931
  navDragRef.current = null;
8713
8932
  setNavDropSlots([]);
8714
8933
  setActiveNavDropIndex(null);
8715
8934
  setDraggedItemRect(null);
8716
8935
  setSiblingHintRects([]);
8717
8936
  setIsItemDragging(false);
8718
- setNavGroupForceOpen(null, false);
8937
+ if (keepOpenEl?.isConnected) {
8938
+ setNavGroupForceOpen(keepOpenEl, true);
8939
+ } else {
8940
+ setNavGroupForceOpen(null, false);
8941
+ }
8719
8942
  document.documentElement.removeAttribute("data-ohw-nav-dragging-root");
8720
8943
  unlockItemDragInteraction();
8721
8944
  }, [setDraggedItemRect, setIsItemDragging, setSiblingHintRects]);
8722
- const refreshNavDragVisuals = (0, import_react9.useCallback)(
8945
+ const refreshNavDragVisuals = (0, import_react10.useCallback)(
8723
8946
  (session, activeSlot, clientX, clientY) => {
8724
8947
  setDraggedItemRect(session.draggedEl.getBoundingClientRect());
8725
8948
  if (typeof clientX === "number" && typeof clientY === "number") {
@@ -8737,13 +8960,13 @@ function useNavItemDrag({
8737
8960
  },
8738
8961
  [setDraggedItemRect, setSiblingHintRects]
8739
8962
  );
8740
- const refreshNavDragVisualsRef = (0, import_react9.useRef)(refreshNavDragVisuals);
8963
+ const refreshNavDragVisualsRef = (0, import_react10.useRef)(refreshNavDragVisuals);
8741
8964
  refreshNavDragVisualsRef.current = refreshNavDragVisuals;
8742
- const commitNavDragRef = (0, import_react9.useRef)(() => {
8965
+ const commitNavDragRef = (0, import_react10.useRef)(() => {
8743
8966
  });
8744
- const beginNavDragRef = (0, import_react9.useRef)(() => {
8967
+ const beginNavDragRef = (0, import_react10.useRef)(() => {
8745
8968
  });
8746
- const beginNavDrag = (0, import_react9.useCallback)(
8969
+ const beginNavDrag = (0, import_react10.useCallback)(
8747
8970
  (session) => {
8748
8971
  const rect = session.draggedEl.getBoundingClientRect();
8749
8972
  session.lastClientX = session.lastClientX || rect.left + rect.width / 2;
@@ -8777,7 +9000,7 @@ function useNavItemDrag({
8777
9000
  ]
8778
9001
  );
8779
9002
  beginNavDragRef.current = beginNavDrag;
8780
- const commitNavDrag = (0, import_react9.useCallback)(
9003
+ const commitNavDrag = (0, import_react10.useCallback)(
8781
9004
  (clientX, clientY) => {
8782
9005
  const session = navDragRef.current;
8783
9006
  if (!session) {
@@ -8838,7 +9061,7 @@ function useNavItemDrag({
8838
9061
  [clearNavDragVisuals, deselectRef, editContentRef, postToParentRef, selectRef]
8839
9062
  );
8840
9063
  commitNavDragRef.current = commitNavDrag;
8841
- const startNavLinkDrag = (0, import_react9.useCallback)(
9064
+ const startNavLinkDrag = (0, import_react10.useCallback)(
8842
9065
  (anchor, clientX, clientY, wasSelected) => {
8843
9066
  if (footerDragRef.current) return false;
8844
9067
  const hrefKey = anchor.getAttribute("data-ohw-href-key");
@@ -8856,7 +9079,7 @@ function useNavItemDrag({
8856
9079
  },
8857
9080
  [beginNavDrag, footerDragRef, isDragHandleDisabled2, isNavbarButton3]
8858
9081
  );
8859
- const onNavDragOver = (0, import_react9.useCallback)(
9082
+ const onNavDragOver = (0, import_react10.useCallback)(
8860
9083
  (e) => {
8861
9084
  const session = navDragRef.current;
8862
9085
  if (!session) return false;
@@ -8868,7 +9091,7 @@ function useNavItemDrag({
8868
9091
  },
8869
9092
  []
8870
9093
  );
8871
- (0, import_react9.useEffect)(() => {
9094
+ (0, import_react10.useEffect)(() => {
8872
9095
  if (!isEditMode) return;
8873
9096
  const THRESHOLD = 10;
8874
9097
  const resolveWasSelected = (el) => {
@@ -8993,7 +9216,7 @@ function useNavItemDrag({
8993
9216
  setLinkPopover,
8994
9217
  suppressNextClickRef
8995
9218
  ]);
8996
- const armNavPressFromChrome = (0, import_react9.useCallback)(
9219
+ const armNavPressFromChrome = (0, import_react10.useCallback)(
8997
9220
  (selected, clientX, clientY, pointerId) => {
8998
9221
  const hrefKey = selected.getAttribute("data-ohw-href-key");
8999
9222
  if (!hrefKey || !isNavbarHrefKey(hrefKey)) return false;
@@ -9075,7 +9298,7 @@ function FooterContainerChrome({
9075
9298
  }
9076
9299
 
9077
9300
  // src/lib/carousel.ts
9078
- var import_react10 = require("react");
9301
+ var import_react11 = require("react");
9079
9302
  var CAROUSEL_ATTR = "data-ohw-carousel";
9080
9303
  var CAROUSEL_VALUE_ATTR = "data-ohw-carousel-value";
9081
9304
  var CAROUSEL_SLIDE_ATTR = "data-ohw-carousel-slide";
@@ -9137,8 +9360,8 @@ function applyCarouselNode(key, val) {
9137
9360
  return true;
9138
9361
  }
9139
9362
  function useOhwCarousel(key, initial) {
9140
- const [images, setImages] = (0, import_react10.useState)(initial);
9141
- (0, import_react10.useEffect)(() => {
9363
+ const [images, setImages] = (0, import_react11.useState)(initial);
9364
+ (0, import_react11.useEffect)(() => {
9142
9365
  const el = document.querySelector(
9143
9366
  `[${CAROUSEL_ATTR}][data-ohw-key="${CSS.escape(key)}"]`
9144
9367
  );
@@ -9537,7 +9760,7 @@ function NavbarContainerChrome({
9537
9760
  }
9538
9761
 
9539
9762
  // src/ui/drop-indicator.tsx
9540
- var React10 = __toESM(require("react"), 1);
9763
+ var React9 = __toESM(require("react"), 1);
9541
9764
  var import_jsx_runtime25 = require("react/jsx-runtime");
9542
9765
  var dropIndicatorVariants = cva(
9543
9766
  "ov-gap-line pointer-events-none shrink-0 transition-opacity duration-150",
@@ -9560,7 +9783,7 @@ var dropIndicatorVariants = cva(
9560
9783
  }
9561
9784
  }
9562
9785
  );
9563
- var DropIndicator = React10.forwardRef(
9786
+ var DropIndicator = React9.forwardRef(
9564
9787
  ({ className, direction, state, ...props }, ref) => {
9565
9788
  return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
9566
9789
  "div",
@@ -9969,6 +10192,15 @@ function isNavDropdownPanelOpen(childrenRoot) {
9969
10192
  }
9970
10193
  return true;
9971
10194
  }
10195
+ function getOpenNavDropdownPanelRect(anchor) {
10196
+ const group = anchor.closest("[data-ohw-nav-group]");
10197
+ if (!group?.hasAttribute("data-ohw-nav-force-open")) return null;
10198
+ const panel = group.querySelector(":scope > [data-ohw-nav-children]");
10199
+ if (!panel || !isNavDropdownPanelOpen(panel)) return null;
10200
+ const panelRect = panel.getBoundingClientRect();
10201
+ if (panelRect.height < 2 || panelRect.width < 2) return null;
10202
+ return panelRect;
10203
+ }
9972
10204
  function isNavItemPointerTarget(el) {
9973
10205
  const childrenRoot = el.closest("[data-ohw-nav-children]");
9974
10206
  if (!childrenRoot) return true;
@@ -10605,9 +10837,9 @@ function FloatingToolbar({
10605
10837
  showEditLink,
10606
10838
  onEditLink
10607
10839
  }) {
10608
- const localRef = import_react11.default.useRef(null);
10609
- const [measuredW, setMeasuredW] = import_react11.default.useState(330);
10610
- const setRefs = import_react11.default.useCallback(
10840
+ const localRef = import_react12.default.useRef(null);
10841
+ const [measuredW, setMeasuredW] = import_react12.default.useState(330);
10842
+ const setRefs = import_react12.default.useCallback(
10611
10843
  (node) => {
10612
10844
  localRef.current = node;
10613
10845
  if (typeof elRef === "function") elRef(node);
@@ -10619,7 +10851,7 @@ function FloatingToolbar({
10619
10851
  },
10620
10852
  [elRef]
10621
10853
  );
10622
- import_react11.default.useLayoutEffect(() => {
10854
+ import_react12.default.useLayoutEffect(() => {
10623
10855
  const node = localRef.current;
10624
10856
  if (!node) return;
10625
10857
  const update = () => {
@@ -10645,7 +10877,7 @@ function FloatingToolbar({
10645
10877
  pointerEvents: "auto"
10646
10878
  },
10647
10879
  children: /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(CustomToolbar, { children: [
10648
- TOOLBAR_GROUPS.map((btns, gi) => /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(import_react11.default.Fragment, { children: [
10880
+ TOOLBAR_GROUPS.map((btns, gi) => /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(import_react12.default.Fragment, { children: [
10649
10881
  gi > 0 && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(CustomToolbarDivider, {}),
10650
10882
  btns.map((btn) => {
10651
10883
  const isActive = activeCommands.has(btn.cmd);
@@ -10751,8 +10983,8 @@ function OhhwellsBridge() {
10751
10983
  const router = (0, import_navigation2.useRouter)();
10752
10984
  const searchParams = (0, import_navigation2.useSearchParams)();
10753
10985
  const isEditMode = isEditSessionActive();
10754
- const [bridgeRoot, setBridgeRoot] = (0, import_react11.useState)(null);
10755
- (0, import_react11.useEffect)(() => {
10986
+ const [bridgeRoot, setBridgeRoot] = (0, import_react12.useState)(null);
10987
+ (0, import_react12.useEffect)(() => {
10756
10988
  const figtreeFontId = "ohw-figtree-font";
10757
10989
  if (!document.getElementById(figtreeFontId)) {
10758
10990
  const preconnect1 = Object.assign(document.createElement("link"), { rel: "preconnect", href: "https://fonts.googleapis.com" });
@@ -10780,104 +11012,106 @@ function OhhwellsBridge() {
10780
11012
  const subdomainFromQuery = searchParams.get("subdomain");
10781
11013
  const subdomain = resolveSubdomain(subdomainFromQuery);
10782
11014
  useLinkHrefGuardian(pathname, subdomain, isEditMode);
10783
- const postToParent2 = (0, import_react11.useCallback)((data) => {
11015
+ const postToParent2 = (0, import_react12.useCallback)((data) => {
10784
11016
  if (typeof window !== "undefined" && window.parent !== window) {
10785
11017
  window.parent.postMessage(data, "*");
10786
11018
  }
10787
11019
  }, []);
10788
- const [fetchState, setFetchState] = (0, import_react11.useState)("idle");
10789
- const autoSaveTimers = (0, import_react11.useRef)(/* @__PURE__ */ new Map());
10790
- const activeElRef = (0, import_react11.useRef)(null);
10791
- const pointerHeldRef = (0, import_react11.useRef)(false);
10792
- const selectedElRef = (0, import_react11.useRef)(null);
10793
- const selectedHrefKeyRef = (0, import_react11.useRef)(null);
10794
- const selectedFooterColAttrRef = (0, import_react11.useRef)(null);
10795
- const originalContentRef = (0, import_react11.useRef)(null);
10796
- const activeStateElRef = (0, import_react11.useRef)(null);
10797
- const parentScrollRef = (0, import_react11.useRef)(null);
10798
- const visibleViewportRef = (0, import_react11.useRef)(null);
10799
- const [dialogPortalContainer, setDialogPortalContainer] = (0, import_react11.useState)(null);
10800
- const attachVisibleViewport = (0, import_react11.useCallback)((node) => {
11020
+ const [fetchState, setFetchState] = (0, import_react12.useState)("idle");
11021
+ const autoSaveTimers = (0, import_react12.useRef)(/* @__PURE__ */ new Map());
11022
+ const activeElRef = (0, import_react12.useRef)(null);
11023
+ const pointerHeldRef = (0, import_react12.useRef)(false);
11024
+ const selectedElRef = (0, import_react12.useRef)(null);
11025
+ const selectedHrefKeyRef = (0, import_react12.useRef)(null);
11026
+ const selectedFooterColAttrRef = (0, import_react12.useRef)(null);
11027
+ const originalContentRef = (0, import_react12.useRef)(null);
11028
+ const activeStateElRef = (0, import_react12.useRef)(null);
11029
+ const parentScrollRef = (0, import_react12.useRef)(null);
11030
+ const visibleViewportRef = (0, import_react12.useRef)(null);
11031
+ const [dialogPortalContainer, setDialogPortalContainer] = (0, import_react12.useState)(null);
11032
+ const attachVisibleViewport = (0, import_react12.useCallback)((node) => {
10801
11033
  visibleViewportRef.current = node;
10802
11034
  setDialogPortalContainer(node);
10803
11035
  if (node) applyVisibleViewport(node, parentScrollRef.current);
10804
11036
  }, []);
10805
- const toolbarElRef = (0, import_react11.useRef)(null);
10806
- const glowElRef = (0, import_react11.useRef)(null);
10807
- const hoveredImageRef = (0, import_react11.useRef)(null);
10808
- const hoveredImageHasTextOverlapRef = (0, import_react11.useRef)(false);
10809
- const dragOverElRef = (0, import_react11.useRef)(null);
10810
- const [mediaHover, setMediaHover] = (0, import_react11.useState)(null);
10811
- const [carouselHover, setCarouselHover] = (0, import_react11.useState)(null);
10812
- const [uploadingRects, setUploadingRects] = (0, import_react11.useState)({});
10813
- const hoveredGapRef = (0, import_react11.useRef)(null);
10814
- const imageUnhoverTimerRef = (0, import_react11.useRef)(null);
10815
- const imageShowTimerRef = (0, import_react11.useRef)(null);
10816
- const editStylesRef = (0, import_react11.useRef)(null);
10817
- const activateRef = (0, import_react11.useRef)(() => {
11037
+ const toolbarElRef = (0, import_react12.useRef)(null);
11038
+ const glowElRef = (0, import_react12.useRef)(null);
11039
+ const hoveredImageRef = (0, import_react12.useRef)(null);
11040
+ const hoveredImageHasTextOverlapRef = (0, import_react12.useRef)(false);
11041
+ const dragOverElRef = (0, import_react12.useRef)(null);
11042
+ const [mediaHover, setMediaHover] = (0, import_react12.useState)(null);
11043
+ const [carouselHover, setCarouselHover] = (0, import_react12.useState)(null);
11044
+ const [uploadingRects, setUploadingRects] = (0, import_react12.useState)({});
11045
+ const hoveredGapRef = (0, import_react12.useRef)(null);
11046
+ const imageUnhoverTimerRef = (0, import_react12.useRef)(null);
11047
+ const imageShowTimerRef = (0, import_react12.useRef)(null);
11048
+ const editStylesRef = (0, import_react12.useRef)(null);
11049
+ const activateRef = (0, import_react12.useRef)(() => {
10818
11050
  });
10819
- const deactivateRef = (0, import_react11.useRef)(() => {
11051
+ const deactivateRef = (0, import_react12.useRef)(() => {
10820
11052
  });
10821
- const selectRef = (0, import_react11.useRef)(() => {
11053
+ const selectRef = (0, import_react12.useRef)(() => {
10822
11054
  });
10823
- const selectFrameRef = (0, import_react11.useRef)(() => {
11055
+ const selectFrameRef = (0, import_react12.useRef)(() => {
10824
11056
  });
10825
- const deselectRef = (0, import_react11.useRef)(() => {
11057
+ const deselectRef = (0, import_react12.useRef)(() => {
10826
11058
  });
10827
- const reselectNavigationItemRef = (0, import_react11.useRef)(() => {
11059
+ const reselectNavigationItemRef = (0, import_react12.useRef)(() => {
10828
11060
  });
10829
- const commitNavigationTextEditRef = (0, import_react11.useRef)(() => {
11061
+ const commitNavigationTextEditRef = (0, import_react12.useRef)(() => {
10830
11062
  });
10831
- const handleDeleteSelectedRef = (0, import_react11.useRef)(() => false);
10832
- const runPendingDeleteUndoRef = (0, import_react11.useRef)(() => false);
10833
- const isFooterFrameSelectionRef = (0, import_react11.useRef)(false);
10834
- const refreshActiveCommandsRef = (0, import_react11.useRef)(() => {
11063
+ const handleDeleteSelectedRef = (0, import_react12.useRef)(() => false);
11064
+ const runPendingDeleteUndoRef = (0, import_react12.useRef)(() => false);
11065
+ const isFooterFrameSelectionRef = (0, import_react12.useRef)(false);
11066
+ const refreshActiveCommandsRef = (0, import_react12.useRef)(() => {
10835
11067
  });
10836
- const postToParentRef = (0, import_react11.useRef)(postToParent2);
11068
+ const postToParentRef = (0, import_react12.useRef)(postToParent2);
10837
11069
  postToParentRef.current = postToParent2;
10838
- const sectionsLoadedRef = (0, import_react11.useRef)(false);
10839
- const pendingScheduleConfigRequests = (0, import_react11.useRef)([]);
10840
- const [toolbarRect, setToolbarRect] = (0, import_react11.useState)(null);
10841
- const [toolbarVariant, setToolbarVariant] = (0, import_react11.useState)("none");
10842
- const toolbarVariantRef = (0, import_react11.useRef)("none");
11070
+ const sectionsLoadedRef = (0, import_react12.useRef)(false);
11071
+ const pendingScheduleConfigRequests = (0, import_react12.useRef)([]);
11072
+ const [toolbarRect, setToolbarRect] = (0, import_react12.useState)(null);
11073
+ const [toolbarVariant, setToolbarVariant] = (0, import_react12.useState)("none");
11074
+ const toolbarVariantRef = (0, import_react12.useRef)("none");
10843
11075
  toolbarVariantRef.current = toolbarVariant;
10844
- const [selectedIsCta, setSelectedIsCta] = (0, import_react11.useState)(false);
10845
- const [reorderHrefKey, setReorderHrefKey] = (0, import_react11.useState)(null);
10846
- const [reorderDragDisabled, setReorderDragDisabled] = (0, import_react11.useState)(false);
10847
- const [toggleState, setToggleState] = (0, import_react11.useState)(null);
10848
- const [maxBadge, setMaxBadge] = (0, import_react11.useState)(null);
10849
- const [activeCommands, setActiveCommands] = (0, import_react11.useState)(/* @__PURE__ */ new Set());
10850
- const [sectionGap, setSectionGap] = (0, import_react11.useState)(null);
10851
- const [toolbarShowEditLink, setToolbarShowEditLink] = (0, import_react11.useState)(false);
10852
- const hoveredNavContainerRef = (0, import_react11.useRef)(null);
10853
- const [hoveredNavContainerRect, setHoveredNavContainerRect] = (0, import_react11.useState)(null);
10854
- const hoveredItemElRef = (0, import_react11.useRef)(null);
10855
- const [hoveredItemRect, setHoveredItemRect] = (0, import_react11.useState)(null);
10856
- const siblingHintElRef = (0, import_react11.useRef)(null);
10857
- const [siblingHintRect, setSiblingHintRect] = (0, import_react11.useState)(null);
10858
- const [siblingHintRects, setSiblingHintRects] = (0, import_react11.useState)([]);
10859
- const [isItemDragging, setIsItemDragging] = (0, import_react11.useState)(false);
10860
- const [isFooterFrameSelection, setIsFooterFrameSelection] = (0, import_react11.useState)(false);
11076
+ const [selectedIsCta, setSelectedIsCta] = (0, import_react12.useState)(false);
11077
+ const [reorderHrefKey, setReorderHrefKey] = (0, import_react12.useState)(null);
11078
+ const [reorderDragDisabled, setReorderDragDisabled] = (0, import_react12.useState)(false);
11079
+ const [toggleState, setToggleState] = (0, import_react12.useState)(null);
11080
+ const [maxBadge, setMaxBadge] = (0, import_react12.useState)(null);
11081
+ const [activeCommands, setActiveCommands] = (0, import_react12.useState)(/* @__PURE__ */ new Set());
11082
+ const [sectionGap, setSectionGap] = (0, import_react12.useState)(null);
11083
+ const [toolbarShowEditLink, setToolbarShowEditLink] = (0, import_react12.useState)(false);
11084
+ const hoveredNavContainerRef = (0, import_react12.useRef)(null);
11085
+ const [hoveredNavContainerRect, setHoveredNavContainerRect] = (0, import_react12.useState)(null);
11086
+ const hoveredItemElRef = (0, import_react12.useRef)(null);
11087
+ const [hoveredItemRect, setHoveredItemRect] = (0, import_react12.useState)(null);
11088
+ const siblingHintElRef = (0, import_react12.useRef)(null);
11089
+ const [siblingHintRect, setSiblingHintRect] = (0, import_react12.useState)(null);
11090
+ const [siblingHintRects, setSiblingHintRects] = (0, import_react12.useState)([]);
11091
+ const [isItemDragging, setIsItemDragging] = (0, import_react12.useState)(false);
11092
+ const [isFooterFrameSelection, setIsFooterFrameSelection] = (0, import_react12.useState)(false);
10861
11093
  isFooterFrameSelectionRef.current = isFooterFrameSelection;
10862
- const footerDragRef = (0, import_react11.useRef)(null);
10863
- const [footerDropSlots, setFooterDropSlots] = (0, import_react11.useState)([]);
10864
- const [activeFooterDropIndex, setActiveFooterDropIndex] = (0, import_react11.useState)(null);
10865
- const [draggedItemRect, setDraggedItemRect] = (0, import_react11.useState)(null);
10866
- const footerPointerDragRef = (0, import_react11.useRef)(null);
10867
- const suppressNextClickRef = (0, import_react11.useRef)(false);
10868
- const suppressClickUntilRef = (0, import_react11.useRef)(0);
10869
- const [linkPopover, setLinkPopover] = (0, import_react11.useState)(null);
10870
- const linkPopoverSessionRef = (0, import_react11.useRef)(null);
10871
- const addNavAfterAnchorRef = (0, import_react11.useRef)(null);
10872
- const editContentRef = (0, import_react11.useRef)({});
10873
- const pendingDeleteUndoRef = (0, import_react11.useRef)(null);
10874
- const [sitePages, setSitePages] = (0, import_react11.useState)([]);
10875
- const [sectionsByPath, setSectionsByPath] = (0, import_react11.useState)({});
10876
- const sectionsPrefetchGenRef = (0, import_react11.useRef)(0);
10877
- const setLinkPopoverRef = (0, import_react11.useRef)(setLinkPopover);
10878
- const linkPopoverPanelRef = (0, import_react11.useRef)(null);
10879
- const linkPopoverOpenRef = (0, import_react11.useRef)(false);
10880
- const linkPopoverGraceUntilRef = (0, import_react11.useRef)(0);
11094
+ const [navDropdownPreviewOpen, setNavDropdownPreviewOpen] = (0, import_react12.useState)(null);
11095
+ const [footerHeadingVisible, setFooterHeadingVisible] = (0, import_react12.useState)(null);
11096
+ const footerDragRef = (0, import_react12.useRef)(null);
11097
+ const [footerDropSlots, setFooterDropSlots] = (0, import_react12.useState)([]);
11098
+ const [activeFooterDropIndex, setActiveFooterDropIndex] = (0, import_react12.useState)(null);
11099
+ const [draggedItemRect, setDraggedItemRect] = (0, import_react12.useState)(null);
11100
+ const footerPointerDragRef = (0, import_react12.useRef)(null);
11101
+ const suppressNextClickRef = (0, import_react12.useRef)(false);
11102
+ const suppressClickUntilRef = (0, import_react12.useRef)(0);
11103
+ const [linkPopover, setLinkPopover] = (0, import_react12.useState)(null);
11104
+ const linkPopoverSessionRef = (0, import_react12.useRef)(null);
11105
+ const addNavAfterAnchorRef = (0, import_react12.useRef)(null);
11106
+ const editContentRef = (0, import_react12.useRef)({});
11107
+ const pendingDeleteUndoRef = (0, import_react12.useRef)(null);
11108
+ const [sitePages, setSitePages] = (0, import_react12.useState)([]);
11109
+ const [sectionsByPath, setSectionsByPath] = (0, import_react12.useState)({});
11110
+ const sectionsPrefetchGenRef = (0, import_react12.useRef)(0);
11111
+ const setLinkPopoverRef = (0, import_react12.useRef)(setLinkPopover);
11112
+ const linkPopoverPanelRef = (0, import_react12.useRef)(null);
11113
+ const linkPopoverOpenRef = (0, import_react12.useRef)(false);
11114
+ const linkPopoverGraceUntilRef = (0, import_react12.useRef)(0);
10881
11115
  setLinkPopoverRef.current = setLinkPopover;
10882
11116
  linkPopoverSessionRef.current = linkPopover;
10883
11117
  const {
@@ -10916,7 +11150,7 @@ function OhhwellsBridge() {
10916
11150
  const bumpLinkPopoverGrace = () => {
10917
11151
  linkPopoverGraceUntilRef.current = Date.now() + 350;
10918
11152
  };
10919
- const runSectionsPrefetch = (0, import_react11.useCallback)((pages) => {
11153
+ const runSectionsPrefetch = (0, import_react12.useCallback)((pages) => {
10920
11154
  if (!isEditMode || shouldUseDevFixtures() || pages.length === 0) return;
10921
11155
  const gen = ++sectionsPrefetchGenRef.current;
10922
11156
  const paths = pages.map((p) => p.path);
@@ -10935,9 +11169,9 @@ function OhhwellsBridge() {
10935
11169
  );
10936
11170
  });
10937
11171
  }, [isEditMode, pathname]);
10938
- const runSectionsPrefetchRef = (0, import_react11.useRef)(runSectionsPrefetch);
11172
+ const runSectionsPrefetchRef = (0, import_react12.useRef)(runSectionsPrefetch);
10939
11173
  runSectionsPrefetchRef.current = runSectionsPrefetch;
10940
- (0, import_react11.useEffect)(() => {
11174
+ (0, import_react12.useEffect)(() => {
10941
11175
  if (!linkPopover) {
10942
11176
  document.documentElement.removeAttribute("data-ohw-link-popover-open");
10943
11177
  return;
@@ -10965,7 +11199,7 @@ function OhhwellsBridge() {
10965
11199
  document.documentElement.removeAttribute("data-ohw-link-popover-open");
10966
11200
  };
10967
11201
  }, [linkPopover, postToParent2]);
10968
- (0, import_react11.useEffect)(() => {
11202
+ (0, import_react12.useEffect)(() => {
10969
11203
  if (!isEditMode) return;
10970
11204
  const useFixtures = shouldUseDevFixtures();
10971
11205
  if (useFixtures) {
@@ -10989,14 +11223,14 @@ function OhhwellsBridge() {
10989
11223
  if (!useFixtures) postToParent2({ type: "ow:request-site-pages" });
10990
11224
  return () => window.removeEventListener("message", onSitePages);
10991
11225
  }, [isEditMode, postToParent2]);
10992
- (0, import_react11.useEffect)(() => {
11226
+ (0, import_react12.useEffect)(() => {
10993
11227
  if (!isEditMode || shouldUseDevFixtures()) return;
10994
11228
  void loadAllSectionsManifest().then((manifest) => {
10995
11229
  if (Object.keys(manifest).length === 0) return;
10996
11230
  setSectionsByPath((prev) => ({ ...manifest, ...prev }));
10997
11231
  });
10998
11232
  }, [isEditMode]);
10999
- (0, import_react11.useEffect)(() => {
11233
+ (0, import_react12.useEffect)(() => {
11000
11234
  const update = () => {
11001
11235
  const el = activeElRef.current ?? selectedElRef.current;
11002
11236
  if (el) setToolbarRect(getEditMeasureEl(el).getBoundingClientRect());
@@ -11020,10 +11254,10 @@ function OhhwellsBridge() {
11020
11254
  vvp.removeEventListener("resize", update);
11021
11255
  };
11022
11256
  }, []);
11023
- const refreshStateRules = (0, import_react11.useCallback)(() => {
11257
+ const refreshStateRules = (0, import_react12.useCallback)(() => {
11024
11258
  editStylesRef.current?.forceHover && (editStylesRef.current.forceHover.textContent = collectStateRules());
11025
11259
  }, []);
11026
- const processConfigRequest = (0, import_react11.useCallback)((insertAfterVal) => {
11260
+ const processConfigRequest = (0, import_react12.useCallback)((insertAfterVal) => {
11027
11261
  const tracker = getSectionsTracker();
11028
11262
  let entries = [];
11029
11263
  try {
@@ -11046,7 +11280,7 @@ function OhhwellsBridge() {
11046
11280
  }
11047
11281
  window.postMessage({ type: "ow:schedule-config", insertAfter: insertAfterVal, scheduleId: null }, "*");
11048
11282
  }, [isEditMode]);
11049
- const deactivate = (0, import_react11.useCallback)(() => {
11283
+ const deactivate = (0, import_react12.useCallback)(() => {
11050
11284
  const el = activeElRef.current;
11051
11285
  if (!el) return;
11052
11286
  const key = el.dataset.ohwKey;
@@ -11079,12 +11313,12 @@ function OhhwellsBridge() {
11079
11313
  setToolbarShowEditLink(false);
11080
11314
  postToParent2({ type: "ow:exit-edit" });
11081
11315
  }, [postToParent2]);
11082
- const clearSelectedAttr = (0, import_react11.useCallback)(() => {
11316
+ const clearSelectedAttr = (0, import_react12.useCallback)(() => {
11083
11317
  document.querySelectorAll("[data-ohw-selected]").forEach((el) => {
11084
11318
  el.removeAttribute("data-ohw-selected");
11085
11319
  });
11086
11320
  }, []);
11087
- const deselect = (0, import_react11.useCallback)(() => {
11321
+ const deselect = (0, import_react12.useCallback)(() => {
11088
11322
  clearSelectedAttr();
11089
11323
  selectedElRef.current = null;
11090
11324
  selectedHrefKeyRef.current = null;
@@ -11093,6 +11327,8 @@ function OhhwellsBridge() {
11093
11327
  setReorderHrefKey(null);
11094
11328
  setReorderDragDisabled(false);
11095
11329
  setIsFooterFrameSelection(false);
11330
+ setNavDropdownPreviewOpen(null);
11331
+ setFooterHeadingVisible(null);
11096
11332
  siblingHintElRef.current = null;
11097
11333
  setSiblingHintRect(null);
11098
11334
  setSiblingHintRects([]);
@@ -11105,11 +11341,11 @@ function OhhwellsBridge() {
11105
11341
  setToolbarVariant("none");
11106
11342
  }
11107
11343
  }, [clearSelectedAttr]);
11108
- const markSelected = (0, import_react11.useCallback)((el) => {
11344
+ const markSelected = (0, import_react12.useCallback)((el) => {
11109
11345
  clearSelectedAttr();
11110
11346
  el.setAttribute("data-ohw-selected", "");
11111
11347
  }, [clearSelectedAttr]);
11112
- const resolveHrefKeyElement = (0, import_react11.useCallback)((hrefKey) => {
11348
+ const resolveHrefKeyElement = (0, import_react12.useCallback)((hrefKey) => {
11113
11349
  if (isFooterHrefKey(hrefKey)) {
11114
11350
  return document.querySelector(
11115
11351
  `footer [data-ohw-href-key="${CSS.escape(hrefKey)}"]`
@@ -11124,7 +11360,7 @@ function OhhwellsBridge() {
11124
11360
  `[data-ohw-href-key="${CSS.escape(hrefKey)}"]`
11125
11361
  );
11126
11362
  }, []);
11127
- const resyncSelectedNavigationItem = (0, import_react11.useCallback)(() => {
11363
+ const resyncSelectedNavigationItem = (0, import_react12.useCallback)(() => {
11128
11364
  const hrefKey = selectedHrefKeyRef.current;
11129
11365
  if (hrefKey) {
11130
11366
  const link = resolveHrefKeyElement(hrefKey);
@@ -11134,6 +11370,14 @@ function OhhwellsBridge() {
11134
11370
  setReorderHrefKey(key);
11135
11371
  setReorderDragDisabled(disabled);
11136
11372
  setIsFooterFrameSelection(false);
11373
+ setFooterHeadingVisible(null);
11374
+ const isDropdownTrigger = !isNestedNavChild(link) && (navItemHasDropdownChildren(link) || navItemOwnsDropdownPanel(link));
11375
+ if (isDropdownTrigger) {
11376
+ const group = link.closest("[data-ohw-nav-group]");
11377
+ setNavDropdownPreviewOpen(Boolean(group?.hasAttribute("data-ohw-nav-force-open")));
11378
+ } else {
11379
+ setNavDropdownPreviewOpen(null);
11380
+ }
11137
11381
  setToolbarVariant("link-action");
11138
11382
  setToolbarRect(link.getBoundingClientRect());
11139
11383
  setSiblingHintRects(collectNavigationItemSiblingHintRects(link));
@@ -11145,6 +11389,8 @@ function OhhwellsBridge() {
11145
11389
  if (!column || !isNavigationContainer(column)) return;
11146
11390
  selectedElRef.current = column;
11147
11391
  setIsFooterFrameSelection(true);
11392
+ setNavDropdownPreviewOpen(null);
11393
+ setFooterHeadingVisible(isFooterColumnHeadingVisible(column));
11148
11394
  setToolbarVariant("select-frame");
11149
11395
  setToolbarRect(column.getBoundingClientRect());
11150
11396
  setSiblingHintRects(
@@ -11152,13 +11398,26 @@ function OhhwellsBridge() {
11152
11398
  );
11153
11399
  }
11154
11400
  }, [resolveHrefKeyElement]);
11155
- const reselectNavigationItem = (0, import_react11.useCallback)((navAnchor) => {
11401
+ const reselectNavigationItem = (0, import_react12.useCallback)((navAnchor) => {
11156
11402
  selectedElRef.current = navAnchor;
11157
11403
  selectedHrefKeyRef.current = navAnchor.getAttribute("data-ohw-href-key");
11158
11404
  selectedFooterColAttrRef.current = null;
11159
11405
  markSelected(navAnchor);
11160
11406
  setSelectedIsCta(isNavbarButton2(navAnchor));
11161
- setNavGroupForceOpen(navAnchor, navItemOwnsDropdownPanel(navAnchor));
11407
+ const isDropdownTrigger = !isNestedNavChild(navAnchor) && (navItemHasDropdownChildren(navAnchor) || navItemOwnsDropdownPanel(navAnchor));
11408
+ if (isNestedNavChild(navAnchor)) {
11409
+ setNavGroupForceOpen(navAnchor, true);
11410
+ setNavDropdownPreviewOpen(null);
11411
+ } else if (isDropdownTrigger) {
11412
+ const group = navAnchor.closest("[data-ohw-nav-group]");
11413
+ const open = Boolean(group?.hasAttribute("data-ohw-nav-force-open"));
11414
+ setNavDropdownPreviewOpen(open);
11415
+ if (!open) setNavGroupForceOpen(null, false);
11416
+ } else {
11417
+ setNavGroupForceOpen(null, false);
11418
+ setNavDropdownPreviewOpen(null);
11419
+ }
11420
+ setFooterHeadingVisible(null);
11162
11421
  const { key, disabled } = getNavigationItemReorderState(navAnchor);
11163
11422
  setReorderHrefKey(key);
11164
11423
  setReorderDragDisabled(disabled);
@@ -11168,7 +11427,7 @@ function OhhwellsBridge() {
11168
11427
  setToolbarShowEditLink(false);
11169
11428
  setActiveCommands(/* @__PURE__ */ new Set());
11170
11429
  }, [markSelected]);
11171
- const commitNavigationTextEdit = (0, import_react11.useCallback)((navAnchor) => {
11430
+ const commitNavigationTextEdit = (0, import_react12.useCallback)((navAnchor) => {
11172
11431
  const el = activeElRef.current;
11173
11432
  if (!el) return;
11174
11433
  const key = el.dataset.ohwKey;
@@ -11195,7 +11454,7 @@ function OhhwellsBridge() {
11195
11454
  postToParent2({ type: "ow:exit-edit" });
11196
11455
  reselectNavigationItem(navAnchor);
11197
11456
  }, [postToParent2, reselectNavigationItem]);
11198
- const handleAddTopLevelNavItem = (0, import_react11.useCallback)(() => {
11457
+ const handleAddTopLevelNavItem = (0, import_react12.useCallback)(() => {
11199
11458
  const items = listNavbarRootItems();
11200
11459
  addNavAfterAnchorRef.current = items[items.length - 1] ?? null;
11201
11460
  deselectRef.current();
@@ -11207,7 +11466,7 @@ function OhhwellsBridge() {
11207
11466
  intent: "add-nav"
11208
11467
  });
11209
11468
  }, []);
11210
- const maybeWarnNavLinkDropdownConflict = (0, import_react11.useCallback)(
11469
+ const maybeWarnNavLinkDropdownConflict = (0, import_react12.useCallback)(
11211
11470
  (anchor) => {
11212
11471
  if (!isNavbarHrefKey(anchor.getAttribute("data-ohw-href-key"))) return;
11213
11472
  if (!navDropdownsOpenOnClick()) return;
@@ -11220,7 +11479,43 @@ function OhhwellsBridge() {
11220
11479
  },
11221
11480
  [postToParent2]
11222
11481
  );
11223
- const enterEditOnNewItem = (0, import_react11.useCallback)((anchor) => {
11482
+ const handleNavDropdownOpenChange = (0, import_react12.useCallback)((open) => {
11483
+ const selected = selectedElRef.current;
11484
+ if (!selected || !isNavigationItem2(selected)) return;
11485
+ setNavGroupForceOpen(selected, open);
11486
+ setNavDropdownPreviewOpen(open);
11487
+ requestAnimationFrame(() => {
11488
+ const el = selectedElRef.current;
11489
+ if (el?.isConnected && isNavigationItem2(el)) {
11490
+ setToolbarRect(el.getBoundingClientRect());
11491
+ }
11492
+ });
11493
+ }, []);
11494
+ const handleFooterHeadingVisibleChange = (0, import_react12.useCallback)(
11495
+ (visible) => {
11496
+ const selected = selectedElRef.current;
11497
+ if (!selected || !isFooterFrameSelectionRef.current) return;
11498
+ const column = (selected.hasAttribute("data-ohw-footer-col") ? selected : null) ?? selected.closest("[data-ohw-footer-col]") ?? (listFooterColumns().includes(selected) ? selected : null);
11499
+ if (!column) return;
11500
+ const result = setFooterColumnHeadingVisible(column, visible);
11501
+ if (!result) return;
11502
+ editContentRef.current = {
11503
+ ...editContentRef.current,
11504
+ [result.headingKey]: result.text
11505
+ };
11506
+ postToParent2({
11507
+ type: "ow:change",
11508
+ nodes: [{ key: result.headingKey, text: result.text }]
11509
+ });
11510
+ setFooterHeadingVisible(result.visible);
11511
+ requestAnimationFrame(() => {
11512
+ const el = selectedElRef.current;
11513
+ if (el?.isConnected) setToolbarRect(el.getBoundingClientRect());
11514
+ });
11515
+ },
11516
+ [postToParent2]
11517
+ );
11518
+ const enterEditOnNewItem = (0, import_react12.useCallback)((anchor) => {
11224
11519
  const label = anchor.querySelector('[data-ohw-editable="text"]');
11225
11520
  if (!label) {
11226
11521
  selectRef.current(anchor);
@@ -11229,7 +11524,7 @@ function OhhwellsBridge() {
11229
11524
  setNavGroupForceOpen(anchor, true);
11230
11525
  activateRef.current(label);
11231
11526
  }, []);
11232
- const handleAddChildItem = (0, import_react11.useCallback)(() => {
11527
+ const handleAddChildItem = (0, import_react12.useCallback)(() => {
11233
11528
  const selected = selectedElRef.current;
11234
11529
  if (!selected) return;
11235
11530
  if (toolbarVariantRef.current === "select-frame" && isFooterFrameSelection) {
@@ -11297,11 +11592,15 @@ function OhhwellsBridge() {
11297
11592
  );
11298
11593
  }
11299
11594
  enforceLinkHrefs();
11595
+ setNavGroupForceOpen(selected, true);
11596
+ setNavDropdownPreviewOpen(true);
11597
+ setToolbarRect(selected.getBoundingClientRect());
11300
11598
  requestAnimationFrame(() => {
11599
+ if (selected.isConnected) setToolbarRect(selected.getBoundingClientRect());
11301
11600
  enterEditOnNewItem(result.anchor);
11302
11601
  });
11303
11602
  }, [enterEditOnNewItem, isFooterFrameSelection, maybeWarnNavLinkDropdownConflict, postToParent2]);
11304
- const handleAddFooterColumn = (0, import_react11.useCallback)(() => {
11603
+ const handleAddFooterColumn = (0, import_react12.useCallback)(() => {
11305
11604
  if (!canAddFooterColumn()) {
11306
11605
  postToParent2({
11307
11606
  type: "ow:toast",
@@ -11322,7 +11621,7 @@ function OhhwellsBridge() {
11322
11621
  selectRef.current(result.firstLink);
11323
11622
  });
11324
11623
  }, [postToParent2]);
11325
- const clearFooterDragVisuals = (0, import_react11.useCallback)(() => {
11624
+ const clearFooterDragVisuals = (0, import_react12.useCallback)(() => {
11326
11625
  footerDragRef.current = null;
11327
11626
  setSiblingHintRects([]);
11328
11627
  setFooterDropSlots([]);
@@ -11331,7 +11630,7 @@ function OhhwellsBridge() {
11331
11630
  setIsItemDragging(false);
11332
11631
  unlockFooterDragInteraction();
11333
11632
  }, []);
11334
- const refreshFooterDragVisuals = (0, import_react11.useCallback)((session, activeSlot, clientX, clientY) => {
11633
+ const refreshFooterDragVisuals = (0, import_react12.useCallback)((session, activeSlot, clientX, clientY) => {
11335
11634
  const dragged = session.draggedEl;
11336
11635
  setDraggedItemRect(dragged.getBoundingClientRect());
11337
11636
  if (typeof clientX === "number" && typeof clientY === "number") {
@@ -11356,13 +11655,13 @@ function OhhwellsBridge() {
11356
11655
  const activeIdx = activeSlot ? slots.findIndex((s) => s.insertIndex === activeSlot.insertIndex) : -1;
11357
11656
  setActiveFooterDropIndex(activeIdx >= 0 ? activeIdx : null);
11358
11657
  }, []);
11359
- const refreshFooterDragVisualsRef = (0, import_react11.useRef)(refreshFooterDragVisuals);
11658
+ const refreshFooterDragVisualsRef = (0, import_react12.useRef)(refreshFooterDragVisuals);
11360
11659
  refreshFooterDragVisualsRef.current = refreshFooterDragVisuals;
11361
- const commitFooterDragRef = (0, import_react11.useRef)(() => {
11660
+ const commitFooterDragRef = (0, import_react12.useRef)(() => {
11362
11661
  });
11363
- const beginFooterDragRef = (0, import_react11.useRef)(() => {
11662
+ const beginFooterDragRef = (0, import_react12.useRef)(() => {
11364
11663
  });
11365
- const beginFooterDrag = (0, import_react11.useCallback)(
11664
+ const beginFooterDrag = (0, import_react12.useCallback)(
11366
11665
  (session) => {
11367
11666
  const rect = session.draggedEl.getBoundingClientRect();
11368
11667
  session.lastClientX = session.lastClientX || rect.left + rect.width / 2;
@@ -11382,7 +11681,7 @@ function OhhwellsBridge() {
11382
11681
  [refreshFooterDragVisuals]
11383
11682
  );
11384
11683
  beginFooterDragRef.current = beginFooterDrag;
11385
- const commitFooterDrag = (0, import_react11.useCallback)(
11684
+ const commitFooterDrag = (0, import_react12.useCallback)(
11386
11685
  (clientX, clientY) => {
11387
11686
  const session = footerDragRef.current;
11388
11687
  if (!session) {
@@ -11486,7 +11785,7 @@ function OhhwellsBridge() {
11486
11785
  [clearFooterDragVisuals, resolveHrefKeyElement, resyncSelectedNavigationItem]
11487
11786
  );
11488
11787
  commitFooterDragRef.current = commitFooterDrag;
11489
- const startFooterLinkDrag = (0, import_react11.useCallback)(
11788
+ const startFooterLinkDrag = (0, import_react12.useCallback)(
11490
11789
  (anchor, clientX, clientY, wasSelected) => {
11491
11790
  const hrefKey = anchor.getAttribute("data-ohw-href-key");
11492
11791
  if (!hrefKey || !isFooterHrefKey(hrefKey)) return false;
@@ -11507,7 +11806,7 @@ function OhhwellsBridge() {
11507
11806
  },
11508
11807
  [beginFooterDrag]
11509
11808
  );
11510
- const startFooterColumnDrag = (0, import_react11.useCallback)(
11809
+ const startFooterColumnDrag = (0, import_react12.useCallback)(
11511
11810
  (columnEl, clientX, clientY, wasSelected) => {
11512
11811
  const columns = listFooterColumns();
11513
11812
  const idx = columns.indexOf(columnEl);
@@ -11527,7 +11826,7 @@ function OhhwellsBridge() {
11527
11826
  },
11528
11827
  [beginFooterDrag]
11529
11828
  );
11530
- const handleItemDragStart = (0, import_react11.useCallback)(
11829
+ const handleItemDragStart = (0, import_react12.useCallback)(
11531
11830
  (e) => {
11532
11831
  const selected = selectedElRef.current;
11533
11832
  if (!selected) {
@@ -11547,7 +11846,7 @@ function OhhwellsBridge() {
11547
11846
  },
11548
11847
  [startFooterColumnDrag, startFooterLinkDrag, startNavLinkDrag]
11549
11848
  );
11550
- const handleItemDragEnd = (0, import_react11.useCallback)(
11849
+ const handleItemDragEnd = (0, import_react12.useCallback)(
11551
11850
  (e) => {
11552
11851
  if (footerDragRef.current) {
11553
11852
  const x = e?.clientX;
@@ -11573,7 +11872,7 @@ function OhhwellsBridge() {
11573
11872
  },
11574
11873
  [commitFooterDrag, commitNavDrag, navDragRef]
11575
11874
  );
11576
- const handleItemChromePointerDown = (0, import_react11.useCallback)((e) => {
11875
+ const handleItemChromePointerDown = (0, import_react12.useCallback)((e) => {
11577
11876
  if (e.button !== 0) return;
11578
11877
  const selected = selectedElRef.current;
11579
11878
  if (!selected) return;
@@ -11604,7 +11903,7 @@ function OhhwellsBridge() {
11604
11903
  }
11605
11904
  if (armNavPressFromChrome(selected, e.clientX, e.clientY, e.pointerId)) return;
11606
11905
  }, [armNavPressFromChrome]);
11607
- const handleItemChromeClick = (0, import_react11.useCallback)((clientX, clientY) => {
11906
+ const handleItemChromeClick = (0, import_react12.useCallback)((clientX, clientY) => {
11608
11907
  if (suppressNextClickRef.current || Date.now() < suppressClickUntilRef.current) {
11609
11908
  suppressNextClickRef.current = false;
11610
11909
  return;
@@ -11617,7 +11916,7 @@ function OhhwellsBridge() {
11617
11916
  }, []);
11618
11917
  reselectNavigationItemRef.current = reselectNavigationItem;
11619
11918
  commitNavigationTextEditRef.current = commitNavigationTextEdit;
11620
- const select = (0, import_react11.useCallback)((anchor) => {
11919
+ const select = (0, import_react12.useCallback)((anchor) => {
11621
11920
  if (!isNavigationItem2(anchor)) return;
11622
11921
  if (activeElRef.current) deactivate();
11623
11922
  selectedElRef.current = anchor;
@@ -11626,7 +11925,18 @@ function OhhwellsBridge() {
11626
11925
  markSelected(anchor);
11627
11926
  setSelectedIsCta(isNavbarButton2(anchor));
11628
11927
  clearHrefKeyHover(anchor);
11629
- setNavGroupForceOpen(anchor, navItemOwnsDropdownPanel(anchor));
11928
+ const isDropdownTrigger = !isNestedNavChild(anchor) && (navItemHasDropdownChildren(anchor) || navItemOwnsDropdownPanel(anchor));
11929
+ if (isNestedNavChild(anchor)) {
11930
+ setNavGroupForceOpen(anchor, true);
11931
+ setNavDropdownPreviewOpen(null);
11932
+ } else if (isDropdownTrigger) {
11933
+ setNavGroupForceOpen(null, false);
11934
+ setNavDropdownPreviewOpen(false);
11935
+ } else {
11936
+ setNavGroupForceOpen(null, false);
11937
+ setNavDropdownPreviewOpen(null);
11938
+ }
11939
+ setFooterHeadingVisible(null);
11630
11940
  hoveredNavContainerRef.current = null;
11631
11941
  setHoveredNavContainerRect(null);
11632
11942
  setHoveredItemRect(null);
@@ -11644,7 +11954,7 @@ function OhhwellsBridge() {
11644
11954
  setToolbarShowEditLink(false);
11645
11955
  setActiveCommands(/* @__PURE__ */ new Set());
11646
11956
  }, [deactivate, markSelected]);
11647
- const selectFrame = (0, import_react11.useCallback)((el) => {
11957
+ const selectFrame = (0, import_react12.useCallback)((el) => {
11648
11958
  if (!isNavigationContainer(el)) return;
11649
11959
  if (activeElRef.current) deactivate();
11650
11960
  const isFooterColumn = !isFooterLinksContainer(el) && (el.hasAttribute("data-ohw-footer-col") || Boolean(el.closest("footer") && isInferredFooterGroup2(el)));
@@ -11668,12 +11978,29 @@ function OhhwellsBridge() {
11668
11978
  setReorderHrefKey(null);
11669
11979
  setReorderDragDisabled(false);
11670
11980
  setIsFooterFrameSelection(isFooterColumn);
11981
+ setNavDropdownPreviewOpen(null);
11982
+ if (isFooterColumn) {
11983
+ const ensured = ensureFooterColumnDefaultHeading(el, editContentRef.current);
11984
+ if (ensured) {
11985
+ editContentRef.current = {
11986
+ ...editContentRef.current,
11987
+ [ensured.headingKey]: ensured.text
11988
+ };
11989
+ postToParent2({
11990
+ type: "ow:change",
11991
+ nodes: [{ key: ensured.headingKey, text: ensured.text }]
11992
+ });
11993
+ }
11994
+ setFooterHeadingVisible(isFooterColumnHeadingVisible(el));
11995
+ } else {
11996
+ setFooterHeadingVisible(null);
11997
+ }
11671
11998
  setToolbarVariant("select-frame");
11672
11999
  setToolbarRect(el.getBoundingClientRect());
11673
12000
  setToolbarShowEditLink(false);
11674
12001
  setActiveCommands(/* @__PURE__ */ new Set());
11675
- }, [deactivate, markSelected]);
11676
- const activate = (0, import_react11.useCallback)((el, options) => {
12002
+ }, [deactivate, markSelected, postToParent2]);
12003
+ const activate = (0, import_react12.useCallback)((el, options) => {
11677
12004
  if (activeElRef.current === el) return;
11678
12005
  clearSelectedAttr();
11679
12006
  selectedElRef.current = null;
@@ -11722,7 +12049,9 @@ function OhhwellsBridge() {
11722
12049
  setToolbarShowEditLink(Boolean(getHrefKeyFromElement(el)));
11723
12050
  const navAnchor = getNavigationItemAnchor(el);
11724
12051
  if (navAnchor) {
11725
- setNavGroupForceOpen(navAnchor, navItemOwnsDropdownPanel(navAnchor));
12052
+ if (isNestedNavChild(navAnchor)) {
12053
+ setNavGroupForceOpen(navAnchor, true);
12054
+ }
11726
12055
  setReorderHrefKey(null);
11727
12056
  setReorderDragDisabled(false);
11728
12057
  } else {
@@ -11747,7 +12076,7 @@ function OhhwellsBridge() {
11747
12076
  selectRef.current = select;
11748
12077
  selectFrameRef.current = selectFrame;
11749
12078
  deselectRef.current = deselect;
11750
- (0, import_react11.useLayoutEffect)(() => {
12079
+ (0, import_react12.useLayoutEffect)(() => {
11751
12080
  if (!subdomain || isEditMode) {
11752
12081
  setFetchState("done");
11753
12082
  return;
@@ -11818,7 +12147,7 @@ function OhhwellsBridge() {
11818
12147
  cancelled = true;
11819
12148
  };
11820
12149
  }, [subdomain, isEditMode]);
11821
- (0, import_react11.useEffect)(() => {
12150
+ (0, import_react12.useEffect)(() => {
11822
12151
  if (!subdomain || isEditMode) return;
11823
12152
  let debounceTimer = null;
11824
12153
  let observer = null;
@@ -11869,16 +12198,16 @@ function OhhwellsBridge() {
11869
12198
  if (debounceTimer) clearTimeout(debounceTimer);
11870
12199
  };
11871
12200
  }, [subdomain, isEditMode, pathname]);
11872
- (0, import_react11.useLayoutEffect)(() => {
12201
+ (0, import_react12.useLayoutEffect)(() => {
11873
12202
  const el = document.getElementById("ohw-loader");
11874
12203
  if (!el) return;
11875
12204
  const visible = Boolean(subdomain) && fetchState !== "done";
11876
12205
  el.style.display = visible ? "flex" : "none";
11877
12206
  }, [subdomain, fetchState]);
11878
- (0, import_react11.useEffect)(() => {
12207
+ (0, import_react12.useEffect)(() => {
11879
12208
  postToParent2({ type: "ow:navigation", path: pathname });
11880
12209
  }, [pathname, postToParent2]);
11881
- (0, import_react11.useEffect)(() => {
12210
+ (0, import_react12.useEffect)(() => {
11882
12211
  if (!isEditMode) return;
11883
12212
  if (linkPopoverSessionRef.current?.intent === "add-nav") return;
11884
12213
  if (document.querySelector("[data-ohw-section-picker]")) return;
@@ -11886,7 +12215,7 @@ function OhhwellsBridge() {
11886
12215
  deselectRef.current();
11887
12216
  deactivateRef.current();
11888
12217
  }, [pathname, isEditMode]);
11889
- (0, import_react11.useEffect)(() => {
12218
+ (0, import_react12.useEffect)(() => {
11890
12219
  const contentForNav = () => {
11891
12220
  if (isEditMode) return editContentRef.current;
11892
12221
  if (!subdomain) return {};
@@ -11951,7 +12280,7 @@ function OhhwellsBridge() {
11951
12280
  observer?.disconnect();
11952
12281
  };
11953
12282
  }, [isEditMode, pathname, subdomain, fetchState, resyncSelectedNavigationItem]);
11954
- (0, import_react11.useEffect)(() => {
12283
+ (0, import_react12.useEffect)(() => {
11955
12284
  if (!isEditMode) return;
11956
12285
  const measure = () => {
11957
12286
  const h = document.body.scrollHeight;
@@ -11975,7 +12304,7 @@ function OhhwellsBridge() {
11975
12304
  window.removeEventListener("resize", handleResize);
11976
12305
  };
11977
12306
  }, [pathname, isEditMode, postToParent2]);
11978
- (0, import_react11.useEffect)(() => {
12307
+ (0, import_react12.useEffect)(() => {
11979
12308
  if (!subdomainFromQuery || isEditMode) return;
11980
12309
  const handleClick = (e) => {
11981
12310
  const anchor = e.target.closest("a");
@@ -11991,7 +12320,7 @@ function OhhwellsBridge() {
11991
12320
  document.addEventListener("click", handleClick, true);
11992
12321
  return () => document.removeEventListener("click", handleClick, true);
11993
12322
  }, [subdomainFromQuery, isEditMode, router]);
11994
- (0, import_react11.useEffect)(() => {
12323
+ (0, import_react12.useEffect)(() => {
11995
12324
  if (!isEditMode) {
11996
12325
  editStylesRef.current?.base.remove();
11997
12326
  editStylesRef.current?.forceHover.remove();
@@ -12296,7 +12625,7 @@ function OhhwellsBridge() {
12296
12625
  if (selected === target || selected.contains(target)) return;
12297
12626
  }
12298
12627
  if (linkPopoverOpenRef.current) {
12299
- setLinkPopoverRef.current(null);
12628
+ closeLinkPopoverRef.current();
12300
12629
  return;
12301
12630
  }
12302
12631
  deselectRef.current();
@@ -13197,7 +13526,7 @@ function OhhwellsBridge() {
13197
13526
  if (Date.now() < linkPopoverGraceUntilRef.current) return;
13198
13527
  if (document.querySelector("[data-ohw-section-picker]")) return;
13199
13528
  if (linkPopoverOpenRef.current) {
13200
- setLinkPopoverRef.current(null);
13529
+ closeLinkPopoverRef.current();
13201
13530
  return;
13202
13531
  }
13203
13532
  deselectRef.current();
@@ -13216,7 +13545,7 @@ function OhhwellsBridge() {
13216
13545
  if (e.data?.type !== "ui:escape") return;
13217
13546
  if (document.querySelector("[data-ohw-more-menu]")) return;
13218
13547
  if (linkPopoverOpenRef.current) {
13219
- setLinkPopoverRef.current(null);
13548
+ closeLinkPopoverRef.current();
13220
13549
  return;
13221
13550
  }
13222
13551
  if (activeElRef.current) {
@@ -13279,7 +13608,7 @@ function OhhwellsBridge() {
13279
13608
  return;
13280
13609
  }
13281
13610
  if (e.key === "Escape" && linkPopoverOpenRef.current) {
13282
- setLinkPopoverRef.current(null);
13611
+ closeLinkPopoverRef.current();
13283
13612
  return;
13284
13613
  }
13285
13614
  if (e.key === "Escape" && selectedElRef.current && !activeElRef.current) {
@@ -13360,8 +13689,7 @@ function OhhwellsBridge() {
13360
13689
  const handleScroll = () => {
13361
13690
  const focusEl = activeElRef.current ?? selectedElRef.current;
13362
13691
  if (focusEl) {
13363
- const measureEl = activeElRef.current ? getEditMeasureEl(activeElRef.current) : focusEl;
13364
- const r2 = measureEl.getBoundingClientRect();
13692
+ const r2 = activeElRef.current ? getEditMeasureEl(activeElRef.current).getBoundingClientRect() : focusEl.getBoundingClientRect();
13365
13693
  applyToolbarPos(r2);
13366
13694
  setToolbarRect(r2);
13367
13695
  setMaxBadge((prev) => prev && activeElRef.current ? { ...prev, rect: r2 } : prev);
@@ -13776,7 +14104,7 @@ function OhhwellsBridge() {
13776
14104
  if (imageShowTimerRef.current) clearTimeout(imageShowTimerRef.current);
13777
14105
  };
13778
14106
  }, [isEditMode, refreshStateRules]);
13779
- (0, import_react11.useEffect)(() => {
14107
+ (0, import_react12.useEffect)(() => {
13780
14108
  if (!isEditMode) return;
13781
14109
  const THRESHOLD = 10;
13782
14110
  const resolveWasSelected = (el) => {
@@ -13930,7 +14258,7 @@ function OhhwellsBridge() {
13930
14258
  unlockFooterDragInteraction();
13931
14259
  };
13932
14260
  }, [isEditMode]);
13933
- (0, import_react11.useEffect)(() => {
14261
+ (0, import_react12.useEffect)(() => {
13934
14262
  const handler = (e) => {
13935
14263
  if (e.data?.type !== "ow:request-schedule-config") return;
13936
14264
  const insertAfterVal = e.data.insertAfter;
@@ -13946,7 +14274,7 @@ function OhhwellsBridge() {
13946
14274
  window.addEventListener("message", handler);
13947
14275
  return () => window.removeEventListener("message", handler);
13948
14276
  }, [processConfigRequest]);
13949
- (0, import_react11.useEffect)(() => {
14277
+ (0, import_react12.useEffect)(() => {
13950
14278
  if (!isEditMode) return;
13951
14279
  document.querySelectorAll("[data-ohw-active-state]").forEach((el) => {
13952
14280
  el.removeAttribute("data-ohw-active-state");
@@ -13982,13 +14310,13 @@ function OhhwellsBridge() {
13982
14310
  clearTimeout(timer);
13983
14311
  };
13984
14312
  }, [pathname, isEditMode, refreshStateRules, postToParent2]);
13985
- (0, import_react11.useEffect)(() => {
14313
+ (0, import_react12.useEffect)(() => {
13986
14314
  scrollToHashSectionWhenReady();
13987
14315
  const onHashChange = () => scrollToHashSectionWhenReady();
13988
14316
  window.addEventListener("hashchange", onHashChange);
13989
14317
  return () => window.removeEventListener("hashchange", onHashChange);
13990
14318
  }, [pathname]);
13991
- const handleCommand = (0, import_react11.useCallback)((cmd) => {
14319
+ const handleCommand = (0, import_react12.useCallback)((cmd) => {
13992
14320
  const el = activeElRef.current;
13993
14321
  const selBefore = window.getSelection();
13994
14322
  let savedOffsets = null;
@@ -14024,7 +14352,7 @@ function OhhwellsBridge() {
14024
14352
  if (el) setToolbarRect(getEditMeasureEl(el).getBoundingClientRect());
14025
14353
  refreshActiveCommandsRef.current();
14026
14354
  }, []);
14027
- const handleStateChange = (0, import_react11.useCallback)((state) => {
14355
+ const handleStateChange = (0, import_react12.useCallback)((state) => {
14028
14356
  if (!activeStateElRef.current) return;
14029
14357
  const el = activeStateElRef.current;
14030
14358
  if (state === "Default") {
@@ -14037,11 +14365,26 @@ function OhhwellsBridge() {
14037
14365
  }
14038
14366
  setToggleState((prev) => prev ? { ...prev, activeState: state } : null);
14039
14367
  }, [deactivate]);
14040
- const closeLinkPopover = (0, import_react11.useCallback)(() => {
14368
+ const reselectAfterLinkPopover = (0, import_react12.useCallback)(
14369
+ (hrefKey) => {
14370
+ requestAnimationFrame(() => {
14371
+ const el = resolveHrefKeyElement(hrefKey);
14372
+ if (el && isNavigationItem2(el)) selectRef.current(el);
14373
+ });
14374
+ },
14375
+ [resolveHrefKeyElement]
14376
+ );
14377
+ const closeLinkPopover = (0, import_react12.useCallback)(() => {
14378
+ const session = linkPopoverSessionRef.current;
14041
14379
  addNavAfterAnchorRef.current = null;
14042
14380
  setLinkPopover(null);
14043
- }, []);
14044
- const openLinkPopoverForActive = (0, import_react11.useCallback)(() => {
14381
+ if (session && session.intent !== "add-nav" && session.key) {
14382
+ reselectAfterLinkPopover(session.key);
14383
+ }
14384
+ }, [reselectAfterLinkPopover]);
14385
+ const closeLinkPopoverRef = (0, import_react12.useRef)(closeLinkPopover);
14386
+ closeLinkPopoverRef.current = closeLinkPopover;
14387
+ const openLinkPopoverForActive = (0, import_react12.useCallback)(() => {
14045
14388
  const hrefCtx = getHrefKeyFromElement(activeElRef.current);
14046
14389
  if (!hrefCtx) return;
14047
14390
  bumpLinkPopoverGrace();
@@ -14052,7 +14395,7 @@ function OhhwellsBridge() {
14052
14395
  });
14053
14396
  deactivate();
14054
14397
  }, [deactivate]);
14055
- const openLinkPopoverForSelected = (0, import_react11.useCallback)(() => {
14398
+ const openLinkPopoverForSelected = (0, import_react12.useCallback)(() => {
14056
14399
  const anchor = selectedElRef.current;
14057
14400
  if (!anchor) return;
14058
14401
  const key = anchor.getAttribute("data-ohw-href-key");
@@ -14065,7 +14408,7 @@ function OhhwellsBridge() {
14065
14408
  });
14066
14409
  deselect();
14067
14410
  }, [deselect]);
14068
- const handleSelectParent = (0, import_react11.useCallback)(() => {
14411
+ const handleSelectParent = (0, import_react12.useCallback)(() => {
14069
14412
  const selected = selectedElRef.current;
14070
14413
  if (!selected) return;
14071
14414
  if (toolbarVariantRef.current === "select-frame") {
@@ -14092,7 +14435,7 @@ function OhhwellsBridge() {
14092
14435
  }
14093
14436
  deselectRef.current();
14094
14437
  }, []);
14095
- const handleDuplicateSelected = (0, import_react11.useCallback)(() => {
14438
+ const handleDuplicateSelected = (0, import_react12.useCallback)(() => {
14096
14439
  const selected = selectedElRef.current;
14097
14440
  if (!selected || !isNavigationItem2(selected)) return;
14098
14441
  const hrefKey = selected.getAttribute("data-ohw-href-key");
@@ -14142,8 +14485,15 @@ function OhhwellsBridge() {
14142
14485
  };
14143
14486
  postToParent2({ type: "ow:change", nodes });
14144
14487
  enforceLinkHrefs();
14488
+ if (isNestedNavChild(selected) || navItemOwnsDropdownPanel(selected)) {
14489
+ setNavGroupForceOpen(selected, true);
14490
+ }
14145
14491
  requestAnimationFrame(() => {
14146
14492
  selectRef.current(result.anchor);
14493
+ requestAnimationFrame(() => {
14494
+ const el = selectedElRef.current;
14495
+ if (el?.isConnected) setToolbarRect(el.getBoundingClientRect());
14496
+ });
14147
14497
  });
14148
14498
  return;
14149
14499
  }
@@ -14175,7 +14525,7 @@ function OhhwellsBridge() {
14175
14525
  });
14176
14526
  }
14177
14527
  }, [postToParent2]);
14178
- const runPendingDeleteUndo = (0, import_react11.useCallback)(() => {
14528
+ const runPendingDeleteUndo = (0, import_react12.useCallback)(() => {
14179
14529
  const pending = pendingDeleteUndoRef.current;
14180
14530
  if (!pending) return false;
14181
14531
  pendingDeleteUndoRef.current = null;
@@ -14183,7 +14533,7 @@ function OhhwellsBridge() {
14183
14533
  enforceLinkHrefs();
14184
14534
  return true;
14185
14535
  }, []);
14186
- const handleDeleteSelected = (0, import_react11.useCallback)(() => {
14536
+ const handleDeleteSelected = (0, import_react12.useCallback)(() => {
14187
14537
  const selected = selectedElRef.current;
14188
14538
  if (!selected) return false;
14189
14539
  return deleteSelectedNavFooterItem({
@@ -14204,7 +14554,7 @@ function OhhwellsBridge() {
14204
14554
  }, [postToParent2]);
14205
14555
  handleDeleteSelectedRef.current = handleDeleteSelected;
14206
14556
  runPendingDeleteUndoRef.current = runPendingDeleteUndo;
14207
- const handleLinkPopoverSubmit = (0, import_react11.useCallback)(
14557
+ const handleLinkPopoverSubmit = (0, import_react12.useCallback)(
14208
14558
  (target) => {
14209
14559
  const session = linkPopoverSessionRef.current;
14210
14560
  if (!session) return;
@@ -14257,31 +14607,31 @@ function OhhwellsBridge() {
14257
14607
  applyLinkByKey(key, target);
14258
14608
  editContentRef.current = { ...editContentRef.current, [key]: target };
14259
14609
  postToParent2({ type: "ow:change", nodes: [{ key, text: target }] });
14260
- const anchor = document.querySelector(`[data-ohw-href-key="${CSS.escape(key)}"]`) ?? null;
14610
+ const anchor = resolveHrefKeyElement(key);
14261
14611
  if (target.trim()) {
14262
14612
  if (anchor) maybeWarnNavLinkDropdownConflict(anchor);
14263
- postToParent2({ type: "ow:toast", title: "Link added", toastType: "success" });
14613
+ postToParent2({ type: "ow:toast", title: "Link updated", toastType: "success" });
14264
14614
  }
14265
14615
  setLinkPopover(null);
14266
14616
  },
14267
- [maybeWarnNavLinkDropdownConflict, postToParent2, sitePages, sectionsByPath]
14617
+ [maybeWarnNavLinkDropdownConflict, postToParent2, resolveHrefKeyElement, sitePages, sectionsByPath]
14268
14618
  );
14269
14619
  const showEditLink = toolbarShowEditLink;
14270
14620
  const currentSections = sectionsByPath[pathname] ?? [];
14271
14621
  linkPopoverOpenRef.current = linkPopover !== null;
14272
- const handleMediaReplace = (0, import_react11.useCallback)(
14622
+ const handleMediaReplace = (0, import_react12.useCallback)(
14273
14623
  (key) => {
14274
14624
  postToParent2({ type: "ow:image-pick", key, elementType: mediaHover?.elementType ?? "image" });
14275
14625
  },
14276
14626
  [postToParent2, mediaHover?.elementType]
14277
14627
  );
14278
- const handleEditCarousel = (0, import_react11.useCallback)(
14628
+ const handleEditCarousel = (0, import_react12.useCallback)(
14279
14629
  (key) => {
14280
14630
  postToParent2({ type: "ow:carousel-open", key, images: readCarouselValue(key) });
14281
14631
  },
14282
14632
  [postToParent2]
14283
14633
  );
14284
- const handleMediaFadeOutComplete = (0, import_react11.useCallback)((key) => {
14634
+ const handleMediaFadeOutComplete = (0, import_react12.useCallback)((key) => {
14285
14635
  setUploadingRects((prev) => {
14286
14636
  if (!(key in prev)) return prev;
14287
14637
  const next = { ...prev };
@@ -14289,7 +14639,7 @@ function OhhwellsBridge() {
14289
14639
  return next;
14290
14640
  });
14291
14641
  }, []);
14292
- const handleVideoSettingsChange = (0, import_react11.useCallback)(
14642
+ const handleVideoSettingsChange = (0, import_react12.useCallback)(
14293
14643
  (key, settings) => {
14294
14644
  document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
14295
14645
  const video = getVideoEl2(el);
@@ -14395,8 +14745,9 @@ function OhhwellsBridge() {
14395
14745
  ItemInteractionLayer,
14396
14746
  {
14397
14747
  rect: isItemDragging && draggedItemRect && (footerDragRef.current?.wasSelected || navDragRef.current?.wasSelected) ? draggedItemRect : toolbarRect,
14748
+ toolbarBelowRect: selectedElRef.current && isNavigationItem2(selectedElRef.current) ? getOpenNavDropdownPanelRect(selectedElRef.current) : null,
14398
14749
  elRef: glowElRef,
14399
- state: isItemDragging ? "dragging" : resolveItemInteractionState(toolbarRect, parentScrollRef.current),
14750
+ state: isItemDragging ? "dragging" : selectedElRef.current && isNavigationItem2(selectedElRef.current) && getOpenNavDropdownPanelRect(selectedElRef.current) ? "active-bottom" : resolveItemInteractionState(toolbarRect, parentScrollRef.current),
14400
14751
  showHandle: toolbarVariant === "link-action" && Boolean(reorderHrefKey) || toolbarVariant === "select-frame" && isFooterFrameSelection,
14401
14752
  dragDisabled: reorderDragDisabled,
14402
14753
  dragHandleLabel: reorderHrefKey ? `Reorder ${reorderHrefKey}` : "Reorder item",
@@ -14417,11 +14768,15 @@ function OhhwellsBridge() {
14417
14768
  editLinkDisabled: false,
14418
14769
  moreDisabled: false,
14419
14770
  duplicateDisabled: isFooterFrameSelection,
14420
- showEditLink: !isFooterFrameSelection,
14771
+ showEditLink: !isFooterFrameSelection && navDropdownPreviewOpen === null,
14421
14772
  showAddItem: isFooterFrameSelection || !selectedIsCta && Boolean(
14422
14773
  selectedElRef.current && isNavbarHrefKey(selectedElRef.current.getAttribute("data-ohw-href-key")) && !isNestedNavChild(selectedElRef.current)
14423
14774
  ),
14424
- showMore: !selectedIsCta || isFooterFrameSelection
14775
+ showMore: !selectedIsCta || isFooterFrameSelection,
14776
+ dropdownOpen: navDropdownPreviewOpen,
14777
+ onDropdownOpenChange: handleNavDropdownOpenChange,
14778
+ headingVisible: footerHeadingVisible,
14779
+ onHeadingVisibleChange: handleFooterHeadingVisibleChange
14425
14780
  }
14426
14781
  ) : void 0
14427
14782
  }