@ohhwells/bridge 0.1.74 → 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.js CHANGED
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
 
3
3
  // src/OhhwellsBridge.tsx
4
- import React12, { useCallback as useCallback7, useEffect as useEffect12, useLayoutEffect as useLayoutEffect5, useRef as useRef9, useState as useState12 } from "react";
4
+ import React12, { useCallback as useCallback8, useEffect as useEffect13, useLayoutEffect as useLayoutEffect5, useRef as useRef10, useState as useState13 } from "react";
5
5
  import { createRoot as createRoot2 } from "react-dom/client";
6
6
  import { flushSync as flushSync2 } from "react-dom";
7
7
 
@@ -1347,6 +1347,7 @@ function applyAiSectionsToDom(state, options) {
1347
1347
  mounted.delete(entry.id);
1348
1348
  }
1349
1349
  container.setAttribute("data-ohw-section", entry.id);
1350
+ container.setAttribute("data-ohw-instance", entry.id);
1350
1351
  container.setAttribute("data-ohw-section-label", entry.label);
1351
1352
  placeContainer(container, entry);
1352
1353
  const root = mounted.get(entry.id)?.root ?? createRoot(container);
@@ -7317,6 +7318,9 @@ import { Check, X } from "lucide-react";
7317
7318
 
7318
7319
  // src/lib/sections.ts
7319
7320
  var LINK_PICKER_EXCLUDED_IDS = /* @__PURE__ */ new Set(["navbar", "footer"]);
7321
+ function isChromeSection(el) {
7322
+ return el.matches("header, nav, footer, aside");
7323
+ }
7320
7324
  function titleCaseSectionId(id) {
7321
7325
  return id.split("-").filter(Boolean).map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" ");
7322
7326
  }
@@ -7342,10 +7346,158 @@ function parseSectionsFromHtml(html) {
7342
7346
  return parseSectionsFromRoot(doc);
7343
7347
  }
7344
7348
 
7349
+ // src/lib/section-instances.ts
7350
+ var SECTION_ORDER_KEY = "__ohw_section_order";
7351
+ var REMOVED_ATTR2 = "data-ohw-section-removed";
7352
+ function isRemovedSection(el) {
7353
+ return el.hasAttribute(REMOVED_ATTR2);
7354
+ }
7355
+ function topLevelSections() {
7356
+ return Array.from(document.querySelectorAll("[data-ohw-section]")).filter(
7357
+ (el) => !el.parentElement?.closest("[data-ohw-section]") && !isChromeSection(el) && !isRemovedSection(el)
7358
+ );
7359
+ }
7360
+ function instanceIdOf(el) {
7361
+ return el.dataset.ohwInstance ?? el.dataset.ohwSection ?? "";
7362
+ }
7363
+ function planSectionMove(instanceId, targetIndex, currentPath) {
7364
+ const sections = topLevelSections();
7365
+ const index = sections.findIndex((el) => instanceIdOf(el) === instanceId);
7366
+ if (index === -1) return null;
7367
+ const dragged = sections[index];
7368
+ const others = sections.filter((_, i) => i !== index);
7369
+ const clamped = Math.max(0, Math.min(targetIndex, others.length));
7370
+ const reordered = [...others.slice(0, clamped), dragged, ...others.slice(clamped)];
7371
+ return reordered.map((el, order) => ({
7372
+ instanceId: instanceIdOf(el),
7373
+ type: el.getAttribute("data-ohw-section") ?? "",
7374
+ order,
7375
+ pagePath: currentPath
7376
+ }));
7377
+ }
7378
+ function moveSectionInstance(instanceId, direction, currentPath) {
7379
+ const sections = topLevelSections();
7380
+ const index = sections.findIndex((el) => instanceIdOf(el) === instanceId);
7381
+ if (index === -1) return null;
7382
+ const siblingIndex = direction === "up" ? index - 1 : index + 1;
7383
+ if (siblingIndex < 0 || siblingIndex >= sections.length) return null;
7384
+ const entries = planSectionMove(instanceId, siblingIndex, currentPath);
7385
+ if (!entries) return null;
7386
+ applyPersistedOrder(entries);
7387
+ return entries;
7388
+ }
7389
+ function syncRemovedFlags(entries) {
7390
+ const removedIds = new Set(entries.filter((e) => e.removed).map((e) => e.instanceId));
7391
+ document.querySelectorAll(`[${REMOVED_ATTR2}]`).forEach((el) => {
7392
+ if (!removedIds.has(instanceIdOf(el))) {
7393
+ el.style.removeProperty("display");
7394
+ el.removeAttribute(REMOVED_ATTR2);
7395
+ }
7396
+ });
7397
+ for (const id of removedIds) {
7398
+ const el = document.querySelector(`[data-ohw-instance="${CSS.escape(id)}"]`);
7399
+ if (el) {
7400
+ el.style.display = "none";
7401
+ el.setAttribute(REMOVED_ATTR2, "");
7402
+ }
7403
+ }
7404
+ }
7405
+ function applyPersistedOrder(entries) {
7406
+ syncRemovedFlags(entries);
7407
+ if (entries.length === 0) return;
7408
+ const sections = topLevelSections();
7409
+ if (sections.length === 0) return;
7410
+ const orderIndex = new Map(entries.map((e) => [e.instanceId, e.order]));
7411
+ const ordered = [...sections].sort((a, b) => {
7412
+ const aOrder = orderIndex.get(instanceIdOf(a));
7413
+ const bOrder = orderIndex.get(instanceIdOf(b));
7414
+ if (aOrder === void 0 && bOrder === void 0) return 0;
7415
+ if (aOrder === void 0) return 1;
7416
+ if (bOrder === void 0) return -1;
7417
+ return aOrder - bOrder;
7418
+ });
7419
+ let prev = null;
7420
+ for (const el of ordered) {
7421
+ if (prev) prev.after(el);
7422
+ prev = el;
7423
+ }
7424
+ }
7425
+ function setSectionRemoved(instanceId, currentPath, existingEntries, removed) {
7426
+ if (!document.querySelector(`[data-ohw-instance="${CSS.escape(instanceId)}"]`)) return null;
7427
+ const byId = new Map(existingEntries.map((e) => [e.instanceId, e]));
7428
+ const allSections = Array.from(document.querySelectorAll("[data-ohw-section]")).filter(
7429
+ (el) => !el.parentElement?.closest("[data-ohw-section]") && !isChromeSection(el)
7430
+ );
7431
+ allSections.forEach((el, order) => {
7432
+ const id = instanceIdOf(el);
7433
+ if (!byId.has(id)) {
7434
+ byId.set(id, { instanceId: id, type: el.getAttribute("data-ohw-section") ?? "", order, pagePath: currentPath });
7435
+ }
7436
+ });
7437
+ const target = byId.get(instanceId);
7438
+ if (!target) return null;
7439
+ byId.set(instanceId, { ...target, removed });
7440
+ const entries = Array.from(byId.values());
7441
+ applyPersistedOrder(entries);
7442
+ return entries;
7443
+ }
7444
+ function deleteSectionInstance(instanceId, currentPath, existingEntries) {
7445
+ return setSectionRemoved(instanceId, currentPath, existingEntries, true);
7446
+ }
7447
+ function restoreSectionInstance(instanceId, currentPath, existingEntries) {
7448
+ return setSectionRemoved(instanceId, currentPath, existingEntries, false);
7449
+ }
7450
+ function newInstanceId() {
7451
+ return typeof crypto !== "undefined" && "randomUUID" in crypto ? crypto.randomUUID() : `instance-${Date.now()}-${Math.random().toString(36).slice(2)}`;
7452
+ }
7453
+ function getPageSectionOrderEntries(raw, currentPath) {
7454
+ if (!raw) return [];
7455
+ try {
7456
+ const entries = JSON.parse(raw);
7457
+ return entries.filter((e) => !e.pagePath || e.pagePath === currentPath);
7458
+ } catch {
7459
+ return [];
7460
+ }
7461
+ }
7462
+ function rekeySectionSubtree(root, instanceId) {
7463
+ const suffix = `::${instanceId}`;
7464
+ const rekey = (el, attr) => {
7465
+ const current = el.getAttribute(attr);
7466
+ if (current) el.setAttribute(attr, `${current}${suffix}`);
7467
+ };
7468
+ if (root.hasAttribute("data-ohw-key")) rekey(root, "data-ohw-key");
7469
+ if (root.hasAttribute("data-ohw-href-key")) rekey(root, "data-ohw-href-key");
7470
+ root.querySelectorAll("[data-ohw-key]").forEach((el) => rekey(el, "data-ohw-key"));
7471
+ root.querySelectorAll("[data-ohw-href-key]").forEach((el) => rekey(el, "data-ohw-href-key"));
7472
+ }
7473
+ function initSectionInstancesFromContent(content, currentPath) {
7474
+ document.querySelectorAll("[data-ohw-section]:not([data-ohw-instance])").forEach((el) => {
7475
+ el.setAttribute("data-ohw-instance", el.getAttribute("data-ohw-section") ?? "");
7476
+ });
7477
+ const entries = getPageSectionOrderEntries(content[SECTION_ORDER_KEY], currentPath);
7478
+ for (const entry of entries) {
7479
+ if (entry.instanceId === entry.type) continue;
7480
+ if (document.querySelector(`[data-ohw-instance="${CSS.escape(entry.instanceId)}"]`)) continue;
7481
+ const original = document.querySelector(
7482
+ `[data-ohw-section="${CSS.escape(entry.type)}"][data-ohw-instance="${CSS.escape(entry.type)}"]`
7483
+ );
7484
+ if (!original) continue;
7485
+ const clone = original.cloneNode(true);
7486
+ clone.setAttribute("data-ohw-instance", entry.instanceId);
7487
+ rekeySectionSubtree(clone, entry.instanceId);
7488
+ original.insertAdjacentElement("afterend", clone);
7489
+ }
7490
+ applyPersistedOrder(entries);
7491
+ }
7492
+
7345
7493
  // src/ui/ai-section/AiSectionOverlay.tsx
7346
7494
  import { Fragment as Fragment5, jsx as jsx17, jsxs as jsxs9 } from "react/jsx-runtime";
7347
- function readRect(sectionId) {
7348
- const el = document.querySelector(`[data-ohw-section="${CSS.escape(sectionId)}"]`);
7495
+ function findSectionElement(instanceId) {
7496
+ const escaped = CSS.escape(instanceId);
7497
+ return document.querySelector(`[data-ohw-instance="${escaped}"]`) ?? document.querySelector(`[data-ohw-section="${escaped}"]:not([data-ohw-instance])`);
7498
+ }
7499
+ function readRect(instanceId) {
7500
+ const el = findSectionElement(instanceId);
7349
7501
  if (!el) return null;
7350
7502
  const r2 = el.getBoundingClientRect();
7351
7503
  if (r2.width <= 0 || r2.height <= 0) return null;
@@ -7368,7 +7520,7 @@ function useLiveSectionRect(sectionId) {
7368
7520
  const opts = { capture: true, passive: true };
7369
7521
  window.addEventListener("scroll", update, opts);
7370
7522
  window.addEventListener("resize", update);
7371
- const el = document.querySelector(`[data-ohw-section="${CSS.escape(sectionId)}"]`);
7523
+ const el = findSectionElement(sectionId);
7372
7524
  const ro = el ? new ResizeObserver(update) : null;
7373
7525
  if (el && ro) ro.observe(el);
7374
7526
  const interval = setInterval(update, 500);
@@ -7381,6 +7533,12 @@ function useLiveSectionRect(sectionId) {
7381
7533
  }, [sectionId]);
7382
7534
  return rect;
7383
7535
  }
7536
+ function computeSectionBoundaryFlags(instanceId) {
7537
+ const topLevel = topLevelSections();
7538
+ const index = topLevel.findIndex((el) => (el.dataset.ohwInstance ?? el.dataset.ohwSection) === instanceId);
7539
+ if (index === -1) return { isFirst: true, isLast: true };
7540
+ return { isFirst: index === 0, isLast: index === topLevel.length - 1 };
7541
+ }
7384
7542
  var PRIMARY2 = "#0885FE";
7385
7543
  function edgeAwareRadius(rect) {
7386
7544
  const container = window.innerWidth <= 480 ? 16 : 24;
@@ -7462,7 +7620,7 @@ function AiSectionOverlay({
7462
7620
  (el) => {
7463
7621
  postToParent2({
7464
7622
  type: "ow:section-selected",
7465
- sectionId: el?.dataset.ohwSection ?? null,
7623
+ sectionId: el ? el.dataset.ohwInstance ?? el.dataset.ohwSection ?? null : null,
7466
7624
  sectionLabel: el ? el.dataset.ohwSectionLabel ?? titleCaseSectionId(el.dataset.ohwSection ?? "") : null
7467
7625
  });
7468
7626
  },
@@ -7471,7 +7629,7 @@ function AiSectionOverlay({
7471
7629
  const selectFromElement = useCallback2(
7472
7630
  (el, options) => {
7473
7631
  const sectionEl = el?.closest("[data-ohw-section]") ?? null;
7474
- const id = sectionEl?.dataset.ohwSection ?? null;
7632
+ const id = sectionEl ? sectionEl.dataset.ohwInstance ?? sectionEl.dataset.ohwSection ?? null : null;
7475
7633
  if (id === selectedIdRef.current) return;
7476
7634
  setSelectedId(id);
7477
7635
  if (options?.report !== false) report(sectionEl);
@@ -7492,12 +7650,15 @@ function AiSectionOverlay({
7492
7650
  selectFromElement(sectionEl);
7493
7651
  return sectionEl != null;
7494
7652
  },
7495
- clear: () => setSelectedId(null)
7653
+ clear: () => {
7654
+ setSelectedId(null);
7655
+ report(null);
7656
+ }
7496
7657
  };
7497
7658
  return () => {
7498
7659
  apiRef.current = null;
7499
7660
  };
7500
- }, [apiRef, selectFromElement]);
7661
+ }, [apiRef, selectFromElement, report]);
7501
7662
  useEffect4(() => {
7502
7663
  const onMessage = (e) => {
7503
7664
  if (e.data?.type === "ow:ai-select" && e.data.sectionId === null) {
@@ -7514,7 +7675,7 @@ function AiSectionOverlay({
7514
7675
  setReviewId(found ? sectionId : null);
7515
7676
  postToParent2({ type: "ow:ai-review-started", sectionId, found });
7516
7677
  if (found) {
7517
- document.querySelector(`[data-ohw-section="${CSS.escape(sectionId)}"]`)?.scrollIntoView({ behavior: "smooth", block: "nearest" });
7678
+ document.querySelector(`[data-ohw-instance="${CSS.escape(sectionId)}"]`)?.scrollIntoView({ behavior: "smooth", block: "nearest" });
7518
7679
  }
7519
7680
  }
7520
7681
  };
@@ -7533,7 +7694,7 @@ function AiSectionOverlay({
7533
7694
  return;
7534
7695
  }
7535
7696
  const sec = t.closest("[data-ohw-section]");
7536
- setHoveredId(sec?.dataset.ohwSection ?? null);
7697
+ setHoveredId(sec ? sec.dataset.ohwInstance ?? sec.dataset.ohwSection ?? null : null);
7537
7698
  };
7538
7699
  const onLeave = () => setHoveredId(null);
7539
7700
  document.addEventListener("mousemove", onMove, { passive: true });
@@ -7565,9 +7726,30 @@ function AiSectionOverlay({
7565
7726
  },
7566
7727
  [postToParent2]
7567
7728
  );
7568
- const selectionRect = useLiveSectionRect(reviewId ? null : selectedId);
7729
+ const activeSelectionId = reviewId ? null : selectedId;
7730
+ const selectionRect = useLiveSectionRect(activeSelectionId);
7569
7731
  const reviewRect = useLiveSectionRect(reviewId);
7570
7732
  const hoverRect = useLiveSectionRect(reviewId || hoveredId === selectedId ? null : hoveredId);
7733
+ useEffect4(() => {
7734
+ const selectedEl = activeSelectionId ? findSectionElement(activeSelectionId) : null;
7735
+ if (!activeSelectionId || !selectionRect || selectedEl && isChromeSection(selectedEl)) {
7736
+ postToParent2({ type: "ow:section-rect", instanceId: null, rect: null });
7737
+ return;
7738
+ }
7739
+ const { isFirst, isLast } = computeSectionBoundaryFlags(activeSelectionId);
7740
+ postToParent2({
7741
+ type: "ow:section-rect",
7742
+ instanceId: activeSelectionId,
7743
+ rect: {
7744
+ top: selectionRect.top + window.scrollY,
7745
+ left: selectionRect.left + window.scrollX,
7746
+ width: selectionRect.width,
7747
+ height: selectionRect.height
7748
+ },
7749
+ isFirst,
7750
+ isLast
7751
+ });
7752
+ }, [activeSelectionId, selectionRect, postToParent2]);
7571
7753
  return /* @__PURE__ */ jsxs9(Fragment5, { children: [
7572
7754
  hoverRect && /* @__PURE__ */ jsx17(
7573
7755
  "div",
@@ -7647,47 +7829,6 @@ function AiSectionOverlay({
7647
7829
  ] });
7648
7830
  }
7649
7831
 
7650
- // src/lib/section-instances.ts
7651
- var SECTION_ORDER_KEY = "__ohw_section_order";
7652
- function getPageSectionOrderEntries(raw, currentPath) {
7653
- if (!raw) return [];
7654
- try {
7655
- const entries = JSON.parse(raw);
7656
- return entries.filter((e) => !e.pagePath || e.pagePath === currentPath);
7657
- } catch {
7658
- return [];
7659
- }
7660
- }
7661
- function rekeySectionSubtree(root, instanceId) {
7662
- const suffix = `::${instanceId}`;
7663
- const rekey = (el, attr) => {
7664
- const current = el.getAttribute(attr);
7665
- if (current) el.setAttribute(attr, `${current}${suffix}`);
7666
- };
7667
- if (root.hasAttribute("data-ohw-key")) rekey(root, "data-ohw-key");
7668
- if (root.hasAttribute("data-ohw-href-key")) rekey(root, "data-ohw-href-key");
7669
- root.querySelectorAll("[data-ohw-key]").forEach((el) => rekey(el, "data-ohw-key"));
7670
- root.querySelectorAll("[data-ohw-href-key]").forEach((el) => rekey(el, "data-ohw-href-key"));
7671
- }
7672
- function initSectionInstancesFromContent(content, currentPath) {
7673
- document.querySelectorAll("[data-ohw-section]:not([data-ohw-instance])").forEach((el) => {
7674
- el.setAttribute("data-ohw-instance", el.getAttribute("data-ohw-section") ?? "");
7675
- });
7676
- const entries = getPageSectionOrderEntries(content[SECTION_ORDER_KEY], currentPath);
7677
- for (const entry of entries) {
7678
- if (entry.instanceId === entry.type) continue;
7679
- if (document.querySelector(`[data-ohw-instance="${CSS.escape(entry.instanceId)}"]`)) continue;
7680
- const original = document.querySelector(
7681
- `[data-ohw-section="${CSS.escape(entry.type)}"][data-ohw-instance="${CSS.escape(entry.type)}"]`
7682
- );
7683
- if (!original) continue;
7684
- const clone = original.cloneNode(true);
7685
- clone.setAttribute("data-ohw-instance", entry.instanceId);
7686
- rekeySectionSubtree(clone, entry.instanceId);
7687
- original.insertAdjacentElement("afterend", clone);
7688
- }
7689
- }
7690
-
7691
7832
  // src/OhhwellsBridge.tsx
7692
7833
  import { createPortal as createPortal2 } from "react-dom";
7693
7834
  import { usePathname as usePathname2, useRouter as useRouter3, useSearchParams } from "next/navigation";
@@ -12913,6 +13054,333 @@ function useNavItemDrag({
12913
13054
  };
12914
13055
  }
12915
13056
 
13057
+ // src/useSectionDrag.ts
13058
+ import { useCallback as useCallback7, useEffect as useEffect11, useRef as useRef9, useState as useState11 } from "react";
13059
+
13060
+ // src/lib/section-dnd.ts
13061
+ function isFooterSection(el) {
13062
+ return el.dataset.ohwSection === "footer";
13063
+ }
13064
+ function buildSectionDropSlots(draggedInstanceId) {
13065
+ const sections = topLevelSections().filter(
13066
+ (el) => instanceIdOf(el) !== draggedInstanceId && !isFooterSection(el)
13067
+ );
13068
+ const slots = [];
13069
+ if (sections.length === 0) return slots;
13070
+ const left = 0;
13071
+ const width = document.documentElement.clientWidth;
13072
+ for (let i = 0; i <= sections.length; i++) {
13073
+ let y;
13074
+ if (i === 0) {
13075
+ y = sections[0].getBoundingClientRect().top;
13076
+ } else if (i === sections.length) {
13077
+ y = sections[sections.length - 1].getBoundingClientRect().bottom;
13078
+ } else {
13079
+ const prev = sections[i - 1].getBoundingClientRect();
13080
+ const next = sections[i].getBoundingClientRect();
13081
+ y = (prev.bottom + next.top) / 2;
13082
+ }
13083
+ slots.push({ insertIndex: i, y, left, width });
13084
+ }
13085
+ return slots;
13086
+ }
13087
+ function hitTestSectionDropSlot(y, slots) {
13088
+ let best = null;
13089
+ for (const slot of slots) {
13090
+ const dist = Math.abs(y - slot.y);
13091
+ if (!best || dist < best.dist) best = { slot, dist };
13092
+ }
13093
+ return best?.slot ?? null;
13094
+ }
13095
+
13096
+ // src/useSectionDrag.ts
13097
+ var PRESS_THRESHOLD = 10;
13098
+ var EDGE_ZONE = 60;
13099
+ var MAX_AUTO_SCROLL_SPEED = 18;
13100
+ var SECTION_DRAG_EXCLUDED_SELECTOR = [
13101
+ "[data-ohw-toolbar]",
13102
+ "[data-ohw-edit-chrome]",
13103
+ "[data-ohw-item-interaction]",
13104
+ "[data-ohw-drag-handle-container]",
13105
+ '[data-slot="drag-handle"]',
13106
+ "[data-ohw-item-toolbar-anchor]",
13107
+ "[data-ohw-item-drag-surface]",
13108
+ "[data-ohw-more-menu]",
13109
+ '[data-slot="dropdown-menu-content"]',
13110
+ '[data-slot="dropdown-menu-item"]',
13111
+ "[data-ohw-state-toggle]",
13112
+ "[data-ohw-max-badge]",
13113
+ "[data-ohw-floating-panel]",
13114
+ "[data-ohw-section-picker]",
13115
+ "[data-ohw-link-popover-root]",
13116
+ "[data-ohw-link-modal-root]",
13117
+ "[data-ohw-link-page-dropdown]",
13118
+ '[data-slot="popover-content"]',
13119
+ '[data-slot="dialog-content"]',
13120
+ '[data-slot="dialog-overlay"]',
13121
+ "[data-ohw-ai-review]",
13122
+ "[data-ohw-editable]",
13123
+ "[data-ohw-editable-state]",
13124
+ "[contenteditable]",
13125
+ "[data-ohw-href-key]",
13126
+ "[data-ohw-footer-col]",
13127
+ "[data-ohw-social-label]",
13128
+ "a",
13129
+ "button",
13130
+ '[role="button"]',
13131
+ '[data-ohw-role="navbar-button"]',
13132
+ '[data-ohw-role="button"]',
13133
+ "[data-ohw-carousel]",
13134
+ "[data-ohw-carousel-value]",
13135
+ "[data-ohw-carousel-slide]",
13136
+ "[data-ohw-carousel-overlay]",
13137
+ "[data-ohw-media-chrome]",
13138
+ "[data-ohw-media-overlay]",
13139
+ "[data-ohw-media-skeleton]"
13140
+ ].join(", ");
13141
+ function visibleClip(ps) {
13142
+ if (!ps) return null;
13143
+ const top = Math.max(0, ps.headerH - ps.iframeOffsetTop);
13144
+ const bottom = Math.min(window.innerHeight, ps.headerH + ps.canvasH - ps.iframeOffsetTop);
13145
+ return { top, bottom: Math.max(top, bottom) };
13146
+ }
13147
+ function useSectionDrag({
13148
+ isEditMode,
13149
+ editContentRef,
13150
+ postToParentRef,
13151
+ parentScrollRef,
13152
+ navDragRef,
13153
+ footerDragRef,
13154
+ suppressNextClickRef,
13155
+ suppressClickUntilRef
13156
+ }) {
13157
+ const sectionDragRef = useRef9(null);
13158
+ const [sectionDropSlots, setSectionDropSlots] = useState11([]);
13159
+ const [activeSectionDropIndex, setActiveSectionDropIndex] = useState11(null);
13160
+ const [isSectionDragging, setIsSectionDragging] = useState11(false);
13161
+ const sectionPointerDragRef = useRef9(null);
13162
+ const autoScrollRafRef = useRef9(null);
13163
+ const autoScrollDeltaRef = useRef9(0);
13164
+ const stopAutoScroll = useCallback7(() => {
13165
+ if (autoScrollRafRef.current != null) {
13166
+ cancelAnimationFrame(autoScrollRafRef.current);
13167
+ autoScrollRafRef.current = null;
13168
+ }
13169
+ autoScrollDeltaRef.current = 0;
13170
+ }, []);
13171
+ const tickAutoScroll = useCallback7(() => {
13172
+ if (!sectionDragRef.current) {
13173
+ stopAutoScroll();
13174
+ return;
13175
+ }
13176
+ if (autoScrollDeltaRef.current !== 0) {
13177
+ postToParentRef.current({ type: "ow:request-scroll", deltaY: autoScrollDeltaRef.current });
13178
+ }
13179
+ autoScrollRafRef.current = requestAnimationFrame(tickAutoScroll);
13180
+ }, [postToParentRef, stopAutoScroll]);
13181
+ const updateAutoScroll = useCallback7(
13182
+ (clientY) => {
13183
+ const clip = visibleClip(parentScrollRef.current);
13184
+ let delta = 0;
13185
+ if (clip) {
13186
+ const distTop = clientY - clip.top;
13187
+ const distBottom = clip.bottom - clientY;
13188
+ if (distTop >= 0 && distTop < EDGE_ZONE) {
13189
+ delta = -MAX_AUTO_SCROLL_SPEED * (1 - distTop / EDGE_ZONE);
13190
+ } else if (distBottom >= 0 && distBottom < EDGE_ZONE) {
13191
+ delta = MAX_AUTO_SCROLL_SPEED * (1 - distBottom / EDGE_ZONE);
13192
+ }
13193
+ }
13194
+ autoScrollDeltaRef.current = delta;
13195
+ if (delta !== 0 && autoScrollRafRef.current == null) {
13196
+ autoScrollRafRef.current = requestAnimationFrame(tickAutoScroll);
13197
+ } else if (delta === 0) {
13198
+ stopAutoScroll();
13199
+ }
13200
+ },
13201
+ [parentScrollRef, stopAutoScroll, tickAutoScroll]
13202
+ );
13203
+ const clearSectionDragVisuals = useCallback7(() => {
13204
+ sectionDragRef.current?.draggedEl.removeAttribute("data-ohw-section-dragging");
13205
+ sectionDragRef.current = null;
13206
+ setSectionDropSlots([]);
13207
+ setActiveSectionDropIndex(null);
13208
+ setIsSectionDragging(false);
13209
+ stopAutoScroll();
13210
+ document.documentElement.removeAttribute("data-ohw-section-dragging-root");
13211
+ unlockItemDragInteraction();
13212
+ }, [stopAutoScroll]);
13213
+ const refreshSectionDragVisuals = useCallback7(
13214
+ (session, clientX, clientY) => {
13215
+ session.lastClientX = clientX;
13216
+ session.lastClientY = clientY;
13217
+ const slots = buildSectionDropSlots(session.instanceId);
13218
+ const activeSlot = hitTestSectionDropSlot(clientY, slots);
13219
+ session.activeSlot = activeSlot;
13220
+ setSectionDropSlots(slots);
13221
+ const activeIdx = activeSlot ? slots.findIndex((s) => s.insertIndex === activeSlot.insertIndex) : -1;
13222
+ setActiveSectionDropIndex(activeIdx >= 0 ? activeIdx : null);
13223
+ updateAutoScroll(clientY);
13224
+ },
13225
+ [updateAutoScroll]
13226
+ );
13227
+ const beginSectionDrag = useCallback7(
13228
+ (session) => {
13229
+ sectionDragRef.current = session;
13230
+ setIsSectionDragging(true);
13231
+ lockItemDuringDrag();
13232
+ document.documentElement.setAttribute("data-ohw-section-dragging-root", "");
13233
+ session.draggedEl.setAttribute("data-ohw-section-dragging", "");
13234
+ refreshSectionDragVisuals(session, session.lastClientX, session.lastClientY);
13235
+ },
13236
+ [refreshSectionDragVisuals]
13237
+ );
13238
+ const commitSectionDrag = useCallback7(() => {
13239
+ const session = sectionDragRef.current;
13240
+ if (!session) {
13241
+ clearSectionDragVisuals();
13242
+ return;
13243
+ }
13244
+ const slot = session.activeSlot ?? hitTestSectionDropSlot(session.lastClientY, buildSectionDropSlots(session.instanceId));
13245
+ const entries = slot ? planSectionMove(session.instanceId, slot.insertIndex, window.location.pathname) : null;
13246
+ if (!entries) {
13247
+ clearSectionDragVisuals();
13248
+ return;
13249
+ }
13250
+ const orderJson = JSON.stringify(entries);
13251
+ editContentRef.current = { ...editContentRef.current, [SECTION_ORDER_KEY]: orderJson };
13252
+ postToParentRef.current({ type: "ow:change", nodes: [{ key: SECTION_ORDER_KEY, text: orderJson }] });
13253
+ applyPersistedOrder(entries);
13254
+ clearSectionDragVisuals();
13255
+ requestAnimationFrame(() => {
13256
+ if (editContentRef.current[SECTION_ORDER_KEY] === orderJson) {
13257
+ applyPersistedOrder(entries);
13258
+ }
13259
+ requestAnimationFrame(() => {
13260
+ window.dispatchEvent(new Event("resize"));
13261
+ });
13262
+ });
13263
+ }, [clearSectionDragVisuals, editContentRef, postToParentRef]);
13264
+ const startSectionPressDrag = useCallback7(
13265
+ (el, clientX, clientY, pointerId) => {
13266
+ if (navDragRef.current || footerDragRef.current || sectionDragRef.current) return false;
13267
+ const instanceId = instanceIdOf(el);
13268
+ if (!instanceId) return false;
13269
+ sectionPointerDragRef.current = {
13270
+ el,
13271
+ instanceId,
13272
+ startX: clientX,
13273
+ startY: clientY,
13274
+ pointerId,
13275
+ started: false
13276
+ };
13277
+ return true;
13278
+ },
13279
+ [footerDragRef, navDragRef]
13280
+ );
13281
+ useEffect11(() => {
13282
+ if (!isEditMode) return;
13283
+ const onPointerDown = (e) => {
13284
+ if (e.button !== 0) return;
13285
+ if (navDragRef.current || footerDragRef.current || sectionDragRef.current) return;
13286
+ if (sectionPointerDragRef.current) return;
13287
+ const target = e.target;
13288
+ if (!(target instanceof HTMLElement)) return;
13289
+ if (target.closest(SECTION_DRAG_EXCLUDED_SELECTOR)) return;
13290
+ const sectionEl = target.closest("[data-ohw-section]");
13291
+ if (!sectionEl || isChromeSection(sectionEl) || sectionEl.dataset.ohwSection === "footer") return;
13292
+ if (!topLevelSections().includes(sectionEl)) return;
13293
+ startSectionPressDrag(sectionEl, e.clientX, e.clientY, e.pointerId);
13294
+ };
13295
+ const onPointerMove = (e) => {
13296
+ const pending = sectionPointerDragRef.current;
13297
+ if (!pending) return;
13298
+ if (pending.started) {
13299
+ e.preventDefault();
13300
+ clearTextSelection();
13301
+ const session = sectionDragRef.current;
13302
+ if (!session) return;
13303
+ refreshSectionDragVisuals(session, e.clientX, e.clientY);
13304
+ return;
13305
+ }
13306
+ const dx = e.clientX - pending.startX;
13307
+ const dy = e.clientY - pending.startY;
13308
+ if (dx * dx + dy * dy < PRESS_THRESHOLD * PRESS_THRESHOLD) return;
13309
+ e.preventDefault();
13310
+ pending.started = true;
13311
+ armItemPressDrag();
13312
+ clearTextSelection();
13313
+ try {
13314
+ document.body.setPointerCapture(pending.pointerId);
13315
+ } catch {
13316
+ }
13317
+ beginSectionDrag({
13318
+ instanceId: pending.instanceId,
13319
+ draggedEl: pending.el,
13320
+ lastClientX: e.clientX,
13321
+ lastClientY: e.clientY,
13322
+ activeSlot: null
13323
+ });
13324
+ };
13325
+ const endPointerDrag = (e) => {
13326
+ const pending = sectionPointerDragRef.current;
13327
+ sectionPointerDragRef.current = null;
13328
+ try {
13329
+ if (document.body.hasPointerCapture(e.pointerId)) {
13330
+ document.body.releasePointerCapture(e.pointerId);
13331
+ }
13332
+ } catch {
13333
+ }
13334
+ if (!pending) return;
13335
+ if (!pending.started) {
13336
+ unlockItemDragInteraction();
13337
+ return;
13338
+ }
13339
+ suppressNextClickRef.current = true;
13340
+ suppressClickUntilRef.current = Date.now() + 500;
13341
+ commitSectionDrag();
13342
+ };
13343
+ const onKeyDown = (e) => {
13344
+ if (e.key !== "Escape") return;
13345
+ if (!sectionDragRef.current && !sectionPointerDragRef.current) return;
13346
+ sectionPointerDragRef.current = null;
13347
+ clearSectionDragVisuals();
13348
+ };
13349
+ document.addEventListener("pointerdown", onPointerDown, true);
13350
+ document.addEventListener("pointermove", onPointerMove, true);
13351
+ document.addEventListener("pointerup", endPointerDrag, true);
13352
+ document.addEventListener("pointercancel", endPointerDrag, true);
13353
+ document.addEventListener("keydown", onKeyDown, true);
13354
+ return () => {
13355
+ document.removeEventListener("pointerdown", onPointerDown, true);
13356
+ document.removeEventListener("pointermove", onPointerMove, true);
13357
+ document.removeEventListener("pointerup", endPointerDrag, true);
13358
+ document.removeEventListener("pointercancel", endPointerDrag, true);
13359
+ document.removeEventListener("keydown", onKeyDown, true);
13360
+ unlockItemDragInteraction();
13361
+ stopAutoScroll();
13362
+ };
13363
+ }, [
13364
+ beginSectionDrag,
13365
+ clearSectionDragVisuals,
13366
+ commitSectionDrag,
13367
+ footerDragRef,
13368
+ isEditMode,
13369
+ navDragRef,
13370
+ refreshSectionDragVisuals,
13371
+ startSectionPressDrag,
13372
+ stopAutoScroll,
13373
+ suppressClickUntilRef,
13374
+ suppressNextClickRef
13375
+ ]);
13376
+ return {
13377
+ sectionDragRef,
13378
+ sectionDropSlots,
13379
+ activeSectionDropIndex,
13380
+ isSectionDragging
13381
+ };
13382
+ }
13383
+
12916
13384
  // src/ui/footer-container-chrome.tsx
12917
13385
  import { Plus as Plus2 } from "lucide-react";
12918
13386
  import { jsx as jsx29, jsxs as jsxs19 } from "react/jsx-runtime";
@@ -12965,7 +13433,7 @@ function FooterContainerChrome({
12965
13433
  }
12966
13434
 
12967
13435
  // src/lib/carousel.ts
12968
- import { useEffect as useEffect11, useState as useState11 } from "react";
13436
+ import { useEffect as useEffect12, useState as useState12 } from "react";
12969
13437
  var CAROUSEL_ATTR = "data-ohw-carousel";
12970
13438
  var CAROUSEL_VALUE_ATTR = "data-ohw-carousel-value";
12971
13439
  var CAROUSEL_SLIDE_ATTR = "data-ohw-carousel-slide";
@@ -13027,8 +13495,8 @@ function applyCarouselNode(key, val) {
13027
13495
  return true;
13028
13496
  }
13029
13497
  function useOhwCarousel(key, initial) {
13030
- const [images, setImages] = useState11(initial);
13031
- useEffect11(() => {
13498
+ const [images, setImages] = useState12(initial);
13499
+ useEffect12(() => {
13032
13500
  const el = document.querySelector(
13033
13501
  `[${CAROUSEL_ATTR}][data-ohw-key="${CSS.escape(key)}"]`
13034
13502
  );
@@ -13110,6 +13578,7 @@ function collectEditableNodes(extraContent, root = document) {
13110
13578
  NAV_ORDER_KEY,
13111
13579
  FOOTER_ORDER_KEY,
13112
13580
  NAV_COUNT_KEY,
13581
+ SECTION_ORDER_KEY,
13113
13582
  // A socials row's order and its icons-vs-words setting live under keys no element carries,
13114
13583
  // so collecting the DOM alone left them behind: the draft knew the row was showing icons and
13115
13584
  // had gained an item, and the published page went back to the template's own (OHH-736).
@@ -13574,6 +14043,7 @@ function fadeInImageElement(img, onReady) {
13574
14043
  function applyEditableImageSrc(img, url) {
13575
14044
  img.removeAttribute("srcset");
13576
14045
  img.removeAttribute("sizes");
14046
+ if (img.loading === "lazy") img.loading = "eager";
13577
14047
  img.src = url;
13578
14048
  }
13579
14049
  function fadeInBgImage(el, url, onReady) {
@@ -14780,6 +15250,44 @@ function StateToggle({
14780
15250
  );
14781
15251
  }
14782
15252
  var contentCache = /* @__PURE__ */ new Map();
15253
+ var OHW_LOADER_STYLE = {
15254
+ position: "fixed",
15255
+ inset: 0,
15256
+ background: "#fff",
15257
+ zIndex: 2147483646,
15258
+ display: "flex",
15259
+ alignItems: "center",
15260
+ justifyContent: "center"
15261
+ };
15262
+ function OhwLoaderSpinner() {
15263
+ return /* @__PURE__ */ jsxs20("svg", { width: "28", height: "28", viewBox: "0 0 28 28", fill: "none", "aria-hidden": true, children: [
15264
+ /* @__PURE__ */ jsx33("circle", { cx: "14", cy: "14", r: "11", stroke: "#E7E5E4", strokeWidth: "3" }),
15265
+ /* @__PURE__ */ jsx33(
15266
+ "circle",
15267
+ {
15268
+ cx: "14",
15269
+ cy: "14",
15270
+ r: "11",
15271
+ stroke: "#1C1917",
15272
+ strokeWidth: "3",
15273
+ strokeDasharray: "17 52",
15274
+ strokeLinecap: "round",
15275
+ children: /* @__PURE__ */ jsx33(
15276
+ "animateTransform",
15277
+ {
15278
+ attributeName: "transform",
15279
+ type: "rotate",
15280
+ from: "0 14 14",
15281
+ to: "360 14 14",
15282
+ dur: "0.7s",
15283
+ repeatCount: "indefinite"
15284
+ }
15285
+ )
15286
+ }
15287
+ )
15288
+ ] });
15289
+ }
15290
+ 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){}})();`;
14783
15291
  function resolveSubdomain(subdomainFromQuery) {
14784
15292
  if (subdomainFromQuery) return subdomainFromQuery;
14785
15293
  if (typeof window !== "undefined") {
@@ -14802,8 +15310,8 @@ function OhhwellsBridge() {
14802
15310
  const router = useRouter3();
14803
15311
  const searchParams = useSearchParams();
14804
15312
  const isEditMode = isEditSessionActive();
14805
- const [bridgeRoot, setBridgeRoot] = useState12(null);
14806
- useEffect12(() => {
15313
+ const [bridgeRoot, setBridgeRoot] = useState13(null);
15314
+ useEffect13(() => {
14807
15315
  const figtreeFontId = "ohw-figtree-font";
14808
15316
  if (!document.getElementById(figtreeFontId)) {
14809
15317
  const preconnect1 = Object.assign(document.createElement("link"), { rel: "preconnect", href: "https://fonts.googleapis.com" });
@@ -14832,82 +15340,82 @@ function OhhwellsBridge() {
14832
15340
  const subdomain = resolveSubdomain(subdomainFromQuery);
14833
15341
  useLinkHrefGuardian(pathname, subdomain, isEditMode);
14834
15342
  useSavedLinkNavigation(isEditMode);
14835
- const postToParent2 = useCallback7((data) => {
15343
+ const postToParent2 = useCallback8((data) => {
14836
15344
  if (typeof window !== "undefined" && window.parent !== window) {
14837
15345
  window.parent.postMessage(data, "*");
14838
15346
  }
14839
15347
  }, []);
14840
- const [fetchState, setFetchState] = useState12("idle");
14841
- const autoSaveTimers = useRef9(/* @__PURE__ */ new Map());
14842
- const activeElRef = useRef9(null);
14843
- const pointerHeldRef = useRef9(false);
14844
- const selectedElRef = useRef9(null);
14845
- const selectedHrefKeyRef = useRef9(null);
14846
- const selectedFooterColAttrRef = useRef9(null);
14847
- const originalContentRef = useRef9(null);
14848
- const activeStateElRef = useRef9(null);
14849
- const parentScrollRef = useRef9(null);
14850
- const visibleViewportRef = useRef9(null);
14851
- const [dialogPortalContainer, setDialogPortalContainer] = useState12(null);
14852
- const attachVisibleViewport = useCallback7((node) => {
15348
+ const [fetchState, setFetchState] = useState13("idle");
15349
+ const autoSaveTimers = useRef10(/* @__PURE__ */ new Map());
15350
+ const activeElRef = useRef10(null);
15351
+ const pointerHeldRef = useRef10(false);
15352
+ const selectedElRef = useRef10(null);
15353
+ const selectedHrefKeyRef = useRef10(null);
15354
+ const selectedFooterColAttrRef = useRef10(null);
15355
+ const originalContentRef = useRef10(null);
15356
+ const activeStateElRef = useRef10(null);
15357
+ const parentScrollRef = useRef10(null);
15358
+ const visibleViewportRef = useRef10(null);
15359
+ const [dialogPortalContainer, setDialogPortalContainer] = useState13(null);
15360
+ const attachVisibleViewport = useCallback8((node) => {
14853
15361
  visibleViewportRef.current = node;
14854
15362
  setDialogPortalContainer(node);
14855
15363
  if (node) applyVisibleViewport(node, parentScrollRef.current);
14856
15364
  }, []);
14857
- const toolbarElRef = useRef9(null);
14858
- const glowElRef = useRef9(null);
14859
- const hoveredImageRef = useRef9(null);
14860
- const hoveredImageHasTextOverlapRef = useRef9(false);
14861
- const dragOverElRef = useRef9(null);
14862
- const [mediaHover, setMediaHover] = useState12(null);
14863
- const [carouselHover, setCarouselHover] = useState12(null);
14864
- const [uploadingRects, setUploadingRects] = useState12({});
14865
- const hoveredGapRef = useRef9(null);
14866
- const imageUnhoverTimerRef = useRef9(null);
14867
- const imageShowTimerRef = useRef9(null);
14868
- const editStylesRef = useRef9(null);
14869
- const activateRef = useRef9(() => {
15365
+ const toolbarElRef = useRef10(null);
15366
+ const glowElRef = useRef10(null);
15367
+ const hoveredImageRef = useRef10(null);
15368
+ const hoveredImageHasTextOverlapRef = useRef10(false);
15369
+ const dragOverElRef = useRef10(null);
15370
+ const [mediaHover, setMediaHover] = useState13(null);
15371
+ const [carouselHover, setCarouselHover] = useState13(null);
15372
+ const [uploadingRects, setUploadingRects] = useState13({});
15373
+ const hoveredGapRef = useRef10(null);
15374
+ const imageUnhoverTimerRef = useRef10(null);
15375
+ const imageShowTimerRef = useRef10(null);
15376
+ const editStylesRef = useRef10(null);
15377
+ const activateRef = useRef10(() => {
14870
15378
  });
14871
- const deactivateRef = useRef9(() => {
15379
+ const deactivateRef = useRef10(() => {
14872
15380
  });
14873
- const selectRef = useRef9(() => {
15381
+ const selectRef = useRef10(() => {
14874
15382
  });
14875
- const selectFrameRef = useRef9(() => {
15383
+ const selectFrameRef = useRef10(() => {
14876
15384
  });
14877
- const selectLogoRef = useRef9(() => {
15385
+ const selectLogoRef = useRef10(() => {
14878
15386
  });
14879
- const openLogoSizePanelRef = useRef9(() => {
15387
+ const openLogoSizePanelRef = useRef10(() => {
14880
15388
  });
14881
- const deselectRef = useRef9(() => {
15389
+ const deselectRef = useRef10(() => {
14882
15390
  });
14883
- const closeFloatingPanelOnlyRef = useRef9(() => {
15391
+ const closeFloatingPanelOnlyRef = useRef10(() => {
14884
15392
  });
14885
- const reselectNavigationItemRef = useRef9(() => {
15393
+ const reselectNavigationItemRef = useRef10(() => {
14886
15394
  });
14887
- const commitNavigationTextEditRef = useRef9(() => {
15395
+ const commitNavigationTextEditRef = useRef10(() => {
14888
15396
  });
14889
- const handleDeleteSelectedRef = useRef9(() => false);
14890
- const runPendingDeleteUndoRef = useRef9(() => false);
14891
- const isFooterFrameSelectionRef = useRef9(false);
14892
- const refreshActiveCommandsRef = useRef9(() => {
15397
+ const handleDeleteSelectedRef = useRef10(() => false);
15398
+ const runPendingDeleteUndoRef = useRef10(() => false);
15399
+ const isFooterFrameSelectionRef = useRef10(false);
15400
+ const refreshActiveCommandsRef = useRef10(() => {
14893
15401
  });
14894
- const postToParentRef = useRef9(postToParent2);
15402
+ const postToParentRef = useRef10(postToParent2);
14895
15403
  postToParentRef.current = postToParent2;
14896
- const aiSectionApiRef = useRef9(null);
14897
- const sectionsLoadedRef = useRef9(false);
14898
- const pendingScheduleConfigRequests = useRef9([]);
14899
- const [toolbarRect, setToolbarRect] = useState12(null);
14900
- const [formPickRect, setFormPickRect] = useState12(null);
14901
- const formPickElRef = useRef9(null);
14902
- const [formViewState, setFormViewStateUi] = useState12("default");
14903
- const [formPickCount, setFormPickCount] = useState12(null);
14904
- const [formHoverRect, setFormHoverRect] = useState12(null);
14905
- const formHoverElRef = useRef9(null);
14906
- const [fieldPickRect, setFieldPickRect] = useState12(null);
14907
- const fieldPickElRef = useRef9(null);
14908
- const [fieldPickState, setFieldPickState] = useState12(null);
14909
- const [fieldTypePickerOpen, setFieldTypePickerOpen] = useState12(false);
14910
- const clearFormPick = useCallback7(() => {
15404
+ const aiSectionApiRef = useRef10(null);
15405
+ const sectionsLoadedRef = useRef10(false);
15406
+ const pendingScheduleConfigRequests = useRef10([]);
15407
+ const [toolbarRect, setToolbarRect] = useState13(null);
15408
+ const [formPickRect, setFormPickRect] = useState13(null);
15409
+ const formPickElRef = useRef10(null);
15410
+ const [formViewState, setFormViewStateUi] = useState13("default");
15411
+ const [formPickCount, setFormPickCount] = useState13(null);
15412
+ const [formHoverRect, setFormHoverRect] = useState13(null);
15413
+ const formHoverElRef = useRef10(null);
15414
+ const [fieldPickRect, setFieldPickRect] = useState13(null);
15415
+ const fieldPickElRef = useRef10(null);
15416
+ const [fieldPickState, setFieldPickState] = useState13(null);
15417
+ const [fieldTypePickerOpen, setFieldTypePickerOpen] = useState13(false);
15418
+ const clearFormPick = useCallback8(() => {
14911
15419
  const form = formPickElRef.current;
14912
15420
  const editing = fieldPickElRef.current;
14913
15421
  if (commitPlaceholderEdit(editing) && editing) {
@@ -14927,7 +15435,7 @@ function OhhwellsBridge() {
14927
15435
  formPickElRef.current = null;
14928
15436
  setFormPickRect(null);
14929
15437
  }, []);
14930
- const clearFieldPick = useCallback7(() => {
15438
+ const clearFieldPick = useCallback8(() => {
14931
15439
  const wrapper = fieldPickElRef.current;
14932
15440
  if (commitPlaceholderEdit(wrapper) && wrapper) {
14933
15441
  const form = wrapper.closest('[data-ohw-editable="form"]');
@@ -14937,9 +15445,9 @@ function OhhwellsBridge() {
14937
15445
  setFieldPickRect(null);
14938
15446
  setFieldPickState(null);
14939
15447
  }, []);
14940
- const persistFieldsRef = useRef9(() => {
15448
+ const persistFieldsRef = useRef10(() => {
14941
15449
  });
14942
- const persistFields = useCallback7(
15450
+ const persistFields = useCallback8(
14943
15451
  (form) => {
14944
15452
  const key = formKeyOf(form);
14945
15453
  if (!key) return;
@@ -14950,7 +15458,7 @@ function OhhwellsBridge() {
14950
15458
  []
14951
15459
  );
14952
15460
  persistFieldsRef.current = persistFields;
14953
- const selectField = useCallback7((wrapper) => {
15461
+ const selectField = useCallback8((wrapper) => {
14954
15462
  if (fieldPickElRef.current && fieldPickElRef.current !== wrapper) {
14955
15463
  commitPlaceholderEdit(fieldPickElRef.current);
14956
15464
  }
@@ -14963,7 +15471,7 @@ function OhhwellsBridge() {
14963
15471
  setFieldPickState({ type: fieldTypeOf(wrapper), required: isFieldRequired(wrapper) });
14964
15472
  setFieldTypePickerOpen(false);
14965
15473
  }, []);
14966
- const withSelectedField = useCallback7(
15474
+ const withSelectedField = useCallback8(
14967
15475
  (run) => {
14968
15476
  const wrapper = fieldPickElRef.current;
14969
15477
  const form = formPickElRef.current;
@@ -14976,28 +15484,28 @@ function OhhwellsBridge() {
14976
15484
  },
14977
15485
  [persistFields]
14978
15486
  );
14979
- const handleFieldTypeChange = useCallback7(
15487
+ const handleFieldTypeChange = useCallback8(
14980
15488
  (type) => withSelectedField((_form, wrapper) => {
14981
15489
  applyFieldType(wrapper, type);
14982
15490
  selectField(wrapper);
14983
15491
  }),
14984
15492
  [selectField, withSelectedField]
14985
15493
  );
14986
- const handleFieldRequiredToggle = useCallback7(
15494
+ const handleFieldRequiredToggle = useCallback8(
14987
15495
  () => withSelectedField((_form, wrapper) => {
14988
15496
  setFieldRequired(wrapper, !isFieldRequired(wrapper));
14989
15497
  selectField(wrapper);
14990
15498
  }),
14991
15499
  [selectField, withSelectedField]
14992
15500
  );
14993
- const handleFieldDuplicate = useCallback7(
15501
+ const handleFieldDuplicate = useCallback8(
14994
15502
  () => withSelectedField((form, wrapper) => {
14995
15503
  const copy = duplicateField(form, wrapper);
14996
15504
  selectField(copy);
14997
15505
  }),
14998
15506
  [selectField, withSelectedField]
14999
15507
  );
15000
- const handleFieldDelete = useCallback7(
15508
+ const handleFieldDelete = useCallback8(
15001
15509
  () => withSelectedField((_form, wrapper) => {
15002
15510
  removeField(wrapper);
15003
15511
  clearFieldPick();
@@ -15005,7 +15513,7 @@ function OhhwellsBridge() {
15005
15513
  }),
15006
15514
  [clearFieldPick, withSelectedField]
15007
15515
  );
15008
- const handleAddField = useCallback7(
15516
+ const handleAddField = useCallback8(
15009
15517
  (type) => {
15010
15518
  const form = formPickElRef.current;
15011
15519
  if (!form) return;
@@ -15021,8 +15529,8 @@ function OhhwellsBridge() {
15021
15529
  },
15022
15530
  [persistFields, selectField]
15023
15531
  );
15024
- const fieldDragRef = useRef9(null);
15025
- const buildFieldDropSlots = useCallback7((form, draggedKey) => {
15532
+ const fieldDragRef = useRef10(null);
15533
+ const buildFieldDropSlots = useCallback8((form, draggedKey) => {
15026
15534
  const others = listFieldWrappers(form).filter((el) => fieldKeyOf(el) !== draggedKey);
15027
15535
  const slots = others.map((el) => {
15028
15536
  const rect = el.getBoundingClientRect();
@@ -15035,7 +15543,7 @@ function OhhwellsBridge() {
15035
15543
  }
15036
15544
  return slots;
15037
15545
  }, []);
15038
- const handleFieldDragStart = useCallback7(() => {
15546
+ const handleFieldDragStart = useCallback8(() => {
15039
15547
  const wrapper = fieldPickElRef.current;
15040
15548
  const form = formPickElRef.current;
15041
15549
  if (!wrapper || !form) return;
@@ -15044,18 +15552,18 @@ function OhhwellsBridge() {
15044
15552
  setFieldDragging(true);
15045
15553
  setFieldDropSlots(buildFieldDropSlots(form, key));
15046
15554
  }, [buildFieldDropSlots]);
15047
- const handleFieldDragEnd = useCallback7(() => {
15555
+ const handleFieldDragEnd = useCallback8(() => {
15048
15556
  fieldDragRef.current = null;
15049
15557
  setFieldDropIndex(null);
15050
15558
  setFieldDropSlots([]);
15051
15559
  setFieldDragging(false);
15052
15560
  }, []);
15053
- const [fieldDropIndex, setFieldDropIndex] = useState12(null);
15054
- const [fieldDropSlots, setFieldDropSlots] = useState12([]);
15055
- const [fieldDragging, setFieldDragging] = useState12(false);
15056
- const clearFormPickRef = useRef9(clearFormPick);
15561
+ const [fieldDropIndex, setFieldDropIndex] = useState13(null);
15562
+ const [fieldDropSlots, setFieldDropSlots] = useState13([]);
15563
+ const [fieldDragging, setFieldDragging] = useState13(false);
15564
+ const clearFormPickRef = useRef10(clearFormPick);
15057
15565
  clearFormPickRef.current = clearFormPick;
15058
- useEffect12(() => {
15566
+ useEffect13(() => {
15059
15567
  const el = fieldPickElRef.current;
15060
15568
  if (!el || fieldPickRect === null) return;
15061
15569
  const observer = new ResizeObserver(() => {
@@ -15064,7 +15572,7 @@ function OhhwellsBridge() {
15064
15572
  observer.observe(el);
15065
15573
  return () => observer.disconnect();
15066
15574
  }, [fieldPickRect !== null, fieldPickState]);
15067
- useEffect12(() => {
15575
+ useEffect13(() => {
15068
15576
  const el = formPickElRef.current;
15069
15577
  if (!el || formPickRect === null) return;
15070
15578
  const observer = new ResizeObserver(() => {
@@ -15073,25 +15581,25 @@ function OhhwellsBridge() {
15073
15581
  observer.observe(el);
15074
15582
  return () => observer.disconnect();
15075
15583
  }, [formPickRect !== null, formViewState]);
15076
- const [toolbarVariant, setToolbarVariant] = useState12("none");
15077
- const toolbarVariantRef = useRef9("none");
15584
+ const [toolbarVariant, setToolbarVariant] = useState13("none");
15585
+ const toolbarVariantRef = useRef10("none");
15078
15586
  toolbarVariantRef.current = toolbarVariant;
15079
- const [selectedIsCta, setSelectedIsCta] = useState12(false);
15080
- const [selectedIsSocial, setSelectedIsSocial] = useState12(false);
15081
- const [selectedIsSocialsRow, setSelectedIsSocialsRow] = useState12(false);
15082
- const [reorderHrefKey, setReorderHrefKey] = useState12(null);
15083
- const [reorderDragDisabled, setReorderDragDisabled] = useState12(false);
15084
- const [toggleState, setToggleState] = useState12(null);
15085
- const [maxBadge, setMaxBadge] = useState12(null);
15086
- const [activeCommands, setActiveCommands] = useState12(/* @__PURE__ */ new Set());
15087
- const [sectionGap, setSectionGap] = useState12(null);
15088
- const [toolbarShowEditLink, setToolbarShowEditLink] = useState12(false);
15089
- const hoveredNavContainerRef = useRef9(null);
15090
- const [hoveredNavContainerRect, setHoveredNavContainerRect] = useState12(null);
15091
- const hoveredItemElRef = useRef9(null);
15092
- const [hoveredItemRect, setHoveredItemRect] = useState12(null);
15093
- const [hoveredTextRect, setHoveredTextRect] = useState12(null);
15094
- useEffect12(() => {
15587
+ const [selectedIsCta, setSelectedIsCta] = useState13(false);
15588
+ const [selectedIsSocial, setSelectedIsSocial] = useState13(false);
15589
+ const [selectedIsSocialsRow, setSelectedIsSocialsRow] = useState13(false);
15590
+ const [reorderHrefKey, setReorderHrefKey] = useState13(null);
15591
+ const [reorderDragDisabled, setReorderDragDisabled] = useState13(false);
15592
+ const [toggleState, setToggleState] = useState13(null);
15593
+ const [maxBadge, setMaxBadge] = useState13(null);
15594
+ const [activeCommands, setActiveCommands] = useState13(/* @__PURE__ */ new Set());
15595
+ const [sectionGap, setSectionGap] = useState13(null);
15596
+ const [toolbarShowEditLink, setToolbarShowEditLink] = useState13(false);
15597
+ const hoveredNavContainerRef = useRef10(null);
15598
+ const [hoveredNavContainerRect, setHoveredNavContainerRect] = useState13(null);
15599
+ const hoveredItemElRef = useRef10(null);
15600
+ const [hoveredItemRect, setHoveredItemRect] = useState13(null);
15601
+ const [hoveredTextRect, setHoveredTextRect] = useState13(null);
15602
+ useEffect13(() => {
15095
15603
  const sync = () => {
15096
15604
  const el = document.querySelector(
15097
15605
  '[data-ohw-hovered]:not([contenteditable]):not([data-ohw-href-key]):not([data-ohw-editable="form"] *)'
@@ -15116,41 +15624,41 @@ function OhhwellsBridge() {
15116
15624
  });
15117
15625
  return () => observer.disconnect();
15118
15626
  }, []);
15119
- const siblingHintElRef = useRef9(null);
15120
- const [siblingHintRect, setSiblingHintRect] = useState12(null);
15121
- const [siblingHintRects, setSiblingHintRects] = useState12([]);
15122
- const [isItemDragging, setIsItemDragging] = useState12(false);
15123
- const [isFooterFrameSelection, setIsFooterFrameSelection] = useState12(false);
15627
+ const siblingHintElRef = useRef10(null);
15628
+ const [siblingHintRect, setSiblingHintRect] = useState13(null);
15629
+ const [siblingHintRects, setSiblingHintRects] = useState13([]);
15630
+ const [isItemDragging, setIsItemDragging] = useState13(false);
15631
+ const [isFooterFrameSelection, setIsFooterFrameSelection] = useState13(false);
15124
15632
  isFooterFrameSelectionRef.current = isFooterFrameSelection;
15125
- const [floatingPanel, setFloatingPanel] = useState12(null);
15126
- const floatingPanelOpenRef = useRef9(false);
15633
+ const [floatingPanel, setFloatingPanel] = useState13(null);
15634
+ const floatingPanelOpenRef = useRef10(false);
15127
15635
  floatingPanelOpenRef.current = floatingPanel !== null;
15128
- const [floatingPanelPos, setFloatingPanelPos] = useState12(null);
15129
- const [logoSizeDraft, setLogoSizeDraft] = useState12(null);
15130
- const [editorViewport, setEditorViewport] = useState12("desktop");
15131
- const [parentScrollSnap, setParentScrollSnap] = useState12(null);
15132
- const [navDropdownPreviewOpen, setNavDropdownPreviewOpen] = useState12(null);
15133
- const [footerHeadingVisible, setFooterHeadingVisible] = useState12(null);
15134
- const footerDragRef = useRef9(null);
15135
- const [footerDropSlots, setFooterDropSlots] = useState12([]);
15136
- const [activeFooterDropIndex, setActiveFooterDropIndex] = useState12(null);
15137
- const [draggedItemRect, setDraggedItemRect] = useState12(null);
15138
- const footerPointerDragRef = useRef9(null);
15139
- const suppressNextClickRef = useRef9(false);
15140
- const suppressClickUntilRef = useRef9(0);
15141
- const [linkPopover, setLinkPopover] = useState12(null);
15142
- const linkPopoverSessionRef = useRef9(null);
15143
- const addNavAfterAnchorRef = useRef9(null);
15144
- const editContentRef = useRef9({});
15145
- const aiSectionsRef = useRef9("");
15146
- const pendingDeleteUndoRef = useRef9(null);
15147
- const [sitePages, setSitePages] = useState12([]);
15148
- const [sectionsByPath, setSectionsByPath] = useState12({});
15149
- const sectionsPrefetchGenRef = useRef9(0);
15150
- const setLinkPopoverRef = useRef9(setLinkPopover);
15151
- const linkPopoverPanelRef = useRef9(null);
15152
- const linkPopoverOpenRef = useRef9(false);
15153
- const linkPopoverGraceUntilRef = useRef9(0);
15636
+ const [floatingPanelPos, setFloatingPanelPos] = useState13(null);
15637
+ const [logoSizeDraft, setLogoSizeDraft] = useState13(null);
15638
+ const [editorViewport, setEditorViewport] = useState13("desktop");
15639
+ const [parentScrollSnap, setParentScrollSnap] = useState13(null);
15640
+ const [navDropdownPreviewOpen, setNavDropdownPreviewOpen] = useState13(null);
15641
+ const [footerHeadingVisible, setFooterHeadingVisible] = useState13(null);
15642
+ const footerDragRef = useRef10(null);
15643
+ const [footerDropSlots, setFooterDropSlots] = useState13([]);
15644
+ const [activeFooterDropIndex, setActiveFooterDropIndex] = useState13(null);
15645
+ const [draggedItemRect, setDraggedItemRect] = useState13(null);
15646
+ const footerPointerDragRef = useRef10(null);
15647
+ const suppressNextClickRef = useRef10(false);
15648
+ const suppressClickUntilRef = useRef10(0);
15649
+ const [linkPopover, setLinkPopover] = useState13(null);
15650
+ const linkPopoverSessionRef = useRef10(null);
15651
+ const addNavAfterAnchorRef = useRef10(null);
15652
+ const editContentRef = useRef10({});
15653
+ const aiSectionsRef = useRef10("");
15654
+ const pendingDeleteUndoRef = useRef10(null);
15655
+ const [sitePages, setSitePages] = useState13([]);
15656
+ const [sectionsByPath, setSectionsByPath] = useState13({});
15657
+ const sectionsPrefetchGenRef = useRef10(0);
15658
+ const setLinkPopoverRef = useRef10(setLinkPopover);
15659
+ const linkPopoverPanelRef = useRef10(null);
15660
+ const linkPopoverOpenRef = useRef10(false);
15661
+ const linkPopoverGraceUntilRef = useRef10(0);
15154
15662
  setLinkPopoverRef.current = setLinkPopover;
15155
15663
  linkPopoverSessionRef.current = linkPopover;
15156
15664
  const {
@@ -15185,10 +15693,20 @@ function OhhwellsBridge() {
15185
15693
  getNavigationItemAnchor,
15186
15694
  isDragHandleDisabled
15187
15695
  });
15696
+ const { sectionDropSlots, activeSectionDropIndex, isSectionDragging } = useSectionDrag({
15697
+ isEditMode,
15698
+ editContentRef,
15699
+ postToParentRef,
15700
+ parentScrollRef,
15701
+ navDragRef,
15702
+ footerDragRef,
15703
+ suppressNextClickRef,
15704
+ suppressClickUntilRef
15705
+ });
15188
15706
  const bumpLinkPopoverGrace = () => {
15189
15707
  linkPopoverGraceUntilRef.current = Date.now() + 350;
15190
15708
  };
15191
- const runSectionsPrefetch = useCallback7((pages) => {
15709
+ const runSectionsPrefetch = useCallback8((pages) => {
15192
15710
  if (!isEditMode || shouldUseDevFixtures() || pages.length === 0) return;
15193
15711
  const gen = ++sectionsPrefetchGenRef.current;
15194
15712
  const paths = pages.map((p) => p.path);
@@ -15207,9 +15725,9 @@ function OhhwellsBridge() {
15207
15725
  );
15208
15726
  });
15209
15727
  }, [isEditMode, pathname]);
15210
- const runSectionsPrefetchRef = useRef9(runSectionsPrefetch);
15728
+ const runSectionsPrefetchRef = useRef10(runSectionsPrefetch);
15211
15729
  runSectionsPrefetchRef.current = runSectionsPrefetch;
15212
- useEffect12(() => {
15730
+ useEffect13(() => {
15213
15731
  if (!linkPopover) {
15214
15732
  document.documentElement.removeAttribute("data-ohw-link-popover-open");
15215
15733
  return;
@@ -15237,7 +15755,7 @@ function OhhwellsBridge() {
15237
15755
  document.documentElement.removeAttribute("data-ohw-link-popover-open");
15238
15756
  };
15239
15757
  }, [linkPopover, postToParent2]);
15240
- useEffect12(() => {
15758
+ useEffect13(() => {
15241
15759
  if (!isEditMode) return;
15242
15760
  const useFixtures = shouldUseDevFixtures();
15243
15761
  if (useFixtures) {
@@ -15261,14 +15779,14 @@ function OhhwellsBridge() {
15261
15779
  if (!useFixtures) postToParent2({ type: "ow:request-site-pages" });
15262
15780
  return () => window.removeEventListener("message", onSitePages);
15263
15781
  }, [isEditMode, postToParent2]);
15264
- useEffect12(() => {
15782
+ useEffect13(() => {
15265
15783
  if (!isEditMode || shouldUseDevFixtures()) return;
15266
15784
  void loadAllSectionsManifest().then((manifest) => {
15267
15785
  if (Object.keys(manifest).length === 0) return;
15268
15786
  setSectionsByPath((prev) => ({ ...manifest, ...prev }));
15269
15787
  });
15270
15788
  }, [isEditMode]);
15271
- useEffect12(() => {
15789
+ useEffect13(() => {
15272
15790
  const update = () => {
15273
15791
  const el = activeElRef.current ?? selectedElRef.current;
15274
15792
  if (el) setToolbarRect(getEditMeasureEl(el).getBoundingClientRect());
@@ -15292,10 +15810,10 @@ function OhhwellsBridge() {
15292
15810
  vvp.removeEventListener("resize", update);
15293
15811
  };
15294
15812
  }, []);
15295
- const refreshStateRules = useCallback7(() => {
15813
+ const refreshStateRules = useCallback8(() => {
15296
15814
  editStylesRef.current?.forceHover && (editStylesRef.current.forceHover.textContent = collectStateRules());
15297
15815
  }, []);
15298
- const processConfigRequest = useCallback7((insertAfterVal) => {
15816
+ const processConfigRequest = useCallback8((insertAfterVal) => {
15299
15817
  const tracker = getSectionsTracker();
15300
15818
  let entries = [];
15301
15819
  try {
@@ -15318,7 +15836,7 @@ function OhhwellsBridge() {
15318
15836
  }
15319
15837
  window.postMessage({ type: "ow:schedule-config", insertAfter: insertAfterVal, scheduleId: null }, "*");
15320
15838
  }, [isEditMode]);
15321
- const deactivate = useCallback7(() => {
15839
+ const deactivate = useCallback8(() => {
15322
15840
  const el = activeElRef.current;
15323
15841
  if (!el) return;
15324
15842
  const isFormBlock = el.dataset.ohwEditable === "form";
@@ -15334,7 +15852,7 @@ function OhhwellsBridge() {
15334
15852
  const original = originalContentRef.current ?? "";
15335
15853
  if (html !== sanitizeHtml(original)) {
15336
15854
  postToParentRef.current({ type: "ow:change", nodes: [{ key, text: html }] });
15337
- const h = document.documentElement.scrollHeight;
15855
+ const h = document.body.scrollHeight;
15338
15856
  if (h > 50) postToParentRef.current({ type: "ow:height", height: h });
15339
15857
  }
15340
15858
  }
@@ -15359,12 +15877,12 @@ function OhhwellsBridge() {
15359
15877
  setToolbarShowEditLink(false);
15360
15878
  postToParent2({ type: "ow:exit-edit" });
15361
15879
  }, [postToParent2]);
15362
- const clearSelectedAttr = useCallback7(() => {
15880
+ const clearSelectedAttr = useCallback8(() => {
15363
15881
  document.querySelectorAll("[data-ohw-selected]").forEach((el) => {
15364
15882
  el.removeAttribute("data-ohw-selected");
15365
15883
  });
15366
15884
  }, []);
15367
- const deselect = useCallback7(() => {
15885
+ const deselect = useCallback8(() => {
15368
15886
  clearSelectedAttr();
15369
15887
  selectedElRef.current = null;
15370
15888
  selectedHrefKeyRef.current = null;
@@ -15393,20 +15911,20 @@ function OhhwellsBridge() {
15393
15911
  setToolbarVariant("none");
15394
15912
  }
15395
15913
  }, [clearSelectedAttr]);
15396
- const markSelected = useCallback7((el) => {
15914
+ const markSelected = useCallback8((el) => {
15397
15915
  clearSelectedAttr();
15398
15916
  el.removeAttribute("data-ohw-hovered");
15399
15917
  el.setAttribute("data-ohw-selected", "");
15400
15918
  }, [clearSelectedAttr]);
15401
- const isSelectedForHover = useCallback7((el) => {
15919
+ const isSelectedForHover = useCallback8((el) => {
15402
15920
  if (!el) return false;
15403
15921
  return [selectedElRef.current, activeElRef.current].some(
15404
15922
  (busy) => busy && (el === busy || busy.contains(el) || el.contains(busy))
15405
15923
  );
15406
15924
  }, []);
15407
- const isSelectedForHoverRef = useRef9(isSelectedForHover);
15925
+ const isSelectedForHoverRef = useRef10(isSelectedForHover);
15408
15926
  isSelectedForHoverRef.current = isSelectedForHover;
15409
- const resolveHrefKeyElement = useCallback7((hrefKey) => {
15927
+ const resolveHrefKeyElement = useCallback8((hrefKey) => {
15410
15928
  if (isFooterHrefKey(hrefKey)) {
15411
15929
  return document.querySelector(
15412
15930
  `footer [data-ohw-href-key="${CSS.escape(hrefKey)}"]`
@@ -15421,7 +15939,7 @@ function OhhwellsBridge() {
15421
15939
  `[data-ohw-href-key="${CSS.escape(hrefKey)}"]`
15422
15940
  );
15423
15941
  }, []);
15424
- const resyncSelectedNavigationItem = useCallback7(() => {
15942
+ const resyncSelectedNavigationItem = useCallback8(() => {
15425
15943
  const hrefKey = selectedHrefKeyRef.current;
15426
15944
  if (hrefKey) {
15427
15945
  const link = resolveHrefKeyElement(hrefKey);
@@ -15459,7 +15977,7 @@ function OhhwellsBridge() {
15459
15977
  );
15460
15978
  }
15461
15979
  }, [resolveHrefKeyElement]);
15462
- const reselectNavigationItem = useCallback7((navAnchor) => {
15980
+ const reselectNavigationItem = useCallback8((navAnchor) => {
15463
15981
  selectedElRef.current = navAnchor;
15464
15982
  selectedHrefKeyRef.current = navAnchor.getAttribute("data-ohw-href-key");
15465
15983
  selectedFooterColAttrRef.current = null;
@@ -15490,7 +16008,7 @@ function OhhwellsBridge() {
15490
16008
  setToolbarShowEditLink(false);
15491
16009
  setActiveCommands(/* @__PURE__ */ new Set());
15492
16010
  }, [markSelected]);
15493
- const commitNavigationTextEdit = useCallback7((navAnchor) => {
16011
+ const commitNavigationTextEdit = useCallback8((navAnchor) => {
15494
16012
  const el = activeElRef.current;
15495
16013
  if (!el) return;
15496
16014
  const key = el.dataset.ohwKey;
@@ -15504,7 +16022,7 @@ function OhhwellsBridge() {
15504
16022
  const original = originalContentRef.current ?? "";
15505
16023
  if (html !== sanitizeHtml(original)) {
15506
16024
  postToParent2({ type: "ow:change", nodes: [{ key, text: html }] });
15507
- const h = document.documentElement.scrollHeight;
16025
+ const h = document.body.scrollHeight;
15508
16026
  if (h > 50) postToParent2({ type: "ow:height", height: h });
15509
16027
  }
15510
16028
  }
@@ -15523,7 +16041,7 @@ function OhhwellsBridge() {
15523
16041
  postToParent2({ type: "ow:exit-edit" });
15524
16042
  reselectNavigationItem(navAnchor);
15525
16043
  }, [postToParent2, reselectNavigationItem]);
15526
- const handleAddTopLevelNavItem = useCallback7(() => {
16044
+ const handleAddTopLevelNavItem = useCallback8(() => {
15527
16045
  const items = listNavbarRootItems();
15528
16046
  addNavAfterAnchorRef.current = items[items.length - 1] ?? null;
15529
16047
  deselectRef.current();
@@ -15535,7 +16053,7 @@ function OhhwellsBridge() {
15535
16053
  intent: "add-nav"
15536
16054
  });
15537
16055
  }, []);
15538
- const maybeWarnNavLinkDropdownConflict = useCallback7(
16056
+ const maybeWarnNavLinkDropdownConflict = useCallback8(
15539
16057
  (anchor) => {
15540
16058
  if (!isNavbarHrefKey(anchor.getAttribute("data-ohw-href-key"))) return;
15541
16059
  if (!navDropdownsOpenOnClick()) return;
@@ -15548,7 +16066,7 @@ function OhhwellsBridge() {
15548
16066
  },
15549
16067
  [postToParent2]
15550
16068
  );
15551
- const handleNavDropdownOpenChange = useCallback7((open) => {
16069
+ const handleNavDropdownOpenChange = useCallback8((open) => {
15552
16070
  const selected = selectedElRef.current;
15553
16071
  if (!selected || !isNavigationItem2(selected)) return;
15554
16072
  setNavGroupForceOpen(selected, open);
@@ -15560,7 +16078,7 @@ function OhhwellsBridge() {
15560
16078
  }
15561
16079
  });
15562
16080
  }, []);
15563
- const handleFooterHeadingVisibleChange = useCallback7(
16081
+ const handleFooterHeadingVisibleChange = useCallback8(
15564
16082
  (visible) => {
15565
16083
  const selected = selectedElRef.current;
15566
16084
  if (!selected || !isFooterFrameSelectionRef.current) return;
@@ -15584,7 +16102,7 @@ function OhhwellsBridge() {
15584
16102
  },
15585
16103
  [postToParent2]
15586
16104
  );
15587
- const enterEditOnNewItem = useCallback7((anchor) => {
16105
+ const enterEditOnNewItem = useCallback8((anchor) => {
15588
16106
  const label = anchor.querySelector('[data-ohw-editable="text"]');
15589
16107
  if (!label) {
15590
16108
  selectRef.current(anchor);
@@ -15593,8 +16111,8 @@ function OhhwellsBridge() {
15593
16111
  setNavGroupForceOpen(anchor, true);
15594
16112
  activateRef.current(label);
15595
16113
  }, []);
15596
- const pendingSocialAddRef = useRef9(null);
15597
- const handleAddChildItem = useCallback7(() => {
16114
+ const pendingSocialAddRef = useRef10(null);
16115
+ const handleAddChildItem = useCallback8(() => {
15598
16116
  const selected = selectedElRef.current;
15599
16117
  if (!selected) return;
15600
16118
  const socialsRow = isSocialsRow(selected) ? selected : findSocialsRow(selected);
@@ -15703,7 +16221,7 @@ function OhhwellsBridge() {
15703
16221
  enterEditOnNewItem(result.anchor);
15704
16222
  });
15705
16223
  }, [enterEditOnNewItem, isFooterFrameSelection, maybeWarnNavLinkDropdownConflict, postToParent2]);
15706
- const handleAddFooterColumn = useCallback7(() => {
16224
+ const handleAddFooterColumn = useCallback8(() => {
15707
16225
  if (!canAddFooterColumn()) {
15708
16226
  postToParent2({
15709
16227
  type: "ow:toast",
@@ -15724,7 +16242,7 @@ function OhhwellsBridge() {
15724
16242
  selectRef.current(result.firstLink);
15725
16243
  });
15726
16244
  }, [postToParent2]);
15727
- const clearFooterDragVisuals = useCallback7(() => {
16245
+ const clearFooterDragVisuals = useCallback8(() => {
15728
16246
  footerDragRef.current = null;
15729
16247
  setSiblingHintRects([]);
15730
16248
  setFooterDropSlots([]);
@@ -15733,7 +16251,7 @@ function OhhwellsBridge() {
15733
16251
  setIsItemDragging(false);
15734
16252
  unlockFooterDragInteraction();
15735
16253
  }, []);
15736
- const refreshFooterDragVisuals = useCallback7((session, activeSlot, clientX, clientY) => {
16254
+ const refreshFooterDragVisuals = useCallback8((session, activeSlot, clientX, clientY) => {
15737
16255
  const dragged = session.draggedEl;
15738
16256
  setDraggedItemRect(dragged.getBoundingClientRect());
15739
16257
  if (typeof clientX === "number" && typeof clientY === "number") {
@@ -15765,13 +16283,13 @@ function OhhwellsBridge() {
15765
16283
  const activeIdx = activeSlot ? slots.findIndex((s) => s.insertIndex === activeSlot.insertIndex) : -1;
15766
16284
  setActiveFooterDropIndex(activeIdx >= 0 ? activeIdx : null);
15767
16285
  }, []);
15768
- const refreshFooterDragVisualsRef = useRef9(refreshFooterDragVisuals);
16286
+ const refreshFooterDragVisualsRef = useRef10(refreshFooterDragVisuals);
15769
16287
  refreshFooterDragVisualsRef.current = refreshFooterDragVisuals;
15770
- const commitFooterDragRef = useRef9(() => {
16288
+ const commitFooterDragRef = useRef10(() => {
15771
16289
  });
15772
- const beginFooterDragRef = useRef9(() => {
16290
+ const beginFooterDragRef = useRef10(() => {
15773
16291
  });
15774
- const beginFooterDrag = useCallback7(
16292
+ const beginFooterDrag = useCallback8(
15775
16293
  (session) => {
15776
16294
  const rect = session.draggedEl.getBoundingClientRect();
15777
16295
  session.lastClientX = session.lastClientX || rect.left + rect.width / 2;
@@ -15791,7 +16309,7 @@ function OhhwellsBridge() {
15791
16309
  [refreshFooterDragVisuals]
15792
16310
  );
15793
16311
  beginFooterDragRef.current = beginFooterDrag;
15794
- const commitFooterDrag = useCallback7(
16312
+ const commitFooterDrag = useCallback8(
15795
16313
  (clientX, clientY) => {
15796
16314
  const session = footerDragRef.current;
15797
16315
  if (!session) {
@@ -15920,7 +16438,7 @@ function OhhwellsBridge() {
15920
16438
  [clearFooterDragVisuals, resolveHrefKeyElement, resyncSelectedNavigationItem]
15921
16439
  );
15922
16440
  commitFooterDragRef.current = commitFooterDrag;
15923
- const startFooterLinkDrag = useCallback7(
16441
+ const startFooterLinkDrag = useCallback8(
15924
16442
  (anchor, clientX, clientY, wasSelected) => {
15925
16443
  const hrefKey = anchor.getAttribute("data-ohw-href-key");
15926
16444
  if (!hrefKey) return false;
@@ -15956,7 +16474,7 @@ function OhhwellsBridge() {
15956
16474
  },
15957
16475
  [beginFooterDrag]
15958
16476
  );
15959
- const startFooterColumnDrag = useCallback7(
16477
+ const startFooterColumnDrag = useCallback8(
15960
16478
  (columnEl, clientX, clientY, wasSelected) => {
15961
16479
  const columns = listFooterColumns();
15962
16480
  const idx = columns.indexOf(columnEl);
@@ -15976,7 +16494,7 @@ function OhhwellsBridge() {
15976
16494
  },
15977
16495
  [beginFooterDrag]
15978
16496
  );
15979
- const handleItemDragStart = useCallback7(
16497
+ const handleItemDragStart = useCallback8(
15980
16498
  (e) => {
15981
16499
  const selected = selectedElRef.current;
15982
16500
  if (!selected) {
@@ -15996,7 +16514,7 @@ function OhhwellsBridge() {
15996
16514
  },
15997
16515
  [startFooterColumnDrag, startFooterLinkDrag, startNavLinkDrag]
15998
16516
  );
15999
- const handleItemDragEnd = useCallback7(
16517
+ const handleItemDragEnd = useCallback8(
16000
16518
  (e) => {
16001
16519
  if (footerDragRef.current) {
16002
16520
  const x = e?.clientX;
@@ -16022,7 +16540,7 @@ function OhhwellsBridge() {
16022
16540
  },
16023
16541
  [commitFooterDrag, commitNavDrag, navDragRef]
16024
16542
  );
16025
- const handleItemChromePointerDown = useCallback7((e) => {
16543
+ const handleItemChromePointerDown = useCallback8((e) => {
16026
16544
  if (e.button !== 0) return;
16027
16545
  const selected = selectedElRef.current;
16028
16546
  if (!selected) return;
@@ -16053,7 +16571,7 @@ function OhhwellsBridge() {
16053
16571
  }
16054
16572
  if (armNavPressFromChrome(selected, e.clientX, e.clientY, e.pointerId)) return;
16055
16573
  }, [armNavPressFromChrome]);
16056
- const handleItemChromeClick = useCallback7((clientX, clientY) => {
16574
+ const handleItemChromeClick = useCallback8((clientX, clientY) => {
16057
16575
  if (suppressNextClickRef.current || Date.now() < suppressClickUntilRef.current) {
16058
16576
  suppressNextClickRef.current = false;
16059
16577
  return;
@@ -16066,7 +16584,7 @@ function OhhwellsBridge() {
16066
16584
  }, []);
16067
16585
  reselectNavigationItemRef.current = reselectNavigationItem;
16068
16586
  commitNavigationTextEditRef.current = commitNavigationTextEdit;
16069
- const select = useCallback7((anchor) => {
16587
+ const select = useCallback8((anchor) => {
16070
16588
  if (!isNavigationItem2(anchor)) return;
16071
16589
  if (activeElRef.current) deactivate();
16072
16590
  aiSectionApiRef.current?.selectFromElement(anchor);
@@ -16109,7 +16627,7 @@ function OhhwellsBridge() {
16109
16627
  setFloatingPanel(null);
16110
16628
  setLogoSizeDraft(null);
16111
16629
  }, [deactivate, markSelected]);
16112
- const selectFrame = useCallback7((el) => {
16630
+ const selectFrame = useCallback8((el) => {
16113
16631
  if (!isNavigationContainer(el)) return;
16114
16632
  if (activeElRef.current) deactivate();
16115
16633
  aiSectionApiRef.current?.selectFromElement(el);
@@ -16160,7 +16678,7 @@ function OhhwellsBridge() {
16160
16678
  setFloatingPanel(null);
16161
16679
  setLogoSizeDraft(null);
16162
16680
  }, [deactivate, markSelected, postToParent2]);
16163
- const selectLogo = useCallback7(
16681
+ const selectLogo = useCallback8(
16164
16682
  (logoEl) => {
16165
16683
  if (activeElRef.current) deactivate();
16166
16684
  selectedElRef.current = logoEl;
@@ -16189,7 +16707,7 @@ function OhhwellsBridge() {
16189
16707
  },
16190
16708
  [deactivate, markSelected]
16191
16709
  );
16192
- const openLogoSizePanel = useCallback7((logoEl) => {
16710
+ const openLogoSizePanel = useCallback8((logoEl) => {
16193
16711
  const placement = getLogoPlacement(logoEl);
16194
16712
  const draft = readLogoSizeState(editContentRef.current, placement);
16195
16713
  setLogoSizeDraft(draft);
@@ -16202,7 +16720,7 @@ function OhhwellsBridge() {
16202
16720
  placement
16203
16721
  });
16204
16722
  }, []);
16205
- const openSocialsDisplayPanel = useCallback7((row) => {
16723
+ const openSocialsDisplayPanel = useCallback8((row) => {
16206
16724
  setParentScrollSnap(parentScrollRef.current);
16207
16725
  setFloatingPanel({
16208
16726
  key: "socials-display",
@@ -16212,11 +16730,11 @@ function OhhwellsBridge() {
16212
16730
  row
16213
16731
  });
16214
16732
  }, []);
16215
- const isEditModeRef = useRef9(false);
16216
- const requestMissingSocialIconsRef = useRef9(() => {
16733
+ const isEditModeRef = useRef10(false);
16734
+ const requestMissingSocialIconsRef = useRef10(() => {
16217
16735
  });
16218
- const askedSocialIconsRef = useRef9(/* @__PURE__ */ new Set());
16219
- const requestMissingSocialIcons = useCallback7(() => {
16736
+ const askedSocialIconsRef = useRef10(/* @__PURE__ */ new Set());
16737
+ const requestMissingSocialIcons = useCallback8(() => {
16220
16738
  const items = Array.from(document.querySelectorAll(`[${SOCIALS_ROW_ATTR}]`)).filter((row) => socialsDisplayFor(row, editContentRef.current).icon).flatMap((row) => {
16221
16739
  const missing = socialsMissingIcons(row);
16222
16740
  listSocialItems(row).forEach((item) => ensureIconSlot(item));
@@ -16228,7 +16746,7 @@ function OhhwellsBridge() {
16228
16746
  }, []);
16229
16747
  requestMissingSocialIconsRef.current = requestMissingSocialIcons;
16230
16748
  isEditModeRef.current = isEditMode;
16231
- const changeSocialsDisplay = useCallback7(
16749
+ const changeSocialsDisplay = useCallback8(
16232
16750
  (row, next) => {
16233
16751
  if (next.icon) {
16234
16752
  const missing = socialsMissingIcons(row);
@@ -16252,17 +16770,17 @@ function OhhwellsBridge() {
16252
16770
  },
16253
16771
  []
16254
16772
  );
16255
- const closeFloatingPanelOnly = useCallback7(() => {
16773
+ const closeFloatingPanelOnly = useCallback8(() => {
16256
16774
  setFloatingPanel(null);
16257
16775
  setLogoSizeDraft(null);
16258
16776
  }, []);
16259
16777
  closeFloatingPanelOnlyRef.current = closeFloatingPanelOnly;
16260
- const closeFloatingPanelAndDeselect = useCallback7(() => {
16778
+ const closeFloatingPanelAndDeselect = useCallback8(() => {
16261
16779
  setFloatingPanel(null);
16262
16780
  setLogoSizeDraft(null);
16263
16781
  deselectRef.current();
16264
16782
  }, []);
16265
- useEffect12(() => {
16783
+ useEffect13(() => {
16266
16784
  const session = floatingPanel && floatingPanel.kind === "logo-size" ? floatingPanel : null;
16267
16785
  if (!session || !logoSizeDraft) {
16268
16786
  postToParentRef.current({ type: "ow:logo-size-panel", open: false });
@@ -16281,7 +16799,7 @@ function OhhwellsBridge() {
16281
16799
  max: LOGO_SIZE_MAX
16282
16800
  });
16283
16801
  }, [floatingPanel, logoSizeDraft, editorViewport]);
16284
- const persistLogoSizeDraft = useCallback7(
16802
+ const persistLogoSizeDraft = useCallback8(
16285
16803
  (placement, draft) => {
16286
16804
  const desktopKey = LOGO_SIZE_DESKTOP_KEYS[placement];
16287
16805
  const mobileKey = LOGO_SIZE_MOBILE_KEYS[placement];
@@ -16321,7 +16839,7 @@ function OhhwellsBridge() {
16321
16839
  },
16322
16840
  [postToParent2]
16323
16841
  );
16324
- const activate = useCallback7((el, options) => {
16842
+ const activate = useCallback8((el, options) => {
16325
16843
  if (activeElRef.current === el) return;
16326
16844
  document.querySelectorAll("[data-ohw-hovered]").forEach((hovered) => {
16327
16845
  hovered.removeAttribute("data-ohw-hovered");
@@ -16419,8 +16937,8 @@ function OhhwellsBridge() {
16419
16937
  openLogoSizePanelRef.current = openLogoSizePanel;
16420
16938
  deselectRef.current = deselect;
16421
16939
  closeFloatingPanelOnlyRef.current = closeFloatingPanelOnly;
16422
- const lastSiteWideScopeRef = useRef9(null);
16423
- useEffect12(() => {
16940
+ const lastSiteWideScopeRef = useRef10(null);
16941
+ useEffect13(() => {
16424
16942
  if (!isEditMode) {
16425
16943
  if (lastSiteWideScopeRef.current !== false) {
16426
16944
  lastSiteWideScopeRef.current = false;
@@ -16540,7 +17058,7 @@ function OhhwellsBridge() {
16540
17058
  cancelled = true;
16541
17059
  };
16542
17060
  }, [subdomain, isEditMode]);
16543
- useEffect12(() => {
17061
+ useEffect13(() => {
16544
17062
  if (!isEditMode) return;
16545
17063
  const resolveIndex = (form, clientY) => {
16546
17064
  const wrappers = listFieldWrappers(form).filter((el) => fieldKeyOf(el) !== fieldDragRef.current?.key);
@@ -16581,7 +17099,7 @@ function OhhwellsBridge() {
16581
17099
  window.removeEventListener("drop", onDrop, true);
16582
17100
  };
16583
17101
  }, [buildFieldDropSlots, isEditMode, persistFields, selectField]);
16584
- useEffect12(() => {
17102
+ useEffect13(() => {
16585
17103
  if (!isEditMode) return;
16586
17104
  const mark = () => document.querySelectorAll('[data-ohw-editable="form"]').forEach((form) => {
16587
17105
  markFormFields(form);
@@ -16593,7 +17111,7 @@ function OhhwellsBridge() {
16593
17111
  });
16594
17112
  return () => observer.disconnect();
16595
17113
  }, [isEditMode, fetchState, pathname]);
16596
- useEffect12(() => {
17114
+ useEffect13(() => {
16597
17115
  if (!isEditMode) return;
16598
17116
  let saveTimer = null;
16599
17117
  const onInput = (e) => {
@@ -16615,14 +17133,14 @@ function OhhwellsBridge() {
16615
17133
  document.addEventListener("input", onInput, true);
16616
17134
  return () => document.removeEventListener("input", onInput, true);
16617
17135
  }, [isEditMode, persistFields]);
16618
- useEffect12(() => {
17136
+ useEffect13(() => {
16619
17137
  if (isEditMode || fetchState !== "done") return;
16620
17138
  const content = contentCache.get(subdomain) ?? {};
16621
17139
  document.querySelectorAll('[data-ohw-editable="form"]').forEach((form) => {
16622
17140
  reconcileFieldsFromContent(form, content);
16623
17141
  });
16624
17142
  }, [isEditMode, fetchState, subdomain]);
16625
- useEffect12(() => {
17143
+ useEffect13(() => {
16626
17144
  if (!isEditMode) return;
16627
17145
  const swallow = (e) => {
16628
17146
  const target = e.target;
@@ -16631,12 +17149,12 @@ function OhhwellsBridge() {
16631
17149
  document.addEventListener("submit", swallow, true);
16632
17150
  return () => document.removeEventListener("submit", swallow, true);
16633
17151
  }, [isEditMode]);
16634
- useEffect12(() => {
17152
+ useEffect13(() => {
16635
17153
  if (isEditMode || fetchState !== "done") return;
16636
17154
  const apiUrl = process.env.NEXT_PUBLIC_FLOWOPS_API_URL ?? "https://flowops-backend-staging-2yfdh7pwpq-as.a.run.app";
16637
17155
  bindPublishedForms(apiUrl, subdomain, contentCache.get(subdomain) ?? {});
16638
17156
  }, [isEditMode, fetchState, subdomain]);
16639
- useEffect12(() => {
17157
+ useEffect13(() => {
16640
17158
  if (!subdomain || isEditMode) return;
16641
17159
  let debounceTimer = null;
16642
17160
  let observer = null;
@@ -16709,10 +17227,10 @@ function OhhwellsBridge() {
16709
17227
  const visible = Boolean(subdomain) && fetchState !== "done";
16710
17228
  el.style.display = visible ? "flex" : "none";
16711
17229
  }, [subdomain, fetchState]);
16712
- useEffect12(() => {
17230
+ useEffect13(() => {
16713
17231
  postToParent2({ type: "ow:navigation", path: pathname });
16714
17232
  }, [pathname, postToParent2]);
16715
- useEffect12(() => {
17233
+ useEffect13(() => {
16716
17234
  if (!isEditMode) return;
16717
17235
  if (linkPopoverSessionRef.current?.intent === "add-nav") return;
16718
17236
  if (document.querySelector("[data-ohw-section-picker]")) return;
@@ -16720,7 +17238,7 @@ function OhhwellsBridge() {
16720
17238
  deselectRef.current();
16721
17239
  deactivateRef.current();
16722
17240
  }, [pathname, isEditMode]);
16723
- useEffect12(() => {
17241
+ useEffect13(() => {
16724
17242
  const contentForNav = () => {
16725
17243
  if (isEditMode) return editContentRef.current;
16726
17244
  if (!subdomain) return {};
@@ -16789,7 +17307,7 @@ function OhhwellsBridge() {
16789
17307
  observer?.disconnect();
16790
17308
  };
16791
17309
  }, [isEditMode, pathname, subdomain, fetchState, resyncSelectedNavigationItem]);
16792
- useEffect12(() => {
17310
+ useEffect13(() => {
16793
17311
  if (!isEditMode) return;
16794
17312
  const measure = () => {
16795
17313
  const h = document.body.scrollHeight;
@@ -16817,7 +17335,7 @@ function OhhwellsBridge() {
16817
17335
  window.removeEventListener("resize", handleResize);
16818
17336
  };
16819
17337
  }, [pathname, isEditMode, postToParent2]);
16820
- useEffect12(() => {
17338
+ useEffect13(() => {
16821
17339
  if (!subdomainFromQuery || isEditMode) return;
16822
17340
  const handleClick = (e) => {
16823
17341
  const anchor = e.target.closest("a");
@@ -16833,7 +17351,7 @@ function OhhwellsBridge() {
16833
17351
  document.addEventListener("click", handleClick, true);
16834
17352
  return () => document.removeEventListener("click", handleClick, true);
16835
17353
  }, [subdomainFromQuery, isEditMode, router]);
16836
- useEffect12(() => {
17354
+ useEffect13(() => {
16837
17355
  if (!isEditMode) {
16838
17356
  editStylesRef.current?.base.remove();
16839
17357
  editStylesRef.current?.forceHover.remove();
@@ -17217,6 +17735,14 @@ function OhhwellsBridge() {
17217
17735
  }
17218
17736
  const clickedButton = findClosestButtonLike(target);
17219
17737
  const buttonOnMedia = Boolean(clickedButton && isMediaEditable(editable) && editable.contains(clickedButton));
17738
+ console.log("[click-debug]", {
17739
+ editableType: editable.dataset.ohwEditable,
17740
+ editableTag: editable.tagName,
17741
+ targetTag: target.tagName,
17742
+ clickedButtonTag: clickedButton?.tagName ?? null,
17743
+ buttonOnMedia,
17744
+ isMediaEditableEditable: isMediaEditable(editable)
17745
+ });
17220
17746
  if (isMediaEditable(editable) && !buttonOnMedia) {
17221
17747
  e.preventDefault();
17222
17748
  e.stopPropagation();
@@ -17240,6 +17766,11 @@ function OhhwellsBridge() {
17240
17766
  const hrefLookupTarget = buttonOnMedia ? clickedButton : editable;
17241
17767
  const hrefCtx = getHrefKeyFromElement(hrefLookupTarget);
17242
17768
  const navAnchor = hrefCtx ? getNavigationItemAnchor(hrefCtx.anchor) : null;
17769
+ console.log("[click-debug 2]", {
17770
+ hrefLookupTargetTag: hrefLookupTarget.tagName,
17771
+ hrefCtx: hrefCtx ? { key: hrefCtx.key } : null,
17772
+ navAnchorTag: navAnchor?.tagName ?? null
17773
+ });
17243
17774
  if (navAnchor) {
17244
17775
  e.preventDefault();
17245
17776
  e.stopPropagation();
@@ -18481,7 +19012,7 @@ function OhhwellsBridge() {
18481
19012
  timers.set(key, setTimeout(() => {
18482
19013
  timers.delete(key);
18483
19014
  postToParentRef.current({ type: "ow:change", nodes: [{ key, text: html }] });
18484
- const h = document.documentElement.scrollHeight;
19015
+ const h = document.body.scrollHeight;
18485
19016
  if (h > 50) postToParentRef.current({ type: "ow:height", height: h });
18486
19017
  }, 400));
18487
19018
  };
@@ -18535,7 +19066,7 @@ function OhhwellsBridge() {
18535
19066
  reconcileFooterOrderFromContent(editContentRef.current);
18536
19067
  syncNavigationDragCursorAttrs();
18537
19068
  enforceLinkHrefs();
18538
- const hydratedHeight = document.documentElement.scrollHeight;
19069
+ const hydratedHeight = document.body.scrollHeight;
18539
19070
  if (hydratedHeight > 50) postToParentRef.current({ type: "ow:height", height: hydratedHeight });
18540
19071
  postToParentRef.current({ type: "ow:hydrate-done" });
18541
19072
  };
@@ -18608,7 +19139,7 @@ function OhhwellsBridge() {
18608
19139
  const nextValue = serializeAiSectionsState(nextState);
18609
19140
  aiSectionsRef.current = nextValue;
18610
19141
  applyAiSectionsToDom(nextState);
18611
- const newHeight = document.documentElement.scrollHeight;
19142
+ const newHeight = document.body.scrollHeight;
18612
19143
  if (newHeight > 50) postToParentRef.current({ type: "ow:height", height: newHeight });
18613
19144
  postToParentRef.current({ type: "ow:change", nodes: [{ key: AI_SECTIONS_KEY, text: nextValue }] });
18614
19145
  const appliedEl = document.querySelector(`[data-ohw-section="${CSS.escape(payload.id)}"]`);
@@ -18630,7 +19161,7 @@ function OhhwellsBridge() {
18630
19161
  const nextValue = serializeAiSectionsState(nextState);
18631
19162
  aiSectionsRef.current = nextValue;
18632
19163
  applyAiSectionsToDom(nextState);
18633
- const newHeight = document.documentElement.scrollHeight;
19164
+ const newHeight = document.body.scrollHeight;
18634
19165
  if (newHeight > 50) postToParentRef.current({ type: "ow:height", height: newHeight });
18635
19166
  postToParentRef.current({ type: "ow:change", nodes: [{ key: AI_SECTIONS_KEY, text: nextValue }] });
18636
19167
  postToParentRef.current({ type: "ow:ai-section-deleted", sectionId, previous, value: nextValue });
@@ -18642,18 +19173,73 @@ function OhhwellsBridge() {
18642
19173
  const value = typeof e.data.value === "string" ? e.data.value : "";
18643
19174
  aiSectionsRef.current = value;
18644
19175
  applyAiSectionsToDom(parseAiSectionsState(value));
18645
- const restoredHeight = document.documentElement.scrollHeight;
19176
+ const restoredHeight = document.body.scrollHeight;
18646
19177
  if (restoredHeight > 50) postToParentRef.current({ type: "ow:height", height: restoredHeight });
18647
19178
  postToParentRef.current({ type: "ow:change", nodes: [{ key: AI_SECTIONS_KEY, text: value }] });
18648
19179
  postAiSectionsChanged();
18649
19180
  };
18650
19181
  window.addEventListener("message", handleAiSetSections);
19182
+ const handleMoveSection = (e) => {
19183
+ if (e.data?.type !== "ow:move-section") return;
19184
+ const instanceId = typeof e.data.instanceId === "string" ? e.data.instanceId : "";
19185
+ const direction = e.data.direction === "up" || e.data.direction === "down" ? e.data.direction : null;
19186
+ if (!instanceId || !direction) return;
19187
+ const entries = moveSectionInstance(instanceId, direction, window.location.pathname);
19188
+ if (!entries) return;
19189
+ const orderJson = JSON.stringify(entries);
19190
+ editContentRef.current = { ...editContentRef.current, [SECTION_ORDER_KEY]: orderJson };
19191
+ postToParentRef.current({ type: "ow:change", nodes: [{ key: SECTION_ORDER_KEY, text: orderJson }] });
19192
+ window.dispatchEvent(new Event("resize"));
19193
+ };
19194
+ window.addEventListener("message", handleMoveSection);
18651
19195
  const handlePanelDragging = (e) => {
18652
19196
  if (e.data?.type !== "ow:panel-dragging") return;
18653
19197
  if (e.data.dragging) document.documentElement.setAttribute("data-ohw-panel-dragging", "");
18654
19198
  else document.documentElement.removeAttribute("data-ohw-panel-dragging");
18655
19199
  };
18656
19200
  window.addEventListener("message", handlePanelDragging);
19201
+ const handleDeleteSection = (e) => {
19202
+ if (e.data?.type !== "ow:delete-section") return;
19203
+ const instanceId = typeof e.data.instanceId === "string" ? e.data.instanceId : "";
19204
+ if (!instanceId) return;
19205
+ const currentEntries = getPageSectionOrderEntries(editContentRef.current[SECTION_ORDER_KEY], window.location.pathname);
19206
+ const entries = deleteSectionInstance(instanceId, window.location.pathname, currentEntries);
19207
+ if (!entries) return;
19208
+ const orderJson = JSON.stringify(entries);
19209
+ editContentRef.current = { ...editContentRef.current, [SECTION_ORDER_KEY]: orderJson };
19210
+ postToParentRef.current({ type: "ow:change", nodes: [{ key: SECTION_ORDER_KEY, text: orderJson }] });
19211
+ aiSectionApiRef.current?.clear();
19212
+ window.dispatchEvent(new Event("resize"));
19213
+ const deleteHeight = document.body.scrollHeight;
19214
+ if (deleteHeight > 50) postToParentRef.current({ type: "ow:height", height: deleteHeight });
19215
+ const actionId = newInstanceId();
19216
+ pendingDeleteUndoRef.current = {
19217
+ actionId,
19218
+ restore: () => {
19219
+ const restoredEntries = getPageSectionOrderEntries(
19220
+ editContentRef.current[SECTION_ORDER_KEY],
19221
+ window.location.pathname
19222
+ );
19223
+ const restored = restoreSectionInstance(instanceId, window.location.pathname, restoredEntries);
19224
+ if (!restored) return;
19225
+ const restoredJson = JSON.stringify(restored);
19226
+ editContentRef.current = { ...editContentRef.current, [SECTION_ORDER_KEY]: restoredJson };
19227
+ postToParentRef.current({ type: "ow:change", nodes: [{ key: SECTION_ORDER_KEY, text: restoredJson }] });
19228
+ window.dispatchEvent(new Event("resize"));
19229
+ const restoreHeight = document.body.scrollHeight;
19230
+ if (restoreHeight > 50) postToParentRef.current({ type: "ow:height", height: restoreHeight });
19231
+ }
19232
+ };
19233
+ postToParentRef.current({
19234
+ type: "ow:toast",
19235
+ title: "Section deleted",
19236
+ toastType: "success",
19237
+ actionLabel: "Undo",
19238
+ actionId,
19239
+ duration: 6e3
19240
+ });
19241
+ };
19242
+ window.addEventListener("message", handleDeleteSection);
18657
19243
  const handleDeactivate = (e) => {
18658
19244
  if (e.data?.type !== "ow:deactivate") return;
18659
19245
  if (document.documentElement.hasAttribute("data-ohw-panel-dragging")) return;
@@ -18926,7 +19512,7 @@ function OhhwellsBridge() {
18926
19512
  if (inserted) {
18927
19513
  const tracker = getSectionsTracker();
18928
19514
  postToParentRef.current({ type: "ow:change", nodes: [{ key: "__ohw_sections", text: tracker.textContent ?? "[]" }] });
18929
- const h = document.documentElement.scrollHeight;
19515
+ const h = document.body.scrollHeight;
18930
19516
  if (h > 50) postToParentRef.current({ type: "ow:height", height: h });
18931
19517
  }
18932
19518
  };
@@ -18968,7 +19554,7 @@ function OhhwellsBridge() {
18968
19554
  const updated = sections.filter((s) => !(s.type === "scheduling" && s.pagePath === currentPath));
18969
19555
  tracker.textContent = JSON.stringify(updated);
18970
19556
  postToParentRef.current({ type: "ow:change", nodes: [{ key: "__ohw_sections", text: tracker.textContent }] });
18971
- const h = document.documentElement.scrollHeight;
19557
+ const h = document.body.scrollHeight;
18972
19558
  if (h > 50) postToParentRef.current({ type: "ow:height", height: h });
18973
19559
  };
18974
19560
  const handleCollectSection = (e) => {
@@ -19323,7 +19909,9 @@ function OhhwellsBridge() {
19323
19909
  window.removeEventListener("message", handleAiApplyTree);
19324
19910
  window.removeEventListener("message", handleAiDeleteSection);
19325
19911
  window.removeEventListener("message", handleAiSetSections);
19912
+ window.removeEventListener("message", handleMoveSection);
19326
19913
  window.removeEventListener("message", handlePanelDragging);
19914
+ window.removeEventListener("message", handleDeleteSection);
19327
19915
  window.removeEventListener("message", handleDeactivate);
19328
19916
  document.documentElement.removeAttribute("data-ohw-panel-dragging");
19329
19917
  window.removeEventListener("message", handleToastAction);
@@ -19335,7 +19923,7 @@ function OhhwellsBridge() {
19335
19923
  if (imageShowTimerRef.current) clearTimeout(imageShowTimerRef.current);
19336
19924
  };
19337
19925
  }, [isEditMode, refreshStateRules]);
19338
- useEffect12(() => {
19926
+ useEffect13(() => {
19339
19927
  if (!isEditMode) return;
19340
19928
  const THRESHOLD = 10;
19341
19929
  const resolveWasSelected = (el) => {
@@ -19491,7 +20079,7 @@ function OhhwellsBridge() {
19491
20079
  unlockFooterDragInteraction();
19492
20080
  };
19493
20081
  }, [isEditMode]);
19494
- useEffect12(() => {
20082
+ useEffect13(() => {
19495
20083
  const handler = (e) => {
19496
20084
  if (e.data?.type !== "ow:request-schedule-config") return;
19497
20085
  const insertAfterVal = e.data.insertAfter;
@@ -19507,7 +20095,7 @@ function OhhwellsBridge() {
19507
20095
  window.addEventListener("message", handler);
19508
20096
  return () => window.removeEventListener("message", handler);
19509
20097
  }, [processConfigRequest]);
19510
- useEffect12(() => {
20098
+ useEffect13(() => {
19511
20099
  if (!isEditMode) return;
19512
20100
  document.querySelectorAll("[data-ohw-active-state]").forEach((el) => {
19513
20101
  el.removeAttribute("data-ohw-active-state");
@@ -19531,7 +20119,7 @@ function OhhwellsBridge() {
19531
20119
  postToParent2({
19532
20120
  type: "ow:ready",
19533
20121
  version: "1",
19534
- bridgeVersion: "0.1.74",
20122
+ bridgeVersion: "0.1.75",
19535
20123
  path: pathname,
19536
20124
  nodes: collectEditableNodes(editContentRef.current),
19537
20125
  sections
@@ -19543,13 +20131,13 @@ function OhhwellsBridge() {
19543
20131
  clearTimeout(timer);
19544
20132
  };
19545
20133
  }, [pathname, isEditMode, refreshStateRules, postToParent2]);
19546
- useEffect12(() => {
20134
+ useEffect13(() => {
19547
20135
  scrollToHashSectionWhenReady();
19548
20136
  const onHashChange = () => scrollToHashSectionWhenReady();
19549
20137
  window.addEventListener("hashchange", onHashChange);
19550
20138
  return () => window.removeEventListener("hashchange", onHashChange);
19551
20139
  }, [pathname]);
19552
- const handleCommand = useCallback7((cmd) => {
20140
+ const handleCommand = useCallback8((cmd) => {
19553
20141
  const el = activeElRef.current;
19554
20142
  const selBefore = window.getSelection();
19555
20143
  let savedOffsets = null;
@@ -19585,7 +20173,7 @@ function OhhwellsBridge() {
19585
20173
  if (el) setToolbarRect(getEditMeasureEl(el).getBoundingClientRect());
19586
20174
  refreshActiveCommandsRef.current();
19587
20175
  }, []);
19588
- useEffect12(() => {
20176
+ useEffect13(() => {
19589
20177
  const session = floatingPanel && floatingPanel.kind === "logo-size" ? floatingPanel : null;
19590
20178
  if (!session || !logoSizeDraft) return;
19591
20179
  const onPanelAction = (e) => {
@@ -19623,7 +20211,7 @@ function OhhwellsBridge() {
19623
20211
  window.addEventListener("message", onPanelAction);
19624
20212
  return () => window.removeEventListener("message", onPanelAction);
19625
20213
  }, [floatingPanel, logoSizeDraft, editorViewport, persistLogoSizeDraft, closeFloatingPanelAndDeselect]);
19626
- const handleStateChange = useCallback7((state) => {
20214
+ const handleStateChange = useCallback8((state) => {
19627
20215
  if (!activeStateElRef.current) return;
19628
20216
  const el = activeStateElRef.current;
19629
20217
  if (state === "Default") {
@@ -19636,7 +20224,7 @@ function OhhwellsBridge() {
19636
20224
  }
19637
20225
  setToggleState((prev) => prev ? { ...prev, activeState: state } : null);
19638
20226
  }, [deactivate]);
19639
- const reselectAfterLinkPopover = useCallback7(
20227
+ const reselectAfterLinkPopover = useCallback8(
19640
20228
  (hrefKey) => {
19641
20229
  requestAnimationFrame(() => {
19642
20230
  const el = resolveHrefKeyElement(hrefKey);
@@ -19645,7 +20233,7 @@ function OhhwellsBridge() {
19645
20233
  },
19646
20234
  [resolveHrefKeyElement]
19647
20235
  );
19648
- const closeLinkPopover = useCallback7(() => {
20236
+ const closeLinkPopover = useCallback8(() => {
19649
20237
  const session = linkPopoverSessionRef.current;
19650
20238
  addNavAfterAnchorRef.current = null;
19651
20239
  setLinkPopover(null);
@@ -19653,9 +20241,9 @@ function OhhwellsBridge() {
19653
20241
  reselectAfterLinkPopover(session.key);
19654
20242
  }
19655
20243
  }, [reselectAfterLinkPopover]);
19656
- const closeLinkPopoverRef = useRef9(closeLinkPopover);
20244
+ const closeLinkPopoverRef = useRef10(closeLinkPopover);
19657
20245
  closeLinkPopoverRef.current = closeLinkPopover;
19658
- const openLinkPopoverForActive = useCallback7(() => {
20246
+ const openLinkPopoverForActive = useCallback8(() => {
19659
20247
  const hrefCtx = getHrefKeyFromElement(activeElRef.current);
19660
20248
  if (!hrefCtx) return;
19661
20249
  bumpLinkPopoverGrace();
@@ -19666,7 +20254,7 @@ function OhhwellsBridge() {
19666
20254
  });
19667
20255
  deactivate();
19668
20256
  }, [deactivate]);
19669
- const openLinkPopoverForSelected = useCallback7(() => {
20257
+ const openLinkPopoverForSelected = useCallback8(() => {
19670
20258
  const anchor = selectedElRef.current;
19671
20259
  if (!anchor) return;
19672
20260
  const key = anchor.getAttribute("data-ohw-href-key");
@@ -19683,7 +20271,7 @@ function OhhwellsBridge() {
19683
20271
  });
19684
20272
  deselect();
19685
20273
  }, [deselect]);
19686
- const handleSelectParent = useCallback7(() => {
20274
+ const handleSelectParent = useCallback8(() => {
19687
20275
  const selected = selectedElRef.current;
19688
20276
  if (!selected) return;
19689
20277
  if (toolbarVariantRef.current === "select-frame") {
@@ -19710,7 +20298,7 @@ function OhhwellsBridge() {
19710
20298
  }
19711
20299
  deselectRef.current();
19712
20300
  }, []);
19713
- const handleDuplicateSelected = useCallback7(() => {
20301
+ const handleDuplicateSelected = useCallback8(() => {
19714
20302
  const selected = selectedElRef.current;
19715
20303
  if (!selected || !isNavigationItem2(selected)) return;
19716
20304
  const hrefKey = selected.getAttribute("data-ohw-href-key");
@@ -19843,7 +20431,7 @@ function OhhwellsBridge() {
19843
20431
  });
19844
20432
  }
19845
20433
  }, [postToParent2]);
19846
- const runPendingDeleteUndo = useCallback7(() => {
20434
+ const runPendingDeleteUndo = useCallback8(() => {
19847
20435
  const pending = pendingDeleteUndoRef.current;
19848
20436
  if (!pending) return false;
19849
20437
  pendingDeleteUndoRef.current = null;
@@ -19851,7 +20439,7 @@ function OhhwellsBridge() {
19851
20439
  enforceLinkHrefs();
19852
20440
  return true;
19853
20441
  }, []);
19854
- const handleDeleteSelected = useCallback7(() => {
20442
+ const handleDeleteSelected = useCallback8(() => {
19855
20443
  const selected = selectedElRef.current;
19856
20444
  if (!selected) return false;
19857
20445
  return deleteSelectedNavFooterItem({
@@ -19872,7 +20460,7 @@ function OhhwellsBridge() {
19872
20460
  }, [postToParent2]);
19873
20461
  handleDeleteSelectedRef.current = handleDeleteSelected;
19874
20462
  runPendingDeleteUndoRef.current = runPendingDeleteUndo;
19875
- const handleLinkPopoverSubmit = useCallback7(
20463
+ const handleLinkPopoverSubmit = useCallback8(
19876
20464
  (target) => {
19877
20465
  const session = linkPopoverSessionRef.current;
19878
20466
  if (!session) return;
@@ -19938,19 +20526,19 @@ function OhhwellsBridge() {
19938
20526
  const showEditLink = toolbarShowEditLink;
19939
20527
  const currentSections = sectionsByPath[pathname] ?? [];
19940
20528
  linkPopoverOpenRef.current = linkPopover !== null;
19941
- const handleMediaReplace = useCallback7(
20529
+ const handleMediaReplace = useCallback8(
19942
20530
  (key) => {
19943
20531
  postToParent2({ type: "ow:image-pick", key, elementType: mediaHover?.elementType ?? "image" });
19944
20532
  },
19945
20533
  [postToParent2, mediaHover?.elementType]
19946
20534
  );
19947
- const handleEditCarousel = useCallback7(
20535
+ const handleEditCarousel = useCallback8(
19948
20536
  (key) => {
19949
20537
  postToParent2({ type: "ow:carousel-open", key, images: readCarouselValue(key) });
19950
20538
  },
19951
20539
  [postToParent2]
19952
20540
  );
19953
- const handleMediaFadeOutComplete = useCallback7((key) => {
20541
+ const handleMediaFadeOutComplete = useCallback8((key) => {
19954
20542
  setUploadingRects((prev) => {
19955
20543
  if (!(key in prev)) return prev;
19956
20544
  const next = { ...prev };
@@ -19958,7 +20546,7 @@ function OhhwellsBridge() {
19958
20546
  return next;
19959
20547
  });
19960
20548
  }, []);
19961
- const handleVideoSettingsChange = useCallback7(
20549
+ const handleVideoSettingsChange = useCallback8(
19962
20550
  (key, settings) => {
19963
20551
  document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
19964
20552
  const video = getVideoEl2(el);
@@ -19980,430 +20568,450 @@ function OhhwellsBridge() {
19980
20568
  },
19981
20569
  [postToParent2]
19982
20570
  );
19983
- return bridgeRoot ? createPortal2(
19984
- /* @__PURE__ */ jsxs20(Fragment8, { children: [
19985
- /* @__PURE__ */ jsx33("div", { ref: attachVisibleViewport, "data-ohw-visible-viewport": "", "aria-hidden": true }),
19986
- isEditMode && /* @__PURE__ */ jsx33(AiSectionOverlay, { postToParent: postToParent2, apiRef: aiSectionApiRef }),
19987
- Object.entries(uploadingRects).map(([key, { rect, fadingOut }]) => /* @__PURE__ */ jsx33(
19988
- MediaOverlay,
19989
- {
19990
- hover: { key, rect, elementType: "image", isDragOver: false, hasTextOverlap: false },
19991
- isUploading: true,
19992
- fadingOut,
19993
- onFadeOutComplete: handleMediaFadeOutComplete,
19994
- onReplace: handleMediaReplace
19995
- },
19996
- `uploading-${key}`
19997
- )),
19998
- mediaHover && !(mediaHover.key in uploadingRects) && /* @__PURE__ */ jsx33(
19999
- MediaOverlay,
20000
- {
20001
- hover: mediaHover,
20002
- isUploading: false,
20003
- onReplace: handleMediaReplace,
20004
- onVideoSettingsChange: handleVideoSettingsChange
20005
- }
20006
- ),
20007
- carouselHover && !linkPopover && !isItemDragging && /* @__PURE__ */ jsx33(CarouselOverlay, { hover: carouselHover, onEdit: handleEditCarousel }),
20008
- siblingHintRect && !linkPopover && !isItemDragging && siblingHintRects.length === 0 && /* @__PURE__ */ jsx33(ItemInteractionLayer, { rect: siblingHintRect, state: "sibling-hint" }),
20009
- siblingHintRects.length > 0 && !linkPopover && !isItemDragging && siblingHintRects.map((rect, i) => /* @__PURE__ */ jsx33(ItemInteractionLayer, { rect, state: "sibling-hint" }, `sibling-hint-${i}`)),
20010
- isItemDragging && draggedItemRect && selectedElRef.current !== footerDragRef.current?.draggedEl && selectedElRef.current !== navDragRef.current?.draggedEl && /* @__PURE__ */ jsx33(ItemInteractionLayer, { rect: draggedItemRect, state: "dragging" }),
20011
- isItemDragging && footerDropSlots.map((slot, i) => /* @__PURE__ */ jsx33(
20012
- "div",
20013
- {
20014
- className: "pointer-events-none fixed z-2147483646",
20015
- style: {
20016
- left: slot.left,
20017
- top: slot.top,
20018
- width: slot.width,
20019
- height: slot.height
20571
+ return /* @__PURE__ */ jsxs20(Fragment8, { children: [
20572
+ /* @__PURE__ */ jsx33("div", { id: "ohw-loader", suppressHydrationWarning: true, style: { ...OHW_LOADER_STYLE, display: "none" }, children: /* @__PURE__ */ jsx33(OhwLoaderSpinner, {}) }),
20573
+ /* @__PURE__ */ jsx33("script", { suppressHydrationWarning: true, dangerouslySetInnerHTML: { __html: OHW_LOADER_PREHYDRATE_SCRIPT } }),
20574
+ bridgeRoot ? createPortal2(
20575
+ /* @__PURE__ */ jsxs20(Fragment8, { children: [
20576
+ /* @__PURE__ */ jsx33("div", { ref: attachVisibleViewport, "data-ohw-visible-viewport": "", "aria-hidden": true }),
20577
+ isEditMode && /* @__PURE__ */ jsx33(AiSectionOverlay, { postToParent: postToParent2, apiRef: aiSectionApiRef }),
20578
+ isSectionDragging && sectionDropSlots.map((slot, i) => /* @__PURE__ */ jsx33(
20579
+ "div",
20580
+ {
20581
+ className: "pointer-events-none fixed z-2147483646",
20582
+ style: { left: slot.left, top: slot.y, width: slot.width, height: 3, transform: "translateY(-50%)" },
20583
+ children: /* @__PURE__ */ jsx33(
20584
+ DropIndicator,
20585
+ {
20586
+ direction: "horizontal",
20587
+ state: activeSectionDropIndex === i ? "dragActive" : "dragIdle",
20588
+ className: "!h-full !w-full"
20589
+ }
20590
+ )
20020
20591
  },
20021
- children: /* @__PURE__ */ jsx33(
20022
- DropIndicator,
20023
- {
20024
- direction: slot.direction,
20025
- state: activeFooterDropIndex === i ? "dragActive" : "dragIdle",
20026
- className: "!h-full !w-full"
20027
- }
20028
- )
20029
- },
20030
- `footer-drop-${slot.direction}-${slot.columnIndex}-${slot.insertIndex}-${i}`
20031
- )),
20032
- isItemDragging && navDropSlots.map((slot, i) => /* @__PURE__ */ jsx33(
20033
- "div",
20034
- {
20035
- className: "pointer-events-none fixed z-2147483646",
20036
- style: {
20037
- left: slot.left,
20038
- top: slot.top,
20039
- width: slot.width,
20040
- height: slot.height
20592
+ `section-drop-${slot.insertIndex}-${i}`
20593
+ )),
20594
+ Object.entries(uploadingRects).map(([key, { rect, fadingOut }]) => /* @__PURE__ */ jsx33(
20595
+ MediaOverlay,
20596
+ {
20597
+ hover: { key, rect, elementType: "image", isDragOver: false, hasTextOverlap: false },
20598
+ isUploading: true,
20599
+ fadingOut,
20600
+ onFadeOutComplete: handleMediaFadeOutComplete,
20601
+ onReplace: handleMediaReplace
20041
20602
  },
20042
- children: /* @__PURE__ */ jsx33(
20043
- DropIndicator,
20044
- {
20045
- direction: slot.direction,
20046
- state: activeNavDropIndex === i ? "dragActive" : "dragIdle",
20047
- className: "!h-full !w-full"
20048
- }
20049
- )
20050
- },
20051
- `nav-drop-${slot.direction}-${slot.parentId ?? "root"}-${slot.insertIndex}-${i}`
20052
- )),
20053
- hoveredNavContainerRect && (toolbarVariant !== "select-frame" || isFooterFrameSelection) && !linkPopover && !isItemDragging && /* @__PURE__ */ jsx33(ItemInteractionLayer, { rect: hoveredNavContainerRect, state: "hover" }),
20054
- hoveredItemRect && !linkPopover && !hoveredNavContainerRect && !isItemDragging && hoveredItemElRef.current !== selectedElRef.current && /* @__PURE__ */ jsx33(ItemInteractionLayer, { rect: hoveredItemRect, state: "hover" }),
20055
- hoveredTextRect && !hoveredNavContainerRect && !hoveredItemRect && !isItemDragging && toolbarVariant !== "rich-text" && /* @__PURE__ */ jsx33(ItemInteractionLayer, { rect: hoveredTextRect, state: "hover" }),
20056
- formPickRect && !isItemDragging && /* @__PURE__ */ jsx33(
20057
- ItemInteractionLayer,
20058
- {
20059
- rect: formPickRect,
20060
- state: "active-top",
20061
- itemDragSurface: false,
20062
- toolbarAlign: "left",
20063
- chromeGap: 24,
20064
- toolbar: fieldPickRect ? void 0 : /* @__PURE__ */ jsxs20(
20603
+ `uploading-${key}`
20604
+ )),
20605
+ mediaHover && !(mediaHover.key in uploadingRects) && /* @__PURE__ */ jsx33(
20606
+ MediaOverlay,
20607
+ {
20608
+ hover: mediaHover,
20609
+ isUploading: false,
20610
+ onReplace: handleMediaReplace,
20611
+ onVideoSettingsChange: handleVideoSettingsChange
20612
+ }
20613
+ ),
20614
+ carouselHover && !linkPopover && !isItemDragging && /* @__PURE__ */ jsx33(CarouselOverlay, { hover: carouselHover, onEdit: handleEditCarousel }),
20615
+ siblingHintRect && !linkPopover && !isItemDragging && siblingHintRects.length === 0 && /* @__PURE__ */ jsx33(ItemInteractionLayer, { rect: siblingHintRect, state: "sibling-hint" }),
20616
+ siblingHintRects.length > 0 && !linkPopover && !isItemDragging && siblingHintRects.map((rect, i) => /* @__PURE__ */ jsx33(ItemInteractionLayer, { rect, state: "sibling-hint" }, `sibling-hint-${i}`)),
20617
+ isItemDragging && draggedItemRect && selectedElRef.current !== footerDragRef.current?.draggedEl && selectedElRef.current !== navDragRef.current?.draggedEl && /* @__PURE__ */ jsx33(ItemInteractionLayer, { rect: draggedItemRect, state: "dragging" }),
20618
+ isItemDragging && footerDropSlots.map((slot, i) => /* @__PURE__ */ jsx33(
20619
+ "div",
20620
+ {
20621
+ className: "pointer-events-none fixed z-2147483646",
20622
+ style: {
20623
+ left: slot.left,
20624
+ top: slot.top,
20625
+ width: slot.width,
20626
+ height: slot.height
20627
+ },
20628
+ children: /* @__PURE__ */ jsx33(
20629
+ DropIndicator,
20630
+ {
20631
+ direction: slot.direction,
20632
+ state: activeFooterDropIndex === i ? "dragActive" : "dragIdle",
20633
+ className: "!h-full !w-full"
20634
+ }
20635
+ )
20636
+ },
20637
+ `footer-drop-${slot.direction}-${slot.columnIndex}-${slot.insertIndex}-${i}`
20638
+ )),
20639
+ isItemDragging && navDropSlots.map((slot, i) => /* @__PURE__ */ jsx33(
20640
+ "div",
20641
+ {
20642
+ className: "pointer-events-none fixed z-2147483646",
20643
+ style: {
20644
+ left: slot.left,
20645
+ top: slot.top,
20646
+ width: slot.width,
20647
+ height: slot.height
20648
+ },
20649
+ children: /* @__PURE__ */ jsx33(
20650
+ DropIndicator,
20651
+ {
20652
+ direction: slot.direction,
20653
+ state: activeNavDropIndex === i ? "dragActive" : "dragIdle",
20654
+ className: "!h-full !w-full"
20655
+ }
20656
+ )
20657
+ },
20658
+ `nav-drop-${slot.direction}-${slot.parentId ?? "root"}-${slot.insertIndex}-${i}`
20659
+ )),
20660
+ hoveredNavContainerRect && (toolbarVariant !== "select-frame" || isFooterFrameSelection) && !linkPopover && !isItemDragging && /* @__PURE__ */ jsx33(ItemInteractionLayer, { rect: hoveredNavContainerRect, state: "hover" }),
20661
+ hoveredItemRect && !linkPopover && !hoveredNavContainerRect && !isItemDragging && hoveredItemElRef.current !== selectedElRef.current && /* @__PURE__ */ jsx33(ItemInteractionLayer, { rect: hoveredItemRect, state: "hover" }),
20662
+ hoveredTextRect && !hoveredNavContainerRect && !hoveredItemRect && !isItemDragging && toolbarVariant !== "rich-text" && /* @__PURE__ */ jsx33(ItemInteractionLayer, { rect: hoveredTextRect, state: "hover" }),
20663
+ formPickRect && !isItemDragging && /* @__PURE__ */ jsx33(
20664
+ ItemInteractionLayer,
20665
+ {
20666
+ rect: formPickRect,
20667
+ state: "active-top",
20668
+ itemDragSurface: false,
20669
+ toolbarAlign: "left",
20670
+ chromeGap: 24,
20671
+ toolbar: fieldPickRect ? void 0 : /* @__PURE__ */ jsxs20(
20672
+ "div",
20673
+ {
20674
+ "data-ohw-form-toolbar": "",
20675
+ className: "pointer-events-auto flex items-center gap-0.5 whitespace-nowrap rounded-lg border border-border bg-background p-1 shadow-md",
20676
+ children: [
20677
+ /* @__PURE__ */ jsx33(
20678
+ "button",
20679
+ {
20680
+ type: "button",
20681
+ "aria-label": "Add field",
20682
+ className: "flex h-7 w-7 items-center justify-center rounded-md text-foreground transition-colors hover:bg-muted/80",
20683
+ onClick: () => setFieldTypePickerOpen((open) => !open),
20684
+ "data-ohw-add-field": "",
20685
+ children: /* @__PURE__ */ jsx33(Plus4, { size: 15, "aria-hidden": true })
20686
+ }
20687
+ ),
20688
+ /* @__PURE__ */ jsx33("div", { className: "mx-0.5 h-5 w-px bg-border" }),
20689
+ /* @__PURE__ */ jsxs20(
20690
+ "button",
20691
+ {
20692
+ type: "button",
20693
+ 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",
20694
+ onClick: () => {
20695
+ setFieldTypePickerOpen(false);
20696
+ const form = formPickElRef.current;
20697
+ if (!form) return;
20698
+ postToParent2({
20699
+ type: "ow:form-pick",
20700
+ formKey: formKeyOf(form),
20701
+ hasLongText: formHasLongText(form)
20702
+ });
20703
+ },
20704
+ children: [
20705
+ /* @__PURE__ */ jsx33(Settings, { size: 14, "aria-hidden": true }),
20706
+ "Form settings",
20707
+ formPickCount ? (
20708
+ // Counter pill, per the design — not a text suffix.
20709
+ /* @__PURE__ */ jsx33(
20710
+ "span",
20711
+ {
20712
+ "data-ohw-form-count": "",
20713
+ 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",
20714
+ children: formPickCount
20715
+ }
20716
+ )
20717
+ ) : null
20718
+ ]
20719
+ }
20720
+ ),
20721
+ /* @__PURE__ */ jsx33("div", { className: "mx-0.5 h-5 w-px bg-border" }),
20722
+ /* @__PURE__ */ jsx33("div", { className: "flex items-center rounded-md bg-muted/70 p-0.5", children: ["default", "success"].map((state) => /* @__PURE__ */ jsx33(
20723
+ "button",
20724
+ {
20725
+ type: "button",
20726
+ "aria-pressed": formViewState === state,
20727
+ 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"),
20728
+ onClick: () => {
20729
+ setFieldTypePickerOpen(false);
20730
+ const form = formPickElRef.current;
20731
+ const key = form ? formKeyOf(form) : null;
20732
+ if (!form || !key) return;
20733
+ const initial = successInitialFor(form, key, editContentRef.current);
20734
+ setFormViewState(form, key, state, initial);
20735
+ setFormViewStateUi(state);
20736
+ setFormPickRect(form.getBoundingClientRect());
20737
+ if (state === "success") {
20738
+ const successEl = form.querySelector(`[${SUCCESS_TEXT_ATTR}]`);
20739
+ if (successEl) requestAnimationFrame(() => activateRef.current(successEl));
20740
+ } else {
20741
+ deactivateRef.current();
20742
+ }
20743
+ },
20744
+ children: state
20745
+ },
20746
+ state
20747
+ )) })
20748
+ ]
20749
+ }
20750
+ )
20751
+ }
20752
+ ),
20753
+ formHoverRect && !isItemDragging && /* @__PURE__ */ jsx33(
20754
+ ItemInteractionLayer,
20755
+ {
20756
+ rect: formHoverRect,
20757
+ state: "hover",
20758
+ chromeGap: formHoverElRef.current && getFieldWrapper(formHoverElRef.current) ? 8 : 24
20759
+ }
20760
+ ),
20761
+ fieldPickRect && fieldPickState && !isItemDragging && toolbarVariant !== "rich-text" && /* @__PURE__ */ jsx33(
20762
+ ItemInteractionLayer,
20763
+ {
20764
+ rect: fieldPickRect,
20765
+ state: fieldDragging ? "dragging" : "active-top",
20766
+ itemDragSurface: false,
20767
+ toolbarAlign: "left",
20768
+ chromeGap: 10,
20769
+ showHandle: true,
20770
+ dragHandleLabel: "Reorder field",
20771
+ onDragHandleDragStart: handleFieldDragStart,
20772
+ onDragHandleDragEnd: handleFieldDragEnd,
20773
+ toolbar: /* @__PURE__ */ jsx33(
20774
+ FormFieldToolbar,
20775
+ {
20776
+ type: fieldPickState.type,
20777
+ required: fieldPickState.required,
20778
+ onTypeChange: handleFieldTypeChange,
20779
+ onRequiredToggle: handleFieldRequiredToggle,
20780
+ onDuplicate: handleFieldDuplicate,
20781
+ onDelete: handleFieldDelete
20782
+ }
20783
+ )
20784
+ }
20785
+ ),
20786
+ fieldDragging ? fieldDropSlots.map((slot, i) => /* @__PURE__ */ jsx33(
20787
+ "div",
20788
+ {
20789
+ className: "pointer-events-none fixed z-[2147483644]",
20790
+ style: { top: slot.top, left: slot.left, width: slot.width },
20791
+ children: /* @__PURE__ */ jsx33(
20792
+ DropIndicator,
20793
+ {
20794
+ direction: "horizontal",
20795
+ state: fieldDropIndex === i ? "dragActive" : "dragIdle",
20796
+ className: "!w-full"
20797
+ }
20798
+ )
20799
+ },
20800
+ `field-drop-${i}`
20801
+ )) : null,
20802
+ fieldTypePickerOpen && formPickRect ? (() => {
20803
+ const toolbar = document.querySelector("[data-ohw-form-toolbar]")?.getBoundingClientRect();
20804
+ return /* @__PURE__ */ jsx33(
20065
20805
  "div",
20066
20806
  {
20067
- "data-ohw-form-toolbar": "",
20068
- className: "pointer-events-auto flex items-center gap-0.5 whitespace-nowrap rounded-lg border border-border bg-background p-1 shadow-md",
20069
- children: [
20070
- /* @__PURE__ */ jsx33(
20071
- "button",
20072
- {
20073
- type: "button",
20074
- "aria-label": "Add field",
20075
- className: "flex h-7 w-7 items-center justify-center rounded-md text-foreground transition-colors hover:bg-muted/80",
20076
- onClick: () => setFieldTypePickerOpen((open) => !open),
20077
- "data-ohw-add-field": "",
20078
- children: /* @__PURE__ */ jsx33(Plus4, { size: 15, "aria-hidden": true })
20079
- }
20080
- ),
20081
- /* @__PURE__ */ jsx33("div", { className: "mx-0.5 h-5 w-px bg-border" }),
20082
- /* @__PURE__ */ jsxs20(
20083
- "button",
20084
- {
20085
- type: "button",
20086
- 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",
20087
- onClick: () => {
20088
- setFieldTypePickerOpen(false);
20089
- const form = formPickElRef.current;
20090
- if (!form) return;
20091
- postToParent2({
20092
- type: "ow:form-pick",
20093
- formKey: formKeyOf(form),
20094
- hasLongText: formHasLongText(form)
20095
- });
20096
- },
20097
- children: [
20098
- /* @__PURE__ */ jsx33(Settings, { size: 14, "aria-hidden": true }),
20099
- "Form settings",
20100
- formPickCount ? (
20101
- // Counter pill, per the design — not a text suffix.
20102
- /* @__PURE__ */ jsx33(
20103
- "span",
20104
- {
20105
- "data-ohw-form-count": "",
20106
- 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",
20107
- children: formPickCount
20108
- }
20109
- )
20110
- ) : null
20111
- ]
20112
- }
20113
- ),
20114
- /* @__PURE__ */ jsx33("div", { className: "mx-0.5 h-5 w-px bg-border" }),
20115
- /* @__PURE__ */ jsx33("div", { className: "flex items-center rounded-md bg-muted/70 p-0.5", children: ["default", "success"].map((state) => /* @__PURE__ */ jsx33(
20116
- "button",
20117
- {
20118
- type: "button",
20119
- "aria-pressed": formViewState === state,
20120
- 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"),
20121
- onClick: () => {
20122
- setFieldTypePickerOpen(false);
20123
- const form = formPickElRef.current;
20124
- const key = form ? formKeyOf(form) : null;
20125
- if (!form || !key) return;
20126
- const initial = successInitialFor(form, key, editContentRef.current);
20127
- setFormViewState(form, key, state, initial);
20128
- setFormViewStateUi(state);
20129
- setFormPickRect(form.getBoundingClientRect());
20130
- if (state === "success") {
20131
- const successEl = form.querySelector(`[${SUCCESS_TEXT_ATTR}]`);
20132
- if (successEl) requestAnimationFrame(() => activateRef.current(successEl));
20133
- } else {
20134
- deactivateRef.current();
20135
- }
20136
- },
20137
- children: state
20138
- },
20139
- state
20140
- )) })
20141
- ]
20807
+ className: "pointer-events-none fixed z-[2147483645]",
20808
+ style: {
20809
+ top: toolbar ? toolbar.bottom + 6 : formPickRect.top + 16,
20810
+ left: toolbar ? toolbar.left : formPickRect.left + 24
20811
+ },
20812
+ children: /* @__PURE__ */ jsx33(FieldTypePicker, { onPick: handleAddField })
20142
20813
  }
20143
- )
20144
- }
20145
- ),
20146
- formHoverRect && !isItemDragging && /* @__PURE__ */ jsx33(
20147
- ItemInteractionLayer,
20148
- {
20149
- rect: formHoverRect,
20150
- state: "hover",
20151
- chromeGap: formHoverElRef.current && getFieldWrapper(formHoverElRef.current) ? 8 : 24
20152
- }
20153
- ),
20154
- fieldPickRect && fieldPickState && !isItemDragging && toolbarVariant !== "rich-text" && /* @__PURE__ */ jsx33(
20155
- ItemInteractionLayer,
20156
- {
20157
- rect: fieldPickRect,
20158
- state: fieldDragging ? "dragging" : "active-top",
20159
- itemDragSurface: false,
20160
- toolbarAlign: "left",
20161
- chromeGap: 10,
20162
- showHandle: true,
20163
- dragHandleLabel: "Reorder field",
20164
- onDragHandleDragStart: handleFieldDragStart,
20165
- onDragHandleDragEnd: handleFieldDragEnd,
20166
- toolbar: /* @__PURE__ */ jsx33(
20167
- FormFieldToolbar,
20814
+ );
20815
+ })() : null,
20816
+ toolbarVariant === "select-frame" && toolbarRect && !linkPopover && !isItemDragging && !isFooterFrameSelection && selectedElRef.current && isNavbarLinksContainer2(selectedElRef.current) && /* @__PURE__ */ jsx33(NavbarContainerChrome, { rect: toolbarRect, onAdd: handleAddTopLevelNavItem }),
20817
+ toolbarVariant === "select-frame" && toolbarRect && !linkPopover && !isItemDragging && !isFooterFrameSelection && selectedElRef.current && isFooterLinksContainer(selectedElRef.current) && /* @__PURE__ */ jsx33(
20818
+ FooterContainerChrome,
20819
+ {
20820
+ rect: toolbarRect,
20821
+ onAdd: handleAddFooterColumn,
20822
+ addDisabled: !canAddFooterColumn()
20823
+ }
20824
+ ),
20825
+ toolbarRect && !linkPopover && (toolbarVariant === "link-action" || toolbarVariant === "select-frame" || toolbarVariant === "logo") && /* @__PURE__ */ jsx33(
20826
+ ItemInteractionLayer,
20827
+ {
20828
+ rect: isItemDragging && draggedItemRect && (footerDragRef.current?.wasSelected || navDragRef.current?.wasSelected) ? draggedItemRect : toolbarRect,
20829
+ toolbarBelowRect: selectedElRef.current && isNavigationItem2(selectedElRef.current) ? getOpenNavDropdownPanelRect(selectedElRef.current) : null,
20830
+ elRef: glowElRef,
20831
+ state: isItemDragging ? "dragging" : selectedElRef.current && isNavigationItem2(selectedElRef.current) && getOpenNavDropdownPanelRect(selectedElRef.current) ? "active-bottom" : resolveItemInteractionState(toolbarRect, parentScrollRef.current),
20832
+ showHandle: toolbarVariant === "link-action" && Boolean(reorderHrefKey) || toolbarVariant === "select-frame" && isFooterFrameSelection,
20833
+ dragDisabled: reorderDragDisabled,
20834
+ dragHandleLabel: reorderHrefKey ? `Reorder ${reorderHrefKey}` : "Reorder item",
20835
+ onDragHandleDragStart: handleItemDragStart,
20836
+ onDragHandleDragEnd: handleItemDragEnd,
20837
+ onItemPointerDown: toolbarVariant === "logo" ? void 0 : handleItemChromePointerDown,
20838
+ onItemClick: toolbarVariant === "logo" ? void 0 : handleItemChromeClick,
20839
+ itemDragSurface: toolbarVariant !== "logo" && !isFooterFrameSelection && !selectedIsSocialsRow,
20840
+ toolbar: toolbarVariant === "link-action" && !isItemDragging || toolbarVariant === "select-frame" && (isFooterFrameSelection || selectedIsSocialsRow) && !isItemDragging ? /* @__PURE__ */ jsx33(
20841
+ ItemActionToolbar,
20842
+ {
20843
+ onEditLink: openLinkPopoverForSelected,
20844
+ onStyle: () => {
20845
+ const row = selectedElRef.current;
20846
+ if (!row) return;
20847
+ if (floatingPanel?.kind === "socials-display") closeFloatingPanelOnly();
20848
+ else openSocialsDisplayPanel(row);
20849
+ },
20850
+ showStyle: selectedIsSocialsRow,
20851
+ styleActive: floatingPanel?.kind === "socials-display",
20852
+ onAddItem: handleAddChildItem,
20853
+ onSelectParent: handleSelectParent,
20854
+ onDuplicate: handleDuplicateSelected,
20855
+ onDelete: handleDeleteSelected,
20856
+ addItemDisabled: isFooterFrameSelection && isFooterAddItemDisabled(selectedElRef.current) || selectedElRef.current !== null && (() => {
20857
+ const row = isSocialsRow(selectedElRef.current) ? selectedElRef.current : findSocialsRow(selectedElRef.current);
20858
+ return row ? !canAddSocialItem(row) : false;
20859
+ })(),
20860
+ editLinkDisabled: false,
20861
+ moreDisabled: false,
20862
+ deleteDisabled: selectedElRef.current !== null && (() => {
20863
+ const social = getSocialItem(selectedElRef.current);
20864
+ return social ? !canRemoveSocialItem(social) : false;
20865
+ })(),
20866
+ duplicateDisabled: isFooterFrameSelection || selectedIsSocialsRow || selectedElRef.current !== null && (() => {
20867
+ const social = getSocialItem(selectedElRef.current);
20868
+ const row = social ? findSocialsRow(social) : null;
20869
+ return row ? !canAddSocialItem(row) : false;
20870
+ })(),
20871
+ showEditLink: !isFooterFrameSelection && !selectedIsSocialsRow && navDropdownPreviewOpen === null,
20872
+ showAddItem: isFooterFrameSelection || selectedIsSocialsRow || !selectedIsCta && Boolean(
20873
+ selectedElRef.current && isNavbarHrefKey(selectedElRef.current.getAttribute("data-ohw-href-key")) && !isNestedNavChild(selectedElRef.current)
20874
+ ),
20875
+ showMore: (!selectedIsCta || isFooterFrameSelection) && !selectedIsSocialsRow,
20876
+ dropdownOpen: navDropdownPreviewOpen,
20877
+ onDropdownOpenChange: handleNavDropdownOpenChange,
20878
+ headingVisible: footerHeadingVisible,
20879
+ onHeadingVisibleChange: handleFooterHeadingVisibleChange
20880
+ }
20881
+ ) : void 0
20882
+ }
20883
+ ),
20884
+ toolbarRect && toolbarVariant === "rich-text" && !linkPopover && /* @__PURE__ */ jsxs20(Fragment8, { children: [
20885
+ /* @__PURE__ */ jsx33(
20886
+ EditGlowChrome,
20168
20887
  {
20169
- type: fieldPickState.type,
20170
- required: fieldPickState.required,
20171
- onTypeChange: handleFieldTypeChange,
20172
- onRequiredToggle: handleFieldRequiredToggle,
20173
- onDuplicate: handleFieldDuplicate,
20174
- onDelete: handleFieldDelete
20888
+ rect: toolbarRect,
20889
+ elRef: glowElRef,
20890
+ reorderHrefKey,
20891
+ dragDisabled: reorderDragDisabled,
20892
+ hideHandle: isItemDragging
20175
20893
  }
20176
- )
20177
- }
20178
- ),
20179
- fieldDragging ? fieldDropSlots.map((slot, i) => /* @__PURE__ */ jsx33(
20180
- "div",
20181
- {
20182
- className: "pointer-events-none fixed z-[2147483644]",
20183
- style: { top: slot.top, left: slot.left, width: slot.width },
20184
- children: /* @__PURE__ */ jsx33(
20185
- DropIndicator,
20894
+ ),
20895
+ /* @__PURE__ */ jsx33(
20896
+ FloatingToolbar,
20186
20897
  {
20187
- direction: "horizontal",
20188
- state: fieldDropIndex === i ? "dragActive" : "dragIdle",
20189
- className: "!w-full"
20898
+ rect: toolbarRect,
20899
+ parentScroll: parentScrollRef.current,
20900
+ elRef: toolbarElRef,
20901
+ onCommand: handleCommand,
20902
+ activeCommands,
20903
+ showEditLink,
20904
+ onEditLink: openLinkPopoverForActive
20190
20905
  }
20191
20906
  )
20192
- },
20193
- `field-drop-${i}`
20194
- )) : null,
20195
- fieldTypePickerOpen && formPickRect ? (() => {
20196
- const toolbar = document.querySelector("[data-ohw-form-toolbar]")?.getBoundingClientRect();
20197
- return /* @__PURE__ */ jsx33(
20907
+ ] }),
20908
+ maxBadge && /* @__PURE__ */ jsxs20(
20198
20909
  "div",
20199
20910
  {
20200
- className: "pointer-events-none fixed z-[2147483645]",
20911
+ "data-ohw-max-badge": "",
20201
20912
  style: {
20202
- top: toolbar ? toolbar.bottom + 6 : formPickRect.top + 16,
20203
- left: toolbar ? toolbar.left : formPickRect.left + 24
20913
+ position: "fixed",
20914
+ top: maxBadge.rect.bottom + 4,
20915
+ left: maxBadge.rect.right,
20916
+ transform: "translateX(-100%)",
20917
+ zIndex: 2147483647,
20918
+ background: maxBadge.current > maxBadge.max ? "#FEF2F2" : "#F5F5F4",
20919
+ color: maxBadge.current > maxBadge.max ? "#DC2626" : "#78716C",
20920
+ border: `1px solid ${maxBadge.current > maxBadge.max ? "#FECACA" : "#E7E5E4"}`,
20921
+ borderRadius: 4,
20922
+ padding: "2px 6px",
20923
+ fontSize: 11,
20924
+ fontWeight: 500,
20925
+ pointerEvents: "none"
20204
20926
  },
20205
- children: /* @__PURE__ */ jsx33(FieldTypePicker, { onPick: handleAddField })
20927
+ children: [
20928
+ maxBadge.current,
20929
+ "/",
20930
+ maxBadge.max
20931
+ ]
20206
20932
  }
20207
- );
20208
- })() : null,
20209
- toolbarVariant === "select-frame" && toolbarRect && !linkPopover && !isItemDragging && !isFooterFrameSelection && selectedElRef.current && isNavbarLinksContainer2(selectedElRef.current) && /* @__PURE__ */ jsx33(NavbarContainerChrome, { rect: toolbarRect, onAdd: handleAddTopLevelNavItem }),
20210
- toolbarVariant === "select-frame" && toolbarRect && !linkPopover && !isItemDragging && !isFooterFrameSelection && selectedElRef.current && isFooterLinksContainer(selectedElRef.current) && /* @__PURE__ */ jsx33(
20211
- FooterContainerChrome,
20212
- {
20213
- rect: toolbarRect,
20214
- onAdd: handleAddFooterColumn,
20215
- addDisabled: !canAddFooterColumn()
20216
- }
20217
- ),
20218
- toolbarRect && !linkPopover && (toolbarVariant === "link-action" || toolbarVariant === "select-frame" || toolbarVariant === "logo") && /* @__PURE__ */ jsx33(
20219
- ItemInteractionLayer,
20220
- {
20221
- rect: isItemDragging && draggedItemRect && (footerDragRef.current?.wasSelected || navDragRef.current?.wasSelected) ? draggedItemRect : toolbarRect,
20222
- toolbarBelowRect: selectedElRef.current && isNavigationItem2(selectedElRef.current) ? getOpenNavDropdownPanelRect(selectedElRef.current) : null,
20223
- elRef: glowElRef,
20224
- state: isItemDragging ? "dragging" : selectedElRef.current && isNavigationItem2(selectedElRef.current) && getOpenNavDropdownPanelRect(selectedElRef.current) ? "active-bottom" : resolveItemInteractionState(toolbarRect, parentScrollRef.current),
20225
- showHandle: toolbarVariant === "link-action" && Boolean(reorderHrefKey) || toolbarVariant === "select-frame" && isFooterFrameSelection,
20226
- dragDisabled: reorderDragDisabled,
20227
- dragHandleLabel: reorderHrefKey ? `Reorder ${reorderHrefKey}` : "Reorder item",
20228
- onDragHandleDragStart: handleItemDragStart,
20229
- onDragHandleDragEnd: handleItemDragEnd,
20230
- onItemPointerDown: toolbarVariant === "logo" ? void 0 : handleItemChromePointerDown,
20231
- onItemClick: toolbarVariant === "logo" ? void 0 : handleItemChromeClick,
20232
- itemDragSurface: toolbarVariant !== "logo" && !isFooterFrameSelection && !selectedIsSocialsRow,
20233
- toolbar: toolbarVariant === "link-action" && !isItemDragging || toolbarVariant === "select-frame" && (isFooterFrameSelection || selectedIsSocialsRow) && !isItemDragging ? /* @__PURE__ */ jsx33(
20234
- ItemActionToolbar,
20235
- {
20236
- onEditLink: openLinkPopoverForSelected,
20237
- onStyle: () => {
20238
- const row = selectedElRef.current;
20239
- if (!row) return;
20240
- if (floatingPanel?.kind === "socials-display") closeFloatingPanelOnly();
20241
- else openSocialsDisplayPanel(row);
20242
- },
20243
- showStyle: selectedIsSocialsRow,
20244
- styleActive: floatingPanel?.kind === "socials-display",
20245
- onAddItem: handleAddChildItem,
20246
- onSelectParent: handleSelectParent,
20247
- onDuplicate: handleDuplicateSelected,
20248
- onDelete: handleDeleteSelected,
20249
- addItemDisabled: isFooterFrameSelection && isFooterAddItemDisabled(selectedElRef.current) || selectedElRef.current !== null && (() => {
20250
- const row = isSocialsRow(selectedElRef.current) ? selectedElRef.current : findSocialsRow(selectedElRef.current);
20251
- return row ? !canAddSocialItem(row) : false;
20252
- })(),
20253
- editLinkDisabled: false,
20254
- moreDisabled: false,
20255
- deleteDisabled: selectedElRef.current !== null && (() => {
20256
- const social = getSocialItem(selectedElRef.current);
20257
- return social ? !canRemoveSocialItem(social) : false;
20258
- })(),
20259
- duplicateDisabled: isFooterFrameSelection || selectedIsSocialsRow || selectedElRef.current !== null && (() => {
20260
- const social = getSocialItem(selectedElRef.current);
20261
- const row = social ? findSocialsRow(social) : null;
20262
- return row ? !canAddSocialItem(row) : false;
20263
- })(),
20264
- showEditLink: !isFooterFrameSelection && !selectedIsSocialsRow && navDropdownPreviewOpen === null,
20265
- showAddItem: isFooterFrameSelection || selectedIsSocialsRow || !selectedIsCta && Boolean(
20266
- selectedElRef.current && isNavbarHrefKey(selectedElRef.current.getAttribute("data-ohw-href-key")) && !isNestedNavChild(selectedElRef.current)
20267
- ),
20268
- showMore: (!selectedIsCta || isFooterFrameSelection) && !selectedIsSocialsRow,
20269
- dropdownOpen: navDropdownPreviewOpen,
20270
- onDropdownOpenChange: handleNavDropdownOpenChange,
20271
- headingVisible: footerHeadingVisible,
20272
- onHeadingVisibleChange: handleFooterHeadingVisibleChange
20273
- }
20274
- ) : void 0
20275
- }
20276
- ),
20277
- toolbarRect && toolbarVariant === "rich-text" && !linkPopover && /* @__PURE__ */ jsxs20(Fragment8, { children: [
20278
- /* @__PURE__ */ jsx33(
20279
- EditGlowChrome,
20933
+ ),
20934
+ toggleState && !linkPopover && /* @__PURE__ */ jsx33(
20935
+ StateToggle,
20280
20936
  {
20281
- rect: toolbarRect,
20282
- elRef: glowElRef,
20283
- reorderHrefKey,
20284
- dragDisabled: reorderDragDisabled,
20285
- hideHandle: isItemDragging
20937
+ rect: toggleState.rect,
20938
+ activeState: toggleState.activeState,
20939
+ states: toggleState.states,
20940
+ onStateChange: handleStateChange
20286
20941
  }
20287
20942
  ),
20288
- /* @__PURE__ */ jsx33(
20289
- FloatingToolbar,
20943
+ sectionGap && !linkPopover && /* @__PURE__ */ jsxs20(
20944
+ "div",
20290
20945
  {
20291
- rect: toolbarRect,
20292
- parentScroll: parentScrollRef.current,
20293
- elRef: toolbarElRef,
20294
- onCommand: handleCommand,
20295
- activeCommands,
20296
- showEditLink,
20297
- onEditLink: openLinkPopoverForActive
20946
+ "data-ohw-section-insert-line": "",
20947
+ className: "fixed left-0 w-full z-2147483646 flex items-center pointer-events-none",
20948
+ style: { top: sectionGap.y, transform: "translateY(-50%)" },
20949
+ children: [
20950
+ /* @__PURE__ */ jsx33("div", { className: "flex-1 bg-primary", style: { height: 3 } }),
20951
+ /* @__PURE__ */ jsx33(
20952
+ Badge,
20953
+ {
20954
+ 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",
20955
+ onClick: () => {
20956
+ window.parent.postMessage(
20957
+ {
20958
+ type: "ow:add-section",
20959
+ insertAfter: sectionGap.insertAfter,
20960
+ insertBefore: sectionGap.insertBefore
20961
+ },
20962
+ "*"
20963
+ );
20964
+ },
20965
+ children: "Add Section"
20966
+ }
20967
+ ),
20968
+ /* @__PURE__ */ jsx33("div", { className: "flex-1 bg-primary", style: { height: 3 } })
20969
+ ]
20298
20970
  }
20299
- )
20300
- ] }),
20301
- maxBadge && /* @__PURE__ */ jsxs20(
20302
- "div",
20303
- {
20304
- "data-ohw-max-badge": "",
20305
- style: {
20306
- position: "fixed",
20307
- top: maxBadge.rect.bottom + 4,
20308
- left: maxBadge.rect.right,
20309
- transform: "translateX(-100%)",
20310
- zIndex: 2147483647,
20311
- background: maxBadge.current > maxBadge.max ? "#FEF2F2" : "#F5F5F4",
20312
- color: maxBadge.current > maxBadge.max ? "#DC2626" : "#78716C",
20313
- border: `1px solid ${maxBadge.current > maxBadge.max ? "#FECACA" : "#E7E5E4"}`,
20314
- borderRadius: 4,
20315
- padding: "2px 6px",
20316
- fontSize: 11,
20317
- fontWeight: 500,
20318
- pointerEvents: "none"
20971
+ ),
20972
+ linkPopover && dialogPortalContainer ? /* @__PURE__ */ jsx33(
20973
+ LinkPopover,
20974
+ {
20975
+ panelRef: linkPopoverPanelRef,
20976
+ portalContainer: dialogPortalContainer,
20977
+ open: true,
20978
+ mode: linkPopover.mode ?? "edit",
20979
+ pages: sitePages,
20980
+ sections: currentSections,
20981
+ sectionsByPath,
20982
+ initialTarget: linkPopover.target,
20983
+ existingTargets: linkPopover.intent === "add-nav" ? getNavbarExistingTargets() : [],
20984
+ onClose: closeLinkPopover,
20985
+ onSubmit: handleLinkPopoverSubmit
20319
20986
  },
20320
- children: [
20321
- maxBadge.current,
20322
- "/",
20323
- maxBadge.max
20324
- ]
20325
- }
20326
- ),
20327
- toggleState && !linkPopover && /* @__PURE__ */ jsx33(
20328
- StateToggle,
20329
- {
20330
- rect: toggleState.rect,
20331
- activeState: toggleState.activeState,
20332
- states: toggleState.states,
20333
- onStateChange: handleStateChange
20334
- }
20335
- ),
20336
- sectionGap && !linkPopover && /* @__PURE__ */ jsxs20(
20337
- "div",
20338
- {
20339
- "data-ohw-section-insert-line": "",
20340
- className: "fixed left-0 w-full z-2147483646 flex items-center pointer-events-none",
20341
- style: { top: sectionGap.y, transform: "translateY(-50%)" },
20342
- children: [
20343
- /* @__PURE__ */ jsx33("div", { className: "flex-1 bg-primary", style: { height: 3 } }),
20344
- /* @__PURE__ */ jsx33(
20345
- Badge,
20987
+ linkPopover.key
20988
+ ) : null,
20989
+ floatingPanel && floatingPanel.kind === "socials-display" ? /* @__PURE__ */ jsx33(
20990
+ FloatingPanel,
20991
+ {
20992
+ open: true,
20993
+ title: floatingPanel.title,
20994
+ context: floatingPanel.context,
20995
+ position: floatingPanelPos,
20996
+ onPositionChange: setFloatingPanelPos,
20997
+ parentScroll: parentScrollSnap ?? parentScrollRef.current,
20998
+ onClose: closeFloatingPanelOnly,
20999
+ children: /* @__PURE__ */ jsx33(
21000
+ SocialsDisplayPanel,
20346
21001
  {
20347
- 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",
20348
- onClick: () => {
20349
- window.parent.postMessage(
20350
- {
20351
- type: "ow:add-section",
20352
- insertAfter: sectionGap.insertAfter,
20353
- insertBefore: sectionGap.insertBefore
20354
- },
20355
- "*"
20356
- );
20357
- },
20358
- children: "Add Section"
20359
- }
20360
- ),
20361
- /* @__PURE__ */ jsx33("div", { className: "flex-1 bg-primary", style: { height: 3 } })
20362
- ]
20363
- }
20364
- ),
20365
- linkPopover && dialogPortalContainer ? /* @__PURE__ */ jsx33(
20366
- LinkPopover,
20367
- {
20368
- panelRef: linkPopoverPanelRef,
20369
- portalContainer: dialogPortalContainer,
20370
- open: true,
20371
- mode: linkPopover.mode ?? "edit",
20372
- pages: sitePages,
20373
- sections: currentSections,
20374
- sectionsByPath,
20375
- initialTarget: linkPopover.target,
20376
- existingTargets: linkPopover.intent === "add-nav" ? getNavbarExistingTargets() : [],
20377
- onClose: closeLinkPopover,
20378
- onSubmit: handleLinkPopoverSubmit
20379
- },
20380
- linkPopover.key
20381
- ) : null,
20382
- floatingPanel && floatingPanel.kind === "socials-display" ? /* @__PURE__ */ jsx33(
20383
- FloatingPanel,
20384
- {
20385
- open: true,
20386
- title: floatingPanel.title,
20387
- context: floatingPanel.context,
20388
- position: floatingPanelPos,
20389
- onPositionChange: setFloatingPanelPos,
20390
- parentScroll: parentScrollSnap ?? parentScrollRef.current,
20391
- onClose: closeFloatingPanelOnly,
20392
- children: /* @__PURE__ */ jsx33(
20393
- SocialsDisplayPanel,
20394
- {
20395
- display: socialsDisplayFor(floatingPanel.row, editContentRef.current),
20396
- onChange: (next) => {
20397
- changeSocialsDisplay(floatingPanel.row, next);
20398
- setFloatingPanel({ ...floatingPanel });
21002
+ display: socialsDisplayFor(floatingPanel.row, editContentRef.current),
21003
+ onChange: (next) => {
21004
+ changeSocialsDisplay(floatingPanel.row, next);
21005
+ setFloatingPanel({ ...floatingPanel });
21006
+ }
20399
21007
  }
20400
- }
20401
- )
20402
- }
20403
- ) : null
20404
- ] }),
20405
- bridgeRoot
20406
- ) : null;
21008
+ )
21009
+ }
21010
+ ) : null
21011
+ ] }),
21012
+ bridgeRoot
21013
+ ) : null
21014
+ ] });
20407
21015
  }
20408
21016
  export {
20409
21017
  AI_DEFAULT_BRAND,