@ohhwells/bridge 0.1.108 → 0.1.110

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -76,7 +76,7 @@ module.exports = __toCommonJS(index_exports);
76
76
  // src/OhhwellsBridge.tsx
77
77
  var import_react17 = __toESM(require("react"), 1);
78
78
  var import_client2 = require("react-dom/client");
79
- var import_react_dom3 = require("react-dom");
79
+ var import_react_dom4 = require("react-dom");
80
80
 
81
81
  // src/linkHrefStore.ts
82
82
  var linkHrefStore = /* @__PURE__ */ new Map();
@@ -7772,6 +7772,7 @@ function ItemActionToolbar({
7772
7772
 
7773
7773
  // src/ui/item-interaction-layer.tsx
7774
7774
  var import_react7 = require("react");
7775
+ var import_react_dom2 = require("react-dom");
7775
7776
  var import_jsx_runtime12 = require("react/jsx-runtime");
7776
7777
  var PRIMARY = "var(--ohw-primary, #0885FE)";
7777
7778
  var CHROME_RADIUS = 6;
@@ -7781,6 +7782,7 @@ var TOOLBAR_EDGE_MARGIN = 4;
7781
7782
  var SELECTION_CHROME_GAP = 4;
7782
7783
  var HOVER_CHROME_GAP = 2;
7783
7784
  var TOOLBAR_STROKE_GAP = 4;
7785
+ var DETACHED_TOOLBAR_Z = 2147483647;
7784
7786
  function getChromeZIndex(state) {
7785
7787
  switch (state) {
7786
7788
  case "active-top":
@@ -7838,6 +7840,14 @@ function ClampedToolbarSlot({
7838
7840
  const parent = slot.offsetParent;
7839
7841
  if (!parent) return;
7840
7842
  const parentRect = parent.getBoundingClientRect();
7843
+ if (align === "left") {
7844
+ const leftEdge = parentRect.left;
7845
+ const maxLeft = window.innerWidth - TOOLBAR_EDGE_MARGIN - w;
7846
+ const minLeft = TOOLBAR_EDGE_MARGIN;
7847
+ const clampedLeft = Math.max(minLeft, Math.min(leftEdge, maxLeft));
7848
+ slot.style.transform = `translateX(${clampedLeft - leftEdge}px)`;
7849
+ return;
7850
+ }
7841
7851
  const centerX = parentRect.left + parentRect.width / 2;
7842
7852
  const half = w / 2;
7843
7853
  const clampedCenter = Math.max(
@@ -7845,7 +7855,7 @@ function ClampedToolbarSlot({
7845
7855
  Math.min(centerX, window.innerWidth - TOOLBAR_EDGE_MARGIN - half)
7846
7856
  );
7847
7857
  const offsetX = clampedCenter - centerX;
7848
- slot.style.transform = align === "left" ? "none" : `translateX(calc(-50% + ${offsetX}px))`;
7858
+ slot.style.transform = `translateX(calc(-50% + ${offsetX}px))`;
7849
7859
  };
7850
7860
  clamp();
7851
7861
  const ro = new ResizeObserver(clamp);
@@ -7879,13 +7889,25 @@ function ClampedToolbarSlot({
7879
7889
  function DetachedBelowToolbarSlot({
7880
7890
  centerX,
7881
7891
  belowRect,
7892
+ belowEl,
7882
7893
  children
7883
7894
  }) {
7884
7895
  const slotRef = (0, import_react7.useRef)(null);
7896
+ const [anchorBottom, setAnchorBottom] = (0, import_react7.useState)(belowRect.bottom);
7897
+ const [portalTarget] = (0, import_react7.useState)(
7898
+ () => typeof document === "undefined" ? null : document.querySelector("[data-ohw-bridge-root]") ?? document.body
7899
+ );
7900
+ (0, import_react7.useLayoutEffect)(() => {
7901
+ setAnchorBottom(belowRect.bottom);
7902
+ }, [belowRect.bottom, belowRect.height, belowRect.top]);
7885
7903
  (0, import_react7.useLayoutEffect)(() => {
7886
7904
  const slot = slotRef.current;
7887
7905
  if (!slot) return;
7888
- const clamp = () => {
7906
+ const sync = () => {
7907
+ if (belowEl?.isConnected) {
7908
+ const nextBottom = belowEl.getBoundingClientRect().bottom;
7909
+ setAnchorBottom((prev) => Math.abs(prev - nextBottom) < 0.5 ? prev : nextBottom);
7910
+ }
7889
7911
  const toolbar = slot.firstElementChild;
7890
7912
  if (!toolbar) return;
7891
7913
  const w = toolbar.offsetWidth;
@@ -7897,30 +7919,46 @@ function DetachedBelowToolbarSlot({
7897
7919
  );
7898
7920
  slot.style.left = `${clampedCenter}px`;
7899
7921
  };
7900
- clamp();
7901
- const ro = new ResizeObserver(clamp);
7922
+ sync();
7923
+ const ro = new ResizeObserver(sync);
7902
7924
  ro.observe(slot);
7903
7925
  if (slot.firstElementChild) ro.observe(slot.firstElementChild);
7904
- window.addEventListener("resize", clamp);
7926
+ if (belowEl) {
7927
+ ro.observe(belowEl);
7928
+ const mo = new MutationObserver(sync);
7929
+ mo.observe(belowEl, { childList: true, subtree: true });
7930
+ window.addEventListener("resize", sync);
7931
+ return () => {
7932
+ ro.disconnect();
7933
+ mo.disconnect();
7934
+ window.removeEventListener("resize", sync);
7935
+ };
7936
+ }
7937
+ window.addEventListener("resize", sync);
7905
7938
  return () => {
7906
7939
  ro.disconnect();
7907
- window.removeEventListener("resize", clamp);
7940
+ window.removeEventListener("resize", sync);
7908
7941
  };
7909
- }, [centerX, belowRect, children]);
7910
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
7911
- "div",
7912
- {
7913
- ref: slotRef,
7914
- className: "pointer-events-auto fixed",
7915
- style: {
7916
- top: belowRect.bottom + TOOLBAR_STROKE_GAP,
7917
- left: centerX,
7918
- transform: "translateX(-50%)",
7919
- zIndex: getChromeZIndex("active-bottom")
7920
- },
7921
- "data-ohw-item-toolbar-anchor": "below-external",
7922
- children
7923
- }
7942
+ }, [centerX, belowRect, belowEl, children]);
7943
+ if (!portalTarget) return null;
7944
+ return (0, import_react_dom2.createPortal)(
7945
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
7946
+ "div",
7947
+ {
7948
+ ref: slotRef,
7949
+ className: "pointer-events-auto fixed",
7950
+ style: {
7951
+ top: anchorBottom + TOOLBAR_STROKE_GAP,
7952
+ left: centerX,
7953
+ transform: "translateX(-50%)",
7954
+ zIndex: DETACHED_TOOLBAR_Z
7955
+ },
7956
+ "data-ohw-bridge": "",
7957
+ "data-ohw-item-toolbar-anchor": "below-external",
7958
+ children
7959
+ }
7960
+ ),
7961
+ portalTarget
7924
7962
  );
7925
7963
  }
7926
7964
  function ItemInteractionLayer({
@@ -7929,6 +7967,7 @@ function ItemInteractionLayer({
7929
7967
  elRef,
7930
7968
  toolbar,
7931
7969
  toolbarBelowRect = null,
7970
+ toolbarBelowEl = null,
7932
7971
  showHandle = false,
7933
7972
  dragDisabled = false,
7934
7973
  dragHandleLabel = "Reorder item",
@@ -8034,6 +8073,7 @@ function ItemInteractionLayer({
8034
8073
  {
8035
8074
  centerX: rect.left + rect.width / 2,
8036
8075
  belowRect: toolbarBelowRect,
8076
+ belowEl: toolbarBelowEl,
8037
8077
  children: toolbar
8038
8078
  }
8039
8079
  ) : null
@@ -8404,6 +8444,7 @@ function setFieldRequired(wrapper, required) {
8404
8444
  function beginPlaceholderEdit(wrapper) {
8405
8445
  const input = fieldInputOf(wrapper);
8406
8446
  if (!input || input.hasAttribute(PLACEHOLDER_EDIT_ATTR)) return;
8447
+ input.style.setProperty("--ohw-placeholder-edit-color", getComputedStyle(input).color);
8407
8448
  input.setAttribute(PLACEHOLDER_EDIT_ATTR, "");
8408
8449
  input.value = input.getAttribute("placeholder") ?? "";
8409
8450
  input.setAttribute("placeholder", "");
@@ -8414,6 +8455,7 @@ function commitPlaceholderEdit(wrapper) {
8414
8455
  if (!input || !input.hasAttribute(PLACEHOLDER_EDIT_ATTR)) return false;
8415
8456
  const typed = input.value;
8416
8457
  input.removeAttribute(PLACEHOLDER_EDIT_ATTR);
8458
+ input.style.removeProperty("--ohw-placeholder-edit-color");
8417
8459
  input.value = "";
8418
8460
  const previous = input.getAttribute("placeholder") ?? "";
8419
8461
  input.setAttribute("placeholder", typed);
@@ -9237,10 +9279,25 @@ function AiSectionOverlay({
9237
9279
  },
9238
9280
  [postToParent2]
9239
9281
  );
9282
+ const [navDropdownForceOpen, setNavDropdownForceOpen] = (0, import_react8.useState)(false);
9283
+ (0, import_react8.useEffect)(() => {
9284
+ const update = () => {
9285
+ setNavDropdownForceOpen(Boolean(document.querySelector("[data-ohw-nav-force-open]")));
9286
+ };
9287
+ update();
9288
+ const mo = new MutationObserver(update);
9289
+ mo.observe(document.documentElement, {
9290
+ attributes: true,
9291
+ attributeFilter: ["data-ohw-nav-force-open"],
9292
+ subtree: true
9293
+ });
9294
+ return () => mo.disconnect();
9295
+ }, []);
9240
9296
  const activeSelectionId = reviewId ? null : selectedId;
9241
9297
  const selectionRect = useLiveSectionRect(activeSelectionId);
9242
9298
  const reviewRect = useLiveSectionRect(reviewId);
9243
9299
  const hoverRect = useLiveSectionRect(reviewId || hoveredId === selectedId ? null : hoveredId);
9300
+ const showSelectionBorder = Boolean(selectionRect) && !navDropdownForceOpen;
9244
9301
  (0, import_react8.useEffect)(() => {
9245
9302
  const selectedEl = activeSelectionId ? findSectionElement(activeSelectionId) : null;
9246
9303
  if (!activeSelectionId || !selectionRect || selectedEl && isChromeSection(selectedEl)) {
@@ -9280,7 +9337,7 @@ function AiSectionOverlay({
9280
9337
  }
9281
9338
  }
9282
9339
  ),
9283
- selectionRect && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
9340
+ showSelectionBorder && selectionRect && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
9284
9341
  "div",
9285
9342
  {
9286
9343
  "data-ohw-ai-section-selected": "",
@@ -9344,7 +9401,7 @@ function AiSectionOverlay({
9344
9401
  }
9345
9402
 
9346
9403
  // src/OhhwellsBridge.tsx
9347
- var import_react_dom4 = require("react-dom");
9404
+ var import_react_dom5 = require("react-dom");
9348
9405
  var import_navigation3 = require("next/navigation");
9349
9406
 
9350
9407
  // src/lib/cta-button.ts
@@ -10128,7 +10185,7 @@ function LinkEditorPanel({ state, onClose }) {
10128
10185
 
10129
10186
  // src/ui/link-modal/SectionPickerOverlay.tsx
10130
10187
  var import_react10 = require("react");
10131
- var import_react_dom2 = require("react-dom");
10188
+ var import_react_dom3 = require("react-dom");
10132
10189
  var import_lucide_react13 = require("lucide-react");
10133
10190
  var import_navigation2 = require("next/navigation");
10134
10191
  var import_jsx_runtime25 = require("react/jsx-runtime");
@@ -10359,7 +10416,7 @@ function SectionPickerOverlay({
10359
10416
  }, [onBack]);
10360
10417
  const portalRoot = typeof document !== "undefined" ? document.querySelector("[data-ohw-bridge-root]") ?? document.body : null;
10361
10418
  if (!portalRoot) return null;
10362
- return (0, import_react_dom2.createPortal)(
10419
+ return (0, import_react_dom3.createPortal)(
10363
10420
  /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
10364
10421
  "div",
10365
10422
  {
@@ -11382,7 +11439,11 @@ function isNestedNavChild(anchor) {
11382
11439
  function navItemOwnsDropdownPanel(anchor) {
11383
11440
  if (isNestedNavChild(anchor)) return true;
11384
11441
  const group = anchor.closest("[data-ohw-nav-group]");
11385
- return Boolean(group?.querySelector(":scope > [data-ohw-nav-children]"));
11442
+ const childrenRoot = group?.querySelector(":scope > [data-ohw-nav-children]");
11443
+ if (!childrenRoot) return false;
11444
+ return Array.from(childrenRoot.querySelectorAll(":scope > [data-ohw-href-key]")).some(
11445
+ isNavbarLinkItem
11446
+ );
11386
11447
  }
11387
11448
  function setNavGroupForceOpen(anchor, open) {
11388
11449
  document.querySelectorAll("[data-ohw-nav-force-open]").forEach((el) => {
@@ -11522,6 +11583,12 @@ function addNavbarSubitem(parentAnchor, href = "/", label = "New") {
11522
11583
  };
11523
11584
  }
11524
11585
  function reconcileNavbarItemsFromContent(content) {
11586
+ const openParentKeys = Array.from(
11587
+ document.querySelectorAll("[data-ohw-nav-group][data-ohw-nav-force-open]")
11588
+ ).map((group) => {
11589
+ const trigger = group.querySelector(":scope > [data-ohw-href-key]");
11590
+ return trigger?.getAttribute("data-ohw-href-key") ?? null;
11591
+ }).filter((key) => Boolean(key));
11525
11592
  const orderForest = parseNavOrderJson(content[NAV_ORDER_KEY]);
11526
11593
  if (orderForest?.length) {
11527
11594
  const allowed = new Set(flattenNavOrder(orderForest));
@@ -11577,6 +11644,12 @@ function reconcileNavbarItemsFromContent(content) {
11577
11644
  }
11578
11645
  pruneNavbarItemsNotInOrder(allowed);
11579
11646
  applyNavForest(orderForest);
11647
+ for (const parentKey of openParentKeys) {
11648
+ const trigger = document.querySelector(
11649
+ `[data-ohw-href-key="${CSS.escape(parentKey)}"]`
11650
+ );
11651
+ if (trigger) setNavGroupForceOpen(trigger, true);
11652
+ }
11580
11653
  return;
11581
11654
  }
11582
11655
  const indices = collectNavbarIndicesFromContent(content);
@@ -11587,6 +11660,12 @@ function reconcileNavbarItemsFromContent(content) {
11587
11660
  if (!href && !label) continue;
11588
11661
  insertNavbarItemDom(index, href ?? "/", label ?? "Untitled", null);
11589
11662
  }
11663
+ for (const parentKey of openParentKeys) {
11664
+ const trigger = document.querySelector(
11665
+ `[data-ohw-href-key="${CSS.escape(parentKey)}"]`
11666
+ );
11667
+ if (trigger) setNavGroupForceOpen(trigger, true);
11668
+ }
11590
11669
  }
11591
11670
  function pruneNavbarItemsNotInOrder(allowed) {
11592
11671
  const roots = [getNavbarDesktopContainer(), getNavbarDrawerContainer()].filter(
@@ -11935,19 +12014,31 @@ function deleteNavbarItem(sourceAnchor) {
11935
12014
 
11936
12015
  // src/lib/icon-markup.ts
11937
12016
  var GLYPH_SELECTOR = "svg, img";
12017
+ function squareIconSide(width, height) {
12018
+ if (!(width > 0) || !(height > 0)) return Math.max(width, height, 0);
12019
+ const ratio = width / height;
12020
+ if (ratio > 1.35 || ratio < 1 / 1.35) return Math.min(width, height);
12021
+ return (width + height) / 2;
12022
+ }
11938
12023
  function referenceBox(slot) {
11939
12024
  const row = slot.closest("[data-ohw-socials-row]") ?? slot.closest("a")?.parentElement ?? null;
11940
12025
  const neighbour = row ? Array.from(row.querySelectorAll('[data-ohw-editable="icon"]')).find(
11941
12026
  (el) => el !== slot && !el.hasAttribute("data-ohw-social-icon-placeholder")
11942
12027
  ) : null;
12028
+ const fromRect = (box) => {
12029
+ if (!box?.width || !box.height) return null;
12030
+ const side = Math.round(squareIconSide(box.width, box.height));
12031
+ return side > 0 ? { width: side, height: side } : null;
12032
+ };
11943
12033
  if (neighbour) {
11944
- const box2 = neighbour.querySelector(GLYPH_SELECTOR)?.getBoundingClientRect();
11945
- if (box2?.width && box2.height) return box2;
12034
+ const sized = fromRect(
12035
+ neighbour.querySelector(GLYPH_SELECTOR)?.getBoundingClientRect()
12036
+ );
12037
+ if (sized) return sized;
11946
12038
  }
11947
- const own = slot.getBoundingClientRect();
11948
- if (own.width && own.height) return own;
11949
- const box = slot.querySelector(GLYPH_SELECTOR)?.getBoundingClientRect() ?? null;
11950
- return box?.width && box.height ? box : null;
12039
+ const own = fromRect(slot.getBoundingClientRect());
12040
+ if (own) return own;
12041
+ return fromRect(slot.querySelector(GLYPH_SELECTOR)?.getBoundingClientRect());
11951
12042
  }
11952
12043
  function iconMarkupSizedFor(slot, markup) {
11953
12044
  const box = referenceBox(slot);
@@ -11961,8 +12052,8 @@ function iconMarkupSizedFor(slot, markup) {
11961
12052
  glyph.style.height = "1.5em";
11962
12053
  return holder.innerHTML;
11963
12054
  }
11964
- glyph.style.width = `${Math.round(box.width)}px`;
11965
- glyph.style.height = `${Math.round(box.height)}px`;
12055
+ glyph.style.width = `${box.width}px`;
12056
+ glyph.style.height = `${box.height}px`;
11966
12057
  return holder.innerHTML;
11967
12058
  }
11968
12059
  var ICON_SOURCE_ATTR = "data-ohw-icon-source";
@@ -11981,16 +12072,6 @@ function applyIconMarkup(slot, markup) {
11981
12072
  });
11982
12073
  }
11983
12074
  }
11984
- function detectIconStyle(el) {
11985
- const row = el.closest("[data-ohw-socials-row]");
11986
- const glyphs = Array.from((row ?? el).querySelectorAll("svg"));
11987
- const outlined = glyphs.some((svg) => {
11988
- return Array.from(svg.querySelectorAll("*")).some((node) => {
11989
- return node.getAttribute("stroke") !== null && node.getAttribute("stroke") !== "none";
11990
- });
11991
- });
11992
- return outlined ? "outline" : "fill";
11993
- }
11994
12075
  function iconMarkupInheritingColour(markup) {
11995
12076
  const holder = document.createElement("div");
11996
12077
  holder.innerHTML = markup;
@@ -12013,6 +12094,9 @@ var SOCIAL_KEY_RE = /(^|-)social(s)?(-|$)/i;
12013
12094
  var SOCIAL_PLATFORM_KEY_RE = /(^|-)(instagram|facebook|fb|linkedin|twitter|tiktok|youtube|threads|whatsapp|telegram|pinterest|snapchat|discord|behance|dribbble|vimeo|spotify|github|reddit|medium|twitch)(-|$)/i;
12014
12095
  var SOCIALS_ROW_ATTR = "data-ohw-socials-row";
12015
12096
  var SOCIALS_ITEM_ATTR = "data-ohw-social-item";
12097
+ var SOCIALS_ICONS_ATTR = "data-ohw-socials-icons";
12098
+ var SOCIALS_TEXT_ATTR = "data-ohw-socials-text";
12099
+ var SOCIALS_DISPLAY_STYLE_ID = "ohw-socials-display-style";
12016
12100
  function isSocialItem(el) {
12017
12101
  if (!el) return false;
12018
12102
  const anchor = el instanceof HTMLAnchorElement ? el : el.closest("a");
@@ -12119,9 +12203,11 @@ var SOCIALS_EMPTY_LABEL_ATTR = "data-ohw-empty-label";
12119
12203
  var EMPTY_LABEL_WIDTH = "8ch";
12120
12204
  function markEmptySocialLabels(root = document, skip) {
12121
12205
  root.querySelectorAll(`[${SOCIALS_ROW_ATTR}]`).forEach((row) => {
12206
+ if (row.getAttribute(SOCIALS_TEXT_ATTR) === "off") return;
12122
12207
  listSocialItems(row).forEach((item) => {
12123
12208
  const label = socialLabelElement(item);
12124
12209
  if (!label || label === skip) return;
12210
+ if (label.hasAttribute("data-ohw-hidden")) return;
12125
12211
  const empty = !label.textContent?.trim();
12126
12212
  if (empty === label.hasAttribute(SOCIALS_EMPTY_LABEL_ATTR)) return;
12127
12213
  if (empty) {
@@ -12448,6 +12534,11 @@ function planSocialMove(hrefKey, insertIndex, root = document) {
12448
12534
  }
12449
12535
  var SOCIALS_DISPLAY_KEY = "__ohw_socials_display";
12450
12536
  function readSocialsDisplay(row) {
12537
+ const iconsAttr = row.getAttribute(SOCIALS_ICONS_ATTR);
12538
+ const textAttr = row.getAttribute(SOCIALS_TEXT_ATTR);
12539
+ if ((iconsAttr === "on" || iconsAttr === "off") && (textAttr === "on" || textAttr === "off")) {
12540
+ return { text: textAttr === "on", icon: iconsAttr === "on" };
12541
+ }
12451
12542
  const items = listSocialItems(row);
12452
12543
  const visible = (el) => Boolean(el) && el.style.display !== "none" && el.getAttribute("data-ohw-hidden") === null;
12453
12544
  const drawn = (el) => Boolean(el && visible(el) && el.innerHTML.trim());
@@ -12472,15 +12563,48 @@ function socialsDisplayWith(row, display, content) {
12472
12563
  return { ...parseSocialsDisplay(content[SOCIALS_DISPLAY_KEY]) ?? {}, [rowKeyOf(row)]: display };
12473
12564
  }
12474
12565
  function applySocialsDisplayToRow(row, display) {
12566
+ ensureSocialsDisplayStyles(row.ownerDocument);
12567
+ row.setAttribute(SOCIALS_ICONS_ATTR, display.icon ? "on" : "off");
12568
+ row.setAttribute(SOCIALS_TEXT_ATTR, display.text ? "on" : "off");
12475
12569
  listSocialItems(row).forEach((item) => {
12476
12570
  const label = socialLabelElement(item);
12477
12571
  const icon = item.querySelector(ICON_SELECTOR);
12478
- if (label) label.style.display = display.text ? "" : "none";
12479
- if (icon) icon.style.display = display.icon ? "" : "none";
12572
+ setSocialSlotVisible(label, display.text);
12573
+ setSocialSlotVisible(icon, display.icon);
12480
12574
  layOutIconAndLabel(item, Boolean(display.text));
12481
12575
  });
12482
12576
  allowRowToWrap(row);
12483
12577
  }
12578
+ function setSocialSlotVisible(el, visible) {
12579
+ if (!el) return;
12580
+ if (visible) {
12581
+ el.removeAttribute("data-ohw-hidden");
12582
+ if (el.style.display === "none") el.style.display = "";
12583
+ } else {
12584
+ el.setAttribute("data-ohw-hidden", "");
12585
+ el.style.display = "none";
12586
+ }
12587
+ }
12588
+ function ensureSocialsDisplayStyles(doc) {
12589
+ if (!doc?.head) return;
12590
+ if (doc.getElementById(SOCIALS_DISPLAY_STYLE_ID)) return;
12591
+ const style = doc.createElement("style");
12592
+ style.id = SOCIALS_DISPLAY_STYLE_ID;
12593
+ style.textContent = `
12594
+ [${SOCIALS_ROW_ATTR}][${SOCIALS_ICONS_ATTR}="off"] [data-ohw-editable="icon"],
12595
+ [${SOCIALS_ROW_ATTR}][${SOCIALS_ICONS_ATTR}="off"] [data-ohw-editable="icon"] * {
12596
+ display: none !important;
12597
+ }
12598
+ [${SOCIALS_ROW_ATTR}][${SOCIALS_TEXT_ATTR}="off"] [${SOCIALS_LABEL_ATTR}],
12599
+ [${SOCIALS_ROW_ATTR}][${SOCIALS_TEXT_ATTR}="off"] [data-ohw-href-key] > [data-ohw-editable="text"],
12600
+ [${SOCIALS_ROW_ATTR}][${SOCIALS_TEXT_ATTR}="off"] [data-ohw-href-key] > [data-ohw-editable="plain"],
12601
+ [${SOCIALS_ROW_ATTR}][${SOCIALS_TEXT_ATTR}="off"] [data-ohw-social-item] [data-ohw-editable="text"],
12602
+ [${SOCIALS_ROW_ATTR}][${SOCIALS_TEXT_ATTR}="off"] [data-ohw-social-item] [data-ohw-editable="plain"] {
12603
+ display: none !important;
12604
+ }
12605
+ `;
12606
+ doc.head.appendChild(style);
12607
+ }
12484
12608
  function layOutIconAndLabel(item, on) {
12485
12609
  const hasBoth = Boolean(item.querySelector(ICON_SELECTOR)) && Boolean(socialLabelElement(item));
12486
12610
  if (!hasBoth) {
@@ -12900,15 +13024,6 @@ function setFooterColumnHeadingVisible(column, visible) {
12900
13024
  else column.prepend(heading);
12901
13025
  return { headingKey, text, visible: true };
12902
13026
  }
12903
- function ensureFooterColumnDefaultHeading(column, content) {
12904
- if (isFooterColumnHeadingVisible(column)) return null;
12905
- const headingKey = getFooterColumnHeadingKey(column);
12906
- if (!headingKey) return null;
12907
- if (content && content[headingKey] === "") return null;
12908
- const result = setFooterColumnHeadingVisible(column, true);
12909
- if (!result?.visible) return null;
12910
- return { headingKey: result.headingKey, text: result.text };
12911
- }
12912
13027
  function reconcileFooterHeadingVisibility(content) {
12913
13028
  for (const column of listFooterColumns()) {
12914
13029
  const headingKey = getFooterColumnHeadingKey(column);
@@ -14426,20 +14541,30 @@ function useNavItemDrag({
14426
14541
  const navPointerDragRef = (0, import_react14.useRef)(null);
14427
14542
  const clearNavDragVisuals = (0, import_react14.useCallback)(() => {
14428
14543
  const session = navDragRef.current;
14429
- const keepOpenEl = session?.draggedEl?.closest("[data-ohw-nav-children]") != null ? session.draggedEl : null;
14544
+ const nestedHrefKey = session?.draggedEl?.closest("[data-ohw-nav-children]") != null ? session.hrefKey : null;
14430
14545
  navDragRef.current = null;
14431
14546
  setNavDropSlots([]);
14432
14547
  setActiveNavDropIndex(null);
14433
14548
  setDraggedItemRect(null);
14434
14549
  setSiblingHintRects([]);
14435
14550
  setIsItemDragging(false);
14436
- if (keepOpenEl?.isConnected) {
14437
- setNavGroupForceOpen(keepOpenEl, true);
14551
+ if (nestedHrefKey) {
14552
+ const reopen = () => {
14553
+ const desktop = document.querySelector("[data-ohw-nav-container]");
14554
+ const drawer = document.querySelector("[data-ohw-nav-drawer]");
14555
+ const link = desktop?.querySelector(
14556
+ `[data-ohw-href-key="${CSS.escape(nestedHrefKey)}"]`
14557
+ ) ?? drawer?.querySelector(
14558
+ `[data-ohw-href-key="${CSS.escape(nestedHrefKey)}"]`
14559
+ ) ?? document.querySelector(
14560
+ `[data-ohw-href-key="${CSS.escape(nestedHrefKey)}"]`
14561
+ );
14562
+ if (link) setNavGroupForceOpen(link, true);
14563
+ };
14564
+ reopen();
14438
14565
  requestAnimationFrame(() => {
14439
- if (keepOpenEl.isConnected) setNavGroupForceOpen(keepOpenEl, true);
14440
- requestAnimationFrame(() => {
14441
- if (keepOpenEl.isConnected) setNavGroupForceOpen(keepOpenEl, true);
14442
- });
14566
+ reopen();
14567
+ requestAnimationFrame(reopen);
14443
14568
  });
14444
14569
  } else {
14445
14570
  setNavGroupForceOpen(null, false);
@@ -14524,19 +14649,24 @@ function useNavItemDrag({
14524
14649
  const wasSelected = session.wasSelected;
14525
14650
  const hrefKey = session.hrefKey;
14526
14651
  const keepDropdownOpen = Boolean(session.draggedEl.closest("[data-ohw-nav-children]"));
14527
- const applySelectionAfterDrop = () => {
14528
- if (!wasSelected) {
14529
- deselectRef.current();
14530
- return;
14531
- }
14652
+ const findDroppedLink = () => {
14532
14653
  const desktop = document.querySelector("[data-ohw-nav-container]");
14533
14654
  const drawer = document.querySelector("[data-ohw-nav-drawer]");
14534
- const link = desktop?.querySelector(`[data-ohw-href-key="${CSS.escape(hrefKey)}"]`) ?? drawer?.querySelector(`[data-ohw-href-key="${CSS.escape(hrefKey)}"]`) ?? document.querySelector(`[data-ohw-href-key="${CSS.escape(hrefKey)}"]`);
14535
- if (link) {
14655
+ return desktop?.querySelector(`[data-ohw-href-key="${CSS.escape(hrefKey)}"]`) ?? drawer?.querySelector(`[data-ohw-href-key="${CSS.escape(hrefKey)}"]`) ?? document.querySelector(`[data-ohw-href-key="${CSS.escape(hrefKey)}"]`);
14656
+ };
14657
+ const reopenDropdown = () => {
14658
+ if (!keepDropdownOpen) return;
14659
+ const link = findDroppedLink();
14660
+ if (link) setNavGroupForceOpen(link, true);
14661
+ };
14662
+ const applySelectionAfterDrop = () => {
14663
+ const link = findDroppedLink();
14664
+ if (wasSelected && link) {
14536
14665
  selectRef.current(link);
14537
- return;
14666
+ } else {
14667
+ deselectRef.current();
14538
14668
  }
14539
- deselectRef.current();
14669
+ reopenDropdown();
14540
14670
  };
14541
14671
  if (planned) {
14542
14672
  editContentRef.current = {
@@ -14555,27 +14685,31 @@ function useNavItemDrag({
14555
14685
  type: "ow:change",
14556
14686
  nodes: [{ key: NAV_ORDER_KEY, text: planned.orderJson }]
14557
14687
  });
14688
+ reopenDropdown();
14558
14689
  applySelectionAfterDrop();
14559
14690
  clearNavDragVisuals();
14560
- if (keepDropdownOpen) {
14561
- requestAnimationFrame(() => {
14562
- const desktop = document.querySelector("[data-ohw-nav-container]");
14563
- const drawer = document.querySelector("[data-ohw-nav-drawer]");
14564
- const link = desktop?.querySelector(`[data-ohw-href-key="${CSS.escape(hrefKey)}"]`) ?? drawer?.querySelector(`[data-ohw-href-key="${CSS.escape(hrefKey)}"]`) ?? document.querySelector(`[data-ohw-href-key="${CSS.escape(hrefKey)}"]`);
14565
- if (link) setNavGroupForceOpen(link, true);
14566
- });
14567
- }
14691
+ reopenDropdown();
14568
14692
  requestAnimationFrame(() => {
14569
14693
  if (editContentRef.current[NAV_ORDER_KEY] === planned.orderJson) {
14570
14694
  applyNavForest(planned.forest);
14571
14695
  }
14696
+ reopenDropdown();
14572
14697
  applySelectionAfterDrop();
14573
- requestAnimationFrame(applySelectionAfterDrop);
14698
+ requestAnimationFrame(() => {
14699
+ reopenDropdown();
14700
+ applySelectionAfterDrop();
14701
+ });
14702
+ window.setTimeout(reopenDropdown, 0);
14703
+ window.setTimeout(reopenDropdown, 50);
14704
+ window.setTimeout(reopenDropdown, 150);
14574
14705
  });
14575
14706
  return;
14576
14707
  }
14577
14708
  applySelectionAfterDrop();
14578
14709
  clearNavDragVisuals();
14710
+ reopenDropdown();
14711
+ window.setTimeout(reopenDropdown, 0);
14712
+ window.setTimeout(reopenDropdown, 50);
14579
14713
  },
14580
14714
  [clearNavDragVisuals, deselectRef, editContentRef, postToParentRef, selectRef]
14581
14715
  );
@@ -14667,7 +14801,7 @@ function useNavItemDrag({
14667
14801
  }
14668
14802
  if (linkPopoverOpenRef.current) setLinkPopover(null);
14669
14803
  const isNestedDrag = Boolean(pending.el.closest("[data-ohw-nav-children]"));
14670
- if (activeElRef.current && !isNestedDrag) deactivateRef.current();
14804
+ if (activeElRef.current) deactivateRef.current();
14671
14805
  const key = pending.el.getAttribute("data-ohw-href-key");
14672
14806
  if (!key) return;
14673
14807
  beginNavDragRef.current({
@@ -14678,9 +14812,7 @@ function useNavItemDrag({
14678
14812
  lastClientY: e.clientY,
14679
14813
  activeSlot: null
14680
14814
  });
14681
- if (activeElRef.current && isNestedDrag) {
14682
- deactivateRef.current();
14683
- }
14815
+ if (isNestedDrag) setNavGroupForceOpen(pending.el, true);
14684
14816
  };
14685
14817
  const endPointerDrag = (e) => {
14686
14818
  const pending = navPointerDragRef.current;
@@ -15857,7 +15989,7 @@ function duplicateSchedulingWidget(instanceId, scheduleId) {
15857
15989
  try {
15858
15990
  const root = (0, import_client2.createRoot)(container);
15859
15991
  schedulingRoots.set(container, root);
15860
- (0, import_react_dom3.flushSync)(() => {
15992
+ (0, import_react_dom4.flushSync)(() => {
15861
15993
  root.render(
15862
15994
  /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
15863
15995
  SchedulingWidget,
@@ -15995,7 +16127,7 @@ function mountSchedulingWidget(insertAfter, notifyOnConnect = false, scheduleId,
15995
16127
  }
15996
16128
  const root = (0, import_client2.createRoot)(container);
15997
16129
  schedulingRoots.set(container, root);
15998
- (0, import_react_dom3.flushSync)(() => {
16130
+ (0, import_react_dom4.flushSync)(() => {
15999
16131
  root.render(
16000
16132
  /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
16001
16133
  SchedulingWidget,
@@ -16238,14 +16370,18 @@ function isNavDropdownPanelOpen(childrenRoot) {
16238
16370
  }
16239
16371
  return true;
16240
16372
  }
16241
- function getOpenNavDropdownPanelRect(anchor) {
16373
+ function getOpenNavDropdownPanel(anchor) {
16242
16374
  const group = anchor.closest("[data-ohw-nav-group]");
16243
16375
  if (!group?.hasAttribute("data-ohw-nav-force-open")) return null;
16244
16376
  const panel = group.querySelector(":scope > [data-ohw-nav-children]");
16245
16377
  if (!panel || !isNavDropdownPanelOpen(panel)) return null;
16246
16378
  const panelRect = panel.getBoundingClientRect();
16247
16379
  if (panelRect.height < 2 || panelRect.width < 2) return null;
16248
- return panelRect;
16380
+ return panel;
16381
+ }
16382
+ function getOpenNavDropdownPanelRect(anchor) {
16383
+ const panel = getOpenNavDropdownPanel(anchor);
16384
+ return panel ? panel.getBoundingClientRect() : null;
16249
16385
  }
16250
16386
  function isNavItemPointerTarget(el) {
16251
16387
  const childrenRoot = el.closest("[data-ohw-nav-children]");
@@ -16281,7 +16417,7 @@ function requestSocialDialog(anchor, post, content) {
16281
16417
  hrefKey: item.getAttribute("data-ohw-href-key") ?? "",
16282
16418
  iconKey,
16283
16419
  url: getLinkHref4(item),
16284
- iconStyle: detectIconStyle(item),
16420
+ iconStyle: "outline",
16285
16421
  // What was chosen last time. Guessing from the address instead reads as "Website" for anything
16286
16422
  // unrecognised, and for an item with no address at all — so a deliberate choice looked lost.
16287
16423
  platformId: content[socialPlatformKey(iconKey)] ?? ""
@@ -16784,6 +16920,10 @@ function getIframeVisibleClip(parentScroll) {
16784
16920
  );
16785
16921
  return { top: clipTop, bottom: Math.max(clipTop, clipBottom) };
16786
16922
  }
16923
+ function isRectOutsideClip(rect, clip) {
16924
+ if (!clip) return false;
16925
+ return rect.bottom < clip.top || rect.top > clip.bottom;
16926
+ }
16787
16927
  function applyVisibleViewport(el, parentScroll) {
16788
16928
  const clip = getIframeVisibleClip(parentScroll);
16789
16929
  const top = clip?.top ?? 0;
@@ -17853,11 +17993,16 @@ function OhhwellsBridge() {
17853
17993
  if (owner) persistFieldsRef.current(owner);
17854
17994
  }
17855
17995
  activeElRef.current = null;
17856
- const preserveNavDropdown = Boolean(navPointerDragRef.current?.el?.closest("[data-ohw-nav-children]")) || Boolean(navDragRef.current?.draggedEl?.closest("[data-ohw-nav-children]")) || Boolean(
17996
+ const preserveNavDropdown = Boolean(navPointerDragRef.current?.el?.closest("[data-ohw-nav-children]")) || Boolean(navDragRef.current?.draggedEl?.closest("[data-ohw-nav-children]")) || Boolean(el.closest("[data-ohw-nav-children]")) || Boolean(
17857
17997
  selectedElRef.current?.closest("[data-ohw-nav-children]") && selectedElRef.current?.closest("[data-ohw-nav-group]")?.hasAttribute("data-ohw-nav-force-open")
17858
17998
  );
17859
17999
  if (!preserveNavDropdown) {
17860
18000
  setNavGroupForceOpen(null, false);
18001
+ } else {
18002
+ const keepAnchor = selectedElRef.current?.closest("[data-ohw-nav-children]") != null ? selectedElRef.current : el.closest("[data-ohw-href-key]") ?? el;
18003
+ if (keepAnchor.closest("[data-ohw-nav-children]")) {
18004
+ setNavGroupForceOpen(keepAnchor, true);
18005
+ }
17861
18006
  }
17862
18007
  setReorderHrefKey(null);
17863
18008
  setReorderDragDisabled(false);
@@ -17876,6 +18021,7 @@ function OhhwellsBridge() {
17876
18021
  });
17877
18022
  }, []);
17878
18023
  const deselect = (0, import_react17.useCallback)(() => {
18024
+ const nestedGroup = selectedElRef.current?.closest("[data-ohw-nav-children]") != null ? selectedElRef.current.closest("[data-ohw-nav-group]") : null;
17879
18025
  clearSelectedAttr();
17880
18026
  selectedElRef.current = null;
17881
18027
  selectedHrefKeyRef.current = null;
@@ -17899,7 +18045,11 @@ function OhhwellsBridge() {
17899
18045
  setFloatingPanel(null);
17900
18046
  setLogoSizeDraft(null);
17901
18047
  if (!activeElRef.current) {
17902
- setNavGroupForceOpen(null, false);
18048
+ if (nestedGroup?.isConnected) {
18049
+ nestedGroup.setAttribute("data-ohw-nav-force-open", "");
18050
+ } else {
18051
+ setNavGroupForceOpen(null, false);
18052
+ }
17903
18053
  setToolbarRect(null);
17904
18054
  setToolbarVariant("none");
17905
18055
  }
@@ -17980,10 +18130,7 @@ function OhhwellsBridge() {
17980
18130
  setSelectedIsSocialsRow(false);
17981
18131
  const isDropdownTrigger = !isNestedNavChild(navAnchor) && (navItemHasDropdownChildren(navAnchor) || navItemOwnsDropdownPanel(navAnchor));
17982
18132
  if (isNestedNavChild(navAnchor)) {
17983
- const group = navAnchor.closest("[data-ohw-nav-group]");
17984
- if (group?.hasAttribute("data-ohw-nav-force-open")) {
17985
- setNavGroupForceOpen(navAnchor, true);
17986
- }
18133
+ setNavGroupForceOpen(navAnchor, true);
17987
18134
  setNavDropdownPreviewOpen(null);
17988
18135
  } else if (isDropdownTrigger) {
17989
18136
  const group = navAnchor.closest("[data-ohw-nav-group]");
@@ -18135,7 +18282,7 @@ function OhhwellsBridge() {
18135
18282
  hrefKey: planned.hrefKey,
18136
18283
  iconKey: planned.iconKey,
18137
18284
  url: "",
18138
- iconStyle: detectIconStyle(getSocialItem(selected) ?? socialsRow),
18285
+ iconStyle: "outline",
18139
18286
  platformId: "",
18140
18287
  // Tells the editor this one is not on the page yet, so dismissing means "never mind".
18141
18288
  isNew: true
@@ -18217,8 +18364,10 @@ function OhhwellsBridge() {
18217
18364
  setNavDropdownPreviewOpen(true);
18218
18365
  setToolbarRect(selected.getBoundingClientRect());
18219
18366
  requestAnimationFrame(() => {
18220
- if (selected.isConnected) setToolbarRect(selected.getBoundingClientRect());
18221
- enterEditOnNewItem(result.anchor);
18367
+ requestAnimationFrame(() => {
18368
+ if (selected.isConnected) setToolbarRect(selected.getBoundingClientRect());
18369
+ enterEditOnNewItem(result.anchor);
18370
+ });
18222
18371
  });
18223
18372
  }, [enterEditOnNewItem, isFooterFrameSelection, maybeWarnNavLinkDropdownConflict, postToParent2]);
18224
18373
  const handleAddFooterColumn = (0, import_react17.useCallback)(() => {
@@ -18598,10 +18747,7 @@ function OhhwellsBridge() {
18598
18747
  clearHrefKeyHover(anchor);
18599
18748
  const isDropdownTrigger = !isNestedNavChild(anchor) && (navItemHasDropdownChildren(anchor) || navItemOwnsDropdownPanel(anchor));
18600
18749
  if (isNestedNavChild(anchor)) {
18601
- const group = anchor.closest("[data-ohw-nav-group]");
18602
- if (group?.hasAttribute("data-ohw-nav-force-open")) {
18603
- setNavGroupForceOpen(anchor, true);
18604
- }
18750
+ setNavGroupForceOpen(anchor, true);
18605
18751
  setNavDropdownPreviewOpen(null);
18606
18752
  } else if (isDropdownTrigger) {
18607
18753
  setNavGroupForceOpen(null, false);
@@ -18659,17 +18805,6 @@ function OhhwellsBridge() {
18659
18805
  setIsFooterFrameSelection(isFooterColumn);
18660
18806
  setNavDropdownPreviewOpen(null);
18661
18807
  if (isFooterColumn) {
18662
- const ensured = ensureFooterColumnDefaultHeading(el, editContentRef.current);
18663
- if (ensured) {
18664
- editContentRef.current = {
18665
- ...editContentRef.current,
18666
- [ensured.headingKey]: ensured.text
18667
- };
18668
- postToParent2({
18669
- type: "ow:change",
18670
- nodes: [{ key: ensured.headingKey, text: ensured.text }]
18671
- });
18672
- }
18673
18808
  setFooterHeadingVisible(isFooterColumnHeadingVisible(el));
18674
18809
  } else {
18675
18810
  setFooterHeadingVisible(null);
@@ -19513,8 +19648,10 @@ function OhhwellsBridge() {
19513
19648
  /* The glyph too, and this one mattered most: as a block it filled the whole width of its
19514
19649
  link and sat over the words, so every click meant for the text landed on the icon. */
19515
19650
  [data-ohw-socials-row] [data-ohw-editable="icon"] {
19516
- display: inline-flex;
19517
- flex: 0 0 auto;
19651
+ display: inline-flex !important;
19652
+ flex: 0 0 auto !important;
19653
+ width: auto !important;
19654
+ max-width: max-content !important;
19518
19655
  align-items: center;
19519
19656
  }
19520
19657
  [data-ohw-socials-row] a {
@@ -19593,9 +19730,24 @@ function OhhwellsBridge() {
19593
19730
  /* Somewhere to click the block itself, on every side (OHH-642) \u2014 editor only. */
19594
19731
  [data-ohw-editable="form"] {
19595
19732
  padding: 18px !important;
19733
+ /* Horizontal newsletter rows collapse added fields into pill-circles without wrap. */
19734
+ flex-wrap: wrap !important;
19735
+ align-items: flex-end !important;
19596
19736
  }
19737
+ [data-ohw-editable="form"] [data-ohw-form-field] {
19738
+ flex: 1 1 12rem !important;
19739
+ min-width: min(12rem, 100%) !important;
19740
+ max-width: 100% !important;
19741
+ }
19742
+ /* Placeholder text lives in the value while selected. currentColor inside color-mix
19743
+ resolves to the *inherited* color, so reverse-print footers washed it out on white
19744
+ inputs \u2014 pin to the control's own color captured in beginPlaceholderEdit. */
19597
19745
  [data-ohw-placeholder-edit] {
19598
- color: color-mix(in srgb, currentColor 55%, transparent) !important;
19746
+ color: color-mix(
19747
+ in srgb,
19748
+ var(--ohw-placeholder-edit-color, CanvasText) 55%,
19749
+ transparent
19750
+ ) !important;
19599
19751
  cursor: text !important;
19600
19752
  }
19601
19753
  /* Text hover chrome is drawn by the overlay (see hoveredTextRect) \u2014 the CSS outline
@@ -20871,6 +21023,7 @@ function OhhwellsBridge() {
20871
21023
  setHoveredItemRect(null);
20872
21024
  hoveredNavContainerRef.current = null;
20873
21025
  setHoveredNavContainerRect(null);
21026
+ dismissImageHover();
20874
21027
  return;
20875
21028
  }
20876
21029
  if (probeSocialsRowAt(clientX, clientY)) return;
@@ -22119,14 +22272,20 @@ function OhhwellsBridge() {
22119
22272
  };
22120
22273
  const applyToolbarPos = (rect) => {
22121
22274
  const ps = parentScrollRef.current;
22275
+ const hidden = isRectOutsideClip(rect, getIframeVisibleClip(ps));
22122
22276
  const measuredW = toolbarElRef.current?.offsetWidth || 330;
22123
22277
  if (toolbarElRef.current) {
22124
- const { top, left, transform } = calcToolbarPos(rect, ps, measuredW);
22125
- toolbarElRef.current.style.top = `${top}px`;
22126
- toolbarElRef.current.style.left = `${left}px`;
22127
- toolbarElRef.current.style.transform = transform;
22278
+ toolbarElRef.current.style.display = hidden ? "none" : "";
22279
+ if (!hidden) {
22280
+ const { top, left, transform } = calcToolbarPos(rect, ps, measuredW);
22281
+ toolbarElRef.current.style.top = `${top}px`;
22282
+ toolbarElRef.current.style.left = `${left}px`;
22283
+ toolbarElRef.current.style.transform = transform;
22284
+ }
22128
22285
  }
22129
22286
  if (glowElRef.current) {
22287
+ glowElRef.current.style.display = hidden ? "none" : "";
22288
+ if (hidden) return;
22130
22289
  const GAP = SELECTION_CHROME_GAP2;
22131
22290
  glowElRef.current.style.top = `${rect.top - GAP}px`;
22132
22291
  glowElRef.current.style.left = `${rect.left - GAP}px`;
@@ -22568,7 +22727,7 @@ function OhhwellsBridge() {
22568
22727
  postToParent2({
22569
22728
  type: "ow:ready",
22570
22729
  version: "1",
22571
- bridgeVersion: "0.1.107",
22730
+ bridgeVersion: "0.1.109",
22572
22731
  path: pathname,
22573
22732
  nodes: collectEditableNodes(editContentRef.current),
22574
22733
  sections
@@ -23032,7 +23191,7 @@ function OhhwellsBridge() {
23032
23191
  /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { id: "ohw-loader", suppressHydrationWarning: true, style: { ...OHW_LOADER_STYLE, display: "none" }, children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(OhwLoaderSpinner, {}) }),
23033
23192
  /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("script", { suppressHydrationWarning: true, dangerouslySetInnerHTML: { __html: OHW_LOADER_PREHYDRATE_SCRIPT } }),
23034
23193
  subdomain && !isEditMode && showBranding && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(MadeWithOhhWells, {}),
23035
- bridgeRoot ? (0, import_react_dom4.createPortal)(
23194
+ bridgeRoot ? (0, import_react_dom5.createPortal)(
23036
23195
  /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(import_jsx_runtime33.Fragment, { children: [
23037
23196
  /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { ref: attachVisibleViewport, "data-ohw-visible-viewport": "", "aria-hidden": true }),
23038
23197
  isEditMode && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(AiSectionOverlay, { postToParent: postToParent2, apiRef: aiSectionApiRef }),
@@ -23301,8 +23460,9 @@ function OhhwellsBridge() {
23301
23460
  {
23302
23461
  rect: isItemDragging && draggedItemRect && (footerDragRef.current?.wasSelected || navDragRef.current?.wasSelected) ? draggedItemRect : toolbarRect,
23303
23462
  toolbarBelowRect: selectedElRef.current && isNavigationItem2(selectedElRef.current) ? getOpenNavDropdownPanelRect(selectedElRef.current) : null,
23463
+ toolbarBelowEl: selectedElRef.current && isNavigationItem2(selectedElRef.current) ? getOpenNavDropdownPanel(selectedElRef.current) : null,
23304
23464
  elRef: glowElRef,
23305
- state: isItemDragging ? "dragging" : selectedElRef.current && isNavigationItem2(selectedElRef.current) && getOpenNavDropdownPanelRect(selectedElRef.current) ? "active-bottom" : resolveItemInteractionState(toolbarRect, parentScrollRef.current),
23465
+ state: isItemDragging ? "dragging" : selectedElRef.current && isNavigationItem2(selectedElRef.current) && getOpenNavDropdownPanel(selectedElRef.current) ? "active-bottom" : resolveItemInteractionState(toolbarRect, parentScrollRef.current),
23306
23466
  showHandle: toolbarVariant === "link-action" && Boolean(reorderHrefKey) || toolbarVariant === "select-frame" && isFooterFrameSelection,
23307
23467
  dragDisabled: reorderDragDisabled,
23308
23468
  dragHandleLabel: reorderHrefKey ? `Reorder ${reorderHrefKey}` : "Reorder item",
@@ -23355,7 +23515,7 @@ function OhhwellsBridge() {
23355
23515
  ) : void 0
23356
23516
  }
23357
23517
  ),
23358
- toolbarRect && toolbarVariant === "rich-text" && !linkPopover && /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(import_jsx_runtime33.Fragment, { children: [
23518
+ toolbarRect && toolbarVariant === "rich-text" && !linkPopover && !isRectOutsideClip(toolbarRect, getIframeVisibleClip(parentScrollRef.current)) && /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(import_jsx_runtime33.Fragment, { children: [
23359
23519
  /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
23360
23520
  EditGlowChrome,
23361
23521
  {