@ohhwells/bridge 0.1.75 → 0.1.76

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
@@ -74,7 +74,7 @@ __export(index_exports, {
74
74
  module.exports = __toCommonJS(index_exports);
75
75
 
76
76
  // src/OhhwellsBridge.tsx
77
- var import_react16 = __toESM(require("react"), 1);
77
+ var import_react17 = __toESM(require("react"), 1);
78
78
  var import_client2 = require("react-dom/client");
79
79
  var import_react_dom3 = require("react-dom");
80
80
 
@@ -1420,6 +1420,7 @@ function applyAiSectionsToDom(state, options) {
1420
1420
  mounted.delete(entry.id);
1421
1421
  }
1422
1422
  container.setAttribute("data-ohw-section", entry.id);
1423
+ container.setAttribute("data-ohw-instance", entry.id);
1423
1424
  container.setAttribute("data-ohw-section-label", entry.label);
1424
1425
  placeContainer(container, entry);
1425
1426
  const root = mounted.get(entry.id)?.root ?? (0, import_client.createRoot)(container);
@@ -7390,6 +7391,9 @@ var import_lucide_react7 = require("lucide-react");
7390
7391
 
7391
7392
  // src/lib/sections.ts
7392
7393
  var LINK_PICKER_EXCLUDED_IDS = /* @__PURE__ */ new Set(["navbar", "footer"]);
7394
+ function isChromeSection(el) {
7395
+ return el.matches("header, nav, footer, aside");
7396
+ }
7393
7397
  function titleCaseSectionId(id) {
7394
7398
  return id.split("-").filter(Boolean).map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" ");
7395
7399
  }
@@ -7415,10 +7419,158 @@ function parseSectionsFromHtml(html) {
7415
7419
  return parseSectionsFromRoot(doc);
7416
7420
  }
7417
7421
 
7422
+ // src/lib/section-instances.ts
7423
+ var SECTION_ORDER_KEY = "__ohw_section_order";
7424
+ var REMOVED_ATTR2 = "data-ohw-section-removed";
7425
+ function isRemovedSection(el) {
7426
+ return el.hasAttribute(REMOVED_ATTR2);
7427
+ }
7428
+ function topLevelSections() {
7429
+ return Array.from(document.querySelectorAll("[data-ohw-section]")).filter(
7430
+ (el) => !el.parentElement?.closest("[data-ohw-section]") && !isChromeSection(el) && !isRemovedSection(el)
7431
+ );
7432
+ }
7433
+ function instanceIdOf(el) {
7434
+ return el.dataset.ohwInstance ?? el.dataset.ohwSection ?? "";
7435
+ }
7436
+ function planSectionMove(instanceId, targetIndex, currentPath) {
7437
+ const sections = topLevelSections();
7438
+ const index = sections.findIndex((el) => instanceIdOf(el) === instanceId);
7439
+ if (index === -1) return null;
7440
+ const dragged = sections[index];
7441
+ const others = sections.filter((_, i) => i !== index);
7442
+ const clamped = Math.max(0, Math.min(targetIndex, others.length));
7443
+ const reordered = [...others.slice(0, clamped), dragged, ...others.slice(clamped)];
7444
+ return reordered.map((el, order) => ({
7445
+ instanceId: instanceIdOf(el),
7446
+ type: el.getAttribute("data-ohw-section") ?? "",
7447
+ order,
7448
+ pagePath: currentPath
7449
+ }));
7450
+ }
7451
+ function moveSectionInstance(instanceId, direction, currentPath) {
7452
+ const sections = topLevelSections();
7453
+ const index = sections.findIndex((el) => instanceIdOf(el) === instanceId);
7454
+ if (index === -1) return null;
7455
+ const siblingIndex = direction === "up" ? index - 1 : index + 1;
7456
+ if (siblingIndex < 0 || siblingIndex >= sections.length) return null;
7457
+ const entries = planSectionMove(instanceId, siblingIndex, currentPath);
7458
+ if (!entries) return null;
7459
+ applyPersistedOrder(entries);
7460
+ return entries;
7461
+ }
7462
+ function syncRemovedFlags(entries) {
7463
+ const removedIds = new Set(entries.filter((e) => e.removed).map((e) => e.instanceId));
7464
+ document.querySelectorAll(`[${REMOVED_ATTR2}]`).forEach((el) => {
7465
+ if (!removedIds.has(instanceIdOf(el))) {
7466
+ el.style.removeProperty("display");
7467
+ el.removeAttribute(REMOVED_ATTR2);
7468
+ }
7469
+ });
7470
+ for (const id of removedIds) {
7471
+ const el = document.querySelector(`[data-ohw-instance="${CSS.escape(id)}"]`);
7472
+ if (el) {
7473
+ el.style.display = "none";
7474
+ el.setAttribute(REMOVED_ATTR2, "");
7475
+ }
7476
+ }
7477
+ }
7478
+ function applyPersistedOrder(entries) {
7479
+ syncRemovedFlags(entries);
7480
+ if (entries.length === 0) return;
7481
+ const sections = topLevelSections();
7482
+ if (sections.length === 0) return;
7483
+ const orderIndex = new Map(entries.map((e) => [e.instanceId, e.order]));
7484
+ const ordered = [...sections].sort((a, b) => {
7485
+ const aOrder = orderIndex.get(instanceIdOf(a));
7486
+ const bOrder = orderIndex.get(instanceIdOf(b));
7487
+ if (aOrder === void 0 && bOrder === void 0) return 0;
7488
+ if (aOrder === void 0) return 1;
7489
+ if (bOrder === void 0) return -1;
7490
+ return aOrder - bOrder;
7491
+ });
7492
+ let prev = null;
7493
+ for (const el of ordered) {
7494
+ if (prev) prev.after(el);
7495
+ prev = el;
7496
+ }
7497
+ }
7498
+ function setSectionRemoved(instanceId, currentPath, existingEntries, removed) {
7499
+ if (!document.querySelector(`[data-ohw-instance="${CSS.escape(instanceId)}"]`)) return null;
7500
+ const byId = new Map(existingEntries.map((e) => [e.instanceId, e]));
7501
+ const allSections = Array.from(document.querySelectorAll("[data-ohw-section]")).filter(
7502
+ (el) => !el.parentElement?.closest("[data-ohw-section]") && !isChromeSection(el)
7503
+ );
7504
+ allSections.forEach((el, order) => {
7505
+ const id = instanceIdOf(el);
7506
+ if (!byId.has(id)) {
7507
+ byId.set(id, { instanceId: id, type: el.getAttribute("data-ohw-section") ?? "", order, pagePath: currentPath });
7508
+ }
7509
+ });
7510
+ const target = byId.get(instanceId);
7511
+ if (!target) return null;
7512
+ byId.set(instanceId, { ...target, removed });
7513
+ const entries = Array.from(byId.values());
7514
+ applyPersistedOrder(entries);
7515
+ return entries;
7516
+ }
7517
+ function deleteSectionInstance(instanceId, currentPath, existingEntries) {
7518
+ return setSectionRemoved(instanceId, currentPath, existingEntries, true);
7519
+ }
7520
+ function restoreSectionInstance(instanceId, currentPath, existingEntries) {
7521
+ return setSectionRemoved(instanceId, currentPath, existingEntries, false);
7522
+ }
7523
+ function newInstanceId() {
7524
+ return typeof crypto !== "undefined" && "randomUUID" in crypto ? crypto.randomUUID() : `instance-${Date.now()}-${Math.random().toString(36).slice(2)}`;
7525
+ }
7526
+ function getPageSectionOrderEntries(raw, currentPath) {
7527
+ if (!raw) return [];
7528
+ try {
7529
+ const entries = JSON.parse(raw);
7530
+ return entries.filter((e) => !e.pagePath || e.pagePath === currentPath);
7531
+ } catch {
7532
+ return [];
7533
+ }
7534
+ }
7535
+ function rekeySectionSubtree(root, instanceId) {
7536
+ const suffix = `::${instanceId}`;
7537
+ const rekey = (el, attr) => {
7538
+ const current = el.getAttribute(attr);
7539
+ if (current) el.setAttribute(attr, `${current}${suffix}`);
7540
+ };
7541
+ if (root.hasAttribute("data-ohw-key")) rekey(root, "data-ohw-key");
7542
+ if (root.hasAttribute("data-ohw-href-key")) rekey(root, "data-ohw-href-key");
7543
+ root.querySelectorAll("[data-ohw-key]").forEach((el) => rekey(el, "data-ohw-key"));
7544
+ root.querySelectorAll("[data-ohw-href-key]").forEach((el) => rekey(el, "data-ohw-href-key"));
7545
+ }
7546
+ function initSectionInstancesFromContent(content, currentPath) {
7547
+ document.querySelectorAll("[data-ohw-section]:not([data-ohw-instance])").forEach((el) => {
7548
+ el.setAttribute("data-ohw-instance", el.getAttribute("data-ohw-section") ?? "");
7549
+ });
7550
+ const entries = getPageSectionOrderEntries(content[SECTION_ORDER_KEY], currentPath);
7551
+ for (const entry of entries) {
7552
+ if (entry.instanceId === entry.type) continue;
7553
+ if (document.querySelector(`[data-ohw-instance="${CSS.escape(entry.instanceId)}"]`)) continue;
7554
+ const original = document.querySelector(
7555
+ `[data-ohw-section="${CSS.escape(entry.type)}"][data-ohw-instance="${CSS.escape(entry.type)}"]`
7556
+ );
7557
+ if (!original) continue;
7558
+ const clone = original.cloneNode(true);
7559
+ clone.setAttribute("data-ohw-instance", entry.instanceId);
7560
+ rekeySectionSubtree(clone, entry.instanceId);
7561
+ original.insertAdjacentElement("afterend", clone);
7562
+ }
7563
+ applyPersistedOrder(entries);
7564
+ }
7565
+
7418
7566
  // src/ui/ai-section/AiSectionOverlay.tsx
7419
7567
  var import_jsx_runtime17 = require("react/jsx-runtime");
7420
- function readRect(sectionId) {
7421
- const el = document.querySelector(`[data-ohw-section="${CSS.escape(sectionId)}"]`);
7568
+ function findSectionElement(instanceId) {
7569
+ const escaped = CSS.escape(instanceId);
7570
+ return document.querySelector(`[data-ohw-instance="${escaped}"]`) ?? document.querySelector(`[data-ohw-section="${escaped}"]:not([data-ohw-instance])`);
7571
+ }
7572
+ function readRect(instanceId) {
7573
+ const el = findSectionElement(instanceId);
7422
7574
  if (!el) return null;
7423
7575
  const r2 = el.getBoundingClientRect();
7424
7576
  if (r2.width <= 0 || r2.height <= 0) return null;
@@ -7441,7 +7593,7 @@ function useLiveSectionRect(sectionId) {
7441
7593
  const opts = { capture: true, passive: true };
7442
7594
  window.addEventListener("scroll", update, opts);
7443
7595
  window.addEventListener("resize", update);
7444
- const el = document.querySelector(`[data-ohw-section="${CSS.escape(sectionId)}"]`);
7596
+ const el = findSectionElement(sectionId);
7445
7597
  const ro = el ? new ResizeObserver(update) : null;
7446
7598
  if (el && ro) ro.observe(el);
7447
7599
  const interval = setInterval(update, 500);
@@ -7454,6 +7606,12 @@ function useLiveSectionRect(sectionId) {
7454
7606
  }, [sectionId]);
7455
7607
  return rect;
7456
7608
  }
7609
+ function computeSectionBoundaryFlags(instanceId) {
7610
+ const topLevel = topLevelSections();
7611
+ const index = topLevel.findIndex((el) => (el.dataset.ohwInstance ?? el.dataset.ohwSection) === instanceId);
7612
+ if (index === -1) return { isFirst: true, isLast: true };
7613
+ return { isFirst: index === 0, isLast: index === topLevel.length - 1 };
7614
+ }
7457
7615
  var PRIMARY2 = "#0885FE";
7458
7616
  function edgeAwareRadius(rect) {
7459
7617
  const container = window.innerWidth <= 480 ? 16 : 24;
@@ -7535,7 +7693,7 @@ function AiSectionOverlay({
7535
7693
  (el) => {
7536
7694
  postToParent2({
7537
7695
  type: "ow:section-selected",
7538
- sectionId: el?.dataset.ohwSection ?? null,
7696
+ sectionId: el ? el.dataset.ohwInstance ?? el.dataset.ohwSection ?? null : null,
7539
7697
  sectionLabel: el ? el.dataset.ohwSectionLabel ?? titleCaseSectionId(el.dataset.ohwSection ?? "") : null
7540
7698
  });
7541
7699
  },
@@ -7544,7 +7702,7 @@ function AiSectionOverlay({
7544
7702
  const selectFromElement = (0, import_react8.useCallback)(
7545
7703
  (el, options) => {
7546
7704
  const sectionEl = el?.closest("[data-ohw-section]") ?? null;
7547
- const id = sectionEl?.dataset.ohwSection ?? null;
7705
+ const id = sectionEl ? sectionEl.dataset.ohwInstance ?? sectionEl.dataset.ohwSection ?? null : null;
7548
7706
  if (id === selectedIdRef.current) return;
7549
7707
  setSelectedId(id);
7550
7708
  if (options?.report !== false) report(sectionEl);
@@ -7565,12 +7723,15 @@ function AiSectionOverlay({
7565
7723
  selectFromElement(sectionEl);
7566
7724
  return sectionEl != null;
7567
7725
  },
7568
- clear: () => setSelectedId(null)
7726
+ clear: () => {
7727
+ setSelectedId(null);
7728
+ report(null);
7729
+ }
7569
7730
  };
7570
7731
  return () => {
7571
7732
  apiRef.current = null;
7572
7733
  };
7573
- }, [apiRef, selectFromElement]);
7734
+ }, [apiRef, selectFromElement, report]);
7574
7735
  (0, import_react8.useEffect)(() => {
7575
7736
  const onMessage = (e) => {
7576
7737
  if (e.data?.type === "ow:ai-select" && e.data.sectionId === null) {
@@ -7587,7 +7748,7 @@ function AiSectionOverlay({
7587
7748
  setReviewId(found ? sectionId : null);
7588
7749
  postToParent2({ type: "ow:ai-review-started", sectionId, found });
7589
7750
  if (found) {
7590
- document.querySelector(`[data-ohw-section="${CSS.escape(sectionId)}"]`)?.scrollIntoView({ behavior: "smooth", block: "nearest" });
7751
+ document.querySelector(`[data-ohw-instance="${CSS.escape(sectionId)}"]`)?.scrollIntoView({ behavior: "smooth", block: "nearest" });
7591
7752
  }
7592
7753
  }
7593
7754
  };
@@ -7606,7 +7767,7 @@ function AiSectionOverlay({
7606
7767
  return;
7607
7768
  }
7608
7769
  const sec = t.closest("[data-ohw-section]");
7609
- setHoveredId(sec?.dataset.ohwSection ?? null);
7770
+ setHoveredId(sec ? sec.dataset.ohwInstance ?? sec.dataset.ohwSection ?? null : null);
7610
7771
  };
7611
7772
  const onLeave = () => setHoveredId(null);
7612
7773
  document.addEventListener("mousemove", onMove, { passive: true });
@@ -7638,9 +7799,30 @@ function AiSectionOverlay({
7638
7799
  },
7639
7800
  [postToParent2]
7640
7801
  );
7641
- const selectionRect = useLiveSectionRect(reviewId ? null : selectedId);
7802
+ const activeSelectionId = reviewId ? null : selectedId;
7803
+ const selectionRect = useLiveSectionRect(activeSelectionId);
7642
7804
  const reviewRect = useLiveSectionRect(reviewId);
7643
7805
  const hoverRect = useLiveSectionRect(reviewId || hoveredId === selectedId ? null : hoveredId);
7806
+ (0, import_react8.useEffect)(() => {
7807
+ const selectedEl = activeSelectionId ? findSectionElement(activeSelectionId) : null;
7808
+ if (!activeSelectionId || !selectionRect || selectedEl && isChromeSection(selectedEl)) {
7809
+ postToParent2({ type: "ow:section-rect", instanceId: null, rect: null });
7810
+ return;
7811
+ }
7812
+ const { isFirst, isLast } = computeSectionBoundaryFlags(activeSelectionId);
7813
+ postToParent2({
7814
+ type: "ow:section-rect",
7815
+ instanceId: activeSelectionId,
7816
+ rect: {
7817
+ top: selectionRect.top + window.scrollY,
7818
+ left: selectionRect.left + window.scrollX,
7819
+ width: selectionRect.width,
7820
+ height: selectionRect.height
7821
+ },
7822
+ isFirst,
7823
+ isLast
7824
+ });
7825
+ }, [activeSelectionId, selectionRect, postToParent2]);
7644
7826
  return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
7645
7827
  hoverRect && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
7646
7828
  "div",
@@ -7720,47 +7902,6 @@ function AiSectionOverlay({
7720
7902
  ] });
7721
7903
  }
7722
7904
 
7723
- // src/lib/section-instances.ts
7724
- var SECTION_ORDER_KEY = "__ohw_section_order";
7725
- function getPageSectionOrderEntries(raw, currentPath) {
7726
- if (!raw) return [];
7727
- try {
7728
- const entries = JSON.parse(raw);
7729
- return entries.filter((e) => !e.pagePath || e.pagePath === currentPath);
7730
- } catch {
7731
- return [];
7732
- }
7733
- }
7734
- function rekeySectionSubtree(root, instanceId) {
7735
- const suffix = `::${instanceId}`;
7736
- const rekey = (el, attr) => {
7737
- const current = el.getAttribute(attr);
7738
- if (current) el.setAttribute(attr, `${current}${suffix}`);
7739
- };
7740
- if (root.hasAttribute("data-ohw-key")) rekey(root, "data-ohw-key");
7741
- if (root.hasAttribute("data-ohw-href-key")) rekey(root, "data-ohw-href-key");
7742
- root.querySelectorAll("[data-ohw-key]").forEach((el) => rekey(el, "data-ohw-key"));
7743
- root.querySelectorAll("[data-ohw-href-key]").forEach((el) => rekey(el, "data-ohw-href-key"));
7744
- }
7745
- function initSectionInstancesFromContent(content, currentPath) {
7746
- document.querySelectorAll("[data-ohw-section]:not([data-ohw-instance])").forEach((el) => {
7747
- el.setAttribute("data-ohw-instance", el.getAttribute("data-ohw-section") ?? "");
7748
- });
7749
- const entries = getPageSectionOrderEntries(content[SECTION_ORDER_KEY], currentPath);
7750
- for (const entry of entries) {
7751
- if (entry.instanceId === entry.type) continue;
7752
- if (document.querySelector(`[data-ohw-instance="${CSS.escape(entry.instanceId)}"]`)) continue;
7753
- const original = document.querySelector(
7754
- `[data-ohw-section="${CSS.escape(entry.type)}"][data-ohw-instance="${CSS.escape(entry.type)}"]`
7755
- );
7756
- if (!original) continue;
7757
- const clone = original.cloneNode(true);
7758
- clone.setAttribute("data-ohw-instance", entry.instanceId);
7759
- rekeySectionSubtree(clone, entry.instanceId);
7760
- original.insertAdjacentElement("afterend", clone);
7761
- }
7762
- }
7763
-
7764
7905
  // src/OhhwellsBridge.tsx
7765
7906
  var import_react_dom4 = require("react-dom");
7766
7907
  var import_navigation3 = require("next/navigation");
@@ -12980,6 +13121,333 @@ function useNavItemDrag({
12980
13121
  };
12981
13122
  }
12982
13123
 
13124
+ // src/useSectionDrag.ts
13125
+ var import_react15 = require("react");
13126
+
13127
+ // src/lib/section-dnd.ts
13128
+ function isFooterSection(el) {
13129
+ return el.dataset.ohwSection === "footer";
13130
+ }
13131
+ function buildSectionDropSlots(draggedInstanceId) {
13132
+ const sections = topLevelSections().filter(
13133
+ (el) => instanceIdOf(el) !== draggedInstanceId && !isFooterSection(el)
13134
+ );
13135
+ const slots = [];
13136
+ if (sections.length === 0) return slots;
13137
+ const left = 0;
13138
+ const width = document.documentElement.clientWidth;
13139
+ for (let i = 0; i <= sections.length; i++) {
13140
+ let y;
13141
+ if (i === 0) {
13142
+ y = sections[0].getBoundingClientRect().top;
13143
+ } else if (i === sections.length) {
13144
+ y = sections[sections.length - 1].getBoundingClientRect().bottom;
13145
+ } else {
13146
+ const prev = sections[i - 1].getBoundingClientRect();
13147
+ const next = sections[i].getBoundingClientRect();
13148
+ y = (prev.bottom + next.top) / 2;
13149
+ }
13150
+ slots.push({ insertIndex: i, y, left, width });
13151
+ }
13152
+ return slots;
13153
+ }
13154
+ function hitTestSectionDropSlot(y, slots) {
13155
+ let best = null;
13156
+ for (const slot of slots) {
13157
+ const dist = Math.abs(y - slot.y);
13158
+ if (!best || dist < best.dist) best = { slot, dist };
13159
+ }
13160
+ return best?.slot ?? null;
13161
+ }
13162
+
13163
+ // src/useSectionDrag.ts
13164
+ var PRESS_THRESHOLD = 10;
13165
+ var EDGE_ZONE = 60;
13166
+ var MAX_AUTO_SCROLL_SPEED = 18;
13167
+ var SECTION_DRAG_EXCLUDED_SELECTOR = [
13168
+ "[data-ohw-toolbar]",
13169
+ "[data-ohw-edit-chrome]",
13170
+ "[data-ohw-item-interaction]",
13171
+ "[data-ohw-drag-handle-container]",
13172
+ '[data-slot="drag-handle"]',
13173
+ "[data-ohw-item-toolbar-anchor]",
13174
+ "[data-ohw-item-drag-surface]",
13175
+ "[data-ohw-more-menu]",
13176
+ '[data-slot="dropdown-menu-content"]',
13177
+ '[data-slot="dropdown-menu-item"]',
13178
+ "[data-ohw-state-toggle]",
13179
+ "[data-ohw-max-badge]",
13180
+ "[data-ohw-floating-panel]",
13181
+ "[data-ohw-section-picker]",
13182
+ "[data-ohw-link-popover-root]",
13183
+ "[data-ohw-link-modal-root]",
13184
+ "[data-ohw-link-page-dropdown]",
13185
+ '[data-slot="popover-content"]',
13186
+ '[data-slot="dialog-content"]',
13187
+ '[data-slot="dialog-overlay"]',
13188
+ "[data-ohw-ai-review]",
13189
+ "[data-ohw-editable]",
13190
+ "[data-ohw-editable-state]",
13191
+ "[contenteditable]",
13192
+ "[data-ohw-href-key]",
13193
+ "[data-ohw-footer-col]",
13194
+ "[data-ohw-social-label]",
13195
+ "a",
13196
+ "button",
13197
+ '[role="button"]',
13198
+ '[data-ohw-role="navbar-button"]',
13199
+ '[data-ohw-role="button"]',
13200
+ "[data-ohw-carousel]",
13201
+ "[data-ohw-carousel-value]",
13202
+ "[data-ohw-carousel-slide]",
13203
+ "[data-ohw-carousel-overlay]",
13204
+ "[data-ohw-media-chrome]",
13205
+ "[data-ohw-media-overlay]",
13206
+ "[data-ohw-media-skeleton]"
13207
+ ].join(", ");
13208
+ function visibleClip(ps) {
13209
+ if (!ps) return null;
13210
+ const top = Math.max(0, ps.headerH - ps.iframeOffsetTop);
13211
+ const bottom = Math.min(window.innerHeight, ps.headerH + ps.canvasH - ps.iframeOffsetTop);
13212
+ return { top, bottom: Math.max(top, bottom) };
13213
+ }
13214
+ function useSectionDrag({
13215
+ isEditMode,
13216
+ editContentRef,
13217
+ postToParentRef,
13218
+ parentScrollRef,
13219
+ navDragRef,
13220
+ footerDragRef,
13221
+ suppressNextClickRef,
13222
+ suppressClickUntilRef
13223
+ }) {
13224
+ const sectionDragRef = (0, import_react15.useRef)(null);
13225
+ const [sectionDropSlots, setSectionDropSlots] = (0, import_react15.useState)([]);
13226
+ const [activeSectionDropIndex, setActiveSectionDropIndex] = (0, import_react15.useState)(null);
13227
+ const [isSectionDragging, setIsSectionDragging] = (0, import_react15.useState)(false);
13228
+ const sectionPointerDragRef = (0, import_react15.useRef)(null);
13229
+ const autoScrollRafRef = (0, import_react15.useRef)(null);
13230
+ const autoScrollDeltaRef = (0, import_react15.useRef)(0);
13231
+ const stopAutoScroll = (0, import_react15.useCallback)(() => {
13232
+ if (autoScrollRafRef.current != null) {
13233
+ cancelAnimationFrame(autoScrollRafRef.current);
13234
+ autoScrollRafRef.current = null;
13235
+ }
13236
+ autoScrollDeltaRef.current = 0;
13237
+ }, []);
13238
+ const tickAutoScroll = (0, import_react15.useCallback)(() => {
13239
+ if (!sectionDragRef.current) {
13240
+ stopAutoScroll();
13241
+ return;
13242
+ }
13243
+ if (autoScrollDeltaRef.current !== 0) {
13244
+ postToParentRef.current({ type: "ow:request-scroll", deltaY: autoScrollDeltaRef.current });
13245
+ }
13246
+ autoScrollRafRef.current = requestAnimationFrame(tickAutoScroll);
13247
+ }, [postToParentRef, stopAutoScroll]);
13248
+ const updateAutoScroll = (0, import_react15.useCallback)(
13249
+ (clientY) => {
13250
+ const clip = visibleClip(parentScrollRef.current);
13251
+ let delta = 0;
13252
+ if (clip) {
13253
+ const distTop = clientY - clip.top;
13254
+ const distBottom = clip.bottom - clientY;
13255
+ if (distTop >= 0 && distTop < EDGE_ZONE) {
13256
+ delta = -MAX_AUTO_SCROLL_SPEED * (1 - distTop / EDGE_ZONE);
13257
+ } else if (distBottom >= 0 && distBottom < EDGE_ZONE) {
13258
+ delta = MAX_AUTO_SCROLL_SPEED * (1 - distBottom / EDGE_ZONE);
13259
+ }
13260
+ }
13261
+ autoScrollDeltaRef.current = delta;
13262
+ if (delta !== 0 && autoScrollRafRef.current == null) {
13263
+ autoScrollRafRef.current = requestAnimationFrame(tickAutoScroll);
13264
+ } else if (delta === 0) {
13265
+ stopAutoScroll();
13266
+ }
13267
+ },
13268
+ [parentScrollRef, stopAutoScroll, tickAutoScroll]
13269
+ );
13270
+ const clearSectionDragVisuals = (0, import_react15.useCallback)(() => {
13271
+ sectionDragRef.current?.draggedEl.removeAttribute("data-ohw-section-dragging");
13272
+ sectionDragRef.current = null;
13273
+ setSectionDropSlots([]);
13274
+ setActiveSectionDropIndex(null);
13275
+ setIsSectionDragging(false);
13276
+ stopAutoScroll();
13277
+ document.documentElement.removeAttribute("data-ohw-section-dragging-root");
13278
+ unlockItemDragInteraction();
13279
+ }, [stopAutoScroll]);
13280
+ const refreshSectionDragVisuals = (0, import_react15.useCallback)(
13281
+ (session, clientX, clientY) => {
13282
+ session.lastClientX = clientX;
13283
+ session.lastClientY = clientY;
13284
+ const slots = buildSectionDropSlots(session.instanceId);
13285
+ const activeSlot = hitTestSectionDropSlot(clientY, slots);
13286
+ session.activeSlot = activeSlot;
13287
+ setSectionDropSlots(slots);
13288
+ const activeIdx = activeSlot ? slots.findIndex((s) => s.insertIndex === activeSlot.insertIndex) : -1;
13289
+ setActiveSectionDropIndex(activeIdx >= 0 ? activeIdx : null);
13290
+ updateAutoScroll(clientY);
13291
+ },
13292
+ [updateAutoScroll]
13293
+ );
13294
+ const beginSectionDrag = (0, import_react15.useCallback)(
13295
+ (session) => {
13296
+ sectionDragRef.current = session;
13297
+ setIsSectionDragging(true);
13298
+ lockItemDuringDrag();
13299
+ document.documentElement.setAttribute("data-ohw-section-dragging-root", "");
13300
+ session.draggedEl.setAttribute("data-ohw-section-dragging", "");
13301
+ refreshSectionDragVisuals(session, session.lastClientX, session.lastClientY);
13302
+ },
13303
+ [refreshSectionDragVisuals]
13304
+ );
13305
+ const commitSectionDrag = (0, import_react15.useCallback)(() => {
13306
+ const session = sectionDragRef.current;
13307
+ if (!session) {
13308
+ clearSectionDragVisuals();
13309
+ return;
13310
+ }
13311
+ const slot = session.activeSlot ?? hitTestSectionDropSlot(session.lastClientY, buildSectionDropSlots(session.instanceId));
13312
+ const entries = slot ? planSectionMove(session.instanceId, slot.insertIndex, window.location.pathname) : null;
13313
+ if (!entries) {
13314
+ clearSectionDragVisuals();
13315
+ return;
13316
+ }
13317
+ const orderJson = JSON.stringify(entries);
13318
+ editContentRef.current = { ...editContentRef.current, [SECTION_ORDER_KEY]: orderJson };
13319
+ postToParentRef.current({ type: "ow:change", nodes: [{ key: SECTION_ORDER_KEY, text: orderJson }] });
13320
+ applyPersistedOrder(entries);
13321
+ clearSectionDragVisuals();
13322
+ requestAnimationFrame(() => {
13323
+ if (editContentRef.current[SECTION_ORDER_KEY] === orderJson) {
13324
+ applyPersistedOrder(entries);
13325
+ }
13326
+ requestAnimationFrame(() => {
13327
+ window.dispatchEvent(new Event("resize"));
13328
+ });
13329
+ });
13330
+ }, [clearSectionDragVisuals, editContentRef, postToParentRef]);
13331
+ const startSectionPressDrag = (0, import_react15.useCallback)(
13332
+ (el, clientX, clientY, pointerId) => {
13333
+ if (navDragRef.current || footerDragRef.current || sectionDragRef.current) return false;
13334
+ const instanceId = instanceIdOf(el);
13335
+ if (!instanceId) return false;
13336
+ sectionPointerDragRef.current = {
13337
+ el,
13338
+ instanceId,
13339
+ startX: clientX,
13340
+ startY: clientY,
13341
+ pointerId,
13342
+ started: false
13343
+ };
13344
+ return true;
13345
+ },
13346
+ [footerDragRef, navDragRef]
13347
+ );
13348
+ (0, import_react15.useEffect)(() => {
13349
+ if (!isEditMode) return;
13350
+ const onPointerDown = (e) => {
13351
+ if (e.button !== 0) return;
13352
+ if (navDragRef.current || footerDragRef.current || sectionDragRef.current) return;
13353
+ if (sectionPointerDragRef.current) return;
13354
+ const target = e.target;
13355
+ if (!(target instanceof HTMLElement)) return;
13356
+ if (target.closest(SECTION_DRAG_EXCLUDED_SELECTOR)) return;
13357
+ const sectionEl = target.closest("[data-ohw-section]");
13358
+ if (!sectionEl || isChromeSection(sectionEl) || sectionEl.dataset.ohwSection === "footer") return;
13359
+ if (!topLevelSections().includes(sectionEl)) return;
13360
+ startSectionPressDrag(sectionEl, e.clientX, e.clientY, e.pointerId);
13361
+ };
13362
+ const onPointerMove = (e) => {
13363
+ const pending = sectionPointerDragRef.current;
13364
+ if (!pending) return;
13365
+ if (pending.started) {
13366
+ e.preventDefault();
13367
+ clearTextSelection();
13368
+ const session = sectionDragRef.current;
13369
+ if (!session) return;
13370
+ refreshSectionDragVisuals(session, e.clientX, e.clientY);
13371
+ return;
13372
+ }
13373
+ const dx = e.clientX - pending.startX;
13374
+ const dy = e.clientY - pending.startY;
13375
+ if (dx * dx + dy * dy < PRESS_THRESHOLD * PRESS_THRESHOLD) return;
13376
+ e.preventDefault();
13377
+ pending.started = true;
13378
+ armItemPressDrag();
13379
+ clearTextSelection();
13380
+ try {
13381
+ document.body.setPointerCapture(pending.pointerId);
13382
+ } catch {
13383
+ }
13384
+ beginSectionDrag({
13385
+ instanceId: pending.instanceId,
13386
+ draggedEl: pending.el,
13387
+ lastClientX: e.clientX,
13388
+ lastClientY: e.clientY,
13389
+ activeSlot: null
13390
+ });
13391
+ };
13392
+ const endPointerDrag = (e) => {
13393
+ const pending = sectionPointerDragRef.current;
13394
+ sectionPointerDragRef.current = null;
13395
+ try {
13396
+ if (document.body.hasPointerCapture(e.pointerId)) {
13397
+ document.body.releasePointerCapture(e.pointerId);
13398
+ }
13399
+ } catch {
13400
+ }
13401
+ if (!pending) return;
13402
+ if (!pending.started) {
13403
+ unlockItemDragInteraction();
13404
+ return;
13405
+ }
13406
+ suppressNextClickRef.current = true;
13407
+ suppressClickUntilRef.current = Date.now() + 500;
13408
+ commitSectionDrag();
13409
+ };
13410
+ const onKeyDown = (e) => {
13411
+ if (e.key !== "Escape") return;
13412
+ if (!sectionDragRef.current && !sectionPointerDragRef.current) return;
13413
+ sectionPointerDragRef.current = null;
13414
+ clearSectionDragVisuals();
13415
+ };
13416
+ document.addEventListener("pointerdown", onPointerDown, true);
13417
+ document.addEventListener("pointermove", onPointerMove, true);
13418
+ document.addEventListener("pointerup", endPointerDrag, true);
13419
+ document.addEventListener("pointercancel", endPointerDrag, true);
13420
+ document.addEventListener("keydown", onKeyDown, true);
13421
+ return () => {
13422
+ document.removeEventListener("pointerdown", onPointerDown, true);
13423
+ document.removeEventListener("pointermove", onPointerMove, true);
13424
+ document.removeEventListener("pointerup", endPointerDrag, true);
13425
+ document.removeEventListener("pointercancel", endPointerDrag, true);
13426
+ document.removeEventListener("keydown", onKeyDown, true);
13427
+ unlockItemDragInteraction();
13428
+ stopAutoScroll();
13429
+ };
13430
+ }, [
13431
+ beginSectionDrag,
13432
+ clearSectionDragVisuals,
13433
+ commitSectionDrag,
13434
+ footerDragRef,
13435
+ isEditMode,
13436
+ navDragRef,
13437
+ refreshSectionDragVisuals,
13438
+ startSectionPressDrag,
13439
+ stopAutoScroll,
13440
+ suppressClickUntilRef,
13441
+ suppressNextClickRef
13442
+ ]);
13443
+ return {
13444
+ sectionDragRef,
13445
+ sectionDropSlots,
13446
+ activeSectionDropIndex,
13447
+ isSectionDragging
13448
+ };
13449
+ }
13450
+
12983
13451
  // src/ui/footer-container-chrome.tsx
12984
13452
  var import_lucide_react15 = require("lucide-react");
12985
13453
  var import_jsx_runtime29 = require("react/jsx-runtime");
@@ -13032,7 +13500,7 @@ function FooterContainerChrome({
13032
13500
  }
13033
13501
 
13034
13502
  // src/lib/carousel.ts
13035
- var import_react15 = require("react");
13503
+ var import_react16 = require("react");
13036
13504
  var CAROUSEL_ATTR = "data-ohw-carousel";
13037
13505
  var CAROUSEL_VALUE_ATTR = "data-ohw-carousel-value";
13038
13506
  var CAROUSEL_SLIDE_ATTR = "data-ohw-carousel-slide";
@@ -13094,8 +13562,8 @@ function applyCarouselNode(key, val) {
13094
13562
  return true;
13095
13563
  }
13096
13564
  function useOhwCarousel(key, initial) {
13097
- const [images, setImages] = (0, import_react15.useState)(initial);
13098
- (0, import_react15.useEffect)(() => {
13565
+ const [images, setImages] = (0, import_react16.useState)(initial);
13566
+ (0, import_react16.useEffect)(() => {
13099
13567
  const el = document.querySelector(
13100
13568
  `[${CAROUSEL_ATTR}][data-ohw-key="${CSS.escape(key)}"]`
13101
13569
  );
@@ -13177,6 +13645,7 @@ function collectEditableNodes(extraContent, root = document) {
13177
13645
  NAV_ORDER_KEY,
13178
13646
  FOOTER_ORDER_KEY,
13179
13647
  NAV_COUNT_KEY,
13648
+ SECTION_ORDER_KEY,
13180
13649
  // A socials row's order and its icons-vs-words setting live under keys no element carries,
13181
13650
  // so collecting the DOM alone left them behind: the draft knew the row was showing icons and
13182
13651
  // had gained an item, and the published page went back to the template's own (OHH-736).
@@ -13641,6 +14110,7 @@ function fadeInImageElement(img, onReady) {
13641
14110
  function applyEditableImageSrc(img, url) {
13642
14111
  img.removeAttribute("srcset");
13643
14112
  img.removeAttribute("sizes");
14113
+ if (img.loading === "lazy") img.loading = "eager";
13644
14114
  img.src = url;
13645
14115
  }
13646
14116
  function fadeInBgImage(el, url, onReady) {
@@ -14723,9 +15193,9 @@ function FloatingToolbar({
14723
15193
  showEditLink,
14724
15194
  onEditLink
14725
15195
  }) {
14726
- const localRef = import_react16.default.useRef(null);
14727
- const [measuredW, setMeasuredW] = import_react16.default.useState(330);
14728
- const setRefs = import_react16.default.useCallback(
15196
+ const localRef = import_react17.default.useRef(null);
15197
+ const [measuredW, setMeasuredW] = import_react17.default.useState(330);
15198
+ const setRefs = import_react17.default.useCallback(
14729
15199
  (node) => {
14730
15200
  localRef.current = node;
14731
15201
  if (typeof elRef === "function") elRef(node);
@@ -14737,7 +15207,7 @@ function FloatingToolbar({
14737
15207
  },
14738
15208
  [elRef]
14739
15209
  );
14740
- import_react16.default.useLayoutEffect(() => {
15210
+ import_react17.default.useLayoutEffect(() => {
14741
15211
  const node = localRef.current;
14742
15212
  if (!node) return;
14743
15213
  const update = () => {
@@ -14763,7 +15233,7 @@ function FloatingToolbar({
14763
15233
  pointerEvents: "auto"
14764
15234
  },
14765
15235
  children: /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(CustomToolbar, { children: [
14766
- TOOLBAR_GROUPS.map((btns, gi) => /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(import_react16.default.Fragment, { children: [
15236
+ TOOLBAR_GROUPS.map((btns, gi) => /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(import_react17.default.Fragment, { children: [
14767
15237
  gi > 0 && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(CustomToolbarDivider, {}),
14768
15238
  btns.map((btn) => {
14769
15239
  const isActive = activeCommands.has(btn.cmd);
@@ -14847,9 +15317,47 @@ function StateToggle({
14847
15317
  );
14848
15318
  }
14849
15319
  var contentCache = /* @__PURE__ */ new Map();
14850
- function resolveSubdomain(subdomainFromQuery) {
14851
- if (subdomainFromQuery) return subdomainFromQuery;
14852
- if (typeof window !== "undefined") {
15320
+ var OHW_LOADER_STYLE = {
15321
+ position: "fixed",
15322
+ inset: 0,
15323
+ background: "#fff",
15324
+ zIndex: 2147483646,
15325
+ display: "flex",
15326
+ alignItems: "center",
15327
+ justifyContent: "center"
15328
+ };
15329
+ function OhwLoaderSpinner() {
15330
+ return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("svg", { width: "28", height: "28", viewBox: "0 0 28 28", fill: "none", "aria-hidden": true, children: [
15331
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("circle", { cx: "14", cy: "14", r: "11", stroke: "#E7E5E4", strokeWidth: "3" }),
15332
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
15333
+ "circle",
15334
+ {
15335
+ cx: "14",
15336
+ cy: "14",
15337
+ r: "11",
15338
+ stroke: "#1C1917",
15339
+ strokeWidth: "3",
15340
+ strokeDasharray: "17 52",
15341
+ strokeLinecap: "round",
15342
+ children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
15343
+ "animateTransform",
15344
+ {
15345
+ attributeName: "transform",
15346
+ type: "rotate",
15347
+ from: "0 14 14",
15348
+ to: "360 14 14",
15349
+ dur: "0.7s",
15350
+ repeatCount: "indefinite"
15351
+ }
15352
+ )
15353
+ }
15354
+ )
15355
+ ] });
15356
+ }
15357
+ var OHW_LOADER_PREHYDRATE_SCRIPT = `(function(){try{var p=location.hostname.split(".");var fromHost=p.length>=3&&p[0]!=="www"?p[0]:"";var fromQuery=new URLSearchParams(location.search).get("subdomain")||"";if(!fromHost&&!fromQuery)return;var e=document.getElementById("ohw-loader");if(e)e.style.display="flex"}catch(e){}})();`;
15358
+ function resolveSubdomain(subdomainFromQuery) {
15359
+ if (subdomainFromQuery) return subdomainFromQuery;
15360
+ if (typeof window !== "undefined") {
14853
15361
  const parts = window.location.hostname.split(".");
14854
15362
  if (parts.length >= 3 && parts[0] !== "www") return parts[0];
14855
15363
  }
@@ -14869,8 +15377,8 @@ function OhhwellsBridge() {
14869
15377
  const router = (0, import_navigation3.useRouter)();
14870
15378
  const searchParams = (0, import_navigation3.useSearchParams)();
14871
15379
  const isEditMode = isEditSessionActive();
14872
- const [bridgeRoot, setBridgeRoot] = (0, import_react16.useState)(null);
14873
- (0, import_react16.useEffect)(() => {
15380
+ const [bridgeRoot, setBridgeRoot] = (0, import_react17.useState)(null);
15381
+ (0, import_react17.useEffect)(() => {
14874
15382
  const figtreeFontId = "ohw-figtree-font";
14875
15383
  if (!document.getElementById(figtreeFontId)) {
14876
15384
  const preconnect1 = Object.assign(document.createElement("link"), { rel: "preconnect", href: "https://fonts.googleapis.com" });
@@ -14899,82 +15407,82 @@ function OhhwellsBridge() {
14899
15407
  const subdomain = resolveSubdomain(subdomainFromQuery);
14900
15408
  useLinkHrefGuardian(pathname, subdomain, isEditMode);
14901
15409
  useSavedLinkNavigation(isEditMode);
14902
- const postToParent2 = (0, import_react16.useCallback)((data) => {
15410
+ const postToParent2 = (0, import_react17.useCallback)((data) => {
14903
15411
  if (typeof window !== "undefined" && window.parent !== window) {
14904
15412
  window.parent.postMessage(data, "*");
14905
15413
  }
14906
15414
  }, []);
14907
- const [fetchState, setFetchState] = (0, import_react16.useState)("idle");
14908
- const autoSaveTimers = (0, import_react16.useRef)(/* @__PURE__ */ new Map());
14909
- const activeElRef = (0, import_react16.useRef)(null);
14910
- const pointerHeldRef = (0, import_react16.useRef)(false);
14911
- const selectedElRef = (0, import_react16.useRef)(null);
14912
- const selectedHrefKeyRef = (0, import_react16.useRef)(null);
14913
- const selectedFooterColAttrRef = (0, import_react16.useRef)(null);
14914
- const originalContentRef = (0, import_react16.useRef)(null);
14915
- const activeStateElRef = (0, import_react16.useRef)(null);
14916
- const parentScrollRef = (0, import_react16.useRef)(null);
14917
- const visibleViewportRef = (0, import_react16.useRef)(null);
14918
- const [dialogPortalContainer, setDialogPortalContainer] = (0, import_react16.useState)(null);
14919
- const attachVisibleViewport = (0, import_react16.useCallback)((node) => {
15415
+ const [fetchState, setFetchState] = (0, import_react17.useState)("idle");
15416
+ const autoSaveTimers = (0, import_react17.useRef)(/* @__PURE__ */ new Map());
15417
+ const activeElRef = (0, import_react17.useRef)(null);
15418
+ const pointerHeldRef = (0, import_react17.useRef)(false);
15419
+ const selectedElRef = (0, import_react17.useRef)(null);
15420
+ const selectedHrefKeyRef = (0, import_react17.useRef)(null);
15421
+ const selectedFooterColAttrRef = (0, import_react17.useRef)(null);
15422
+ const originalContentRef = (0, import_react17.useRef)(null);
15423
+ const activeStateElRef = (0, import_react17.useRef)(null);
15424
+ const parentScrollRef = (0, import_react17.useRef)(null);
15425
+ const visibleViewportRef = (0, import_react17.useRef)(null);
15426
+ const [dialogPortalContainer, setDialogPortalContainer] = (0, import_react17.useState)(null);
15427
+ const attachVisibleViewport = (0, import_react17.useCallback)((node) => {
14920
15428
  visibleViewportRef.current = node;
14921
15429
  setDialogPortalContainer(node);
14922
15430
  if (node) applyVisibleViewport(node, parentScrollRef.current);
14923
15431
  }, []);
14924
- const toolbarElRef = (0, import_react16.useRef)(null);
14925
- const glowElRef = (0, import_react16.useRef)(null);
14926
- const hoveredImageRef = (0, import_react16.useRef)(null);
14927
- const hoveredImageHasTextOverlapRef = (0, import_react16.useRef)(false);
14928
- const dragOverElRef = (0, import_react16.useRef)(null);
14929
- const [mediaHover, setMediaHover] = (0, import_react16.useState)(null);
14930
- const [carouselHover, setCarouselHover] = (0, import_react16.useState)(null);
14931
- const [uploadingRects, setUploadingRects] = (0, import_react16.useState)({});
14932
- const hoveredGapRef = (0, import_react16.useRef)(null);
14933
- const imageUnhoverTimerRef = (0, import_react16.useRef)(null);
14934
- const imageShowTimerRef = (0, import_react16.useRef)(null);
14935
- const editStylesRef = (0, import_react16.useRef)(null);
14936
- const activateRef = (0, import_react16.useRef)(() => {
15432
+ const toolbarElRef = (0, import_react17.useRef)(null);
15433
+ const glowElRef = (0, import_react17.useRef)(null);
15434
+ const hoveredImageRef = (0, import_react17.useRef)(null);
15435
+ const hoveredImageHasTextOverlapRef = (0, import_react17.useRef)(false);
15436
+ const dragOverElRef = (0, import_react17.useRef)(null);
15437
+ const [mediaHover, setMediaHover] = (0, import_react17.useState)(null);
15438
+ const [carouselHover, setCarouselHover] = (0, import_react17.useState)(null);
15439
+ const [uploadingRects, setUploadingRects] = (0, import_react17.useState)({});
15440
+ const hoveredGapRef = (0, import_react17.useRef)(null);
15441
+ const imageUnhoverTimerRef = (0, import_react17.useRef)(null);
15442
+ const imageShowTimerRef = (0, import_react17.useRef)(null);
15443
+ const editStylesRef = (0, import_react17.useRef)(null);
15444
+ const activateRef = (0, import_react17.useRef)(() => {
14937
15445
  });
14938
- const deactivateRef = (0, import_react16.useRef)(() => {
15446
+ const deactivateRef = (0, import_react17.useRef)(() => {
14939
15447
  });
14940
- const selectRef = (0, import_react16.useRef)(() => {
15448
+ const selectRef = (0, import_react17.useRef)(() => {
14941
15449
  });
14942
- const selectFrameRef = (0, import_react16.useRef)(() => {
15450
+ const selectFrameRef = (0, import_react17.useRef)(() => {
14943
15451
  });
14944
- const selectLogoRef = (0, import_react16.useRef)(() => {
15452
+ const selectLogoRef = (0, import_react17.useRef)(() => {
14945
15453
  });
14946
- const openLogoSizePanelRef = (0, import_react16.useRef)(() => {
15454
+ const openLogoSizePanelRef = (0, import_react17.useRef)(() => {
14947
15455
  });
14948
- const deselectRef = (0, import_react16.useRef)(() => {
15456
+ const deselectRef = (0, import_react17.useRef)(() => {
14949
15457
  });
14950
- const closeFloatingPanelOnlyRef = (0, import_react16.useRef)(() => {
15458
+ const closeFloatingPanelOnlyRef = (0, import_react17.useRef)(() => {
14951
15459
  });
14952
- const reselectNavigationItemRef = (0, import_react16.useRef)(() => {
15460
+ const reselectNavigationItemRef = (0, import_react17.useRef)(() => {
14953
15461
  });
14954
- const commitNavigationTextEditRef = (0, import_react16.useRef)(() => {
15462
+ const commitNavigationTextEditRef = (0, import_react17.useRef)(() => {
14955
15463
  });
14956
- const handleDeleteSelectedRef = (0, import_react16.useRef)(() => false);
14957
- const runPendingDeleteUndoRef = (0, import_react16.useRef)(() => false);
14958
- const isFooterFrameSelectionRef = (0, import_react16.useRef)(false);
14959
- const refreshActiveCommandsRef = (0, import_react16.useRef)(() => {
15464
+ const handleDeleteSelectedRef = (0, import_react17.useRef)(() => false);
15465
+ const runPendingDeleteUndoRef = (0, import_react17.useRef)(() => false);
15466
+ const isFooterFrameSelectionRef = (0, import_react17.useRef)(false);
15467
+ const refreshActiveCommandsRef = (0, import_react17.useRef)(() => {
14960
15468
  });
14961
- const postToParentRef = (0, import_react16.useRef)(postToParent2);
15469
+ const postToParentRef = (0, import_react17.useRef)(postToParent2);
14962
15470
  postToParentRef.current = postToParent2;
14963
- const aiSectionApiRef = (0, import_react16.useRef)(null);
14964
- const sectionsLoadedRef = (0, import_react16.useRef)(false);
14965
- const pendingScheduleConfigRequests = (0, import_react16.useRef)([]);
14966
- const [toolbarRect, setToolbarRect] = (0, import_react16.useState)(null);
14967
- const [formPickRect, setFormPickRect] = (0, import_react16.useState)(null);
14968
- const formPickElRef = (0, import_react16.useRef)(null);
14969
- const [formViewState, setFormViewStateUi] = (0, import_react16.useState)("default");
14970
- const [formPickCount, setFormPickCount] = (0, import_react16.useState)(null);
14971
- const [formHoverRect, setFormHoverRect] = (0, import_react16.useState)(null);
14972
- const formHoverElRef = (0, import_react16.useRef)(null);
14973
- const [fieldPickRect, setFieldPickRect] = (0, import_react16.useState)(null);
14974
- const fieldPickElRef = (0, import_react16.useRef)(null);
14975
- const [fieldPickState, setFieldPickState] = (0, import_react16.useState)(null);
14976
- const [fieldTypePickerOpen, setFieldTypePickerOpen] = (0, import_react16.useState)(false);
14977
- const clearFormPick = (0, import_react16.useCallback)(() => {
15471
+ const aiSectionApiRef = (0, import_react17.useRef)(null);
15472
+ const sectionsLoadedRef = (0, import_react17.useRef)(false);
15473
+ const pendingScheduleConfigRequests = (0, import_react17.useRef)([]);
15474
+ const [toolbarRect, setToolbarRect] = (0, import_react17.useState)(null);
15475
+ const [formPickRect, setFormPickRect] = (0, import_react17.useState)(null);
15476
+ const formPickElRef = (0, import_react17.useRef)(null);
15477
+ const [formViewState, setFormViewStateUi] = (0, import_react17.useState)("default");
15478
+ const [formPickCount, setFormPickCount] = (0, import_react17.useState)(null);
15479
+ const [formHoverRect, setFormHoverRect] = (0, import_react17.useState)(null);
15480
+ const formHoverElRef = (0, import_react17.useRef)(null);
15481
+ const [fieldPickRect, setFieldPickRect] = (0, import_react17.useState)(null);
15482
+ const fieldPickElRef = (0, import_react17.useRef)(null);
15483
+ const [fieldPickState, setFieldPickState] = (0, import_react17.useState)(null);
15484
+ const [fieldTypePickerOpen, setFieldTypePickerOpen] = (0, import_react17.useState)(false);
15485
+ const clearFormPick = (0, import_react17.useCallback)(() => {
14978
15486
  const form = formPickElRef.current;
14979
15487
  const editing = fieldPickElRef.current;
14980
15488
  if (commitPlaceholderEdit(editing) && editing) {
@@ -14994,7 +15502,7 @@ function OhhwellsBridge() {
14994
15502
  formPickElRef.current = null;
14995
15503
  setFormPickRect(null);
14996
15504
  }, []);
14997
- const clearFieldPick = (0, import_react16.useCallback)(() => {
15505
+ const clearFieldPick = (0, import_react17.useCallback)(() => {
14998
15506
  const wrapper = fieldPickElRef.current;
14999
15507
  if (commitPlaceholderEdit(wrapper) && wrapper) {
15000
15508
  const form = wrapper.closest('[data-ohw-editable="form"]');
@@ -15004,9 +15512,9 @@ function OhhwellsBridge() {
15004
15512
  setFieldPickRect(null);
15005
15513
  setFieldPickState(null);
15006
15514
  }, []);
15007
- const persistFieldsRef = (0, import_react16.useRef)(() => {
15515
+ const persistFieldsRef = (0, import_react17.useRef)(() => {
15008
15516
  });
15009
- const persistFields = (0, import_react16.useCallback)(
15517
+ const persistFields = (0, import_react17.useCallback)(
15010
15518
  (form) => {
15011
15519
  const key = formKeyOf(form);
15012
15520
  if (!key) return;
@@ -15017,7 +15525,7 @@ function OhhwellsBridge() {
15017
15525
  []
15018
15526
  );
15019
15527
  persistFieldsRef.current = persistFields;
15020
- const selectField = (0, import_react16.useCallback)((wrapper) => {
15528
+ const selectField = (0, import_react17.useCallback)((wrapper) => {
15021
15529
  if (fieldPickElRef.current && fieldPickElRef.current !== wrapper) {
15022
15530
  commitPlaceholderEdit(fieldPickElRef.current);
15023
15531
  }
@@ -15030,7 +15538,7 @@ function OhhwellsBridge() {
15030
15538
  setFieldPickState({ type: fieldTypeOf(wrapper), required: isFieldRequired(wrapper) });
15031
15539
  setFieldTypePickerOpen(false);
15032
15540
  }, []);
15033
- const withSelectedField = (0, import_react16.useCallback)(
15541
+ const withSelectedField = (0, import_react17.useCallback)(
15034
15542
  (run) => {
15035
15543
  const wrapper = fieldPickElRef.current;
15036
15544
  const form = formPickElRef.current;
@@ -15043,28 +15551,28 @@ function OhhwellsBridge() {
15043
15551
  },
15044
15552
  [persistFields]
15045
15553
  );
15046
- const handleFieldTypeChange = (0, import_react16.useCallback)(
15554
+ const handleFieldTypeChange = (0, import_react17.useCallback)(
15047
15555
  (type) => withSelectedField((_form, wrapper) => {
15048
15556
  applyFieldType(wrapper, type);
15049
15557
  selectField(wrapper);
15050
15558
  }),
15051
15559
  [selectField, withSelectedField]
15052
15560
  );
15053
- const handleFieldRequiredToggle = (0, import_react16.useCallback)(
15561
+ const handleFieldRequiredToggle = (0, import_react17.useCallback)(
15054
15562
  () => withSelectedField((_form, wrapper) => {
15055
15563
  setFieldRequired(wrapper, !isFieldRequired(wrapper));
15056
15564
  selectField(wrapper);
15057
15565
  }),
15058
15566
  [selectField, withSelectedField]
15059
15567
  );
15060
- const handleFieldDuplicate = (0, import_react16.useCallback)(
15568
+ const handleFieldDuplicate = (0, import_react17.useCallback)(
15061
15569
  () => withSelectedField((form, wrapper) => {
15062
15570
  const copy = duplicateField(form, wrapper);
15063
15571
  selectField(copy);
15064
15572
  }),
15065
15573
  [selectField, withSelectedField]
15066
15574
  );
15067
- const handleFieldDelete = (0, import_react16.useCallback)(
15575
+ const handleFieldDelete = (0, import_react17.useCallback)(
15068
15576
  () => withSelectedField((_form, wrapper) => {
15069
15577
  removeField(wrapper);
15070
15578
  clearFieldPick();
@@ -15072,7 +15580,7 @@ function OhhwellsBridge() {
15072
15580
  }),
15073
15581
  [clearFieldPick, withSelectedField]
15074
15582
  );
15075
- const handleAddField = (0, import_react16.useCallback)(
15583
+ const handleAddField = (0, import_react17.useCallback)(
15076
15584
  (type) => {
15077
15585
  const form = formPickElRef.current;
15078
15586
  if (!form) return;
@@ -15088,8 +15596,8 @@ function OhhwellsBridge() {
15088
15596
  },
15089
15597
  [persistFields, selectField]
15090
15598
  );
15091
- const fieldDragRef = (0, import_react16.useRef)(null);
15092
- const buildFieldDropSlots = (0, import_react16.useCallback)((form, draggedKey) => {
15599
+ const fieldDragRef = (0, import_react17.useRef)(null);
15600
+ const buildFieldDropSlots = (0, import_react17.useCallback)((form, draggedKey) => {
15093
15601
  const others = listFieldWrappers(form).filter((el) => fieldKeyOf(el) !== draggedKey);
15094
15602
  const slots = others.map((el) => {
15095
15603
  const rect = el.getBoundingClientRect();
@@ -15102,7 +15610,7 @@ function OhhwellsBridge() {
15102
15610
  }
15103
15611
  return slots;
15104
15612
  }, []);
15105
- const handleFieldDragStart = (0, import_react16.useCallback)(() => {
15613
+ const handleFieldDragStart = (0, import_react17.useCallback)(() => {
15106
15614
  const wrapper = fieldPickElRef.current;
15107
15615
  const form = formPickElRef.current;
15108
15616
  if (!wrapper || !form) return;
@@ -15111,18 +15619,18 @@ function OhhwellsBridge() {
15111
15619
  setFieldDragging(true);
15112
15620
  setFieldDropSlots(buildFieldDropSlots(form, key));
15113
15621
  }, [buildFieldDropSlots]);
15114
- const handleFieldDragEnd = (0, import_react16.useCallback)(() => {
15622
+ const handleFieldDragEnd = (0, import_react17.useCallback)(() => {
15115
15623
  fieldDragRef.current = null;
15116
15624
  setFieldDropIndex(null);
15117
15625
  setFieldDropSlots([]);
15118
15626
  setFieldDragging(false);
15119
15627
  }, []);
15120
- const [fieldDropIndex, setFieldDropIndex] = (0, import_react16.useState)(null);
15121
- const [fieldDropSlots, setFieldDropSlots] = (0, import_react16.useState)([]);
15122
- const [fieldDragging, setFieldDragging] = (0, import_react16.useState)(false);
15123
- const clearFormPickRef = (0, import_react16.useRef)(clearFormPick);
15628
+ const [fieldDropIndex, setFieldDropIndex] = (0, import_react17.useState)(null);
15629
+ const [fieldDropSlots, setFieldDropSlots] = (0, import_react17.useState)([]);
15630
+ const [fieldDragging, setFieldDragging] = (0, import_react17.useState)(false);
15631
+ const clearFormPickRef = (0, import_react17.useRef)(clearFormPick);
15124
15632
  clearFormPickRef.current = clearFormPick;
15125
- (0, import_react16.useEffect)(() => {
15633
+ (0, import_react17.useEffect)(() => {
15126
15634
  const el = fieldPickElRef.current;
15127
15635
  if (!el || fieldPickRect === null) return;
15128
15636
  const observer = new ResizeObserver(() => {
@@ -15131,7 +15639,7 @@ function OhhwellsBridge() {
15131
15639
  observer.observe(el);
15132
15640
  return () => observer.disconnect();
15133
15641
  }, [fieldPickRect !== null, fieldPickState]);
15134
- (0, import_react16.useEffect)(() => {
15642
+ (0, import_react17.useEffect)(() => {
15135
15643
  const el = formPickElRef.current;
15136
15644
  if (!el || formPickRect === null) return;
15137
15645
  const observer = new ResizeObserver(() => {
@@ -15140,25 +15648,25 @@ function OhhwellsBridge() {
15140
15648
  observer.observe(el);
15141
15649
  return () => observer.disconnect();
15142
15650
  }, [formPickRect !== null, formViewState]);
15143
- const [toolbarVariant, setToolbarVariant] = (0, import_react16.useState)("none");
15144
- const toolbarVariantRef = (0, import_react16.useRef)("none");
15651
+ const [toolbarVariant, setToolbarVariant] = (0, import_react17.useState)("none");
15652
+ const toolbarVariantRef = (0, import_react17.useRef)("none");
15145
15653
  toolbarVariantRef.current = toolbarVariant;
15146
- const [selectedIsCta, setSelectedIsCta] = (0, import_react16.useState)(false);
15147
- const [selectedIsSocial, setSelectedIsSocial] = (0, import_react16.useState)(false);
15148
- const [selectedIsSocialsRow, setSelectedIsSocialsRow] = (0, import_react16.useState)(false);
15149
- const [reorderHrefKey, setReorderHrefKey] = (0, import_react16.useState)(null);
15150
- const [reorderDragDisabled, setReorderDragDisabled] = (0, import_react16.useState)(false);
15151
- const [toggleState, setToggleState] = (0, import_react16.useState)(null);
15152
- const [maxBadge, setMaxBadge] = (0, import_react16.useState)(null);
15153
- const [activeCommands, setActiveCommands] = (0, import_react16.useState)(/* @__PURE__ */ new Set());
15154
- const [sectionGap, setSectionGap] = (0, import_react16.useState)(null);
15155
- const [toolbarShowEditLink, setToolbarShowEditLink] = (0, import_react16.useState)(false);
15156
- const hoveredNavContainerRef = (0, import_react16.useRef)(null);
15157
- const [hoveredNavContainerRect, setHoveredNavContainerRect] = (0, import_react16.useState)(null);
15158
- const hoveredItemElRef = (0, import_react16.useRef)(null);
15159
- const [hoveredItemRect, setHoveredItemRect] = (0, import_react16.useState)(null);
15160
- const [hoveredTextRect, setHoveredTextRect] = (0, import_react16.useState)(null);
15161
- (0, import_react16.useEffect)(() => {
15654
+ const [selectedIsCta, setSelectedIsCta] = (0, import_react17.useState)(false);
15655
+ const [selectedIsSocial, setSelectedIsSocial] = (0, import_react17.useState)(false);
15656
+ const [selectedIsSocialsRow, setSelectedIsSocialsRow] = (0, import_react17.useState)(false);
15657
+ const [reorderHrefKey, setReorderHrefKey] = (0, import_react17.useState)(null);
15658
+ const [reorderDragDisabled, setReorderDragDisabled] = (0, import_react17.useState)(false);
15659
+ const [toggleState, setToggleState] = (0, import_react17.useState)(null);
15660
+ const [maxBadge, setMaxBadge] = (0, import_react17.useState)(null);
15661
+ const [activeCommands, setActiveCommands] = (0, import_react17.useState)(/* @__PURE__ */ new Set());
15662
+ const [sectionGap, setSectionGap] = (0, import_react17.useState)(null);
15663
+ const [toolbarShowEditLink, setToolbarShowEditLink] = (0, import_react17.useState)(false);
15664
+ const hoveredNavContainerRef = (0, import_react17.useRef)(null);
15665
+ const [hoveredNavContainerRect, setHoveredNavContainerRect] = (0, import_react17.useState)(null);
15666
+ const hoveredItemElRef = (0, import_react17.useRef)(null);
15667
+ const [hoveredItemRect, setHoveredItemRect] = (0, import_react17.useState)(null);
15668
+ const [hoveredTextRect, setHoveredTextRect] = (0, import_react17.useState)(null);
15669
+ (0, import_react17.useEffect)(() => {
15162
15670
  const sync = () => {
15163
15671
  const el = document.querySelector(
15164
15672
  '[data-ohw-hovered]:not([contenteditable]):not([data-ohw-href-key]):not([data-ohw-editable="form"] *)'
@@ -15183,41 +15691,41 @@ function OhhwellsBridge() {
15183
15691
  });
15184
15692
  return () => observer.disconnect();
15185
15693
  }, []);
15186
- const siblingHintElRef = (0, import_react16.useRef)(null);
15187
- const [siblingHintRect, setSiblingHintRect] = (0, import_react16.useState)(null);
15188
- const [siblingHintRects, setSiblingHintRects] = (0, import_react16.useState)([]);
15189
- const [isItemDragging, setIsItemDragging] = (0, import_react16.useState)(false);
15190
- const [isFooterFrameSelection, setIsFooterFrameSelection] = (0, import_react16.useState)(false);
15694
+ const siblingHintElRef = (0, import_react17.useRef)(null);
15695
+ const [siblingHintRect, setSiblingHintRect] = (0, import_react17.useState)(null);
15696
+ const [siblingHintRects, setSiblingHintRects] = (0, import_react17.useState)([]);
15697
+ const [isItemDragging, setIsItemDragging] = (0, import_react17.useState)(false);
15698
+ const [isFooterFrameSelection, setIsFooterFrameSelection] = (0, import_react17.useState)(false);
15191
15699
  isFooterFrameSelectionRef.current = isFooterFrameSelection;
15192
- const [floatingPanel, setFloatingPanel] = (0, import_react16.useState)(null);
15193
- const floatingPanelOpenRef = (0, import_react16.useRef)(false);
15700
+ const [floatingPanel, setFloatingPanel] = (0, import_react17.useState)(null);
15701
+ const floatingPanelOpenRef = (0, import_react17.useRef)(false);
15194
15702
  floatingPanelOpenRef.current = floatingPanel !== null;
15195
- const [floatingPanelPos, setFloatingPanelPos] = (0, import_react16.useState)(null);
15196
- const [logoSizeDraft, setLogoSizeDraft] = (0, import_react16.useState)(null);
15197
- const [editorViewport, setEditorViewport] = (0, import_react16.useState)("desktop");
15198
- const [parentScrollSnap, setParentScrollSnap] = (0, import_react16.useState)(null);
15199
- const [navDropdownPreviewOpen, setNavDropdownPreviewOpen] = (0, import_react16.useState)(null);
15200
- const [footerHeadingVisible, setFooterHeadingVisible] = (0, import_react16.useState)(null);
15201
- const footerDragRef = (0, import_react16.useRef)(null);
15202
- const [footerDropSlots, setFooterDropSlots] = (0, import_react16.useState)([]);
15203
- const [activeFooterDropIndex, setActiveFooterDropIndex] = (0, import_react16.useState)(null);
15204
- const [draggedItemRect, setDraggedItemRect] = (0, import_react16.useState)(null);
15205
- const footerPointerDragRef = (0, import_react16.useRef)(null);
15206
- const suppressNextClickRef = (0, import_react16.useRef)(false);
15207
- const suppressClickUntilRef = (0, import_react16.useRef)(0);
15208
- const [linkPopover, setLinkPopover] = (0, import_react16.useState)(null);
15209
- const linkPopoverSessionRef = (0, import_react16.useRef)(null);
15210
- const addNavAfterAnchorRef = (0, import_react16.useRef)(null);
15211
- const editContentRef = (0, import_react16.useRef)({});
15212
- const aiSectionsRef = (0, import_react16.useRef)("");
15213
- const pendingDeleteUndoRef = (0, import_react16.useRef)(null);
15214
- const [sitePages, setSitePages] = (0, import_react16.useState)([]);
15215
- const [sectionsByPath, setSectionsByPath] = (0, import_react16.useState)({});
15216
- const sectionsPrefetchGenRef = (0, import_react16.useRef)(0);
15217
- const setLinkPopoverRef = (0, import_react16.useRef)(setLinkPopover);
15218
- const linkPopoverPanelRef = (0, import_react16.useRef)(null);
15219
- const linkPopoverOpenRef = (0, import_react16.useRef)(false);
15220
- const linkPopoverGraceUntilRef = (0, import_react16.useRef)(0);
15703
+ const [floatingPanelPos, setFloatingPanelPos] = (0, import_react17.useState)(null);
15704
+ const [logoSizeDraft, setLogoSizeDraft] = (0, import_react17.useState)(null);
15705
+ const [editorViewport, setEditorViewport] = (0, import_react17.useState)("desktop");
15706
+ const [parentScrollSnap, setParentScrollSnap] = (0, import_react17.useState)(null);
15707
+ const [navDropdownPreviewOpen, setNavDropdownPreviewOpen] = (0, import_react17.useState)(null);
15708
+ const [footerHeadingVisible, setFooterHeadingVisible] = (0, import_react17.useState)(null);
15709
+ const footerDragRef = (0, import_react17.useRef)(null);
15710
+ const [footerDropSlots, setFooterDropSlots] = (0, import_react17.useState)([]);
15711
+ const [activeFooterDropIndex, setActiveFooterDropIndex] = (0, import_react17.useState)(null);
15712
+ const [draggedItemRect, setDraggedItemRect] = (0, import_react17.useState)(null);
15713
+ const footerPointerDragRef = (0, import_react17.useRef)(null);
15714
+ const suppressNextClickRef = (0, import_react17.useRef)(false);
15715
+ const suppressClickUntilRef = (0, import_react17.useRef)(0);
15716
+ const [linkPopover, setLinkPopover] = (0, import_react17.useState)(null);
15717
+ const linkPopoverSessionRef = (0, import_react17.useRef)(null);
15718
+ const addNavAfterAnchorRef = (0, import_react17.useRef)(null);
15719
+ const editContentRef = (0, import_react17.useRef)({});
15720
+ const aiSectionsRef = (0, import_react17.useRef)("");
15721
+ const pendingDeleteUndoRef = (0, import_react17.useRef)(null);
15722
+ const [sitePages, setSitePages] = (0, import_react17.useState)([]);
15723
+ const [sectionsByPath, setSectionsByPath] = (0, import_react17.useState)({});
15724
+ const sectionsPrefetchGenRef = (0, import_react17.useRef)(0);
15725
+ const setLinkPopoverRef = (0, import_react17.useRef)(setLinkPopover);
15726
+ const linkPopoverPanelRef = (0, import_react17.useRef)(null);
15727
+ const linkPopoverOpenRef = (0, import_react17.useRef)(false);
15728
+ const linkPopoverGraceUntilRef = (0, import_react17.useRef)(0);
15221
15729
  setLinkPopoverRef.current = setLinkPopover;
15222
15730
  linkPopoverSessionRef.current = linkPopover;
15223
15731
  const {
@@ -15252,10 +15760,20 @@ function OhhwellsBridge() {
15252
15760
  getNavigationItemAnchor,
15253
15761
  isDragHandleDisabled
15254
15762
  });
15763
+ const { sectionDropSlots, activeSectionDropIndex, isSectionDragging } = useSectionDrag({
15764
+ isEditMode,
15765
+ editContentRef,
15766
+ postToParentRef,
15767
+ parentScrollRef,
15768
+ navDragRef,
15769
+ footerDragRef,
15770
+ suppressNextClickRef,
15771
+ suppressClickUntilRef
15772
+ });
15255
15773
  const bumpLinkPopoverGrace = () => {
15256
15774
  linkPopoverGraceUntilRef.current = Date.now() + 350;
15257
15775
  };
15258
- const runSectionsPrefetch = (0, import_react16.useCallback)((pages) => {
15776
+ const runSectionsPrefetch = (0, import_react17.useCallback)((pages) => {
15259
15777
  if (!isEditMode || shouldUseDevFixtures() || pages.length === 0) return;
15260
15778
  const gen = ++sectionsPrefetchGenRef.current;
15261
15779
  const paths = pages.map((p) => p.path);
@@ -15274,9 +15792,9 @@ function OhhwellsBridge() {
15274
15792
  );
15275
15793
  });
15276
15794
  }, [isEditMode, pathname]);
15277
- const runSectionsPrefetchRef = (0, import_react16.useRef)(runSectionsPrefetch);
15795
+ const runSectionsPrefetchRef = (0, import_react17.useRef)(runSectionsPrefetch);
15278
15796
  runSectionsPrefetchRef.current = runSectionsPrefetch;
15279
- (0, import_react16.useEffect)(() => {
15797
+ (0, import_react17.useEffect)(() => {
15280
15798
  if (!linkPopover) {
15281
15799
  document.documentElement.removeAttribute("data-ohw-link-popover-open");
15282
15800
  return;
@@ -15304,7 +15822,7 @@ function OhhwellsBridge() {
15304
15822
  document.documentElement.removeAttribute("data-ohw-link-popover-open");
15305
15823
  };
15306
15824
  }, [linkPopover, postToParent2]);
15307
- (0, import_react16.useEffect)(() => {
15825
+ (0, import_react17.useEffect)(() => {
15308
15826
  if (!isEditMode) return;
15309
15827
  const useFixtures = shouldUseDevFixtures();
15310
15828
  if (useFixtures) {
@@ -15328,14 +15846,14 @@ function OhhwellsBridge() {
15328
15846
  if (!useFixtures) postToParent2({ type: "ow:request-site-pages" });
15329
15847
  return () => window.removeEventListener("message", onSitePages);
15330
15848
  }, [isEditMode, postToParent2]);
15331
- (0, import_react16.useEffect)(() => {
15849
+ (0, import_react17.useEffect)(() => {
15332
15850
  if (!isEditMode || shouldUseDevFixtures()) return;
15333
15851
  void loadAllSectionsManifest().then((manifest) => {
15334
15852
  if (Object.keys(manifest).length === 0) return;
15335
15853
  setSectionsByPath((prev) => ({ ...manifest, ...prev }));
15336
15854
  });
15337
15855
  }, [isEditMode]);
15338
- (0, import_react16.useEffect)(() => {
15856
+ (0, import_react17.useEffect)(() => {
15339
15857
  const update = () => {
15340
15858
  const el = activeElRef.current ?? selectedElRef.current;
15341
15859
  if (el) setToolbarRect(getEditMeasureEl(el).getBoundingClientRect());
@@ -15359,10 +15877,10 @@ function OhhwellsBridge() {
15359
15877
  vvp.removeEventListener("resize", update);
15360
15878
  };
15361
15879
  }, []);
15362
- const refreshStateRules = (0, import_react16.useCallback)(() => {
15880
+ const refreshStateRules = (0, import_react17.useCallback)(() => {
15363
15881
  editStylesRef.current?.forceHover && (editStylesRef.current.forceHover.textContent = collectStateRules());
15364
15882
  }, []);
15365
- const processConfigRequest = (0, import_react16.useCallback)((insertAfterVal) => {
15883
+ const processConfigRequest = (0, import_react17.useCallback)((insertAfterVal) => {
15366
15884
  const tracker = getSectionsTracker();
15367
15885
  let entries = [];
15368
15886
  try {
@@ -15385,7 +15903,7 @@ function OhhwellsBridge() {
15385
15903
  }
15386
15904
  window.postMessage({ type: "ow:schedule-config", insertAfter: insertAfterVal, scheduleId: null }, "*");
15387
15905
  }, [isEditMode]);
15388
- const deactivate = (0, import_react16.useCallback)(() => {
15906
+ const deactivate = (0, import_react17.useCallback)(() => {
15389
15907
  const el = activeElRef.current;
15390
15908
  if (!el) return;
15391
15909
  const isFormBlock = el.dataset.ohwEditable === "form";
@@ -15401,7 +15919,7 @@ function OhhwellsBridge() {
15401
15919
  const original = originalContentRef.current ?? "";
15402
15920
  if (html !== sanitizeHtml(original)) {
15403
15921
  postToParentRef.current({ type: "ow:change", nodes: [{ key, text: html }] });
15404
- const h = document.documentElement.scrollHeight;
15922
+ const h = document.body.scrollHeight;
15405
15923
  if (h > 50) postToParentRef.current({ type: "ow:height", height: h });
15406
15924
  }
15407
15925
  }
@@ -15426,12 +15944,12 @@ function OhhwellsBridge() {
15426
15944
  setToolbarShowEditLink(false);
15427
15945
  postToParent2({ type: "ow:exit-edit" });
15428
15946
  }, [postToParent2]);
15429
- const clearSelectedAttr = (0, import_react16.useCallback)(() => {
15947
+ const clearSelectedAttr = (0, import_react17.useCallback)(() => {
15430
15948
  document.querySelectorAll("[data-ohw-selected]").forEach((el) => {
15431
15949
  el.removeAttribute("data-ohw-selected");
15432
15950
  });
15433
15951
  }, []);
15434
- const deselect = (0, import_react16.useCallback)(() => {
15952
+ const deselect = (0, import_react17.useCallback)(() => {
15435
15953
  clearSelectedAttr();
15436
15954
  selectedElRef.current = null;
15437
15955
  selectedHrefKeyRef.current = null;
@@ -15460,20 +15978,20 @@ function OhhwellsBridge() {
15460
15978
  setToolbarVariant("none");
15461
15979
  }
15462
15980
  }, [clearSelectedAttr]);
15463
- const markSelected = (0, import_react16.useCallback)((el) => {
15981
+ const markSelected = (0, import_react17.useCallback)((el) => {
15464
15982
  clearSelectedAttr();
15465
15983
  el.removeAttribute("data-ohw-hovered");
15466
15984
  el.setAttribute("data-ohw-selected", "");
15467
15985
  }, [clearSelectedAttr]);
15468
- const isSelectedForHover = (0, import_react16.useCallback)((el) => {
15986
+ const isSelectedForHover = (0, import_react17.useCallback)((el) => {
15469
15987
  if (!el) return false;
15470
15988
  return [selectedElRef.current, activeElRef.current].some(
15471
15989
  (busy) => busy && (el === busy || busy.contains(el) || el.contains(busy))
15472
15990
  );
15473
15991
  }, []);
15474
- const isSelectedForHoverRef = (0, import_react16.useRef)(isSelectedForHover);
15992
+ const isSelectedForHoverRef = (0, import_react17.useRef)(isSelectedForHover);
15475
15993
  isSelectedForHoverRef.current = isSelectedForHover;
15476
- const resolveHrefKeyElement = (0, import_react16.useCallback)((hrefKey) => {
15994
+ const resolveHrefKeyElement = (0, import_react17.useCallback)((hrefKey) => {
15477
15995
  if (isFooterHrefKey(hrefKey)) {
15478
15996
  return document.querySelector(
15479
15997
  `footer [data-ohw-href-key="${CSS.escape(hrefKey)}"]`
@@ -15488,7 +16006,7 @@ function OhhwellsBridge() {
15488
16006
  `[data-ohw-href-key="${CSS.escape(hrefKey)}"]`
15489
16007
  );
15490
16008
  }, []);
15491
- const resyncSelectedNavigationItem = (0, import_react16.useCallback)(() => {
16009
+ const resyncSelectedNavigationItem = (0, import_react17.useCallback)(() => {
15492
16010
  const hrefKey = selectedHrefKeyRef.current;
15493
16011
  if (hrefKey) {
15494
16012
  const link = resolveHrefKeyElement(hrefKey);
@@ -15526,7 +16044,7 @@ function OhhwellsBridge() {
15526
16044
  );
15527
16045
  }
15528
16046
  }, [resolveHrefKeyElement]);
15529
- const reselectNavigationItem = (0, import_react16.useCallback)((navAnchor) => {
16047
+ const reselectNavigationItem = (0, import_react17.useCallback)((navAnchor) => {
15530
16048
  selectedElRef.current = navAnchor;
15531
16049
  selectedHrefKeyRef.current = navAnchor.getAttribute("data-ohw-href-key");
15532
16050
  selectedFooterColAttrRef.current = null;
@@ -15557,7 +16075,7 @@ function OhhwellsBridge() {
15557
16075
  setToolbarShowEditLink(false);
15558
16076
  setActiveCommands(/* @__PURE__ */ new Set());
15559
16077
  }, [markSelected]);
15560
- const commitNavigationTextEdit = (0, import_react16.useCallback)((navAnchor) => {
16078
+ const commitNavigationTextEdit = (0, import_react17.useCallback)((navAnchor) => {
15561
16079
  const el = activeElRef.current;
15562
16080
  if (!el) return;
15563
16081
  const key = el.dataset.ohwKey;
@@ -15571,7 +16089,7 @@ function OhhwellsBridge() {
15571
16089
  const original = originalContentRef.current ?? "";
15572
16090
  if (html !== sanitizeHtml(original)) {
15573
16091
  postToParent2({ type: "ow:change", nodes: [{ key, text: html }] });
15574
- const h = document.documentElement.scrollHeight;
16092
+ const h = document.body.scrollHeight;
15575
16093
  if (h > 50) postToParent2({ type: "ow:height", height: h });
15576
16094
  }
15577
16095
  }
@@ -15590,7 +16108,7 @@ function OhhwellsBridge() {
15590
16108
  postToParent2({ type: "ow:exit-edit" });
15591
16109
  reselectNavigationItem(navAnchor);
15592
16110
  }, [postToParent2, reselectNavigationItem]);
15593
- const handleAddTopLevelNavItem = (0, import_react16.useCallback)(() => {
16111
+ const handleAddTopLevelNavItem = (0, import_react17.useCallback)(() => {
15594
16112
  const items = listNavbarRootItems();
15595
16113
  addNavAfterAnchorRef.current = items[items.length - 1] ?? null;
15596
16114
  deselectRef.current();
@@ -15602,7 +16120,7 @@ function OhhwellsBridge() {
15602
16120
  intent: "add-nav"
15603
16121
  });
15604
16122
  }, []);
15605
- const maybeWarnNavLinkDropdownConflict = (0, import_react16.useCallback)(
16123
+ const maybeWarnNavLinkDropdownConflict = (0, import_react17.useCallback)(
15606
16124
  (anchor) => {
15607
16125
  if (!isNavbarHrefKey(anchor.getAttribute("data-ohw-href-key"))) return;
15608
16126
  if (!navDropdownsOpenOnClick()) return;
@@ -15615,7 +16133,7 @@ function OhhwellsBridge() {
15615
16133
  },
15616
16134
  [postToParent2]
15617
16135
  );
15618
- const handleNavDropdownOpenChange = (0, import_react16.useCallback)((open) => {
16136
+ const handleNavDropdownOpenChange = (0, import_react17.useCallback)((open) => {
15619
16137
  const selected = selectedElRef.current;
15620
16138
  if (!selected || !isNavigationItem2(selected)) return;
15621
16139
  setNavGroupForceOpen(selected, open);
@@ -15627,7 +16145,7 @@ function OhhwellsBridge() {
15627
16145
  }
15628
16146
  });
15629
16147
  }, []);
15630
- const handleFooterHeadingVisibleChange = (0, import_react16.useCallback)(
16148
+ const handleFooterHeadingVisibleChange = (0, import_react17.useCallback)(
15631
16149
  (visible) => {
15632
16150
  const selected = selectedElRef.current;
15633
16151
  if (!selected || !isFooterFrameSelectionRef.current) return;
@@ -15651,7 +16169,7 @@ function OhhwellsBridge() {
15651
16169
  },
15652
16170
  [postToParent2]
15653
16171
  );
15654
- const enterEditOnNewItem = (0, import_react16.useCallback)((anchor) => {
16172
+ const enterEditOnNewItem = (0, import_react17.useCallback)((anchor) => {
15655
16173
  const label = anchor.querySelector('[data-ohw-editable="text"]');
15656
16174
  if (!label) {
15657
16175
  selectRef.current(anchor);
@@ -15660,8 +16178,8 @@ function OhhwellsBridge() {
15660
16178
  setNavGroupForceOpen(anchor, true);
15661
16179
  activateRef.current(label);
15662
16180
  }, []);
15663
- const pendingSocialAddRef = (0, import_react16.useRef)(null);
15664
- const handleAddChildItem = (0, import_react16.useCallback)(() => {
16181
+ const pendingSocialAddRef = (0, import_react17.useRef)(null);
16182
+ const handleAddChildItem = (0, import_react17.useCallback)(() => {
15665
16183
  const selected = selectedElRef.current;
15666
16184
  if (!selected) return;
15667
16185
  const socialsRow = isSocialsRow(selected) ? selected : findSocialsRow(selected);
@@ -15770,7 +16288,7 @@ function OhhwellsBridge() {
15770
16288
  enterEditOnNewItem(result.anchor);
15771
16289
  });
15772
16290
  }, [enterEditOnNewItem, isFooterFrameSelection, maybeWarnNavLinkDropdownConflict, postToParent2]);
15773
- const handleAddFooterColumn = (0, import_react16.useCallback)(() => {
16291
+ const handleAddFooterColumn = (0, import_react17.useCallback)(() => {
15774
16292
  if (!canAddFooterColumn()) {
15775
16293
  postToParent2({
15776
16294
  type: "ow:toast",
@@ -15791,7 +16309,7 @@ function OhhwellsBridge() {
15791
16309
  selectRef.current(result.firstLink);
15792
16310
  });
15793
16311
  }, [postToParent2]);
15794
- const clearFooterDragVisuals = (0, import_react16.useCallback)(() => {
16312
+ const clearFooterDragVisuals = (0, import_react17.useCallback)(() => {
15795
16313
  footerDragRef.current = null;
15796
16314
  setSiblingHintRects([]);
15797
16315
  setFooterDropSlots([]);
@@ -15800,7 +16318,7 @@ function OhhwellsBridge() {
15800
16318
  setIsItemDragging(false);
15801
16319
  unlockFooterDragInteraction();
15802
16320
  }, []);
15803
- const refreshFooterDragVisuals = (0, import_react16.useCallback)((session, activeSlot, clientX, clientY) => {
16321
+ const refreshFooterDragVisuals = (0, import_react17.useCallback)((session, activeSlot, clientX, clientY) => {
15804
16322
  const dragged = session.draggedEl;
15805
16323
  setDraggedItemRect(dragged.getBoundingClientRect());
15806
16324
  if (typeof clientX === "number" && typeof clientY === "number") {
@@ -15832,13 +16350,13 @@ function OhhwellsBridge() {
15832
16350
  const activeIdx = activeSlot ? slots.findIndex((s) => s.insertIndex === activeSlot.insertIndex) : -1;
15833
16351
  setActiveFooterDropIndex(activeIdx >= 0 ? activeIdx : null);
15834
16352
  }, []);
15835
- const refreshFooterDragVisualsRef = (0, import_react16.useRef)(refreshFooterDragVisuals);
16353
+ const refreshFooterDragVisualsRef = (0, import_react17.useRef)(refreshFooterDragVisuals);
15836
16354
  refreshFooterDragVisualsRef.current = refreshFooterDragVisuals;
15837
- const commitFooterDragRef = (0, import_react16.useRef)(() => {
16355
+ const commitFooterDragRef = (0, import_react17.useRef)(() => {
15838
16356
  });
15839
- const beginFooterDragRef = (0, import_react16.useRef)(() => {
16357
+ const beginFooterDragRef = (0, import_react17.useRef)(() => {
15840
16358
  });
15841
- const beginFooterDrag = (0, import_react16.useCallback)(
16359
+ const beginFooterDrag = (0, import_react17.useCallback)(
15842
16360
  (session) => {
15843
16361
  const rect = session.draggedEl.getBoundingClientRect();
15844
16362
  session.lastClientX = session.lastClientX || rect.left + rect.width / 2;
@@ -15858,7 +16376,7 @@ function OhhwellsBridge() {
15858
16376
  [refreshFooterDragVisuals]
15859
16377
  );
15860
16378
  beginFooterDragRef.current = beginFooterDrag;
15861
- const commitFooterDrag = (0, import_react16.useCallback)(
16379
+ const commitFooterDrag = (0, import_react17.useCallback)(
15862
16380
  (clientX, clientY) => {
15863
16381
  const session = footerDragRef.current;
15864
16382
  if (!session) {
@@ -15987,7 +16505,7 @@ function OhhwellsBridge() {
15987
16505
  [clearFooterDragVisuals, resolveHrefKeyElement, resyncSelectedNavigationItem]
15988
16506
  );
15989
16507
  commitFooterDragRef.current = commitFooterDrag;
15990
- const startFooterLinkDrag = (0, import_react16.useCallback)(
16508
+ const startFooterLinkDrag = (0, import_react17.useCallback)(
15991
16509
  (anchor, clientX, clientY, wasSelected) => {
15992
16510
  const hrefKey = anchor.getAttribute("data-ohw-href-key");
15993
16511
  if (!hrefKey) return false;
@@ -16023,7 +16541,7 @@ function OhhwellsBridge() {
16023
16541
  },
16024
16542
  [beginFooterDrag]
16025
16543
  );
16026
- const startFooterColumnDrag = (0, import_react16.useCallback)(
16544
+ const startFooterColumnDrag = (0, import_react17.useCallback)(
16027
16545
  (columnEl, clientX, clientY, wasSelected) => {
16028
16546
  const columns = listFooterColumns();
16029
16547
  const idx = columns.indexOf(columnEl);
@@ -16043,7 +16561,7 @@ function OhhwellsBridge() {
16043
16561
  },
16044
16562
  [beginFooterDrag]
16045
16563
  );
16046
- const handleItemDragStart = (0, import_react16.useCallback)(
16564
+ const handleItemDragStart = (0, import_react17.useCallback)(
16047
16565
  (e) => {
16048
16566
  const selected = selectedElRef.current;
16049
16567
  if (!selected) {
@@ -16063,7 +16581,7 @@ function OhhwellsBridge() {
16063
16581
  },
16064
16582
  [startFooterColumnDrag, startFooterLinkDrag, startNavLinkDrag]
16065
16583
  );
16066
- const handleItemDragEnd = (0, import_react16.useCallback)(
16584
+ const handleItemDragEnd = (0, import_react17.useCallback)(
16067
16585
  (e) => {
16068
16586
  if (footerDragRef.current) {
16069
16587
  const x = e?.clientX;
@@ -16089,7 +16607,7 @@ function OhhwellsBridge() {
16089
16607
  },
16090
16608
  [commitFooterDrag, commitNavDrag, navDragRef]
16091
16609
  );
16092
- const handleItemChromePointerDown = (0, import_react16.useCallback)((e) => {
16610
+ const handleItemChromePointerDown = (0, import_react17.useCallback)((e) => {
16093
16611
  if (e.button !== 0) return;
16094
16612
  const selected = selectedElRef.current;
16095
16613
  if (!selected) return;
@@ -16120,7 +16638,7 @@ function OhhwellsBridge() {
16120
16638
  }
16121
16639
  if (armNavPressFromChrome(selected, e.clientX, e.clientY, e.pointerId)) return;
16122
16640
  }, [armNavPressFromChrome]);
16123
- const handleItemChromeClick = (0, import_react16.useCallback)((clientX, clientY) => {
16641
+ const handleItemChromeClick = (0, import_react17.useCallback)((clientX, clientY) => {
16124
16642
  if (suppressNextClickRef.current || Date.now() < suppressClickUntilRef.current) {
16125
16643
  suppressNextClickRef.current = false;
16126
16644
  return;
@@ -16133,7 +16651,7 @@ function OhhwellsBridge() {
16133
16651
  }, []);
16134
16652
  reselectNavigationItemRef.current = reselectNavigationItem;
16135
16653
  commitNavigationTextEditRef.current = commitNavigationTextEdit;
16136
- const select = (0, import_react16.useCallback)((anchor) => {
16654
+ const select = (0, import_react17.useCallback)((anchor) => {
16137
16655
  if (!isNavigationItem2(anchor)) return;
16138
16656
  if (activeElRef.current) deactivate();
16139
16657
  aiSectionApiRef.current?.selectFromElement(anchor);
@@ -16176,7 +16694,7 @@ function OhhwellsBridge() {
16176
16694
  setFloatingPanel(null);
16177
16695
  setLogoSizeDraft(null);
16178
16696
  }, [deactivate, markSelected]);
16179
- const selectFrame = (0, import_react16.useCallback)((el) => {
16697
+ const selectFrame = (0, import_react17.useCallback)((el) => {
16180
16698
  if (!isNavigationContainer(el)) return;
16181
16699
  if (activeElRef.current) deactivate();
16182
16700
  aiSectionApiRef.current?.selectFromElement(el);
@@ -16227,7 +16745,7 @@ function OhhwellsBridge() {
16227
16745
  setFloatingPanel(null);
16228
16746
  setLogoSizeDraft(null);
16229
16747
  }, [deactivate, markSelected, postToParent2]);
16230
- const selectLogo = (0, import_react16.useCallback)(
16748
+ const selectLogo = (0, import_react17.useCallback)(
16231
16749
  (logoEl) => {
16232
16750
  if (activeElRef.current) deactivate();
16233
16751
  selectedElRef.current = logoEl;
@@ -16256,7 +16774,7 @@ function OhhwellsBridge() {
16256
16774
  },
16257
16775
  [deactivate, markSelected]
16258
16776
  );
16259
- const openLogoSizePanel = (0, import_react16.useCallback)((logoEl) => {
16777
+ const openLogoSizePanel = (0, import_react17.useCallback)((logoEl) => {
16260
16778
  const placement = getLogoPlacement(logoEl);
16261
16779
  const draft = readLogoSizeState(editContentRef.current, placement);
16262
16780
  setLogoSizeDraft(draft);
@@ -16269,7 +16787,7 @@ function OhhwellsBridge() {
16269
16787
  placement
16270
16788
  });
16271
16789
  }, []);
16272
- const openSocialsDisplayPanel = (0, import_react16.useCallback)((row) => {
16790
+ const openSocialsDisplayPanel = (0, import_react17.useCallback)((row) => {
16273
16791
  setParentScrollSnap(parentScrollRef.current);
16274
16792
  setFloatingPanel({
16275
16793
  key: "socials-display",
@@ -16279,11 +16797,11 @@ function OhhwellsBridge() {
16279
16797
  row
16280
16798
  });
16281
16799
  }, []);
16282
- const isEditModeRef = (0, import_react16.useRef)(false);
16283
- const requestMissingSocialIconsRef = (0, import_react16.useRef)(() => {
16800
+ const isEditModeRef = (0, import_react17.useRef)(false);
16801
+ const requestMissingSocialIconsRef = (0, import_react17.useRef)(() => {
16284
16802
  });
16285
- const askedSocialIconsRef = (0, import_react16.useRef)(/* @__PURE__ */ new Set());
16286
- const requestMissingSocialIcons = (0, import_react16.useCallback)(() => {
16803
+ const askedSocialIconsRef = (0, import_react17.useRef)(/* @__PURE__ */ new Set());
16804
+ const requestMissingSocialIcons = (0, import_react17.useCallback)(() => {
16287
16805
  const items = Array.from(document.querySelectorAll(`[${SOCIALS_ROW_ATTR}]`)).filter((row) => socialsDisplayFor(row, editContentRef.current).icon).flatMap((row) => {
16288
16806
  const missing = socialsMissingIcons(row);
16289
16807
  listSocialItems(row).forEach((item) => ensureIconSlot(item));
@@ -16295,7 +16813,7 @@ function OhhwellsBridge() {
16295
16813
  }, []);
16296
16814
  requestMissingSocialIconsRef.current = requestMissingSocialIcons;
16297
16815
  isEditModeRef.current = isEditMode;
16298
- const changeSocialsDisplay = (0, import_react16.useCallback)(
16816
+ const changeSocialsDisplay = (0, import_react17.useCallback)(
16299
16817
  (row, next) => {
16300
16818
  if (next.icon) {
16301
16819
  const missing = socialsMissingIcons(row);
@@ -16319,17 +16837,17 @@ function OhhwellsBridge() {
16319
16837
  },
16320
16838
  []
16321
16839
  );
16322
- const closeFloatingPanelOnly = (0, import_react16.useCallback)(() => {
16840
+ const closeFloatingPanelOnly = (0, import_react17.useCallback)(() => {
16323
16841
  setFloatingPanel(null);
16324
16842
  setLogoSizeDraft(null);
16325
16843
  }, []);
16326
16844
  closeFloatingPanelOnlyRef.current = closeFloatingPanelOnly;
16327
- const closeFloatingPanelAndDeselect = (0, import_react16.useCallback)(() => {
16845
+ const closeFloatingPanelAndDeselect = (0, import_react17.useCallback)(() => {
16328
16846
  setFloatingPanel(null);
16329
16847
  setLogoSizeDraft(null);
16330
16848
  deselectRef.current();
16331
16849
  }, []);
16332
- (0, import_react16.useEffect)(() => {
16850
+ (0, import_react17.useEffect)(() => {
16333
16851
  const session = floatingPanel && floatingPanel.kind === "logo-size" ? floatingPanel : null;
16334
16852
  if (!session || !logoSizeDraft) {
16335
16853
  postToParentRef.current({ type: "ow:logo-size-panel", open: false });
@@ -16348,7 +16866,7 @@ function OhhwellsBridge() {
16348
16866
  max: LOGO_SIZE_MAX
16349
16867
  });
16350
16868
  }, [floatingPanel, logoSizeDraft, editorViewport]);
16351
- const persistLogoSizeDraft = (0, import_react16.useCallback)(
16869
+ const persistLogoSizeDraft = (0, import_react17.useCallback)(
16352
16870
  (placement, draft) => {
16353
16871
  const desktopKey = LOGO_SIZE_DESKTOP_KEYS[placement];
16354
16872
  const mobileKey = LOGO_SIZE_MOBILE_KEYS[placement];
@@ -16388,7 +16906,7 @@ function OhhwellsBridge() {
16388
16906
  },
16389
16907
  [postToParent2]
16390
16908
  );
16391
- const activate = (0, import_react16.useCallback)((el, options) => {
16909
+ const activate = (0, import_react17.useCallback)((el, options) => {
16392
16910
  if (activeElRef.current === el) return;
16393
16911
  document.querySelectorAll("[data-ohw-hovered]").forEach((hovered) => {
16394
16912
  hovered.removeAttribute("data-ohw-hovered");
@@ -16486,8 +17004,8 @@ function OhhwellsBridge() {
16486
17004
  openLogoSizePanelRef.current = openLogoSizePanel;
16487
17005
  deselectRef.current = deselect;
16488
17006
  closeFloatingPanelOnlyRef.current = closeFloatingPanelOnly;
16489
- const lastSiteWideScopeRef = (0, import_react16.useRef)(null);
16490
- (0, import_react16.useEffect)(() => {
17007
+ const lastSiteWideScopeRef = (0, import_react17.useRef)(null);
17008
+ (0, import_react17.useEffect)(() => {
16491
17009
  if (!isEditMode) {
16492
17010
  if (lastSiteWideScopeRef.current !== false) {
16493
17011
  lastSiteWideScopeRef.current = false;
@@ -16513,7 +17031,7 @@ function OhhwellsBridge() {
16513
17031
  isFooterFrameSelection,
16514
17032
  postToParent2
16515
17033
  ]);
16516
- (0, import_react16.useLayoutEffect)(() => {
17034
+ (0, import_react17.useLayoutEffect)(() => {
16517
17035
  if (!subdomain || isEditMode) {
16518
17036
  setFetchState("done");
16519
17037
  return;
@@ -16607,7 +17125,7 @@ function OhhwellsBridge() {
16607
17125
  cancelled = true;
16608
17126
  };
16609
17127
  }, [subdomain, isEditMode]);
16610
- (0, import_react16.useEffect)(() => {
17128
+ (0, import_react17.useEffect)(() => {
16611
17129
  if (!isEditMode) return;
16612
17130
  const resolveIndex = (form, clientY) => {
16613
17131
  const wrappers = listFieldWrappers(form).filter((el) => fieldKeyOf(el) !== fieldDragRef.current?.key);
@@ -16648,7 +17166,7 @@ function OhhwellsBridge() {
16648
17166
  window.removeEventListener("drop", onDrop, true);
16649
17167
  };
16650
17168
  }, [buildFieldDropSlots, isEditMode, persistFields, selectField]);
16651
- (0, import_react16.useEffect)(() => {
17169
+ (0, import_react17.useEffect)(() => {
16652
17170
  if (!isEditMode) return;
16653
17171
  const mark = () => document.querySelectorAll('[data-ohw-editable="form"]').forEach((form) => {
16654
17172
  markFormFields(form);
@@ -16660,7 +17178,7 @@ function OhhwellsBridge() {
16660
17178
  });
16661
17179
  return () => observer.disconnect();
16662
17180
  }, [isEditMode, fetchState, pathname]);
16663
- (0, import_react16.useEffect)(() => {
17181
+ (0, import_react17.useEffect)(() => {
16664
17182
  if (!isEditMode) return;
16665
17183
  let saveTimer = null;
16666
17184
  const onInput = (e) => {
@@ -16682,14 +17200,14 @@ function OhhwellsBridge() {
16682
17200
  document.addEventListener("input", onInput, true);
16683
17201
  return () => document.removeEventListener("input", onInput, true);
16684
17202
  }, [isEditMode, persistFields]);
16685
- (0, import_react16.useEffect)(() => {
17203
+ (0, import_react17.useEffect)(() => {
16686
17204
  if (isEditMode || fetchState !== "done") return;
16687
17205
  const content = contentCache.get(subdomain) ?? {};
16688
17206
  document.querySelectorAll('[data-ohw-editable="form"]').forEach((form) => {
16689
17207
  reconcileFieldsFromContent(form, content);
16690
17208
  });
16691
17209
  }, [isEditMode, fetchState, subdomain]);
16692
- (0, import_react16.useEffect)(() => {
17210
+ (0, import_react17.useEffect)(() => {
16693
17211
  if (!isEditMode) return;
16694
17212
  const swallow = (e) => {
16695
17213
  const target = e.target;
@@ -16698,12 +17216,12 @@ function OhhwellsBridge() {
16698
17216
  document.addEventListener("submit", swallow, true);
16699
17217
  return () => document.removeEventListener("submit", swallow, true);
16700
17218
  }, [isEditMode]);
16701
- (0, import_react16.useEffect)(() => {
17219
+ (0, import_react17.useEffect)(() => {
16702
17220
  if (isEditMode || fetchState !== "done") return;
16703
17221
  const apiUrl = process.env.NEXT_PUBLIC_FLOWOPS_API_URL ?? "https://flowops-backend-staging-2yfdh7pwpq-as.a.run.app";
16704
17222
  bindPublishedForms(apiUrl, subdomain, contentCache.get(subdomain) ?? {});
16705
17223
  }, [isEditMode, fetchState, subdomain]);
16706
- (0, import_react16.useEffect)(() => {
17224
+ (0, import_react17.useEffect)(() => {
16707
17225
  if (!subdomain || isEditMode) return;
16708
17226
  let debounceTimer = null;
16709
17227
  let observer = null;
@@ -16770,16 +17288,16 @@ function OhhwellsBridge() {
16770
17288
  if (debounceTimer) clearTimeout(debounceTimer);
16771
17289
  };
16772
17290
  }, [subdomain, isEditMode, pathname]);
16773
- (0, import_react16.useLayoutEffect)(() => {
17291
+ (0, import_react17.useLayoutEffect)(() => {
16774
17292
  const el = document.getElementById("ohw-loader");
16775
17293
  if (!el) return;
16776
17294
  const visible = Boolean(subdomain) && fetchState !== "done";
16777
17295
  el.style.display = visible ? "flex" : "none";
16778
17296
  }, [subdomain, fetchState]);
16779
- (0, import_react16.useEffect)(() => {
17297
+ (0, import_react17.useEffect)(() => {
16780
17298
  postToParent2({ type: "ow:navigation", path: pathname });
16781
17299
  }, [pathname, postToParent2]);
16782
- (0, import_react16.useEffect)(() => {
17300
+ (0, import_react17.useEffect)(() => {
16783
17301
  if (!isEditMode) return;
16784
17302
  if (linkPopoverSessionRef.current?.intent === "add-nav") return;
16785
17303
  if (document.querySelector("[data-ohw-section-picker]")) return;
@@ -16787,7 +17305,7 @@ function OhhwellsBridge() {
16787
17305
  deselectRef.current();
16788
17306
  deactivateRef.current();
16789
17307
  }, [pathname, isEditMode]);
16790
- (0, import_react16.useEffect)(() => {
17308
+ (0, import_react17.useEffect)(() => {
16791
17309
  const contentForNav = () => {
16792
17310
  if (isEditMode) return editContentRef.current;
16793
17311
  if (!subdomain) return {};
@@ -16856,7 +17374,7 @@ function OhhwellsBridge() {
16856
17374
  observer?.disconnect();
16857
17375
  };
16858
17376
  }, [isEditMode, pathname, subdomain, fetchState, resyncSelectedNavigationItem]);
16859
- (0, import_react16.useEffect)(() => {
17377
+ (0, import_react17.useEffect)(() => {
16860
17378
  if (!isEditMode) return;
16861
17379
  const measure = () => {
16862
17380
  const h = document.body.scrollHeight;
@@ -16884,7 +17402,7 @@ function OhhwellsBridge() {
16884
17402
  window.removeEventListener("resize", handleResize);
16885
17403
  };
16886
17404
  }, [pathname, isEditMode, postToParent2]);
16887
- (0, import_react16.useEffect)(() => {
17405
+ (0, import_react17.useEffect)(() => {
16888
17406
  if (!subdomainFromQuery || isEditMode) return;
16889
17407
  const handleClick = (e) => {
16890
17408
  const anchor = e.target.closest("a");
@@ -16900,7 +17418,7 @@ function OhhwellsBridge() {
16900
17418
  document.addEventListener("click", handleClick, true);
16901
17419
  return () => document.removeEventListener("click", handleClick, true);
16902
17420
  }, [subdomainFromQuery, isEditMode, router]);
16903
- (0, import_react16.useEffect)(() => {
17421
+ (0, import_react17.useEffect)(() => {
16904
17422
  if (!isEditMode) {
16905
17423
  editStylesRef.current?.base.remove();
16906
17424
  editStylesRef.current?.forceHover.remove();
@@ -17284,6 +17802,14 @@ function OhhwellsBridge() {
17284
17802
  }
17285
17803
  const clickedButton = findClosestButtonLike(target);
17286
17804
  const buttonOnMedia = Boolean(clickedButton && isMediaEditable(editable) && editable.contains(clickedButton));
17805
+ console.log("[click-debug]", {
17806
+ editableType: editable.dataset.ohwEditable,
17807
+ editableTag: editable.tagName,
17808
+ targetTag: target.tagName,
17809
+ clickedButtonTag: clickedButton?.tagName ?? null,
17810
+ buttonOnMedia,
17811
+ isMediaEditableEditable: isMediaEditable(editable)
17812
+ });
17287
17813
  if (isMediaEditable(editable) && !buttonOnMedia) {
17288
17814
  e.preventDefault();
17289
17815
  e.stopPropagation();
@@ -17307,6 +17833,11 @@ function OhhwellsBridge() {
17307
17833
  const hrefLookupTarget = buttonOnMedia ? clickedButton : editable;
17308
17834
  const hrefCtx = getHrefKeyFromElement(hrefLookupTarget);
17309
17835
  const navAnchor = hrefCtx ? getNavigationItemAnchor(hrefCtx.anchor) : null;
17836
+ console.log("[click-debug 2]", {
17837
+ hrefLookupTargetTag: hrefLookupTarget.tagName,
17838
+ hrefCtx: hrefCtx ? { key: hrefCtx.key } : null,
17839
+ navAnchorTag: navAnchor?.tagName ?? null
17840
+ });
17310
17841
  if (navAnchor) {
17311
17842
  e.preventDefault();
17312
17843
  e.stopPropagation();
@@ -18548,7 +19079,7 @@ function OhhwellsBridge() {
18548
19079
  timers.set(key, setTimeout(() => {
18549
19080
  timers.delete(key);
18550
19081
  postToParentRef.current({ type: "ow:change", nodes: [{ key, text: html }] });
18551
- const h = document.documentElement.scrollHeight;
19082
+ const h = document.body.scrollHeight;
18552
19083
  if (h > 50) postToParentRef.current({ type: "ow:height", height: h });
18553
19084
  }, 400));
18554
19085
  };
@@ -18602,7 +19133,7 @@ function OhhwellsBridge() {
18602
19133
  reconcileFooterOrderFromContent(editContentRef.current);
18603
19134
  syncNavigationDragCursorAttrs();
18604
19135
  enforceLinkHrefs();
18605
- const hydratedHeight = document.documentElement.scrollHeight;
19136
+ const hydratedHeight = document.body.scrollHeight;
18606
19137
  if (hydratedHeight > 50) postToParentRef.current({ type: "ow:height", height: hydratedHeight });
18607
19138
  postToParentRef.current({ type: "ow:hydrate-done" });
18608
19139
  };
@@ -18675,7 +19206,7 @@ function OhhwellsBridge() {
18675
19206
  const nextValue = serializeAiSectionsState(nextState);
18676
19207
  aiSectionsRef.current = nextValue;
18677
19208
  applyAiSectionsToDom(nextState);
18678
- const newHeight = document.documentElement.scrollHeight;
19209
+ const newHeight = document.body.scrollHeight;
18679
19210
  if (newHeight > 50) postToParentRef.current({ type: "ow:height", height: newHeight });
18680
19211
  postToParentRef.current({ type: "ow:change", nodes: [{ key: AI_SECTIONS_KEY, text: nextValue }] });
18681
19212
  const appliedEl = document.querySelector(`[data-ohw-section="${CSS.escape(payload.id)}"]`);
@@ -18697,7 +19228,7 @@ function OhhwellsBridge() {
18697
19228
  const nextValue = serializeAiSectionsState(nextState);
18698
19229
  aiSectionsRef.current = nextValue;
18699
19230
  applyAiSectionsToDom(nextState);
18700
- const newHeight = document.documentElement.scrollHeight;
19231
+ const newHeight = document.body.scrollHeight;
18701
19232
  if (newHeight > 50) postToParentRef.current({ type: "ow:height", height: newHeight });
18702
19233
  postToParentRef.current({ type: "ow:change", nodes: [{ key: AI_SECTIONS_KEY, text: nextValue }] });
18703
19234
  postToParentRef.current({ type: "ow:ai-section-deleted", sectionId, previous, value: nextValue });
@@ -18709,18 +19240,73 @@ function OhhwellsBridge() {
18709
19240
  const value = typeof e.data.value === "string" ? e.data.value : "";
18710
19241
  aiSectionsRef.current = value;
18711
19242
  applyAiSectionsToDom(parseAiSectionsState(value));
18712
- const restoredHeight = document.documentElement.scrollHeight;
19243
+ const restoredHeight = document.body.scrollHeight;
18713
19244
  if (restoredHeight > 50) postToParentRef.current({ type: "ow:height", height: restoredHeight });
18714
19245
  postToParentRef.current({ type: "ow:change", nodes: [{ key: AI_SECTIONS_KEY, text: value }] });
18715
19246
  postAiSectionsChanged();
18716
19247
  };
18717
19248
  window.addEventListener("message", handleAiSetSections);
19249
+ const handleMoveSection = (e) => {
19250
+ if (e.data?.type !== "ow:move-section") return;
19251
+ const instanceId = typeof e.data.instanceId === "string" ? e.data.instanceId : "";
19252
+ const direction = e.data.direction === "up" || e.data.direction === "down" ? e.data.direction : null;
19253
+ if (!instanceId || !direction) return;
19254
+ const entries = moveSectionInstance(instanceId, direction, window.location.pathname);
19255
+ if (!entries) return;
19256
+ const orderJson = JSON.stringify(entries);
19257
+ editContentRef.current = { ...editContentRef.current, [SECTION_ORDER_KEY]: orderJson };
19258
+ postToParentRef.current({ type: "ow:change", nodes: [{ key: SECTION_ORDER_KEY, text: orderJson }] });
19259
+ window.dispatchEvent(new Event("resize"));
19260
+ };
19261
+ window.addEventListener("message", handleMoveSection);
18718
19262
  const handlePanelDragging = (e) => {
18719
19263
  if (e.data?.type !== "ow:panel-dragging") return;
18720
19264
  if (e.data.dragging) document.documentElement.setAttribute("data-ohw-panel-dragging", "");
18721
19265
  else document.documentElement.removeAttribute("data-ohw-panel-dragging");
18722
19266
  };
18723
19267
  window.addEventListener("message", handlePanelDragging);
19268
+ const handleDeleteSection = (e) => {
19269
+ if (e.data?.type !== "ow:delete-section") return;
19270
+ const instanceId = typeof e.data.instanceId === "string" ? e.data.instanceId : "";
19271
+ if (!instanceId) return;
19272
+ const currentEntries = getPageSectionOrderEntries(editContentRef.current[SECTION_ORDER_KEY], window.location.pathname);
19273
+ const entries = deleteSectionInstance(instanceId, window.location.pathname, currentEntries);
19274
+ if (!entries) return;
19275
+ const orderJson = JSON.stringify(entries);
19276
+ editContentRef.current = { ...editContentRef.current, [SECTION_ORDER_KEY]: orderJson };
19277
+ postToParentRef.current({ type: "ow:change", nodes: [{ key: SECTION_ORDER_KEY, text: orderJson }] });
19278
+ aiSectionApiRef.current?.clear();
19279
+ window.dispatchEvent(new Event("resize"));
19280
+ const deleteHeight = document.body.scrollHeight;
19281
+ if (deleteHeight > 50) postToParentRef.current({ type: "ow:height", height: deleteHeight });
19282
+ const actionId = newInstanceId();
19283
+ pendingDeleteUndoRef.current = {
19284
+ actionId,
19285
+ restore: () => {
19286
+ const restoredEntries = getPageSectionOrderEntries(
19287
+ editContentRef.current[SECTION_ORDER_KEY],
19288
+ window.location.pathname
19289
+ );
19290
+ const restored = restoreSectionInstance(instanceId, window.location.pathname, restoredEntries);
19291
+ if (!restored) return;
19292
+ const restoredJson = JSON.stringify(restored);
19293
+ editContentRef.current = { ...editContentRef.current, [SECTION_ORDER_KEY]: restoredJson };
19294
+ postToParentRef.current({ type: "ow:change", nodes: [{ key: SECTION_ORDER_KEY, text: restoredJson }] });
19295
+ window.dispatchEvent(new Event("resize"));
19296
+ const restoreHeight = document.body.scrollHeight;
19297
+ if (restoreHeight > 50) postToParentRef.current({ type: "ow:height", height: restoreHeight });
19298
+ }
19299
+ };
19300
+ postToParentRef.current({
19301
+ type: "ow:toast",
19302
+ title: "Section deleted",
19303
+ toastType: "success",
19304
+ actionLabel: "Undo",
19305
+ actionId,
19306
+ duration: 6e3
19307
+ });
19308
+ };
19309
+ window.addEventListener("message", handleDeleteSection);
18724
19310
  const handleDeactivate = (e) => {
18725
19311
  if (e.data?.type !== "ow:deactivate") return;
18726
19312
  if (document.documentElement.hasAttribute("data-ohw-panel-dragging")) return;
@@ -18993,7 +19579,7 @@ function OhhwellsBridge() {
18993
19579
  if (inserted) {
18994
19580
  const tracker = getSectionsTracker();
18995
19581
  postToParentRef.current({ type: "ow:change", nodes: [{ key: "__ohw_sections", text: tracker.textContent ?? "[]" }] });
18996
- const h = document.documentElement.scrollHeight;
19582
+ const h = document.body.scrollHeight;
18997
19583
  if (h > 50) postToParentRef.current({ type: "ow:height", height: h });
18998
19584
  }
18999
19585
  };
@@ -19035,7 +19621,7 @@ function OhhwellsBridge() {
19035
19621
  const updated = sections.filter((s) => !(s.type === "scheduling" && s.pagePath === currentPath));
19036
19622
  tracker.textContent = JSON.stringify(updated);
19037
19623
  postToParentRef.current({ type: "ow:change", nodes: [{ key: "__ohw_sections", text: tracker.textContent }] });
19038
- const h = document.documentElement.scrollHeight;
19624
+ const h = document.body.scrollHeight;
19039
19625
  if (h > 50) postToParentRef.current({ type: "ow:height", height: h });
19040
19626
  };
19041
19627
  const handleCollectSection = (e) => {
@@ -19390,7 +19976,9 @@ function OhhwellsBridge() {
19390
19976
  window.removeEventListener("message", handleAiApplyTree);
19391
19977
  window.removeEventListener("message", handleAiDeleteSection);
19392
19978
  window.removeEventListener("message", handleAiSetSections);
19979
+ window.removeEventListener("message", handleMoveSection);
19393
19980
  window.removeEventListener("message", handlePanelDragging);
19981
+ window.removeEventListener("message", handleDeleteSection);
19394
19982
  window.removeEventListener("message", handleDeactivate);
19395
19983
  document.documentElement.removeAttribute("data-ohw-panel-dragging");
19396
19984
  window.removeEventListener("message", handleToastAction);
@@ -19402,7 +19990,7 @@ function OhhwellsBridge() {
19402
19990
  if (imageShowTimerRef.current) clearTimeout(imageShowTimerRef.current);
19403
19991
  };
19404
19992
  }, [isEditMode, refreshStateRules]);
19405
- (0, import_react16.useEffect)(() => {
19993
+ (0, import_react17.useEffect)(() => {
19406
19994
  if (!isEditMode) return;
19407
19995
  const THRESHOLD = 10;
19408
19996
  const resolveWasSelected = (el) => {
@@ -19558,7 +20146,7 @@ function OhhwellsBridge() {
19558
20146
  unlockFooterDragInteraction();
19559
20147
  };
19560
20148
  }, [isEditMode]);
19561
- (0, import_react16.useEffect)(() => {
20149
+ (0, import_react17.useEffect)(() => {
19562
20150
  const handler = (e) => {
19563
20151
  if (e.data?.type !== "ow:request-schedule-config") return;
19564
20152
  const insertAfterVal = e.data.insertAfter;
@@ -19574,7 +20162,7 @@ function OhhwellsBridge() {
19574
20162
  window.addEventListener("message", handler);
19575
20163
  return () => window.removeEventListener("message", handler);
19576
20164
  }, [processConfigRequest]);
19577
- (0, import_react16.useEffect)(() => {
20165
+ (0, import_react17.useEffect)(() => {
19578
20166
  if (!isEditMode) return;
19579
20167
  document.querySelectorAll("[data-ohw-active-state]").forEach((el) => {
19580
20168
  el.removeAttribute("data-ohw-active-state");
@@ -19598,7 +20186,7 @@ function OhhwellsBridge() {
19598
20186
  postToParent2({
19599
20187
  type: "ow:ready",
19600
20188
  version: "1",
19601
- bridgeVersion: "0.1.74",
20189
+ bridgeVersion: "0.1.75",
19602
20190
  path: pathname,
19603
20191
  nodes: collectEditableNodes(editContentRef.current),
19604
20192
  sections
@@ -19610,13 +20198,13 @@ function OhhwellsBridge() {
19610
20198
  clearTimeout(timer);
19611
20199
  };
19612
20200
  }, [pathname, isEditMode, refreshStateRules, postToParent2]);
19613
- (0, import_react16.useEffect)(() => {
20201
+ (0, import_react17.useEffect)(() => {
19614
20202
  scrollToHashSectionWhenReady();
19615
20203
  const onHashChange = () => scrollToHashSectionWhenReady();
19616
20204
  window.addEventListener("hashchange", onHashChange);
19617
20205
  return () => window.removeEventListener("hashchange", onHashChange);
19618
20206
  }, [pathname]);
19619
- const handleCommand = (0, import_react16.useCallback)((cmd) => {
20207
+ const handleCommand = (0, import_react17.useCallback)((cmd) => {
19620
20208
  const el = activeElRef.current;
19621
20209
  const selBefore = window.getSelection();
19622
20210
  let savedOffsets = null;
@@ -19652,7 +20240,7 @@ function OhhwellsBridge() {
19652
20240
  if (el) setToolbarRect(getEditMeasureEl(el).getBoundingClientRect());
19653
20241
  refreshActiveCommandsRef.current();
19654
20242
  }, []);
19655
- (0, import_react16.useEffect)(() => {
20243
+ (0, import_react17.useEffect)(() => {
19656
20244
  const session = floatingPanel && floatingPanel.kind === "logo-size" ? floatingPanel : null;
19657
20245
  if (!session || !logoSizeDraft) return;
19658
20246
  const onPanelAction = (e) => {
@@ -19690,7 +20278,7 @@ function OhhwellsBridge() {
19690
20278
  window.addEventListener("message", onPanelAction);
19691
20279
  return () => window.removeEventListener("message", onPanelAction);
19692
20280
  }, [floatingPanel, logoSizeDraft, editorViewport, persistLogoSizeDraft, closeFloatingPanelAndDeselect]);
19693
- const handleStateChange = (0, import_react16.useCallback)((state) => {
20281
+ const handleStateChange = (0, import_react17.useCallback)((state) => {
19694
20282
  if (!activeStateElRef.current) return;
19695
20283
  const el = activeStateElRef.current;
19696
20284
  if (state === "Default") {
@@ -19703,7 +20291,7 @@ function OhhwellsBridge() {
19703
20291
  }
19704
20292
  setToggleState((prev) => prev ? { ...prev, activeState: state } : null);
19705
20293
  }, [deactivate]);
19706
- const reselectAfterLinkPopover = (0, import_react16.useCallback)(
20294
+ const reselectAfterLinkPopover = (0, import_react17.useCallback)(
19707
20295
  (hrefKey) => {
19708
20296
  requestAnimationFrame(() => {
19709
20297
  const el = resolveHrefKeyElement(hrefKey);
@@ -19712,7 +20300,7 @@ function OhhwellsBridge() {
19712
20300
  },
19713
20301
  [resolveHrefKeyElement]
19714
20302
  );
19715
- const closeLinkPopover = (0, import_react16.useCallback)(() => {
20303
+ const closeLinkPopover = (0, import_react17.useCallback)(() => {
19716
20304
  const session = linkPopoverSessionRef.current;
19717
20305
  addNavAfterAnchorRef.current = null;
19718
20306
  setLinkPopover(null);
@@ -19720,9 +20308,9 @@ function OhhwellsBridge() {
19720
20308
  reselectAfterLinkPopover(session.key);
19721
20309
  }
19722
20310
  }, [reselectAfterLinkPopover]);
19723
- const closeLinkPopoverRef = (0, import_react16.useRef)(closeLinkPopover);
20311
+ const closeLinkPopoverRef = (0, import_react17.useRef)(closeLinkPopover);
19724
20312
  closeLinkPopoverRef.current = closeLinkPopover;
19725
- const openLinkPopoverForActive = (0, import_react16.useCallback)(() => {
20313
+ const openLinkPopoverForActive = (0, import_react17.useCallback)(() => {
19726
20314
  const hrefCtx = getHrefKeyFromElement(activeElRef.current);
19727
20315
  if (!hrefCtx) return;
19728
20316
  bumpLinkPopoverGrace();
@@ -19733,7 +20321,7 @@ function OhhwellsBridge() {
19733
20321
  });
19734
20322
  deactivate();
19735
20323
  }, [deactivate]);
19736
- const openLinkPopoverForSelected = (0, import_react16.useCallback)(() => {
20324
+ const openLinkPopoverForSelected = (0, import_react17.useCallback)(() => {
19737
20325
  const anchor = selectedElRef.current;
19738
20326
  if (!anchor) return;
19739
20327
  const key = anchor.getAttribute("data-ohw-href-key");
@@ -19750,7 +20338,7 @@ function OhhwellsBridge() {
19750
20338
  });
19751
20339
  deselect();
19752
20340
  }, [deselect]);
19753
- const handleSelectParent = (0, import_react16.useCallback)(() => {
20341
+ const handleSelectParent = (0, import_react17.useCallback)(() => {
19754
20342
  const selected = selectedElRef.current;
19755
20343
  if (!selected) return;
19756
20344
  if (toolbarVariantRef.current === "select-frame") {
@@ -19777,7 +20365,7 @@ function OhhwellsBridge() {
19777
20365
  }
19778
20366
  deselectRef.current();
19779
20367
  }, []);
19780
- const handleDuplicateSelected = (0, import_react16.useCallback)(() => {
20368
+ const handleDuplicateSelected = (0, import_react17.useCallback)(() => {
19781
20369
  const selected = selectedElRef.current;
19782
20370
  if (!selected || !isNavigationItem2(selected)) return;
19783
20371
  const hrefKey = selected.getAttribute("data-ohw-href-key");
@@ -19910,7 +20498,7 @@ function OhhwellsBridge() {
19910
20498
  });
19911
20499
  }
19912
20500
  }, [postToParent2]);
19913
- const runPendingDeleteUndo = (0, import_react16.useCallback)(() => {
20501
+ const runPendingDeleteUndo = (0, import_react17.useCallback)(() => {
19914
20502
  const pending = pendingDeleteUndoRef.current;
19915
20503
  if (!pending) return false;
19916
20504
  pendingDeleteUndoRef.current = null;
@@ -19918,7 +20506,7 @@ function OhhwellsBridge() {
19918
20506
  enforceLinkHrefs();
19919
20507
  return true;
19920
20508
  }, []);
19921
- const handleDeleteSelected = (0, import_react16.useCallback)(() => {
20509
+ const handleDeleteSelected = (0, import_react17.useCallback)(() => {
19922
20510
  const selected = selectedElRef.current;
19923
20511
  if (!selected) return false;
19924
20512
  return deleteSelectedNavFooterItem({
@@ -19939,7 +20527,7 @@ function OhhwellsBridge() {
19939
20527
  }, [postToParent2]);
19940
20528
  handleDeleteSelectedRef.current = handleDeleteSelected;
19941
20529
  runPendingDeleteUndoRef.current = runPendingDeleteUndo;
19942
- const handleLinkPopoverSubmit = (0, import_react16.useCallback)(
20530
+ const handleLinkPopoverSubmit = (0, import_react17.useCallback)(
19943
20531
  (target) => {
19944
20532
  const session = linkPopoverSessionRef.current;
19945
20533
  if (!session) return;
@@ -20005,19 +20593,19 @@ function OhhwellsBridge() {
20005
20593
  const showEditLink = toolbarShowEditLink;
20006
20594
  const currentSections = sectionsByPath[pathname] ?? [];
20007
20595
  linkPopoverOpenRef.current = linkPopover !== null;
20008
- const handleMediaReplace = (0, import_react16.useCallback)(
20596
+ const handleMediaReplace = (0, import_react17.useCallback)(
20009
20597
  (key) => {
20010
20598
  postToParent2({ type: "ow:image-pick", key, elementType: mediaHover?.elementType ?? "image" });
20011
20599
  },
20012
20600
  [postToParent2, mediaHover?.elementType]
20013
20601
  );
20014
- const handleEditCarousel = (0, import_react16.useCallback)(
20602
+ const handleEditCarousel = (0, import_react17.useCallback)(
20015
20603
  (key) => {
20016
20604
  postToParent2({ type: "ow:carousel-open", key, images: readCarouselValue(key) });
20017
20605
  },
20018
20606
  [postToParent2]
20019
20607
  );
20020
- const handleMediaFadeOutComplete = (0, import_react16.useCallback)((key) => {
20608
+ const handleMediaFadeOutComplete = (0, import_react17.useCallback)((key) => {
20021
20609
  setUploadingRects((prev) => {
20022
20610
  if (!(key in prev)) return prev;
20023
20611
  const next = { ...prev };
@@ -20025,7 +20613,7 @@ function OhhwellsBridge() {
20025
20613
  return next;
20026
20614
  });
20027
20615
  }, []);
20028
- const handleVideoSettingsChange = (0, import_react16.useCallback)(
20616
+ const handleVideoSettingsChange = (0, import_react17.useCallback)(
20029
20617
  (key, settings) => {
20030
20618
  document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
20031
20619
  const video = getVideoEl2(el);
@@ -20047,430 +20635,450 @@ function OhhwellsBridge() {
20047
20635
  },
20048
20636
  [postToParent2]
20049
20637
  );
20050
- return bridgeRoot ? (0, import_react_dom4.createPortal)(
20051
- /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(import_jsx_runtime33.Fragment, { children: [
20052
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { ref: attachVisibleViewport, "data-ohw-visible-viewport": "", "aria-hidden": true }),
20053
- isEditMode && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(AiSectionOverlay, { postToParent: postToParent2, apiRef: aiSectionApiRef }),
20054
- Object.entries(uploadingRects).map(([key, { rect, fadingOut }]) => /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
20055
- MediaOverlay,
20056
- {
20057
- hover: { key, rect, elementType: "image", isDragOver: false, hasTextOverlap: false },
20058
- isUploading: true,
20059
- fadingOut,
20060
- onFadeOutComplete: handleMediaFadeOutComplete,
20061
- onReplace: handleMediaReplace
20062
- },
20063
- `uploading-${key}`
20064
- )),
20065
- mediaHover && !(mediaHover.key in uploadingRects) && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
20066
- MediaOverlay,
20067
- {
20068
- hover: mediaHover,
20069
- isUploading: false,
20070
- onReplace: handleMediaReplace,
20071
- onVideoSettingsChange: handleVideoSettingsChange
20072
- }
20073
- ),
20074
- carouselHover && !linkPopover && !isItemDragging && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(CarouselOverlay, { hover: carouselHover, onEdit: handleEditCarousel }),
20075
- siblingHintRect && !linkPopover && !isItemDragging && siblingHintRects.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(ItemInteractionLayer, { rect: siblingHintRect, state: "sibling-hint" }),
20076
- siblingHintRects.length > 0 && !linkPopover && !isItemDragging && siblingHintRects.map((rect, i) => /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(ItemInteractionLayer, { rect, state: "sibling-hint" }, `sibling-hint-${i}`)),
20077
- isItemDragging && draggedItemRect && selectedElRef.current !== footerDragRef.current?.draggedEl && selectedElRef.current !== navDragRef.current?.draggedEl && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(ItemInteractionLayer, { rect: draggedItemRect, state: "dragging" }),
20078
- isItemDragging && footerDropSlots.map((slot, i) => /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
20079
- "div",
20080
- {
20081
- className: "pointer-events-none fixed z-2147483646",
20082
- style: {
20083
- left: slot.left,
20084
- top: slot.top,
20085
- width: slot.width,
20086
- height: slot.height
20638
+ return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(import_jsx_runtime33.Fragment, { children: [
20639
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { id: "ohw-loader", suppressHydrationWarning: true, style: { ...OHW_LOADER_STYLE, display: "none" }, children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(OhwLoaderSpinner, {}) }),
20640
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("script", { suppressHydrationWarning: true, dangerouslySetInnerHTML: { __html: OHW_LOADER_PREHYDRATE_SCRIPT } }),
20641
+ bridgeRoot ? (0, import_react_dom4.createPortal)(
20642
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(import_jsx_runtime33.Fragment, { children: [
20643
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { ref: attachVisibleViewport, "data-ohw-visible-viewport": "", "aria-hidden": true }),
20644
+ isEditMode && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(AiSectionOverlay, { postToParent: postToParent2, apiRef: aiSectionApiRef }),
20645
+ isSectionDragging && sectionDropSlots.map((slot, i) => /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
20646
+ "div",
20647
+ {
20648
+ className: "pointer-events-none fixed z-2147483646",
20649
+ style: { left: slot.left, top: slot.y, width: slot.width, height: 3, transform: "translateY(-50%)" },
20650
+ children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
20651
+ DropIndicator,
20652
+ {
20653
+ direction: "horizontal",
20654
+ state: activeSectionDropIndex === i ? "dragActive" : "dragIdle",
20655
+ className: "!h-full !w-full"
20656
+ }
20657
+ )
20087
20658
  },
20088
- children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
20089
- DropIndicator,
20090
- {
20091
- direction: slot.direction,
20092
- state: activeFooterDropIndex === i ? "dragActive" : "dragIdle",
20093
- className: "!h-full !w-full"
20094
- }
20095
- )
20096
- },
20097
- `footer-drop-${slot.direction}-${slot.columnIndex}-${slot.insertIndex}-${i}`
20098
- )),
20099
- isItemDragging && navDropSlots.map((slot, i) => /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
20100
- "div",
20101
- {
20102
- className: "pointer-events-none fixed z-2147483646",
20103
- style: {
20104
- left: slot.left,
20105
- top: slot.top,
20106
- width: slot.width,
20107
- height: slot.height
20659
+ `section-drop-${slot.insertIndex}-${i}`
20660
+ )),
20661
+ Object.entries(uploadingRects).map(([key, { rect, fadingOut }]) => /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
20662
+ MediaOverlay,
20663
+ {
20664
+ hover: { key, rect, elementType: "image", isDragOver: false, hasTextOverlap: false },
20665
+ isUploading: true,
20666
+ fadingOut,
20667
+ onFadeOutComplete: handleMediaFadeOutComplete,
20668
+ onReplace: handleMediaReplace
20108
20669
  },
20109
- children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
20110
- DropIndicator,
20111
- {
20112
- direction: slot.direction,
20113
- state: activeNavDropIndex === i ? "dragActive" : "dragIdle",
20114
- className: "!h-full !w-full"
20115
- }
20116
- )
20117
- },
20118
- `nav-drop-${slot.direction}-${slot.parentId ?? "root"}-${slot.insertIndex}-${i}`
20119
- )),
20120
- hoveredNavContainerRect && (toolbarVariant !== "select-frame" || isFooterFrameSelection) && !linkPopover && !isItemDragging && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(ItemInteractionLayer, { rect: hoveredNavContainerRect, state: "hover" }),
20121
- hoveredItemRect && !linkPopover && !hoveredNavContainerRect && !isItemDragging && hoveredItemElRef.current !== selectedElRef.current && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(ItemInteractionLayer, { rect: hoveredItemRect, state: "hover" }),
20122
- hoveredTextRect && !hoveredNavContainerRect && !hoveredItemRect && !isItemDragging && toolbarVariant !== "rich-text" && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(ItemInteractionLayer, { rect: hoveredTextRect, state: "hover" }),
20123
- formPickRect && !isItemDragging && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
20124
- ItemInteractionLayer,
20125
- {
20126
- rect: formPickRect,
20127
- state: "active-top",
20128
- itemDragSurface: false,
20129
- toolbarAlign: "left",
20130
- chromeGap: 24,
20131
- toolbar: fieldPickRect ? void 0 : /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(
20670
+ `uploading-${key}`
20671
+ )),
20672
+ mediaHover && !(mediaHover.key in uploadingRects) && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
20673
+ MediaOverlay,
20674
+ {
20675
+ hover: mediaHover,
20676
+ isUploading: false,
20677
+ onReplace: handleMediaReplace,
20678
+ onVideoSettingsChange: handleVideoSettingsChange
20679
+ }
20680
+ ),
20681
+ carouselHover && !linkPopover && !isItemDragging && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(CarouselOverlay, { hover: carouselHover, onEdit: handleEditCarousel }),
20682
+ siblingHintRect && !linkPopover && !isItemDragging && siblingHintRects.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(ItemInteractionLayer, { rect: siblingHintRect, state: "sibling-hint" }),
20683
+ siblingHintRects.length > 0 && !linkPopover && !isItemDragging && siblingHintRects.map((rect, i) => /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(ItemInteractionLayer, { rect, state: "sibling-hint" }, `sibling-hint-${i}`)),
20684
+ isItemDragging && draggedItemRect && selectedElRef.current !== footerDragRef.current?.draggedEl && selectedElRef.current !== navDragRef.current?.draggedEl && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(ItemInteractionLayer, { rect: draggedItemRect, state: "dragging" }),
20685
+ isItemDragging && footerDropSlots.map((slot, i) => /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
20686
+ "div",
20687
+ {
20688
+ className: "pointer-events-none fixed z-2147483646",
20689
+ style: {
20690
+ left: slot.left,
20691
+ top: slot.top,
20692
+ width: slot.width,
20693
+ height: slot.height
20694
+ },
20695
+ children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
20696
+ DropIndicator,
20697
+ {
20698
+ direction: slot.direction,
20699
+ state: activeFooterDropIndex === i ? "dragActive" : "dragIdle",
20700
+ className: "!h-full !w-full"
20701
+ }
20702
+ )
20703
+ },
20704
+ `footer-drop-${slot.direction}-${slot.columnIndex}-${slot.insertIndex}-${i}`
20705
+ )),
20706
+ isItemDragging && navDropSlots.map((slot, i) => /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
20707
+ "div",
20708
+ {
20709
+ className: "pointer-events-none fixed z-2147483646",
20710
+ style: {
20711
+ left: slot.left,
20712
+ top: slot.top,
20713
+ width: slot.width,
20714
+ height: slot.height
20715
+ },
20716
+ children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
20717
+ DropIndicator,
20718
+ {
20719
+ direction: slot.direction,
20720
+ state: activeNavDropIndex === i ? "dragActive" : "dragIdle",
20721
+ className: "!h-full !w-full"
20722
+ }
20723
+ )
20724
+ },
20725
+ `nav-drop-${slot.direction}-${slot.parentId ?? "root"}-${slot.insertIndex}-${i}`
20726
+ )),
20727
+ hoveredNavContainerRect && (toolbarVariant !== "select-frame" || isFooterFrameSelection) && !linkPopover && !isItemDragging && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(ItemInteractionLayer, { rect: hoveredNavContainerRect, state: "hover" }),
20728
+ hoveredItemRect && !linkPopover && !hoveredNavContainerRect && !isItemDragging && hoveredItemElRef.current !== selectedElRef.current && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(ItemInteractionLayer, { rect: hoveredItemRect, state: "hover" }),
20729
+ hoveredTextRect && !hoveredNavContainerRect && !hoveredItemRect && !isItemDragging && toolbarVariant !== "rich-text" && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(ItemInteractionLayer, { rect: hoveredTextRect, state: "hover" }),
20730
+ formPickRect && !isItemDragging && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
20731
+ ItemInteractionLayer,
20732
+ {
20733
+ rect: formPickRect,
20734
+ state: "active-top",
20735
+ itemDragSurface: false,
20736
+ toolbarAlign: "left",
20737
+ chromeGap: 24,
20738
+ toolbar: fieldPickRect ? void 0 : /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(
20739
+ "div",
20740
+ {
20741
+ "data-ohw-form-toolbar": "",
20742
+ className: "pointer-events-auto flex items-center gap-0.5 whitespace-nowrap rounded-lg border border-border bg-background p-1 shadow-md",
20743
+ children: [
20744
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
20745
+ "button",
20746
+ {
20747
+ type: "button",
20748
+ "aria-label": "Add field",
20749
+ className: "flex h-7 w-7 items-center justify-center rounded-md text-foreground transition-colors hover:bg-muted/80",
20750
+ onClick: () => setFieldTypePickerOpen((open) => !open),
20751
+ "data-ohw-add-field": "",
20752
+ children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_lucide_react17.Plus, { size: 15, "aria-hidden": true })
20753
+ }
20754
+ ),
20755
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "mx-0.5 h-5 w-px bg-border" }),
20756
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(
20757
+ "button",
20758
+ {
20759
+ type: "button",
20760
+ className: "flex h-7 items-center gap-1.5 whitespace-nowrap rounded-md px-2 text-[13px] font-semibold text-foreground transition-colors hover:bg-muted/80",
20761
+ onClick: () => {
20762
+ setFieldTypePickerOpen(false);
20763
+ const form = formPickElRef.current;
20764
+ if (!form) return;
20765
+ postToParent2({
20766
+ type: "ow:form-pick",
20767
+ formKey: formKeyOf(form),
20768
+ hasLongText: formHasLongText(form)
20769
+ });
20770
+ },
20771
+ children: [
20772
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_lucide_react17.Settings, { size: 14, "aria-hidden": true }),
20773
+ "Form settings",
20774
+ formPickCount ? (
20775
+ // Counter pill, per the design — not a text suffix.
20776
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
20777
+ "span",
20778
+ {
20779
+ "data-ohw-form-count": "",
20780
+ className: "ml-0.5 inline-flex h-[18px] min-w-[18px] items-center justify-center rounded-full bg-primary px-1.5 text-[11px] font-semibold text-primary-foreground",
20781
+ children: formPickCount
20782
+ }
20783
+ )
20784
+ ) : null
20785
+ ]
20786
+ }
20787
+ ),
20788
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "mx-0.5 h-5 w-px bg-border" }),
20789
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "flex items-center rounded-md bg-muted/70 p-0.5", children: ["default", "success"].map((state) => /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
20790
+ "button",
20791
+ {
20792
+ type: "button",
20793
+ "aria-pressed": formViewState === state,
20794
+ className: "rounded-md px-2.5 py-1 text-[13px] font-semibold capitalize transition-colors " + (formViewState === state ? "bg-background text-foreground shadow-sm" : "text-muted-foreground hover:text-foreground"),
20795
+ onClick: () => {
20796
+ setFieldTypePickerOpen(false);
20797
+ const form = formPickElRef.current;
20798
+ const key = form ? formKeyOf(form) : null;
20799
+ if (!form || !key) return;
20800
+ const initial = successInitialFor(form, key, editContentRef.current);
20801
+ setFormViewState(form, key, state, initial);
20802
+ setFormViewStateUi(state);
20803
+ setFormPickRect(form.getBoundingClientRect());
20804
+ if (state === "success") {
20805
+ const successEl = form.querySelector(`[${SUCCESS_TEXT_ATTR}]`);
20806
+ if (successEl) requestAnimationFrame(() => activateRef.current(successEl));
20807
+ } else {
20808
+ deactivateRef.current();
20809
+ }
20810
+ },
20811
+ children: state
20812
+ },
20813
+ state
20814
+ )) })
20815
+ ]
20816
+ }
20817
+ )
20818
+ }
20819
+ ),
20820
+ formHoverRect && !isItemDragging && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
20821
+ ItemInteractionLayer,
20822
+ {
20823
+ rect: formHoverRect,
20824
+ state: "hover",
20825
+ chromeGap: formHoverElRef.current && getFieldWrapper(formHoverElRef.current) ? 8 : 24
20826
+ }
20827
+ ),
20828
+ fieldPickRect && fieldPickState && !isItemDragging && toolbarVariant !== "rich-text" && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
20829
+ ItemInteractionLayer,
20830
+ {
20831
+ rect: fieldPickRect,
20832
+ state: fieldDragging ? "dragging" : "active-top",
20833
+ itemDragSurface: false,
20834
+ toolbarAlign: "left",
20835
+ chromeGap: 10,
20836
+ showHandle: true,
20837
+ dragHandleLabel: "Reorder field",
20838
+ onDragHandleDragStart: handleFieldDragStart,
20839
+ onDragHandleDragEnd: handleFieldDragEnd,
20840
+ toolbar: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
20841
+ FormFieldToolbar,
20842
+ {
20843
+ type: fieldPickState.type,
20844
+ required: fieldPickState.required,
20845
+ onTypeChange: handleFieldTypeChange,
20846
+ onRequiredToggle: handleFieldRequiredToggle,
20847
+ onDuplicate: handleFieldDuplicate,
20848
+ onDelete: handleFieldDelete
20849
+ }
20850
+ )
20851
+ }
20852
+ ),
20853
+ fieldDragging ? fieldDropSlots.map((slot, i) => /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
20854
+ "div",
20855
+ {
20856
+ className: "pointer-events-none fixed z-[2147483644]",
20857
+ style: { top: slot.top, left: slot.left, width: slot.width },
20858
+ children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
20859
+ DropIndicator,
20860
+ {
20861
+ direction: "horizontal",
20862
+ state: fieldDropIndex === i ? "dragActive" : "dragIdle",
20863
+ className: "!w-full"
20864
+ }
20865
+ )
20866
+ },
20867
+ `field-drop-${i}`
20868
+ )) : null,
20869
+ fieldTypePickerOpen && formPickRect ? (() => {
20870
+ const toolbar = document.querySelector("[data-ohw-form-toolbar]")?.getBoundingClientRect();
20871
+ return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
20132
20872
  "div",
20133
20873
  {
20134
- "data-ohw-form-toolbar": "",
20135
- className: "pointer-events-auto flex items-center gap-0.5 whitespace-nowrap rounded-lg border border-border bg-background p-1 shadow-md",
20136
- children: [
20137
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
20138
- "button",
20139
- {
20140
- type: "button",
20141
- "aria-label": "Add field",
20142
- className: "flex h-7 w-7 items-center justify-center rounded-md text-foreground transition-colors hover:bg-muted/80",
20143
- onClick: () => setFieldTypePickerOpen((open) => !open),
20144
- "data-ohw-add-field": "",
20145
- children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_lucide_react17.Plus, { size: 15, "aria-hidden": true })
20146
- }
20147
- ),
20148
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "mx-0.5 h-5 w-px bg-border" }),
20149
- /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(
20150
- "button",
20151
- {
20152
- type: "button",
20153
- className: "flex h-7 items-center gap-1.5 whitespace-nowrap rounded-md px-2 text-[13px] font-semibold text-foreground transition-colors hover:bg-muted/80",
20154
- onClick: () => {
20155
- setFieldTypePickerOpen(false);
20156
- const form = formPickElRef.current;
20157
- if (!form) return;
20158
- postToParent2({
20159
- type: "ow:form-pick",
20160
- formKey: formKeyOf(form),
20161
- hasLongText: formHasLongText(form)
20162
- });
20163
- },
20164
- children: [
20165
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_lucide_react17.Settings, { size: 14, "aria-hidden": true }),
20166
- "Form settings",
20167
- formPickCount ? (
20168
- // Counter pill, per the design — not a text suffix.
20169
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
20170
- "span",
20171
- {
20172
- "data-ohw-form-count": "",
20173
- className: "ml-0.5 inline-flex h-[18px] min-w-[18px] items-center justify-center rounded-full bg-primary px-1.5 text-[11px] font-semibold text-primary-foreground",
20174
- children: formPickCount
20175
- }
20176
- )
20177
- ) : null
20178
- ]
20179
- }
20180
- ),
20181
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "mx-0.5 h-5 w-px bg-border" }),
20182
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "flex items-center rounded-md bg-muted/70 p-0.5", children: ["default", "success"].map((state) => /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
20183
- "button",
20184
- {
20185
- type: "button",
20186
- "aria-pressed": formViewState === state,
20187
- className: "rounded-md px-2.5 py-1 text-[13px] font-semibold capitalize transition-colors " + (formViewState === state ? "bg-background text-foreground shadow-sm" : "text-muted-foreground hover:text-foreground"),
20188
- onClick: () => {
20189
- setFieldTypePickerOpen(false);
20190
- const form = formPickElRef.current;
20191
- const key = form ? formKeyOf(form) : null;
20192
- if (!form || !key) return;
20193
- const initial = successInitialFor(form, key, editContentRef.current);
20194
- setFormViewState(form, key, state, initial);
20195
- setFormViewStateUi(state);
20196
- setFormPickRect(form.getBoundingClientRect());
20197
- if (state === "success") {
20198
- const successEl = form.querySelector(`[${SUCCESS_TEXT_ATTR}]`);
20199
- if (successEl) requestAnimationFrame(() => activateRef.current(successEl));
20200
- } else {
20201
- deactivateRef.current();
20202
- }
20203
- },
20204
- children: state
20205
- },
20206
- state
20207
- )) })
20208
- ]
20874
+ className: "pointer-events-none fixed z-[2147483645]",
20875
+ style: {
20876
+ top: toolbar ? toolbar.bottom + 6 : formPickRect.top + 16,
20877
+ left: toolbar ? toolbar.left : formPickRect.left + 24
20878
+ },
20879
+ children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(FieldTypePicker, { onPick: handleAddField })
20209
20880
  }
20210
- )
20211
- }
20212
- ),
20213
- formHoverRect && !isItemDragging && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
20214
- ItemInteractionLayer,
20215
- {
20216
- rect: formHoverRect,
20217
- state: "hover",
20218
- chromeGap: formHoverElRef.current && getFieldWrapper(formHoverElRef.current) ? 8 : 24
20219
- }
20220
- ),
20221
- fieldPickRect && fieldPickState && !isItemDragging && toolbarVariant !== "rich-text" && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
20222
- ItemInteractionLayer,
20223
- {
20224
- rect: fieldPickRect,
20225
- state: fieldDragging ? "dragging" : "active-top",
20226
- itemDragSurface: false,
20227
- toolbarAlign: "left",
20228
- chromeGap: 10,
20229
- showHandle: true,
20230
- dragHandleLabel: "Reorder field",
20231
- onDragHandleDragStart: handleFieldDragStart,
20232
- onDragHandleDragEnd: handleFieldDragEnd,
20233
- toolbar: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
20234
- FormFieldToolbar,
20881
+ );
20882
+ })() : null,
20883
+ toolbarVariant === "select-frame" && toolbarRect && !linkPopover && !isItemDragging && !isFooterFrameSelection && selectedElRef.current && isNavbarLinksContainer2(selectedElRef.current) && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(NavbarContainerChrome, { rect: toolbarRect, onAdd: handleAddTopLevelNavItem }),
20884
+ toolbarVariant === "select-frame" && toolbarRect && !linkPopover && !isItemDragging && !isFooterFrameSelection && selectedElRef.current && isFooterLinksContainer(selectedElRef.current) && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
20885
+ FooterContainerChrome,
20886
+ {
20887
+ rect: toolbarRect,
20888
+ onAdd: handleAddFooterColumn,
20889
+ addDisabled: !canAddFooterColumn()
20890
+ }
20891
+ ),
20892
+ toolbarRect && !linkPopover && (toolbarVariant === "link-action" || toolbarVariant === "select-frame" || toolbarVariant === "logo") && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
20893
+ ItemInteractionLayer,
20894
+ {
20895
+ rect: isItemDragging && draggedItemRect && (footerDragRef.current?.wasSelected || navDragRef.current?.wasSelected) ? draggedItemRect : toolbarRect,
20896
+ toolbarBelowRect: selectedElRef.current && isNavigationItem2(selectedElRef.current) ? getOpenNavDropdownPanelRect(selectedElRef.current) : null,
20897
+ elRef: glowElRef,
20898
+ state: isItemDragging ? "dragging" : selectedElRef.current && isNavigationItem2(selectedElRef.current) && getOpenNavDropdownPanelRect(selectedElRef.current) ? "active-bottom" : resolveItemInteractionState(toolbarRect, parentScrollRef.current),
20899
+ showHandle: toolbarVariant === "link-action" && Boolean(reorderHrefKey) || toolbarVariant === "select-frame" && isFooterFrameSelection,
20900
+ dragDisabled: reorderDragDisabled,
20901
+ dragHandleLabel: reorderHrefKey ? `Reorder ${reorderHrefKey}` : "Reorder item",
20902
+ onDragHandleDragStart: handleItemDragStart,
20903
+ onDragHandleDragEnd: handleItemDragEnd,
20904
+ onItemPointerDown: toolbarVariant === "logo" ? void 0 : handleItemChromePointerDown,
20905
+ onItemClick: toolbarVariant === "logo" ? void 0 : handleItemChromeClick,
20906
+ itemDragSurface: toolbarVariant !== "logo" && !isFooterFrameSelection && !selectedIsSocialsRow,
20907
+ toolbar: toolbarVariant === "link-action" && !isItemDragging || toolbarVariant === "select-frame" && (isFooterFrameSelection || selectedIsSocialsRow) && !isItemDragging ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
20908
+ ItemActionToolbar,
20909
+ {
20910
+ onEditLink: openLinkPopoverForSelected,
20911
+ onStyle: () => {
20912
+ const row = selectedElRef.current;
20913
+ if (!row) return;
20914
+ if (floatingPanel?.kind === "socials-display") closeFloatingPanelOnly();
20915
+ else openSocialsDisplayPanel(row);
20916
+ },
20917
+ showStyle: selectedIsSocialsRow,
20918
+ styleActive: floatingPanel?.kind === "socials-display",
20919
+ onAddItem: handleAddChildItem,
20920
+ onSelectParent: handleSelectParent,
20921
+ onDuplicate: handleDuplicateSelected,
20922
+ onDelete: handleDeleteSelected,
20923
+ addItemDisabled: isFooterFrameSelection && isFooterAddItemDisabled(selectedElRef.current) || selectedElRef.current !== null && (() => {
20924
+ const row = isSocialsRow(selectedElRef.current) ? selectedElRef.current : findSocialsRow(selectedElRef.current);
20925
+ return row ? !canAddSocialItem(row) : false;
20926
+ })(),
20927
+ editLinkDisabled: false,
20928
+ moreDisabled: false,
20929
+ deleteDisabled: selectedElRef.current !== null && (() => {
20930
+ const social = getSocialItem(selectedElRef.current);
20931
+ return social ? !canRemoveSocialItem(social) : false;
20932
+ })(),
20933
+ duplicateDisabled: isFooterFrameSelection || selectedIsSocialsRow || selectedElRef.current !== null && (() => {
20934
+ const social = getSocialItem(selectedElRef.current);
20935
+ const row = social ? findSocialsRow(social) : null;
20936
+ return row ? !canAddSocialItem(row) : false;
20937
+ })(),
20938
+ showEditLink: !isFooterFrameSelection && !selectedIsSocialsRow && navDropdownPreviewOpen === null,
20939
+ showAddItem: isFooterFrameSelection || selectedIsSocialsRow || !selectedIsCta && Boolean(
20940
+ selectedElRef.current && isNavbarHrefKey(selectedElRef.current.getAttribute("data-ohw-href-key")) && !isNestedNavChild(selectedElRef.current)
20941
+ ),
20942
+ showMore: (!selectedIsCta || isFooterFrameSelection) && !selectedIsSocialsRow,
20943
+ dropdownOpen: navDropdownPreviewOpen,
20944
+ onDropdownOpenChange: handleNavDropdownOpenChange,
20945
+ headingVisible: footerHeadingVisible,
20946
+ onHeadingVisibleChange: handleFooterHeadingVisibleChange
20947
+ }
20948
+ ) : void 0
20949
+ }
20950
+ ),
20951
+ toolbarRect && toolbarVariant === "rich-text" && !linkPopover && /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(import_jsx_runtime33.Fragment, { children: [
20952
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
20953
+ EditGlowChrome,
20235
20954
  {
20236
- type: fieldPickState.type,
20237
- required: fieldPickState.required,
20238
- onTypeChange: handleFieldTypeChange,
20239
- onRequiredToggle: handleFieldRequiredToggle,
20240
- onDuplicate: handleFieldDuplicate,
20241
- onDelete: handleFieldDelete
20955
+ rect: toolbarRect,
20956
+ elRef: glowElRef,
20957
+ reorderHrefKey,
20958
+ dragDisabled: reorderDragDisabled,
20959
+ hideHandle: isItemDragging
20242
20960
  }
20243
- )
20244
- }
20245
- ),
20246
- fieldDragging ? fieldDropSlots.map((slot, i) => /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
20247
- "div",
20248
- {
20249
- className: "pointer-events-none fixed z-[2147483644]",
20250
- style: { top: slot.top, left: slot.left, width: slot.width },
20251
- children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
20252
- DropIndicator,
20961
+ ),
20962
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
20963
+ FloatingToolbar,
20253
20964
  {
20254
- direction: "horizontal",
20255
- state: fieldDropIndex === i ? "dragActive" : "dragIdle",
20256
- className: "!w-full"
20965
+ rect: toolbarRect,
20966
+ parentScroll: parentScrollRef.current,
20967
+ elRef: toolbarElRef,
20968
+ onCommand: handleCommand,
20969
+ activeCommands,
20970
+ showEditLink,
20971
+ onEditLink: openLinkPopoverForActive
20257
20972
  }
20258
20973
  )
20259
- },
20260
- `field-drop-${i}`
20261
- )) : null,
20262
- fieldTypePickerOpen && formPickRect ? (() => {
20263
- const toolbar = document.querySelector("[data-ohw-form-toolbar]")?.getBoundingClientRect();
20264
- return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
20974
+ ] }),
20975
+ maxBadge && /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(
20265
20976
  "div",
20266
20977
  {
20267
- className: "pointer-events-none fixed z-[2147483645]",
20978
+ "data-ohw-max-badge": "",
20268
20979
  style: {
20269
- top: toolbar ? toolbar.bottom + 6 : formPickRect.top + 16,
20270
- left: toolbar ? toolbar.left : formPickRect.left + 24
20980
+ position: "fixed",
20981
+ top: maxBadge.rect.bottom + 4,
20982
+ left: maxBadge.rect.right,
20983
+ transform: "translateX(-100%)",
20984
+ zIndex: 2147483647,
20985
+ background: maxBadge.current > maxBadge.max ? "#FEF2F2" : "#F5F5F4",
20986
+ color: maxBadge.current > maxBadge.max ? "#DC2626" : "#78716C",
20987
+ border: `1px solid ${maxBadge.current > maxBadge.max ? "#FECACA" : "#E7E5E4"}`,
20988
+ borderRadius: 4,
20989
+ padding: "2px 6px",
20990
+ fontSize: 11,
20991
+ fontWeight: 500,
20992
+ pointerEvents: "none"
20271
20993
  },
20272
- children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(FieldTypePicker, { onPick: handleAddField })
20994
+ children: [
20995
+ maxBadge.current,
20996
+ "/",
20997
+ maxBadge.max
20998
+ ]
20273
20999
  }
20274
- );
20275
- })() : null,
20276
- toolbarVariant === "select-frame" && toolbarRect && !linkPopover && !isItemDragging && !isFooterFrameSelection && selectedElRef.current && isNavbarLinksContainer2(selectedElRef.current) && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(NavbarContainerChrome, { rect: toolbarRect, onAdd: handleAddTopLevelNavItem }),
20277
- toolbarVariant === "select-frame" && toolbarRect && !linkPopover && !isItemDragging && !isFooterFrameSelection && selectedElRef.current && isFooterLinksContainer(selectedElRef.current) && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
20278
- FooterContainerChrome,
20279
- {
20280
- rect: toolbarRect,
20281
- onAdd: handleAddFooterColumn,
20282
- addDisabled: !canAddFooterColumn()
20283
- }
20284
- ),
20285
- toolbarRect && !linkPopover && (toolbarVariant === "link-action" || toolbarVariant === "select-frame" || toolbarVariant === "logo") && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
20286
- ItemInteractionLayer,
20287
- {
20288
- rect: isItemDragging && draggedItemRect && (footerDragRef.current?.wasSelected || navDragRef.current?.wasSelected) ? draggedItemRect : toolbarRect,
20289
- toolbarBelowRect: selectedElRef.current && isNavigationItem2(selectedElRef.current) ? getOpenNavDropdownPanelRect(selectedElRef.current) : null,
20290
- elRef: glowElRef,
20291
- state: isItemDragging ? "dragging" : selectedElRef.current && isNavigationItem2(selectedElRef.current) && getOpenNavDropdownPanelRect(selectedElRef.current) ? "active-bottom" : resolveItemInteractionState(toolbarRect, parentScrollRef.current),
20292
- showHandle: toolbarVariant === "link-action" && Boolean(reorderHrefKey) || toolbarVariant === "select-frame" && isFooterFrameSelection,
20293
- dragDisabled: reorderDragDisabled,
20294
- dragHandleLabel: reorderHrefKey ? `Reorder ${reorderHrefKey}` : "Reorder item",
20295
- onDragHandleDragStart: handleItemDragStart,
20296
- onDragHandleDragEnd: handleItemDragEnd,
20297
- onItemPointerDown: toolbarVariant === "logo" ? void 0 : handleItemChromePointerDown,
20298
- onItemClick: toolbarVariant === "logo" ? void 0 : handleItemChromeClick,
20299
- itemDragSurface: toolbarVariant !== "logo" && !isFooterFrameSelection && !selectedIsSocialsRow,
20300
- toolbar: toolbarVariant === "link-action" && !isItemDragging || toolbarVariant === "select-frame" && (isFooterFrameSelection || selectedIsSocialsRow) && !isItemDragging ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
20301
- ItemActionToolbar,
20302
- {
20303
- onEditLink: openLinkPopoverForSelected,
20304
- onStyle: () => {
20305
- const row = selectedElRef.current;
20306
- if (!row) return;
20307
- if (floatingPanel?.kind === "socials-display") closeFloatingPanelOnly();
20308
- else openSocialsDisplayPanel(row);
20309
- },
20310
- showStyle: selectedIsSocialsRow,
20311
- styleActive: floatingPanel?.kind === "socials-display",
20312
- onAddItem: handleAddChildItem,
20313
- onSelectParent: handleSelectParent,
20314
- onDuplicate: handleDuplicateSelected,
20315
- onDelete: handleDeleteSelected,
20316
- addItemDisabled: isFooterFrameSelection && isFooterAddItemDisabled(selectedElRef.current) || selectedElRef.current !== null && (() => {
20317
- const row = isSocialsRow(selectedElRef.current) ? selectedElRef.current : findSocialsRow(selectedElRef.current);
20318
- return row ? !canAddSocialItem(row) : false;
20319
- })(),
20320
- editLinkDisabled: false,
20321
- moreDisabled: false,
20322
- deleteDisabled: selectedElRef.current !== null && (() => {
20323
- const social = getSocialItem(selectedElRef.current);
20324
- return social ? !canRemoveSocialItem(social) : false;
20325
- })(),
20326
- duplicateDisabled: isFooterFrameSelection || selectedIsSocialsRow || selectedElRef.current !== null && (() => {
20327
- const social = getSocialItem(selectedElRef.current);
20328
- const row = social ? findSocialsRow(social) : null;
20329
- return row ? !canAddSocialItem(row) : false;
20330
- })(),
20331
- showEditLink: !isFooterFrameSelection && !selectedIsSocialsRow && navDropdownPreviewOpen === null,
20332
- showAddItem: isFooterFrameSelection || selectedIsSocialsRow || !selectedIsCta && Boolean(
20333
- selectedElRef.current && isNavbarHrefKey(selectedElRef.current.getAttribute("data-ohw-href-key")) && !isNestedNavChild(selectedElRef.current)
20334
- ),
20335
- showMore: (!selectedIsCta || isFooterFrameSelection) && !selectedIsSocialsRow,
20336
- dropdownOpen: navDropdownPreviewOpen,
20337
- onDropdownOpenChange: handleNavDropdownOpenChange,
20338
- headingVisible: footerHeadingVisible,
20339
- onHeadingVisibleChange: handleFooterHeadingVisibleChange
20340
- }
20341
- ) : void 0
20342
- }
20343
- ),
20344
- toolbarRect && toolbarVariant === "rich-text" && !linkPopover && /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(import_jsx_runtime33.Fragment, { children: [
20345
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
20346
- EditGlowChrome,
21000
+ ),
21001
+ toggleState && !linkPopover && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
21002
+ StateToggle,
20347
21003
  {
20348
- rect: toolbarRect,
20349
- elRef: glowElRef,
20350
- reorderHrefKey,
20351
- dragDisabled: reorderDragDisabled,
20352
- hideHandle: isItemDragging
21004
+ rect: toggleState.rect,
21005
+ activeState: toggleState.activeState,
21006
+ states: toggleState.states,
21007
+ onStateChange: handleStateChange
20353
21008
  }
20354
21009
  ),
20355
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
20356
- FloatingToolbar,
21010
+ sectionGap && !linkPopover && /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(
21011
+ "div",
20357
21012
  {
20358
- rect: toolbarRect,
20359
- parentScroll: parentScrollRef.current,
20360
- elRef: toolbarElRef,
20361
- onCommand: handleCommand,
20362
- activeCommands,
20363
- showEditLink,
20364
- onEditLink: openLinkPopoverForActive
21013
+ "data-ohw-section-insert-line": "",
21014
+ className: "fixed left-0 w-full z-2147483646 flex items-center pointer-events-none",
21015
+ style: { top: sectionGap.y, transform: "translateY(-50%)" },
21016
+ children: [
21017
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } }),
21018
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
21019
+ Badge,
21020
+ {
21021
+ className: "px-8 py-1 bg-primary hover:bg-primary text-primary-foreground text-xs font-medium shrink-0 rounded-full cursor-pointer pointer-events-auto",
21022
+ onClick: () => {
21023
+ window.parent.postMessage(
21024
+ {
21025
+ type: "ow:add-section",
21026
+ insertAfter: sectionGap.insertAfter,
21027
+ insertBefore: sectionGap.insertBefore
21028
+ },
21029
+ "*"
21030
+ );
21031
+ },
21032
+ children: "Add Section"
21033
+ }
21034
+ ),
21035
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } })
21036
+ ]
20365
21037
  }
20366
- )
20367
- ] }),
20368
- maxBadge && /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(
20369
- "div",
20370
- {
20371
- "data-ohw-max-badge": "",
20372
- style: {
20373
- position: "fixed",
20374
- top: maxBadge.rect.bottom + 4,
20375
- left: maxBadge.rect.right,
20376
- transform: "translateX(-100%)",
20377
- zIndex: 2147483647,
20378
- background: maxBadge.current > maxBadge.max ? "#FEF2F2" : "#F5F5F4",
20379
- color: maxBadge.current > maxBadge.max ? "#DC2626" : "#78716C",
20380
- border: `1px solid ${maxBadge.current > maxBadge.max ? "#FECACA" : "#E7E5E4"}`,
20381
- borderRadius: 4,
20382
- padding: "2px 6px",
20383
- fontSize: 11,
20384
- fontWeight: 500,
20385
- pointerEvents: "none"
21038
+ ),
21039
+ linkPopover && dialogPortalContainer ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
21040
+ LinkPopover,
21041
+ {
21042
+ panelRef: linkPopoverPanelRef,
21043
+ portalContainer: dialogPortalContainer,
21044
+ open: true,
21045
+ mode: linkPopover.mode ?? "edit",
21046
+ pages: sitePages,
21047
+ sections: currentSections,
21048
+ sectionsByPath,
21049
+ initialTarget: linkPopover.target,
21050
+ existingTargets: linkPopover.intent === "add-nav" ? getNavbarExistingTargets() : [],
21051
+ onClose: closeLinkPopover,
21052
+ onSubmit: handleLinkPopoverSubmit
20386
21053
  },
20387
- children: [
20388
- maxBadge.current,
20389
- "/",
20390
- maxBadge.max
20391
- ]
20392
- }
20393
- ),
20394
- toggleState && !linkPopover && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
20395
- StateToggle,
20396
- {
20397
- rect: toggleState.rect,
20398
- activeState: toggleState.activeState,
20399
- states: toggleState.states,
20400
- onStateChange: handleStateChange
20401
- }
20402
- ),
20403
- sectionGap && !linkPopover && /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(
20404
- "div",
20405
- {
20406
- "data-ohw-section-insert-line": "",
20407
- className: "fixed left-0 w-full z-2147483646 flex items-center pointer-events-none",
20408
- style: { top: sectionGap.y, transform: "translateY(-50%)" },
20409
- children: [
20410
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } }),
20411
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
20412
- Badge,
21054
+ linkPopover.key
21055
+ ) : null,
21056
+ floatingPanel && floatingPanel.kind === "socials-display" ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
21057
+ FloatingPanel,
21058
+ {
21059
+ open: true,
21060
+ title: floatingPanel.title,
21061
+ context: floatingPanel.context,
21062
+ position: floatingPanelPos,
21063
+ onPositionChange: setFloatingPanelPos,
21064
+ parentScroll: parentScrollSnap ?? parentScrollRef.current,
21065
+ onClose: closeFloatingPanelOnly,
21066
+ children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
21067
+ SocialsDisplayPanel,
20413
21068
  {
20414
- className: "px-8 py-1 bg-primary hover:bg-primary text-primary-foreground text-xs font-medium shrink-0 rounded-full cursor-pointer pointer-events-auto",
20415
- onClick: () => {
20416
- window.parent.postMessage(
20417
- {
20418
- type: "ow:add-section",
20419
- insertAfter: sectionGap.insertAfter,
20420
- insertBefore: sectionGap.insertBefore
20421
- },
20422
- "*"
20423
- );
20424
- },
20425
- children: "Add Section"
20426
- }
20427
- ),
20428
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } })
20429
- ]
20430
- }
20431
- ),
20432
- linkPopover && dialogPortalContainer ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
20433
- LinkPopover,
20434
- {
20435
- panelRef: linkPopoverPanelRef,
20436
- portalContainer: dialogPortalContainer,
20437
- open: true,
20438
- mode: linkPopover.mode ?? "edit",
20439
- pages: sitePages,
20440
- sections: currentSections,
20441
- sectionsByPath,
20442
- initialTarget: linkPopover.target,
20443
- existingTargets: linkPopover.intent === "add-nav" ? getNavbarExistingTargets() : [],
20444
- onClose: closeLinkPopover,
20445
- onSubmit: handleLinkPopoverSubmit
20446
- },
20447
- linkPopover.key
20448
- ) : null,
20449
- floatingPanel && floatingPanel.kind === "socials-display" ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
20450
- FloatingPanel,
20451
- {
20452
- open: true,
20453
- title: floatingPanel.title,
20454
- context: floatingPanel.context,
20455
- position: floatingPanelPos,
20456
- onPositionChange: setFloatingPanelPos,
20457
- parentScroll: parentScrollSnap ?? parentScrollRef.current,
20458
- onClose: closeFloatingPanelOnly,
20459
- children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
20460
- SocialsDisplayPanel,
20461
- {
20462
- display: socialsDisplayFor(floatingPanel.row, editContentRef.current),
20463
- onChange: (next) => {
20464
- changeSocialsDisplay(floatingPanel.row, next);
20465
- setFloatingPanel({ ...floatingPanel });
21069
+ display: socialsDisplayFor(floatingPanel.row, editContentRef.current),
21070
+ onChange: (next) => {
21071
+ changeSocialsDisplay(floatingPanel.row, next);
21072
+ setFloatingPanel({ ...floatingPanel });
21073
+ }
20466
21074
  }
20467
- }
20468
- )
20469
- }
20470
- ) : null
20471
- ] }),
20472
- bridgeRoot
20473
- ) : null;
21075
+ )
21076
+ }
21077
+ ) : null
21078
+ ] }),
21079
+ bridgeRoot
21080
+ ) : null
21081
+ ] });
20474
21082
  }
20475
21083
  // Annotate the CommonJS export names for ESM import in node:
20476
21084
  0 && (module.exports = {