@ohhwells/bridge 0.1.160 → 0.1.161

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.js CHANGED
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
 
3
3
  // src/OhhwellsBridge.tsx
4
- import React12, { useCallback as useCallback12, useEffect as useEffect17, useLayoutEffect as useLayoutEffect6, useRef as useRef14, useState as useState18 } from "react";
4
+ import React12, { useCallback as useCallback12, useEffect as useEffect19, useLayoutEffect as useLayoutEffect6, useRef as useRef14, useState as useState18 } from "react";
5
5
  import { createRoot as createRoot3 } from "react-dom/client";
6
6
  import { flushSync as flushSync3 } from "react-dom";
7
7
 
@@ -11993,8 +11993,136 @@ function useSavedLinkNavigation(isEditMode) {
11993
11993
  }, [isEditMode, router]);
11994
11994
  }
11995
11995
 
11996
+ // src/useNavDropdownToggle.ts
11997
+ import { useEffect as useEffect3 } from "react";
11998
+ import { usePathname } from "next/navigation";
11999
+ var OPEN_ATTR = "data-ohw-nav-force-open";
12000
+ function parentLinkWithDropdown(target) {
12001
+ const anchor = target?.closest?.("a");
12002
+ const group = anchor?.parentElement;
12003
+ if (!anchor || !group?.matches("[data-ohw-nav-group]:not([data-ohw-nav-dropdown-template])")) {
12004
+ return null;
12005
+ }
12006
+ const hasChildren = group.querySelector(":scope > [data-ohw-nav-children] > [data-ohw-href-key]");
12007
+ return hasChildren ? anchor : null;
12008
+ }
12009
+ function closeAll(except) {
12010
+ document.querySelectorAll(`[${OPEN_ATTR}]`).forEach((group) => {
12011
+ if (group === except) return;
12012
+ group.removeAttribute(OPEN_ATTR);
12013
+ group.querySelector(":scope > a")?.setAttribute("aria-expanded", "false");
12014
+ });
12015
+ }
12016
+ function useNavDropdownToggle(isEditMode) {
12017
+ const pathname = usePathname();
12018
+ useEffect3(() => {
12019
+ if (isEditMode) return;
12020
+ const onClick = (e) => {
12021
+ if (e.button !== 0 || e.metaKey || e.ctrlKey || e.shiftKey || e.altKey) return;
12022
+ const anchor = parentLinkWithDropdown(e.target);
12023
+ if (!anchor) {
12024
+ const insideOpen = e.target?.closest?.(`[${OPEN_ATTR}]`);
12025
+ const onChildLink = e.target?.closest?.("[data-ohw-nav-children] a");
12026
+ if (!insideOpen || onChildLink) closeAll();
12027
+ return;
12028
+ }
12029
+ e.preventDefault();
12030
+ e.stopPropagation();
12031
+ const group = anchor.parentElement;
12032
+ const open = !group.hasAttribute(OPEN_ATTR);
12033
+ closeAll(group);
12034
+ group.toggleAttribute(OPEN_ATTR, open);
12035
+ anchor.setAttribute("aria-expanded", String(open));
12036
+ };
12037
+ const onKeyDown = (e) => {
12038
+ if (e.key !== "Escape") return;
12039
+ const open = document.querySelector(`[${OPEN_ATTR}] > a`);
12040
+ closeAll();
12041
+ open?.focus();
12042
+ };
12043
+ window.addEventListener("click", onClick, true);
12044
+ window.addEventListener("keydown", onKeyDown);
12045
+ return () => {
12046
+ window.removeEventListener("click", onClick, true);
12047
+ window.removeEventListener("keydown", onKeyDown);
12048
+ };
12049
+ }, [isEditMode]);
12050
+ useEffect3(() => {
12051
+ if (!isEditMode) closeAll();
12052
+ }, [pathname, isEditMode]);
12053
+ }
12054
+
12055
+ // src/useHashLinkScroll.ts
12056
+ import { useEffect as useEffect4 } from "react";
12057
+
12058
+ // src/lib/scroll-to-section.ts
12059
+ var MAX_ATTEMPTS = 12;
12060
+ var RETRY_MS = 100;
12061
+ function getHashSectionId() {
12062
+ if (typeof window === "undefined") return null;
12063
+ const id = window.location.hash.replace(/^#/, "").trim();
12064
+ return id || null;
12065
+ }
12066
+ function scrollToOhwSection(sectionId, behavior = "smooth") {
12067
+ if (!sectionId || typeof document === "undefined") return false;
12068
+ const el = document.querySelector(`[data-ohw-section="${CSS.escape(sectionId)}"]`);
12069
+ if (!el) return false;
12070
+ el.scrollIntoView({ behavior, block: "start" });
12071
+ return true;
12072
+ }
12073
+ function scrollToHashSectionWhenReady(behavior = "smooth") {
12074
+ const id = getHashSectionId();
12075
+ if (!id) return;
12076
+ let attempt = 0;
12077
+ const tick = () => {
12078
+ if (scrollToOhwSection(id, behavior)) return;
12079
+ attempt += 1;
12080
+ if (attempt < MAX_ATTEMPTS) window.setTimeout(tick, RETRY_MS);
12081
+ };
12082
+ tick();
12083
+ }
12084
+ function scrollToOhwSectionAfterNavigation(sectionId, behavior = "smooth") {
12085
+ let attempt = 0;
12086
+ const tick = () => {
12087
+ if (getHashSectionId() === sectionId && scrollToOhwSection(sectionId, behavior)) return;
12088
+ attempt += 1;
12089
+ if (attempt < MAX_ATTEMPTS) window.setTimeout(tick, RETRY_MS);
12090
+ };
12091
+ window.setTimeout(tick, 0);
12092
+ }
12093
+
12094
+ // src/useHashLinkScroll.ts
12095
+ function samePageSectionId(anchor) {
12096
+ const href = anchor.getAttribute("href");
12097
+ if (!href || !href.includes("#")) return null;
12098
+ if (anchor.target !== "" && anchor.target !== "_self") return null;
12099
+ let url;
12100
+ try {
12101
+ url = new URL(href, window.location.href);
12102
+ } catch {
12103
+ return null;
12104
+ }
12105
+ if (url.origin !== window.location.origin || url.pathname !== window.location.pathname) return null;
12106
+ const id = decodeURIComponent(url.hash.replace(/^#/, "")).trim();
12107
+ return id || null;
12108
+ }
12109
+ function useHashLinkScroll(isEditMode) {
12110
+ useEffect4(() => {
12111
+ if (isEditMode) return;
12112
+ const onClick = (e) => {
12113
+ if (e.button !== 0 || e.metaKey || e.ctrlKey || e.shiftKey || e.altKey) return;
12114
+ const anchor = e.target?.closest?.("a");
12115
+ if (!anchor) return;
12116
+ const id = samePageSectionId(anchor);
12117
+ if (id) scrollToOhwSectionAfterNavigation(id);
12118
+ };
12119
+ window.addEventListener("click", onClick, true);
12120
+ return () => window.removeEventListener("click", onClick, true);
12121
+ }, [isEditMode]);
12122
+ }
12123
+
11996
12124
  // src/ui/SchedulingWidget.tsx
11997
- import { useCallback, useEffect as useEffect3, useId, useMemo, useRef, useState as useState3 } from "react";
12125
+ import { useCallback, useEffect as useEffect5, useId, useMemo, useRef, useState as useState3 } from "react";
11998
12126
 
11999
12127
  // src/ui/EmailCaptureModal.tsx
12000
12128
  import { useState as useState2 } from "react";
@@ -12312,7 +12440,7 @@ function ScheduleView({ schedule, dates, selectedIdx, onSelectDate, onOpenModal
12312
12440
  setCanScrollLeft(el.scrollLeft > 0);
12313
12441
  setCanScrollRight(el.scrollLeft + el.clientWidth < el.scrollWidth - 1);
12314
12442
  };
12315
- useEffect3(() => {
12443
+ useEffect5(() => {
12316
12444
  const el = scrollRef.current;
12317
12445
  if (!el) return;
12318
12446
  updateScrollState();
@@ -12570,7 +12698,7 @@ function SchedulingWidget({ notifyOnConnect = false, initialScheduleId, insertAf
12570
12698
  });
12571
12699
  }, []);
12572
12700
  const [selectedIdx, setSelectedIdx] = useState3(0);
12573
- useEffect3(() => {
12701
+ useEffect5(() => {
12574
12702
  if (!schedule?.classes) return;
12575
12703
  for (let i = 0; i < dates.length; i++) {
12576
12704
  if (schedule.classes.some((c) => classRunsOnDate(c, dates[i], schedule.type))) {
@@ -12579,7 +12707,7 @@ function SchedulingWidget({ notifyOnConnect = false, initialScheduleId, insertAf
12579
12707
  }
12580
12708
  }
12581
12709
  }, [schedule, dates]);
12582
- useEffect3(() => {
12710
+ useEffect5(() => {
12583
12711
  if (typeof window === "undefined") return;
12584
12712
  const onVisible = () => {
12585
12713
  if (!document.hidden) void refetchLiveSchedule();
@@ -12591,7 +12719,7 @@ function SchedulingWidget({ notifyOnConnect = false, initialScheduleId, insertAf
12591
12719
  document.removeEventListener("visibilitychange", onVisible);
12592
12720
  };
12593
12721
  }, [refetchLiveSchedule]);
12594
- useEffect3(() => {
12722
+ useEffect5(() => {
12595
12723
  if (typeof window === "undefined") return;
12596
12724
  const isInEditor = window.self !== window.top;
12597
12725
  setInEditor(isInEditor);
@@ -17225,7 +17353,7 @@ function apiBase() {
17225
17353
  function bridgeVersion() {
17226
17354
  try {
17227
17355
  if (true) {
17228
- return "0.1.160";
17356
+ return "0.1.161";
17229
17357
  }
17230
17358
  } catch {
17231
17359
  }
@@ -17239,7 +17367,7 @@ function stampBridgeVersionOnDocument() {
17239
17367
  return;
17240
17368
  }
17241
17369
  try {
17242
- const v = true ? "0.1.160" : "";
17370
+ const v = true ? "0.1.161" : "";
17243
17371
  if (v) {
17244
17372
  document.documentElement.setAttribute("data-ohw-bridge-version", v);
17245
17373
  window.__OHW_BRIDGE_VERSION__ = v;
@@ -18146,7 +18274,7 @@ function CarouselOverlay({
18146
18274
  }
18147
18275
 
18148
18276
  // src/ui/ai-section/AiSectionOverlay.tsx
18149
- import { useCallback as useCallback2, useEffect as useEffect5, useRef as useRef4, useState as useState7 } from "react";
18277
+ import { useCallback as useCallback2, useEffect as useEffect7, useRef as useRef4, useState as useState7 } from "react";
18150
18278
  import { Check, X } from "lucide-react";
18151
18279
 
18152
18280
  // src/lib/ai-change-highlight.ts
@@ -18242,7 +18370,7 @@ function readRect(instanceId) {
18242
18370
  }
18243
18371
  function useLiveSectionRect(sectionId) {
18244
18372
  const [rect, setRect] = useState7(null);
18245
- useEffect5(() => {
18373
+ useEffect7(() => {
18246
18374
  if (!sectionId) {
18247
18375
  setRect(null);
18248
18376
  return;
@@ -18282,7 +18410,7 @@ function readNavToggleRect() {
18282
18410
  }
18283
18411
  function useLiveNavToggleHole(active) {
18284
18412
  const [rect, setRect] = useState7(null);
18285
- useEffect5(() => {
18413
+ useEffect7(() => {
18286
18414
  if (!active) {
18287
18415
  setRect(null);
18288
18416
  return;
@@ -18406,7 +18534,7 @@ function AiSectionOverlay({
18406
18534
  reviewIdRef.current = reviewId;
18407
18535
  const selectedIdRef = useRef4(null);
18408
18536
  selectedIdRef.current = selectedId;
18409
- useEffect5(() => {
18537
+ useEffect7(() => {
18410
18538
  onSelectionChange?.(selectedId);
18411
18539
  }, [selectedId, onSelectionChange]);
18412
18540
  const report = useCallback2(
@@ -18432,7 +18560,7 @@ function AiSectionOverlay({
18432
18560
  },
18433
18561
  [report]
18434
18562
  );
18435
- useEffect5(() => {
18563
+ useEffect7(() => {
18436
18564
  apiRef.current = {
18437
18565
  selectFromElement,
18438
18566
  handleBackgroundClick: (target, clientX, clientY) => {
@@ -18457,7 +18585,7 @@ function AiSectionOverlay({
18457
18585
  apiRef.current = null;
18458
18586
  };
18459
18587
  }, [apiRef, selectFromElement, report]);
18460
- useEffect5(() => {
18588
+ useEffect7(() => {
18461
18589
  const onMessage = (e) => {
18462
18590
  if (e.data?.type === "ow:ai-select" && e.data.sectionId === null) {
18463
18591
  selectedIdRef.current = null;
@@ -18482,9 +18610,9 @@ function AiSectionOverlay({
18482
18610
  window.addEventListener("message", onMessage);
18483
18611
  return () => window.removeEventListener("message", onMessage);
18484
18612
  }, [postToParent2]);
18485
- useEffect5(() => installAiChangeHighlight(), []);
18613
+ useEffect7(() => installAiChangeHighlight(), []);
18486
18614
  const [hoveredId, setHoveredId] = useState7(null);
18487
- useEffect5(() => {
18615
+ useEffect7(() => {
18488
18616
  const onMove = (e) => {
18489
18617
  const t = e.target;
18490
18618
  if (!(t instanceof Element)) return;
@@ -18509,7 +18637,7 @@ function AiSectionOverlay({
18509
18637
  document.documentElement.removeEventListener("mouseleave", onLeave);
18510
18638
  };
18511
18639
  }, []);
18512
- useEffect5(() => {
18640
+ useEffect7(() => {
18513
18641
  const onKeyDown = (e) => {
18514
18642
  if (e.key !== "Escape") return;
18515
18643
  if (reviewIdRef.current) return;
@@ -18533,7 +18661,7 @@ function AiSectionOverlay({
18533
18661
  [postToParent2]
18534
18662
  );
18535
18663
  const [navDropdownForceOpen, setNavDropdownForceOpen] = useState7(false);
18536
- useEffect5(() => {
18664
+ useEffect7(() => {
18537
18665
  const update = () => {
18538
18666
  setNavDropdownForceOpen(Boolean(document.querySelector("[data-ohw-nav-force-open]")));
18539
18667
  };
@@ -18552,7 +18680,7 @@ function AiSectionOverlay({
18552
18680
  const navToggleHole = useLiveNavToggleHole(Boolean(reviewId));
18553
18681
  const hoverRect = useLiveSectionRect(reviewId || hoveredId === selectedId ? null : hoveredId);
18554
18682
  const showSelectionBorder = Boolean(selectionRect) && !navDropdownForceOpen;
18555
- useEffect5(() => {
18683
+ useEffect7(() => {
18556
18684
  const selectedEl = activeSelectionId ? findSectionElement(activeSelectionId) : null;
18557
18685
  if (!activeSelectionId || !selectionRect || selectedEl && isChromeSection(selectedEl)) {
18558
18686
  postToParent2({ type: "ow:section-rect", instanceId: null, rect: null });
@@ -18672,7 +18800,7 @@ function AiSectionOverlay({
18672
18800
  }
18673
18801
 
18674
18802
  // src/ui/ai-section/AiMediaStripOverlay.tsx
18675
- import { useCallback as useCallback3, useEffect as useEffect6, useRef as useRef5, useState as useState8 } from "react";
18803
+ import { useCallback as useCallback3, useEffect as useEffect8, useRef as useRef5, useState as useState8 } from "react";
18676
18804
  import { Star } from "lucide-react";
18677
18805
 
18678
18806
  // src/lib/ai-media-strip-tree.ts
@@ -18835,7 +18963,7 @@ function readRect2(ref) {
18835
18963
  }
18836
18964
  function useLiveItemRect(ref) {
18837
18965
  const [rect, setRect] = useState8(null);
18838
- useEffect6(() => {
18966
+ useEffect8(() => {
18839
18967
  if (!ref) {
18840
18968
  setRect(null);
18841
18969
  return;
@@ -18931,7 +19059,7 @@ function Pill({
18931
19059
  }
18932
19060
  function AltInput({ value, onCommit }) {
18933
19061
  const [draft, setDraft] = useState8(value);
18934
- useEffect6(() => setDraft(value), [value]);
19062
+ useEffect8(() => setDraft(value), [value]);
18935
19063
  return /* @__PURE__ */ jsxs11(
18936
19064
  "div",
18937
19065
  {
@@ -19020,7 +19148,7 @@ var HTTP_URL_RE = /^https?:\/\/\S+$/i;
19020
19148
  function LinkInput({ value, onCommit }) {
19021
19149
  const [draft, setDraft] = useState8(value);
19022
19150
  const [invalid, setInvalid] = useState8(false);
19023
- useEffect6(() => {
19151
+ useEffect8(() => {
19024
19152
  setDraft(value);
19025
19153
  setInvalid(false);
19026
19154
  }, [value]);
@@ -19215,7 +19343,7 @@ function AiMediaStripOverlay({
19215
19343
  const [error, setError] = useState8(null);
19216
19344
  const activeRef = useRef5(null);
19217
19345
  activeRef.current = active;
19218
- useEffect6(() => {
19346
+ useEffect8(() => {
19219
19347
  const onMove = (e) => {
19220
19348
  const t = e.target;
19221
19349
  if (!(t instanceof HTMLElement)) return;
@@ -19245,7 +19373,7 @@ function AiMediaStripOverlay({
19245
19373
  document.documentElement.removeEventListener("mouseleave", onLeave);
19246
19374
  };
19247
19375
  }, []);
19248
- useEffect6(() => {
19376
+ useEffect8(() => {
19249
19377
  const onClick = (e) => {
19250
19378
  const current = activeRef.current;
19251
19379
  if (!current) return;
@@ -19260,7 +19388,7 @@ function AiMediaStripOverlay({
19260
19388
  document.addEventListener("click", onClick, true);
19261
19389
  return () => document.removeEventListener("click", onClick, true);
19262
19390
  }, []);
19263
- useEffect6(() => {
19391
+ useEffect8(() => {
19264
19392
  const onBlur = () => {
19265
19393
  if (!activeRef.current) return;
19266
19394
  setActive(null);
@@ -19269,7 +19397,7 @@ function AiMediaStripOverlay({
19269
19397
  window.addEventListener("blur", onBlur);
19270
19398
  return () => window.removeEventListener("blur", onBlur);
19271
19399
  }, []);
19272
- useEffect6(() => {
19400
+ useEffect8(() => {
19273
19401
  const onKeyDown = (e) => {
19274
19402
  if (e.key !== "Escape") return;
19275
19403
  if (!activeRef.current) return;
@@ -19433,7 +19561,7 @@ function AiMediaStripOverlay({
19433
19561
  }
19434
19562
 
19435
19563
  // src/ui/ai-section/AiPricingCardOverlay.tsx
19436
- import { useCallback as useCallback4, useEffect as useEffect7, useLayoutEffect as useLayoutEffect4, useRef as useRef6, useState as useState9 } from "react";
19564
+ import { useCallback as useCallback4, useEffect as useEffect9, useLayoutEffect as useLayoutEffect4, useRef as useRef6, useState as useState9 } from "react";
19437
19565
  import { Check as Check2, ChevronDown as ChevronDown3, Minus, Plus as Plus2, Star as Star2 } from "lucide-react";
19438
19566
  import { Fragment as Fragment8, jsx as jsx21, jsxs as jsxs12 } from "react/jsx-runtime";
19439
19567
  var PRIMARY4 = "var(--ohw-primary, #0885FE)";
@@ -19477,7 +19605,7 @@ function readGridRect(ref) {
19477
19605
  }
19478
19606
  function useLiveCardRect(ref, grid = false) {
19479
19607
  const [rect, setRect] = useState9(null);
19480
- useEffect7(() => {
19608
+ useEffect9(() => {
19481
19609
  if (!ref) {
19482
19610
  setRect(null);
19483
19611
  return;
@@ -19771,7 +19899,7 @@ function AiPricingCardOverlay({
19771
19899
  const [error, setError] = useState9(null);
19772
19900
  const activeRef = useRef6(null);
19773
19901
  activeRef.current = active;
19774
- useEffect7(() => {
19902
+ useEffect9(() => {
19775
19903
  const onMove = (e) => {
19776
19904
  const ref = cardRefFromTarget(e.target);
19777
19905
  const t = e.target;
@@ -19789,7 +19917,7 @@ function AiPricingCardOverlay({
19789
19917
  document.documentElement.removeEventListener("mouseleave", onLeave);
19790
19918
  };
19791
19919
  }, []);
19792
- useEffect7(() => {
19920
+ useEffect9(() => {
19793
19921
  const onClick = (e) => {
19794
19922
  const t = e.target;
19795
19923
  if (!(t instanceof Element)) return;
@@ -19801,7 +19929,7 @@ function AiPricingCardOverlay({
19801
19929
  document.addEventListener("click", onClick, true);
19802
19930
  return () => document.removeEventListener("click", onClick, true);
19803
19931
  }, []);
19804
- useEffect7(() => {
19932
+ useEffect9(() => {
19805
19933
  const onBlur = () => {
19806
19934
  if (!activeRef.current) return;
19807
19935
  setActive(null);
@@ -19810,7 +19938,7 @@ function AiPricingCardOverlay({
19810
19938
  window.addEventListener("blur", onBlur);
19811
19939
  return () => window.removeEventListener("blur", onBlur);
19812
19940
  }, []);
19813
- useEffect7(() => {
19941
+ useEffect9(() => {
19814
19942
  const onKeyDown = (e) => {
19815
19943
  if (e.key !== "Escape") return;
19816
19944
  if (!activeRef.current) return;
@@ -19915,7 +20043,7 @@ function AiPricingCardOverlay({
19915
20043
  }
19916
20044
 
19917
20045
  // src/ui/ai-section/AiVideoOverlay.tsx
19918
- import { useCallback as useCallback5, useEffect as useEffect8, useRef as useRef7, useState as useState10 } from "react";
20046
+ import { useCallback as useCallback5, useEffect as useEffect10, useRef as useRef7, useState as useState10 } from "react";
19919
20047
  import { Star as Star3 } from "lucide-react";
19920
20048
 
19921
20049
  // src/lib/ai-video-tree.ts
@@ -20009,7 +20137,7 @@ function readRect4(ref) {
20009
20137
  }
20010
20138
  function useLiveBlockRect(ref) {
20011
20139
  const [rect, setRect] = useState10(null);
20012
- useEffect8(() => {
20140
+ useEffect10(() => {
20013
20141
  if (!ref) {
20014
20142
  setRect(null);
20015
20143
  return;
@@ -20089,7 +20217,7 @@ function watchUrl(id) {
20089
20217
  function VideoUrlInput({ value, onCommit }) {
20090
20218
  const [draft, setDraft] = useState10(value ? watchUrl(value) : "");
20091
20219
  const [invalid, setInvalid] = useState10(false);
20092
- useEffect8(() => {
20220
+ useEffect10(() => {
20093
20221
  setDraft(value ? watchUrl(value) : "");
20094
20222
  setInvalid(false);
20095
20223
  }, [value]);
@@ -20232,7 +20360,7 @@ function AiVideoOverlay({
20232
20360
  const [error, setError] = useState10(null);
20233
20361
  const activeRef = useRef7(null);
20234
20362
  activeRef.current = active;
20235
- useEffect8(() => {
20363
+ useEffect10(() => {
20236
20364
  const onMove = (e) => {
20237
20365
  const t = e.target;
20238
20366
  if (!(t instanceof HTMLElement)) return;
@@ -20262,7 +20390,7 @@ function AiVideoOverlay({
20262
20390
  document.documentElement.removeEventListener("mouseleave", onLeave);
20263
20391
  };
20264
20392
  }, []);
20265
- useEffect8(() => {
20393
+ useEffect10(() => {
20266
20394
  const onClick = (e) => {
20267
20395
  const current = activeRef.current;
20268
20396
  if (!current) return;
@@ -20277,7 +20405,7 @@ function AiVideoOverlay({
20277
20405
  document.addEventListener("click", onClick, true);
20278
20406
  return () => document.removeEventListener("click", onClick, true);
20279
20407
  }, []);
20280
- useEffect8(() => {
20408
+ useEffect10(() => {
20281
20409
  const onBlur = () => {
20282
20410
  if (!activeRef.current) return;
20283
20411
  setActive(null);
@@ -20286,7 +20414,7 @@ function AiVideoOverlay({
20286
20414
  window.addEventListener("blur", onBlur);
20287
20415
  return () => window.removeEventListener("blur", onBlur);
20288
20416
  }, []);
20289
- useEffect8(() => {
20417
+ useEffect10(() => {
20290
20418
  const onKeyDown = (e) => {
20291
20419
  if (e.key !== "Escape") return;
20292
20420
  if (!activeRef.current) return;
@@ -20395,7 +20523,7 @@ function AiVideoOverlay({
20395
20523
  }
20396
20524
 
20397
20525
  // src/ui/ai-section/AiFadeCarouselOverlay.tsx
20398
- import { useCallback as useCallback6, useEffect as useEffect9, useRef as useRef8, useState as useState11 } from "react";
20526
+ import { useCallback as useCallback6, useEffect as useEffect11, useRef as useRef8, useState as useState11 } from "react";
20399
20527
  import { Star as Star4 } from "lucide-react";
20400
20528
 
20401
20529
  // src/lib/ai-carousel-tree.ts
@@ -20469,7 +20597,7 @@ function readRect5(ref) {
20469
20597
  }
20470
20598
  function useLiveItemRect2(ref) {
20471
20599
  const [rect, setRect] = useState11(null);
20472
- useEffect9(() => {
20600
+ useEffect11(() => {
20473
20601
  if (!ref) {
20474
20602
  setRect(null);
20475
20603
  return;
@@ -20685,10 +20813,10 @@ function AiFadeCarouselOverlay({
20685
20813
  const skeletonRef = useRef8(null);
20686
20814
  const activeRef = useRef8(null);
20687
20815
  activeRef.current = active;
20688
- useEffect9(() => {
20816
+ useEffect11(() => {
20689
20817
  setAutoplayOverride(null);
20690
20818
  }, [active?.sectionId, active?.index]);
20691
- useEffect9(() => {
20819
+ useEffect11(() => {
20692
20820
  if (!swapping?.fadingOut || !skeletonRef.current) return;
20693
20821
  const anim = skeletonRef.current.animate([{ opacity: 1 }, { opacity: 0 }], {
20694
20822
  duration: MEDIA_UPLOAD_FADE_MS,
@@ -20698,7 +20826,7 @@ function AiFadeCarouselOverlay({
20698
20826
  anim.finished.then(() => setSwapping(null)).catch(() => setSwapping(null));
20699
20827
  return () => anim.cancel();
20700
20828
  }, [swapping?.fadingOut]);
20701
- useEffect9(() => {
20829
+ useEffect11(() => {
20702
20830
  const onMove = (e) => {
20703
20831
  const t = e.target;
20704
20832
  if (!(t instanceof Element)) return;
@@ -20732,7 +20860,7 @@ function AiFadeCarouselOverlay({
20732
20860
  document.documentElement.removeEventListener("mouseleave", onLeave);
20733
20861
  };
20734
20862
  }, []);
20735
- useEffect9(() => {
20863
+ useEffect11(() => {
20736
20864
  const onClick = (e) => {
20737
20865
  const current = activeRef.current;
20738
20866
  if (!current) return;
@@ -20747,7 +20875,7 @@ function AiFadeCarouselOverlay({
20747
20875
  document.addEventListener("click", onClick, true);
20748
20876
  return () => document.removeEventListener("click", onClick, true);
20749
20877
  }, []);
20750
- useEffect9(() => {
20878
+ useEffect11(() => {
20751
20879
  const onBlur = () => {
20752
20880
  if (!activeRef.current) return;
20753
20881
  setActive(null);
@@ -20756,7 +20884,7 @@ function AiFadeCarouselOverlay({
20756
20884
  window.addEventListener("blur", onBlur);
20757
20885
  return () => window.removeEventListener("blur", onBlur);
20758
20886
  }, []);
20759
- useEffect9(() => {
20887
+ useEffect11(() => {
20760
20888
  const onKeyDown = (e) => {
20761
20889
  if (e.key !== "Escape") return;
20762
20890
  if (!activeRef.current) return;
@@ -20910,7 +21038,7 @@ function AiFadeCarouselOverlay({
20910
21038
 
20911
21039
  // src/OhhwellsBridge.tsx
20912
21040
  import { createPortal as createPortal3 } from "react-dom";
20913
- import { usePathname as usePathname2, useRouter as useRouter3, useSearchParams } from "next/navigation";
21041
+ import { usePathname as usePathname3, useRouter as useRouter3, useSearchParams } from "next/navigation";
20914
21042
 
20915
21043
  // src/lib/media-overlay-guards.ts
20916
21044
  var BRIDGE_CHROME_SELECTOR = [
@@ -21052,35 +21180,8 @@ function mergePrefetchedSections(prev, fetched, livePath, liveSections) {
21052
21180
  return next;
21053
21181
  }
21054
21182
 
21055
- // src/lib/scroll-to-section.ts
21056
- var MAX_ATTEMPTS = 12;
21057
- var RETRY_MS = 100;
21058
- function getHashSectionId() {
21059
- if (typeof window === "undefined") return null;
21060
- const id = window.location.hash.replace(/^#/, "").trim();
21061
- return id || null;
21062
- }
21063
- function scrollToOhwSection(sectionId, behavior = "smooth") {
21064
- if (!sectionId || typeof document === "undefined") return false;
21065
- const el = document.querySelector(`[data-ohw-section="${CSS.escape(sectionId)}"]`);
21066
- if (!el) return false;
21067
- el.scrollIntoView({ behavior, block: "start" });
21068
- return true;
21069
- }
21070
- function scrollToHashSectionWhenReady(behavior = "smooth") {
21071
- const id = getHashSectionId();
21072
- if (!id) return;
21073
- let attempt = 0;
21074
- const tick = () => {
21075
- if (scrollToOhwSection(id, behavior)) return;
21076
- attempt += 1;
21077
- if (attempt < MAX_ATTEMPTS) window.setTimeout(tick, RETRY_MS);
21078
- };
21079
- tick();
21080
- }
21081
-
21082
21183
  // src/ui/link-modal/LinkPopover.tsx
21083
- import { useEffect as useEffect13 } from "react";
21184
+ import { useEffect as useEffect15 } from "react";
21084
21185
 
21085
21186
  // src/ui/dialog.tsx
21086
21187
  import * as React9 from "react";
@@ -21280,7 +21381,7 @@ function SectionTreeItem({
21280
21381
  }
21281
21382
 
21282
21383
  // src/ui/link-modal/UrlOrPageInput.tsx
21283
- import { useEffect as useEffect10, useId as useId2, useRef as useRef9, useState as useState12 } from "react";
21384
+ import { useEffect as useEffect12, useId as useId2, useRef as useRef9, useState as useState12 } from "react";
21284
21385
 
21285
21386
  // src/ui/input.tsx
21286
21387
  import * as React10 from "react";
@@ -21352,7 +21453,7 @@ function UrlOrPageInput({
21352
21453
  const inputRef = useRef9(null);
21353
21454
  const rootRef = useRef9(null);
21354
21455
  const [isFocused, setIsFocused] = useState12(false);
21355
- useEffect10(() => {
21456
+ useEffect12(() => {
21356
21457
  if (!dropdownOpen) return;
21357
21458
  const isOutside = (e) => {
21358
21459
  const root = rootRef.current;
@@ -21560,10 +21661,10 @@ function LinkEditorPanel({ state, onClose }) {
21560
21661
  }
21561
21662
 
21562
21663
  // src/ui/link-modal/SectionPickerOverlay.tsx
21563
- import { useCallback as useCallback7, useEffect as useEffect11, useMemo as useMemo2, useRef as useRef10, useState as useState13 } from "react";
21664
+ import { useCallback as useCallback7, useEffect as useEffect13, useMemo as useMemo2, useRef as useRef10, useState as useState13 } from "react";
21564
21665
  import { createPortal as createPortal2 } from "react-dom";
21565
21666
  import { ArrowLeft as ArrowLeft2, Check as Check3 } from "lucide-react";
21566
- import { usePathname, useRouter as useRouter2 } from "next/navigation";
21667
+ import { usePathname as usePathname2, useRouter as useRouter2 } from "next/navigation";
21567
21668
 
21568
21669
  // src/lib/parent-scroll.ts
21569
21670
  function visibleBand(parentScroll) {
@@ -21622,7 +21723,7 @@ function useSectionRects(sectionIdsKey, enabled) {
21622
21723
  () => sectionIdsKey ? sectionIdsKey.split("\0") : [],
21623
21724
  [sectionIdsKey]
21624
21725
  );
21625
- useEffect11(() => {
21726
+ useEffect13(() => {
21626
21727
  if (!enabled || sectionIds.length === 0) {
21627
21728
  setRects((prev) => prev.size === 0 ? prev : /* @__PURE__ */ new Map());
21628
21729
  return;
@@ -21662,7 +21763,7 @@ function SectionPickerOverlay({
21662
21763
  onSelect
21663
21764
  }) {
21664
21765
  const router = useRouter2();
21665
- const pathname = usePathname();
21766
+ const pathname = usePathname2();
21666
21767
  const [selectedId, setSelectedId] = useState13(null);
21667
21768
  const [hoveredId, setHoveredId] = useState13(null);
21668
21769
  const pointerRef = useRef10(null);
@@ -21677,12 +21778,12 @@ function SectionPickerOverlay({
21677
21778
  );
21678
21779
  const normalizedTarget = normalizePath(pagePath);
21679
21780
  const isOnTargetPage = normalizePath(pathname) === normalizedTarget;
21680
- useEffect11(() => {
21781
+ useEffect13(() => {
21681
21782
  if (isOnTargetPage) return;
21682
21783
  const search = readPreservedSearch();
21683
21784
  router.push(`${normalizedTarget}${search}`);
21684
21785
  }, [isOnTargetPage, normalizedTarget, router]);
21685
- useEffect11(() => {
21786
+ useEffect13(() => {
21686
21787
  document.documentElement.setAttribute("data-ohw-section-picking", "");
21687
21788
  document.querySelectorAll("[data-ohw-hovered]").forEach((el) => {
21688
21789
  el.removeAttribute("data-ohw-hovered");
@@ -21720,7 +21821,7 @@ function SectionPickerOverlay({
21720
21821
  },
21721
21822
  []
21722
21823
  );
21723
- useEffect11(() => {
21824
+ useEffect13(() => {
21724
21825
  const applyClip = (iframeOffsetTop, visibleCanvasTop, canvasH, promptBarH = 0) => {
21725
21826
  const next = getIframeVisibleClip({
21726
21827
  iframeOffsetTop,
@@ -21764,12 +21865,12 @@ function SectionPickerOverlay({
21764
21865
  window.removeEventListener("resize", onResize);
21765
21866
  };
21766
21867
  }, [applyHoverAt]);
21767
- useEffect11(() => {
21868
+ useEffect13(() => {
21768
21869
  const ptr = pointerRef.current;
21769
21870
  if (!ptr) return;
21770
21871
  applyHoverAt(ptr.x, ptr.y, rects);
21771
21872
  }, [rects, applyHoverAt]);
21772
- useEffect11(() => {
21873
+ useEffect13(() => {
21773
21874
  const rememberPointer = (clientX, clientY) => {
21774
21875
  pointerRef.current = { x: clientX, y: clientY };
21775
21876
  const top = iframeOffsetTopRef.current;
@@ -21801,7 +21902,7 @@ function SectionPickerOverlay({
21801
21902
  },
21802
21903
  [selectedId, onSelect]
21803
21904
  );
21804
- useEffect11(() => {
21905
+ useEffect13(() => {
21805
21906
  const onKeyDown = (e) => {
21806
21907
  if (e.key === "Escape") {
21807
21908
  e.preventDefault();
@@ -21924,7 +22025,7 @@ function SectionPickerOverlay({
21924
22025
  }
21925
22026
 
21926
22027
  // src/ui/link-modal/useLinkModalState.ts
21927
- import { useCallback as useCallback8, useEffect as useEffect12, useMemo as useMemo3, useState as useState14 } from "react";
22028
+ import { useCallback as useCallback8, useEffect as useEffect14, useMemo as useMemo3, useState as useState14 } from "react";
21928
22029
  function useLinkModalState({
21929
22030
  open,
21930
22031
  mode,
@@ -21951,7 +22052,7 @@ function useLinkModalState({
21951
22052
  setDropdownOpen(false);
21952
22053
  setUrlError("");
21953
22054
  }, []);
21954
- useEffect12(() => {
22055
+ useEffect14(() => {
21955
22056
  if (!open) return;
21956
22057
  if (mode === "edit" && initialTarget) {
21957
22058
  const { pageRoute } = parseTarget(initialTarget);
@@ -22117,7 +22218,7 @@ function LinkPopover({
22117
22218
  onSubmit
22118
22219
  });
22119
22220
  const sectionPickerActive = state.showSectionPicker && Boolean(state.selectedPage);
22120
- useEffect13(() => {
22221
+ useEffect15(() => {
22121
22222
  if (!open) return;
22122
22223
  if (sectionPickerActive) {
22123
22224
  postToParent({ type: "ui:unlock" });
@@ -22360,7 +22461,7 @@ function addFooterColumnWithPersist({
22360
22461
  // src/ui/FloatingPanel.tsx
22361
22462
  import {
22362
22463
  useCallback as useCallback9,
22363
- useEffect as useEffect14,
22464
+ useEffect as useEffect16,
22364
22465
  useLayoutEffect as useLayoutEffect5,
22365
22466
  useRef as useRef11,
22366
22467
  useState as useState15
@@ -22444,10 +22545,10 @@ function FloatingPanel({
22444
22545
  x: clampX(home.x, measured.w),
22445
22546
  y: fittedY
22446
22547
  };
22447
- useEffect14(() => {
22548
+ useEffect16(() => {
22448
22549
  setLiveScroll(parentScroll);
22449
22550
  }, [parentScroll]);
22450
- useEffect14(() => {
22551
+ useEffect16(() => {
22451
22552
  if (!open) return;
22452
22553
  const onParentScroll = (e) => {
22453
22554
  if (e.data?.type !== "ow:parent-scroll") return;
@@ -22532,11 +22633,11 @@ function FloatingPanel({
22532
22633
  } catch {
22533
22634
  }
22534
22635
  }, []);
22535
- useEffect14(() => {
22636
+ useEffect16(() => {
22536
22637
  if (open) return;
22537
22638
  document.documentElement.removeAttribute("data-ohw-panel-dragging");
22538
22639
  }, [open]);
22539
- useEffect14(() => () => document.documentElement.removeAttribute("data-ohw-panel-dragging"), []);
22640
+ useEffect16(() => () => document.documentElement.removeAttribute("data-ohw-panel-dragging"), []);
22540
22641
  if (!open) return null;
22541
22642
  return /* @__PURE__ */ jsxs22(
22542
22643
  "div",
@@ -23056,7 +23157,7 @@ function hitTestNavDropSlot(clientX, clientY, draggedHrefKey, draggedEl) {
23056
23157
  }
23057
23158
 
23058
23159
  // src/useNavItemDrag.ts
23059
- import { useCallback as useCallback10, useEffect as useEffect15, useRef as useRef12, useState as useState16 } from "react";
23160
+ import { useCallback as useCallback10, useEffect as useEffect17, useRef as useRef12, useState as useState16 } from "react";
23060
23161
  function useNavItemDrag({
23061
23162
  isEditMode,
23062
23163
  editContentRef,
@@ -23289,7 +23390,7 @@ function useNavItemDrag({
23289
23390
  },
23290
23391
  []
23291
23392
  );
23292
- useEffect15(() => {
23393
+ useEffect17(() => {
23293
23394
  if (!isEditMode) return;
23294
23395
  const THRESHOLD = 10;
23295
23396
  const resolveWasSelected = (el) => {
@@ -23448,7 +23549,7 @@ function useNavItemDrag({
23448
23549
  }
23449
23550
 
23450
23551
  // src/useSectionDrag.ts
23451
- import { useCallback as useCallback11, useEffect as useEffect16, useRef as useRef13, useState as useState17 } from "react";
23552
+ import { useCallback as useCallback11, useEffect as useEffect18, useRef as useRef13, useState as useState17 } from "react";
23452
23553
 
23453
23554
  // src/lib/section-dnd.ts
23454
23555
  function isFooterSection(el) {
@@ -23668,7 +23769,7 @@ function useSectionDrag({
23668
23769
  },
23669
23770
  [footerDragRef, navDragRef]
23670
23771
  );
23671
- useEffect16(() => {
23772
+ useEffect18(() => {
23672
23773
  if (!isEditMode) return;
23673
23774
  const onPointerDown = (e) => {
23674
23775
  if (e.button !== 0) return;
@@ -25596,12 +25697,12 @@ function resolveSubdomain(subdomainFromQuery) {
25596
25697
  return "";
25597
25698
  }
25598
25699
  function OhhwellsBridge() {
25599
- const pathname = usePathname2();
25700
+ const pathname = usePathname3();
25600
25701
  const router = useRouter3();
25601
25702
  const searchParams = useSearchParams();
25602
25703
  const isEditMode = isEditSessionActive();
25603
25704
  const [bridgeRoot, setBridgeRoot] = useState18(null);
25604
- useEffect17(() => {
25705
+ useEffect19(() => {
25605
25706
  const figtreeFontId = "ohw-figtree-font";
25606
25707
  if (!document.getElementById(figtreeFontId)) {
25607
25708
  const preconnect1 = Object.assign(document.createElement("link"), { rel: "preconnect", href: "https://fonts.googleapis.com" });
@@ -25640,7 +25741,7 @@ function OhhwellsBridge() {
25640
25741
  }, 0);
25641
25742
  return () => window.clearTimeout(t);
25642
25743
  }, [subdomainFromQuery, subdomain]);
25643
- useEffect17(() => {
25744
+ useEffect19(() => {
25644
25745
  if (!subdomainFromQuery || typeof window === "undefined") return;
25645
25746
  const url = new URL(window.location.href);
25646
25747
  if (!url.searchParams.has("subdomain")) return;
@@ -25650,6 +25751,8 @@ function OhhwellsBridge() {
25650
25751
  }, [subdomainFromQuery]);
25651
25752
  useLinkHrefGuardian(pathname, subdomain, isEditMode);
25652
25753
  useSavedLinkNavigation(isEditMode);
25754
+ useNavDropdownToggle(isEditMode);
25755
+ useHashLinkScroll(isEditMode);
25653
25756
  const postToParent2 = useCallback12((data) => {
25654
25757
  if (typeof window !== "undefined" && window.parent !== window) {
25655
25758
  window.parent.postMessage(data, "*");
@@ -25658,14 +25761,14 @@ function OhhwellsBridge() {
25658
25761
  const [fetchState, setFetchState] = useState18("idle");
25659
25762
  const [showBranding, setShowBranding] = useState18(false);
25660
25763
  const autoSaveTimers = useRef14(/* @__PURE__ */ new Map());
25661
- useEffect17(() => {
25764
+ useEffect19(() => {
25662
25765
  stampBridgeVersionOnDocument();
25663
25766
  }, []);
25664
- useEffect17(() => {
25767
+ useEffect19(() => {
25665
25768
  if (isEditMode) return;
25666
25769
  return armLoaderHangBeacon(subdomain, fetchState);
25667
25770
  }, [isEditMode, subdomain, fetchState]);
25668
- useEffect17(() => {
25771
+ useEffect19(() => {
25669
25772
  if (isEditMode || !subdomain) return;
25670
25773
  const onError = (event) => {
25671
25774
  reportOutageBeacon({
@@ -25806,7 +25909,7 @@ function OhhwellsBridge() {
25806
25909
  }, []);
25807
25910
  const selectMediaElementRef = useRef14(selectMediaElement);
25808
25911
  selectMediaElementRef.current = selectMediaElement;
25809
- useEffect17(() => {
25912
+ useEffect19(() => {
25810
25913
  if (!selectedMedia) return;
25811
25914
  const update = () => {
25812
25915
  const el = selectedMediaElRef.current;
@@ -26021,7 +26124,7 @@ function OhhwellsBridge() {
26021
26124
  const [fieldDragging, setFieldDragging] = useState18(false);
26022
26125
  const clearFormPickRef = useRef14(clearFormPick);
26023
26126
  clearFormPickRef.current = clearFormPick;
26024
- useEffect17(() => {
26127
+ useEffect19(() => {
26025
26128
  const el = fieldPickElRef.current;
26026
26129
  if (!el || fieldPickRect === null) return;
26027
26130
  const observer = new ResizeObserver(() => {
@@ -26030,7 +26133,7 @@ function OhhwellsBridge() {
26030
26133
  observer.observe(el);
26031
26134
  return () => observer.disconnect();
26032
26135
  }, [fieldPickRect !== null, fieldPickState]);
26033
- useEffect17(() => {
26136
+ useEffect19(() => {
26034
26137
  const el = formPickElRef.current;
26035
26138
  if (!el || formPickRect === null) return;
26036
26139
  const observer = new ResizeObserver(() => {
@@ -26057,7 +26160,7 @@ function OhhwellsBridge() {
26057
26160
  const hoveredItemElRef = useRef14(null);
26058
26161
  const [hoveredItemRect, setHoveredItemRect] = useState18(null);
26059
26162
  const [hoveredTextRect, setHoveredTextRect] = useState18(null);
26060
- useEffect17(() => {
26163
+ useEffect19(() => {
26061
26164
  const sync = () => {
26062
26165
  const el = document.querySelector(
26063
26166
  '[data-ohw-hovered]:not([contenteditable]):not([data-ohw-href-key]):not([data-ohw-editable="form"] *)'
@@ -26157,7 +26260,7 @@ function OhhwellsBridge() {
26157
26260
  const linkPopoverGraceUntilRef = useRef14(0);
26158
26261
  setLinkPopoverRef.current = setLinkPopover;
26159
26262
  linkPopoverSessionRef.current = linkPopover;
26160
- useEffect17(() => {
26263
+ useEffect19(() => {
26161
26264
  setSectionOrderPersistHandler((entries) => {
26162
26265
  const currentPath = window.location.pathname;
26163
26266
  const merged = mergePageSectionOrder(editContentRef.current[SECTION_ORDER_KEY], currentPath, entries);
@@ -26167,7 +26270,7 @@ function OhhwellsBridge() {
26167
26270
  });
26168
26271
  return () => setSectionOrderPersistHandler(null);
26169
26272
  }, []);
26170
- useEffect17(() => {
26273
+ useEffect19(() => {
26171
26274
  setAiFooterMountOptions({
26172
26275
  resolvePageHref: (pageOrAnchorId) => {
26173
26276
  const [pageId, anchor] = pageOrAnchorId.split("#");
@@ -26251,7 +26354,7 @@ function OhhwellsBridge() {
26251
26354
  }, [isEditMode, pathname]);
26252
26355
  const runSectionsPrefetchRef = useRef14(runSectionsPrefetch);
26253
26356
  runSectionsPrefetchRef.current = runSectionsPrefetch;
26254
- useEffect17(() => {
26357
+ useEffect19(() => {
26255
26358
  if (!linkPopover) {
26256
26359
  document.documentElement.removeAttribute("data-ohw-link-popover-open");
26257
26360
  return;
@@ -26279,7 +26382,7 @@ function OhhwellsBridge() {
26279
26382
  document.documentElement.removeAttribute("data-ohw-link-popover-open");
26280
26383
  };
26281
26384
  }, [linkPopover, postToParent2]);
26282
- useEffect17(() => {
26385
+ useEffect19(() => {
26283
26386
  if (!isEditMode) return;
26284
26387
  const useFixtures = shouldUseDevFixtures();
26285
26388
  if (useFixtures) {
@@ -26305,14 +26408,14 @@ function OhhwellsBridge() {
26305
26408
  if (!useFixtures) postToParent2({ type: "ow:request-site-pages" });
26306
26409
  return () => window.removeEventListener("message", onSitePages);
26307
26410
  }, [isEditMode, postToParent2]);
26308
- useEffect17(() => {
26411
+ useEffect19(() => {
26309
26412
  if (!isEditMode || shouldUseDevFixtures()) return;
26310
26413
  void loadAllSectionsManifest().then((manifest) => {
26311
26414
  if (Object.keys(manifest).length === 0) return;
26312
26415
  setSectionsByPath((prev) => ({ ...manifest, ...prev }));
26313
26416
  });
26314
26417
  }, [isEditMode]);
26315
- useEffect17(() => {
26418
+ useEffect19(() => {
26316
26419
  const update = () => {
26317
26420
  const el = activeElRef.current ?? selectedElRef.current;
26318
26421
  if (el) setToolbarRect(getEditMeasureEl(el).getBoundingClientRect());
@@ -27571,7 +27674,7 @@ function OhhwellsBridge() {
27571
27674
  },
27572
27675
  [postToParent2]
27573
27676
  );
27574
- useEffect17(() => {
27677
+ useEffect19(() => {
27575
27678
  const onDragOver = (e) => {
27576
27679
  const dragged = buttonCollectionDragRef.current;
27577
27680
  if (!dragged) return;
@@ -27642,7 +27745,7 @@ function OhhwellsBridge() {
27642
27745
  setLogoSizeDraft(null);
27643
27746
  deselectRef.current();
27644
27747
  }, []);
27645
- useEffect17(() => {
27748
+ useEffect19(() => {
27646
27749
  const session = floatingPanel && floatingPanel.kind === "logo-size" ? floatingPanel : null;
27647
27750
  if (!session || !logoSizeDraft) {
27648
27751
  postToParentRef.current({ type: "ow:logo-size-panel", open: false });
@@ -27800,7 +27903,7 @@ function OhhwellsBridge() {
27800
27903
  deselectRef.current = deselect;
27801
27904
  closeFloatingPanelOnlyRef.current = closeFloatingPanelOnly;
27802
27905
  const lastSiteWideScopeRef = useRef14(null);
27803
- useEffect17(() => {
27906
+ useEffect19(() => {
27804
27907
  if (!isEditMode) {
27805
27908
  if (lastSiteWideScopeRef.current !== false) {
27806
27909
  lastSiteWideScopeRef.current = false;
@@ -27977,7 +28080,7 @@ function OhhwellsBridge() {
27977
28080
  cancelled = true;
27978
28081
  };
27979
28082
  }, [subdomain, isEditMode]);
27980
- useEffect17(() => {
28083
+ useEffect19(() => {
27981
28084
  if (!isEditMode) return;
27982
28085
  const resolveIndex = (form, clientY) => {
27983
28086
  const wrappers = listFieldWrappers(form).filter((el) => fieldKeyOf(el) !== fieldDragRef.current?.key);
@@ -28018,7 +28121,7 @@ function OhhwellsBridge() {
28018
28121
  window.removeEventListener("drop", onDrop, true);
28019
28122
  };
28020
28123
  }, [buildFieldDropSlots, isEditMode, persistFields, selectField]);
28021
- useEffect17(() => {
28124
+ useEffect19(() => {
28022
28125
  if (!isEditMode) return;
28023
28126
  const mark = () => document.querySelectorAll('[data-ohw-editable="form"]').forEach((form) => {
28024
28127
  markFormFields(form);
@@ -28030,7 +28133,7 @@ function OhhwellsBridge() {
28030
28133
  });
28031
28134
  return () => observer.disconnect();
28032
28135
  }, [isEditMode, fetchState, pathname]);
28033
- useEffect17(() => {
28136
+ useEffect19(() => {
28034
28137
  if (!isEditMode) return;
28035
28138
  let saveTimer = null;
28036
28139
  const onInput = (e) => {
@@ -28052,14 +28155,14 @@ function OhhwellsBridge() {
28052
28155
  document.addEventListener("input", onInput, true);
28053
28156
  return () => document.removeEventListener("input", onInput, true);
28054
28157
  }, [isEditMode, persistFields]);
28055
- useEffect17(() => {
28158
+ useEffect19(() => {
28056
28159
  if (isEditMode || fetchState !== "done") return;
28057
28160
  const content = contentCache.get(subdomain) ?? {};
28058
28161
  document.querySelectorAll('[data-ohw-editable="form"]').forEach((form) => {
28059
28162
  reconcileFieldsFromContent(form, content);
28060
28163
  });
28061
28164
  }, [isEditMode, fetchState, subdomain]);
28062
- useEffect17(() => {
28165
+ useEffect19(() => {
28063
28166
  if (!isEditMode) return;
28064
28167
  const swallow = (e) => {
28065
28168
  const target = e.target;
@@ -28068,14 +28171,14 @@ function OhhwellsBridge() {
28068
28171
  document.addEventListener("submit", swallow, true);
28069
28172
  return () => document.removeEventListener("submit", swallow, true);
28070
28173
  }, [isEditMode]);
28071
- useEffect17(() => {
28174
+ useEffect19(() => {
28072
28175
  if (isEditMode || fetchState !== "done") return;
28073
28176
  console.log("env", process.env.NEXT_PUBLIC_FLOWOPS_API_URL);
28074
28177
  const apiUrl = process.env.NEXT_PUBLIC_FLOWOPS_API_URL ?? "https://flowops-backend-staging-2yfdh7pwpq-as.a.run.app";
28075
28178
  console.log({ apiUrl, subdomain });
28076
28179
  bindPublishedForms(apiUrl, subdomain, contentCache.get(subdomain) ?? {});
28077
28180
  }, [isEditMode, fetchState, subdomain]);
28078
- useEffect17(() => {
28181
+ useEffect19(() => {
28079
28182
  if (!subdomain || isEditMode) return;
28080
28183
  let debounceTimer = null;
28081
28184
  let observer = null;
@@ -28198,10 +28301,10 @@ function OhhwellsBridge() {
28198
28301
  const visible = Boolean(subdomain) && fetchState !== "done";
28199
28302
  el.style.display = visible ? "flex" : "none";
28200
28303
  }, [subdomain, fetchState]);
28201
- useEffect17(() => {
28304
+ useEffect19(() => {
28202
28305
  postToParent2({ type: "ow:navigation", path: pathname });
28203
28306
  }, [pathname, postToParent2]);
28204
- useEffect17(() => {
28307
+ useEffect19(() => {
28205
28308
  if (!subdomain || isEditMode) return;
28206
28309
  const content = contentCache.get(subdomain);
28207
28310
  if (!content) return;
@@ -28219,7 +28322,7 @@ function OhhwellsBridge() {
28219
28322
  }
28220
28323
  applyAiFooterFromContent(content);
28221
28324
  }, [pathname, subdomain, isEditMode]);
28222
- useEffect17(() => {
28325
+ useEffect19(() => {
28223
28326
  if (!isEditMode) return;
28224
28327
  if (linkPopoverSessionRef.current?.intent === "add-nav") return;
28225
28328
  if (document.querySelector("[data-ohw-section-picker]")) return;
@@ -28227,12 +28330,12 @@ function OhhwellsBridge() {
28227
28330
  deselectRef.current();
28228
28331
  deactivateRef.current();
28229
28332
  }, [pathname, isEditMode]);
28230
- useEffect17(() => {
28333
+ useEffect19(() => {
28231
28334
  if (!isEditMode) return;
28232
28335
  initSectionInstancesFromContent(editContentRef.current, pathname);
28233
28336
  initItemInstancesFromContent(editContentRef.current);
28234
28337
  }, [pathname, isEditMode]);
28235
- useEffect17(() => {
28338
+ useEffect19(() => {
28236
28339
  if (!isEditMode) return;
28237
28340
  const observer = new MutationObserver(() => {
28238
28341
  const drawer = document.querySelector("[data-ohw-nav-drawer]");
@@ -28243,7 +28346,7 @@ function OhhwellsBridge() {
28243
28346
  observer.observe(document.body, { childList: true, subtree: true });
28244
28347
  return () => observer.disconnect();
28245
28348
  }, [isEditMode, pathname]);
28246
- useEffect17(() => {
28349
+ useEffect19(() => {
28247
28350
  const contentForNav = () => {
28248
28351
  if (isEditMode) return editContentRef.current;
28249
28352
  if (!subdomain) return {};
@@ -28316,7 +28419,7 @@ function OhhwellsBridge() {
28316
28419
  observer?.disconnect();
28317
28420
  };
28318
28421
  }, [isEditMode, pathname, subdomain, fetchState, resyncSelectedNavigationItem]);
28319
- useEffect17(() => {
28422
+ useEffect19(() => {
28320
28423
  if (!isEditMode) return;
28321
28424
  let applying = false;
28322
28425
  let rafId = null;
@@ -28354,7 +28457,7 @@ function OhhwellsBridge() {
28354
28457
  observer.disconnect();
28355
28458
  };
28356
28459
  }, [isEditMode, pathname]);
28357
- useEffect17(() => {
28460
+ useEffect19(() => {
28358
28461
  if (!isEditMode) return;
28359
28462
  let lastPosted = 0;
28360
28463
  const measure = () => {
@@ -28398,7 +28501,7 @@ function OhhwellsBridge() {
28398
28501
  window.removeEventListener("resize", handleResize);
28399
28502
  };
28400
28503
  }, [pathname, isEditMode, postToParent2]);
28401
- useEffect17(() => {
28504
+ useEffect19(() => {
28402
28505
  if (isEditMode) return;
28403
28506
  const handleClick = (e) => {
28404
28507
  if (!isPlainLeftClick(e)) return;
@@ -28412,7 +28515,7 @@ function OhhwellsBridge() {
28412
28515
  document.addEventListener("click", handleClick, true);
28413
28516
  return () => document.removeEventListener("click", handleClick, true);
28414
28517
  }, [isEditMode, router, pathname]);
28415
- useEffect17(() => {
28518
+ useEffect19(() => {
28416
28519
  if (!isEditMode) {
28417
28520
  editStylesRef.current?.base.remove();
28418
28521
  editStylesRef.current?.forceHover.remove();
@@ -31867,7 +31970,7 @@ function OhhwellsBridge() {
31867
31970
  if (imageShowTimerRef.current) clearTimeout(imageShowTimerRef.current);
31868
31971
  };
31869
31972
  }, [isEditMode, refreshStateRules]);
31870
- useEffect17(() => {
31973
+ useEffect19(() => {
31871
31974
  if (!isEditMode) return;
31872
31975
  const THRESHOLD = 10;
31873
31976
  const resolveWasSelected = (el) => {
@@ -32023,7 +32126,7 @@ function OhhwellsBridge() {
32023
32126
  unlockFooterDragInteraction();
32024
32127
  };
32025
32128
  }, [isEditMode]);
32026
- useEffect17(() => {
32129
+ useEffect19(() => {
32027
32130
  if (!isEditMode) return;
32028
32131
  const THRESHOLD = 10;
32029
32132
  const onPointerDown = (e) => {
@@ -32114,7 +32217,7 @@ function OhhwellsBridge() {
32114
32217
  document.removeEventListener("selectstart", blockSelectStart, true);
32115
32218
  };
32116
32219
  }, [isEditMode, persistButtonCollectionDrag, refreshButtonDragVisuals]);
32117
- useEffect17(() => {
32220
+ useEffect19(() => {
32118
32221
  const handler = (e) => {
32119
32222
  if (e.data?.type !== "ow:request-schedule-config") return;
32120
32223
  const insertAfterVal = e.data.insertAfter;
@@ -32130,7 +32233,7 @@ function OhhwellsBridge() {
32130
32233
  window.addEventListener("message", handler);
32131
32234
  return () => window.removeEventListener("message", handler);
32132
32235
  }, [processConfigRequest]);
32133
- useEffect17(() => {
32236
+ useEffect19(() => {
32134
32237
  if (!isEditMode) return;
32135
32238
  document.querySelectorAll("[data-ohw-active-state]").forEach((el) => {
32136
32239
  el.removeAttribute("data-ohw-active-state");
@@ -32154,7 +32257,7 @@ function OhhwellsBridge() {
32154
32257
  postToParent2({
32155
32258
  type: "ow:ready",
32156
32259
  version: "1",
32157
- bridgeVersion: "0.1.160",
32260
+ bridgeVersion: "0.1.161",
32158
32261
  path: pathname,
32159
32262
  nodes: collectEditableNodes(editContentRef.current),
32160
32263
  sections
@@ -32166,7 +32269,7 @@ function OhhwellsBridge() {
32166
32269
  clearTimeout(timer);
32167
32270
  };
32168
32271
  }, [pathname, isEditMode, refreshStateRules, postToParent2]);
32169
- useEffect17(() => {
32272
+ useEffect19(() => {
32170
32273
  scrollToHashSectionWhenReady();
32171
32274
  const onHashChange = () => scrollToHashSectionWhenReady();
32172
32275
  window.addEventListener("hashchange", onHashChange);
@@ -32208,7 +32311,7 @@ function OhhwellsBridge() {
32208
32311
  if (el) setToolbarRect(getEditMeasureEl(el).getBoundingClientRect());
32209
32312
  refreshActiveCommandsRef.current();
32210
32313
  }, []);
32211
- useEffect17(() => {
32314
+ useEffect19(() => {
32212
32315
  const session = floatingPanel && floatingPanel.kind === "logo-size" ? floatingPanel : null;
32213
32316
  if (!session || !logoSizeDraft) return;
32214
32317
  const onPanelAction = (e) => {