@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.js CHANGED
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
 
3
3
  // src/OhhwellsBridge.tsx
4
- import React12, { useCallback as useCallback8, useEffect as useEffect13, useLayoutEffect as useLayoutEffect5, useRef as useRef10, useState as useState13 } from "react";
4
+ import React12, { useCallback as useCallback8, useEffect as useEffect13, useLayoutEffect as useLayoutEffect5, useRef as useRef10, useState as useState14 } from "react";
5
5
  import { createRoot as createRoot2 } from "react-dom/client";
6
6
  import { flushSync as flushSync2 } from "react-dom";
7
7
 
@@ -7698,7 +7698,8 @@ function ItemActionToolbar({
7698
7698
  }
7699
7699
 
7700
7700
  // src/ui/item-interaction-layer.tsx
7701
- import { useLayoutEffect as useLayoutEffect2, useRef as useRef2 } from "react";
7701
+ import { useLayoutEffect as useLayoutEffect2, useRef as useRef2, useState as useState4 } from "react";
7702
+ import { createPortal } from "react-dom";
7702
7703
  import { jsx as jsx12, jsxs as jsxs5 } from "react/jsx-runtime";
7703
7704
  var PRIMARY = "var(--ohw-primary, #0885FE)";
7704
7705
  var CHROME_RADIUS = 6;
@@ -7708,6 +7709,7 @@ var TOOLBAR_EDGE_MARGIN = 4;
7708
7709
  var SELECTION_CHROME_GAP = 4;
7709
7710
  var HOVER_CHROME_GAP = 2;
7710
7711
  var TOOLBAR_STROKE_GAP = 4;
7712
+ var DETACHED_TOOLBAR_Z = 2147483647;
7711
7713
  function getChromeZIndex(state) {
7712
7714
  switch (state) {
7713
7715
  case "active-top":
@@ -7765,6 +7767,14 @@ function ClampedToolbarSlot({
7765
7767
  const parent = slot.offsetParent;
7766
7768
  if (!parent) return;
7767
7769
  const parentRect = parent.getBoundingClientRect();
7770
+ if (align === "left") {
7771
+ const leftEdge = parentRect.left;
7772
+ const maxLeft = window.innerWidth - TOOLBAR_EDGE_MARGIN - w;
7773
+ const minLeft = TOOLBAR_EDGE_MARGIN;
7774
+ const clampedLeft = Math.max(minLeft, Math.min(leftEdge, maxLeft));
7775
+ slot.style.transform = `translateX(${clampedLeft - leftEdge}px)`;
7776
+ return;
7777
+ }
7768
7778
  const centerX = parentRect.left + parentRect.width / 2;
7769
7779
  const half = w / 2;
7770
7780
  const clampedCenter = Math.max(
@@ -7772,7 +7782,7 @@ function ClampedToolbarSlot({
7772
7782
  Math.min(centerX, window.innerWidth - TOOLBAR_EDGE_MARGIN - half)
7773
7783
  );
7774
7784
  const offsetX = clampedCenter - centerX;
7775
- slot.style.transform = align === "left" ? "none" : `translateX(calc(-50% + ${offsetX}px))`;
7785
+ slot.style.transform = `translateX(calc(-50% + ${offsetX}px))`;
7776
7786
  };
7777
7787
  clamp();
7778
7788
  const ro = new ResizeObserver(clamp);
@@ -7806,13 +7816,25 @@ function ClampedToolbarSlot({
7806
7816
  function DetachedBelowToolbarSlot({
7807
7817
  centerX,
7808
7818
  belowRect,
7819
+ belowEl,
7809
7820
  children
7810
7821
  }) {
7811
7822
  const slotRef = useRef2(null);
7823
+ const [anchorBottom, setAnchorBottom] = useState4(belowRect.bottom);
7824
+ const [portalTarget] = useState4(
7825
+ () => typeof document === "undefined" ? null : document.querySelector("[data-ohw-bridge-root]") ?? document.body
7826
+ );
7827
+ useLayoutEffect2(() => {
7828
+ setAnchorBottom(belowRect.bottom);
7829
+ }, [belowRect.bottom, belowRect.height, belowRect.top]);
7812
7830
  useLayoutEffect2(() => {
7813
7831
  const slot = slotRef.current;
7814
7832
  if (!slot) return;
7815
- const clamp = () => {
7833
+ const sync = () => {
7834
+ if (belowEl?.isConnected) {
7835
+ const nextBottom = belowEl.getBoundingClientRect().bottom;
7836
+ setAnchorBottom((prev) => Math.abs(prev - nextBottom) < 0.5 ? prev : nextBottom);
7837
+ }
7816
7838
  const toolbar = slot.firstElementChild;
7817
7839
  if (!toolbar) return;
7818
7840
  const w = toolbar.offsetWidth;
@@ -7824,30 +7846,46 @@ function DetachedBelowToolbarSlot({
7824
7846
  );
7825
7847
  slot.style.left = `${clampedCenter}px`;
7826
7848
  };
7827
- clamp();
7828
- const ro = new ResizeObserver(clamp);
7849
+ sync();
7850
+ const ro = new ResizeObserver(sync);
7829
7851
  ro.observe(slot);
7830
7852
  if (slot.firstElementChild) ro.observe(slot.firstElementChild);
7831
- window.addEventListener("resize", clamp);
7853
+ if (belowEl) {
7854
+ ro.observe(belowEl);
7855
+ const mo = new MutationObserver(sync);
7856
+ mo.observe(belowEl, { childList: true, subtree: true });
7857
+ window.addEventListener("resize", sync);
7858
+ return () => {
7859
+ ro.disconnect();
7860
+ mo.disconnect();
7861
+ window.removeEventListener("resize", sync);
7862
+ };
7863
+ }
7864
+ window.addEventListener("resize", sync);
7832
7865
  return () => {
7833
7866
  ro.disconnect();
7834
- window.removeEventListener("resize", clamp);
7867
+ window.removeEventListener("resize", sync);
7835
7868
  };
7836
- }, [centerX, belowRect, children]);
7837
- return /* @__PURE__ */ jsx12(
7838
- "div",
7839
- {
7840
- ref: slotRef,
7841
- className: "pointer-events-auto fixed",
7842
- style: {
7843
- top: belowRect.bottom + TOOLBAR_STROKE_GAP,
7844
- left: centerX,
7845
- transform: "translateX(-50%)",
7846
- zIndex: getChromeZIndex("active-bottom")
7847
- },
7848
- "data-ohw-item-toolbar-anchor": "below-external",
7849
- children
7850
- }
7869
+ }, [centerX, belowRect, belowEl, children]);
7870
+ if (!portalTarget) return null;
7871
+ return createPortal(
7872
+ /* @__PURE__ */ jsx12(
7873
+ "div",
7874
+ {
7875
+ ref: slotRef,
7876
+ className: "pointer-events-auto fixed",
7877
+ style: {
7878
+ top: anchorBottom + TOOLBAR_STROKE_GAP,
7879
+ left: centerX,
7880
+ transform: "translateX(-50%)",
7881
+ zIndex: DETACHED_TOOLBAR_Z
7882
+ },
7883
+ "data-ohw-bridge": "",
7884
+ "data-ohw-item-toolbar-anchor": "below-external",
7885
+ children
7886
+ }
7887
+ ),
7888
+ portalTarget
7851
7889
  );
7852
7890
  }
7853
7891
  function ItemInteractionLayer({
@@ -7856,6 +7894,7 @@ function ItemInteractionLayer({
7856
7894
  elRef,
7857
7895
  toolbar,
7858
7896
  toolbarBelowRect = null,
7897
+ toolbarBelowEl = null,
7859
7898
  showHandle = false,
7860
7899
  dragDisabled = false,
7861
7900
  dragHandleLabel = "Reorder item",
@@ -7961,6 +8000,7 @@ function ItemInteractionLayer({
7961
8000
  {
7962
8001
  centerX: rect.left + rect.width / 2,
7963
8002
  belowRect: toolbarBelowRect,
8003
+ belowEl: toolbarBelowEl,
7964
8004
  children: toolbar
7965
8005
  }
7966
8006
  ) : null
@@ -8331,6 +8371,7 @@ function setFieldRequired(wrapper, required) {
8331
8371
  function beginPlaceholderEdit(wrapper) {
8332
8372
  const input = fieldInputOf(wrapper);
8333
8373
  if (!input || input.hasAttribute(PLACEHOLDER_EDIT_ATTR)) return;
8374
+ input.style.setProperty("--ohw-placeholder-edit-color", getComputedStyle(input).color);
8334
8375
  input.setAttribute(PLACEHOLDER_EDIT_ATTR, "");
8335
8376
  input.value = input.getAttribute("placeholder") ?? "";
8336
8377
  input.setAttribute("placeholder", "");
@@ -8341,6 +8382,7 @@ function commitPlaceholderEdit(wrapper) {
8341
8382
  if (!input || !input.hasAttribute(PLACEHOLDER_EDIT_ATTR)) return false;
8342
8383
  const typed = input.value;
8343
8384
  input.removeAttribute(PLACEHOLDER_EDIT_ATTR);
8385
+ input.style.removeProperty("--ohw-placeholder-edit-color");
8344
8386
  input.value = "";
8345
8387
  const previous = input.getAttribute("placeholder") ?? "";
8346
8388
  input.setAttribute("placeholder", typed);
@@ -8925,7 +8967,7 @@ function CarouselOverlay({
8925
8967
  }
8926
8968
 
8927
8969
  // src/ui/ai-section/AiSectionOverlay.tsx
8928
- import { useCallback as useCallback2, useEffect as useEffect4, useRef as useRef4, useState as useState5 } from "react";
8970
+ import { useCallback as useCallback2, useEffect as useEffect4, useRef as useRef4, useState as useState6 } from "react";
8929
8971
  import { Check, X } from "lucide-react";
8930
8972
  import { Fragment as Fragment5, jsx as jsx17, jsxs as jsxs9 } from "react/jsx-runtime";
8931
8973
  var findSectionElement = findByInstanceId;
@@ -8937,7 +8979,7 @@ function readRect(instanceId) {
8937
8979
  return { top: r2.top, left: r2.left, width: r2.width, height: r2.height };
8938
8980
  }
8939
8981
  function useLiveSectionRect(sectionId) {
8940
- const [rect, setRect] = useState5(null);
8982
+ const [rect, setRect] = useState6(null);
8941
8983
  useEffect4(() => {
8942
8984
  if (!sectionId) {
8943
8985
  setRect(null);
@@ -8989,7 +9031,7 @@ function ReviewButton({
8989
9031
  background,
8990
9032
  color
8991
9033
  }) {
8992
- const [hover, setHover] = useState5(false);
9034
+ const [hover, setHover] = useState6(false);
8993
9035
  return /* @__PURE__ */ jsxs9("div", { style: { position: "relative" }, children: [
8994
9036
  /* @__PURE__ */ jsx17(
8995
9037
  "button",
@@ -9043,9 +9085,9 @@ function AiSectionOverlay({
9043
9085
  postToParent: postToParent2,
9044
9086
  apiRef
9045
9087
  }) {
9046
- const [selectedId, setSelectedId] = useState5(null);
9047
- const [reviewId, setReviewId] = useState5(null);
9048
- const [reviewButtonsHidden, setReviewButtonsHidden] = useState5(false);
9088
+ const [selectedId, setSelectedId] = useState6(null);
9089
+ const [reviewId, setReviewId] = useState6(null);
9090
+ const [reviewButtonsHidden, setReviewButtonsHidden] = useState6(false);
9049
9091
  const reviewIdRef = useRef4(null);
9050
9092
  reviewIdRef.current = reviewId;
9051
9093
  const selectedIdRef = useRef4(null);
@@ -9119,7 +9161,7 @@ function AiSectionOverlay({
9119
9161
  window.addEventListener("message", onMessage);
9120
9162
  return () => window.removeEventListener("message", onMessage);
9121
9163
  }, [postToParent2]);
9122
- const [hoveredId, setHoveredId] = useState5(null);
9164
+ const [hoveredId, setHoveredId] = useState6(null);
9123
9165
  useEffect4(() => {
9124
9166
  const onMove = (e) => {
9125
9167
  const t = e.target;
@@ -9164,10 +9206,25 @@ function AiSectionOverlay({
9164
9206
  },
9165
9207
  [postToParent2]
9166
9208
  );
9209
+ const [navDropdownForceOpen, setNavDropdownForceOpen] = useState6(false);
9210
+ useEffect4(() => {
9211
+ const update = () => {
9212
+ setNavDropdownForceOpen(Boolean(document.querySelector("[data-ohw-nav-force-open]")));
9213
+ };
9214
+ update();
9215
+ const mo = new MutationObserver(update);
9216
+ mo.observe(document.documentElement, {
9217
+ attributes: true,
9218
+ attributeFilter: ["data-ohw-nav-force-open"],
9219
+ subtree: true
9220
+ });
9221
+ return () => mo.disconnect();
9222
+ }, []);
9167
9223
  const activeSelectionId = reviewId ? null : selectedId;
9168
9224
  const selectionRect = useLiveSectionRect(activeSelectionId);
9169
9225
  const reviewRect = useLiveSectionRect(reviewId);
9170
9226
  const hoverRect = useLiveSectionRect(reviewId || hoveredId === selectedId ? null : hoveredId);
9227
+ const showSelectionBorder = Boolean(selectionRect) && !navDropdownForceOpen;
9171
9228
  useEffect4(() => {
9172
9229
  const selectedEl = activeSelectionId ? findSectionElement(activeSelectionId) : null;
9173
9230
  if (!activeSelectionId || !selectionRect || selectedEl && isChromeSection(selectedEl)) {
@@ -9207,7 +9264,7 @@ function AiSectionOverlay({
9207
9264
  }
9208
9265
  }
9209
9266
  ),
9210
- selectionRect && /* @__PURE__ */ jsx17(
9267
+ showSelectionBorder && selectionRect && /* @__PURE__ */ jsx17(
9211
9268
  "div",
9212
9269
  {
9213
9270
  "data-ohw-ai-section-selected": "",
@@ -9271,7 +9328,7 @@ function AiSectionOverlay({
9271
9328
  }
9272
9329
 
9273
9330
  // src/OhhwellsBridge.tsx
9274
- import { createPortal as createPortal2 } from "react-dom";
9331
+ import { createPortal as createPortal3 } from "react-dom";
9275
9332
  import { usePathname as usePathname2, useRouter as useRouter3, useSearchParams } from "next/navigation";
9276
9333
 
9277
9334
  // src/lib/cta-button.ts
@@ -9774,7 +9831,7 @@ function SectionTreeItem({
9774
9831
  }
9775
9832
 
9776
9833
  // src/ui/link-modal/UrlOrPageInput.tsx
9777
- import { useEffect as useEffect5, useId as useId2, useRef as useRef5, useState as useState6 } from "react";
9834
+ import { useEffect as useEffect5, useId as useId2, useRef as useRef5, useState as useState7 } from "react";
9778
9835
 
9779
9836
  // src/ui/input.tsx
9780
9837
  import * as React10 from "react";
@@ -9845,7 +9902,7 @@ function UrlOrPageInput({
9845
9902
  const inputId = useId2();
9846
9903
  const inputRef = useRef5(null);
9847
9904
  const rootRef = useRef5(null);
9848
- const [isFocused, setIsFocused] = useState6(false);
9905
+ const [isFocused, setIsFocused] = useState7(false);
9849
9906
  useEffect5(() => {
9850
9907
  if (!dropdownOpen) return;
9851
9908
  const isOutside = (e) => {
@@ -10054,8 +10111,8 @@ function LinkEditorPanel({ state, onClose }) {
10054
10111
  }
10055
10112
 
10056
10113
  // src/ui/link-modal/SectionPickerOverlay.tsx
10057
- import { useCallback as useCallback3, useEffect as useEffect6, useMemo as useMemo2, useRef as useRef6, useState as useState7 } from "react";
10058
- import { createPortal } from "react-dom";
10114
+ import { useCallback as useCallback3, useEffect as useEffect6, useMemo as useMemo2, useRef as useRef6, useState as useState8 } from "react";
10115
+ import { createPortal as createPortal2 } from "react-dom";
10059
10116
  import { ArrowLeft as ArrowLeft2, Check as Check2 } from "lucide-react";
10060
10117
  import { usePathname, useRouter as useRouter2 } from "next/navigation";
10061
10118
  import { jsx as jsx25, jsxs as jsxs15 } from "react/jsx-runtime";
@@ -10091,7 +10148,7 @@ function hitTestSectionId(x, y, sectionIds, rects) {
10091
10148
  return null;
10092
10149
  }
10093
10150
  function useSectionRects(sectionIdsKey, enabled) {
10094
- const [rects, setRects] = useState7(/* @__PURE__ */ new Map());
10151
+ const [rects, setRects] = useState8(/* @__PURE__ */ new Map());
10095
10152
  const sectionIds = useMemo2(
10096
10153
  () => sectionIdsKey ? sectionIdsKey.split("\0") : [],
10097
10154
  [sectionIdsKey]
@@ -10137,13 +10194,13 @@ function SectionPickerOverlay({
10137
10194
  }) {
10138
10195
  const router = useRouter2();
10139
10196
  const pathname = usePathname();
10140
- const [selectedId, setSelectedId] = useState7(null);
10141
- const [hoveredId, setHoveredId] = useState7(null);
10197
+ const [selectedId, setSelectedId] = useState8(null);
10198
+ const [hoveredId, setHoveredId] = useState8(null);
10142
10199
  const pointerRef = useRef6(null);
10143
10200
  const pointerScreenRef = useRef6(null);
10144
10201
  const iframeOffsetTopRef = useRef6(null);
10145
10202
  const sectionIdsRef = useRef6([]);
10146
- const [chromeClip, setChromeClip] = useState7(
10203
+ const [chromeClip, setChromeClip] = useState8(
10147
10204
  () => ({
10148
10205
  top: 0,
10149
10206
  bottom: typeof window !== "undefined" ? window.innerHeight : 0
@@ -10286,7 +10343,7 @@ function SectionPickerOverlay({
10286
10343
  }, [onBack]);
10287
10344
  const portalRoot = typeof document !== "undefined" ? document.querySelector("[data-ohw-bridge-root]") ?? document.body : null;
10288
10345
  if (!portalRoot) return null;
10289
- return createPortal(
10346
+ return createPortal2(
10290
10347
  /* @__PURE__ */ jsxs15(
10291
10348
  "div",
10292
10349
  {
@@ -10396,7 +10453,7 @@ function SectionPickerOverlay({
10396
10453
  }
10397
10454
 
10398
10455
  // src/ui/link-modal/useLinkModalState.ts
10399
- import { useCallback as useCallback4, useEffect as useEffect7, useMemo as useMemo3, useState as useState8 } from "react";
10456
+ import { useCallback as useCallback4, useEffect as useEffect7, useMemo as useMemo3, useState as useState9 } from "react";
10400
10457
  function useLinkModalState({
10401
10458
  open,
10402
10459
  mode,
@@ -10409,12 +10466,12 @@ function useLinkModalState({
10409
10466
  onSubmit
10410
10467
  }) {
10411
10468
  const availablePages = useMemo3(() => pages, [pages]);
10412
- const [searchValue, setSearchValue] = useState8("");
10413
- const [selectedPage, setSelectedPage] = useState8(null);
10414
- const [selectedSection, setSelectedSection] = useState8(null);
10415
- const [step, setStep] = useState8("input");
10416
- const [dropdownOpen, setDropdownOpen] = useState8(false);
10417
- const [urlError, setUrlError] = useState8("");
10469
+ const [searchValue, setSearchValue] = useState9("");
10470
+ const [selectedPage, setSelectedPage] = useState9(null);
10471
+ const [selectedSection, setSelectedSection] = useState9(null);
10472
+ const [step, setStep] = useState9("input");
10473
+ const [dropdownOpen, setDropdownOpen] = useState9(false);
10474
+ const [urlError, setUrlError] = useState9("");
10418
10475
  const reset = useCallback4(() => {
10419
10476
  setSearchValue("");
10420
10477
  setSelectedPage(null);
@@ -11309,7 +11366,11 @@ function isNestedNavChild(anchor) {
11309
11366
  function navItemOwnsDropdownPanel(anchor) {
11310
11367
  if (isNestedNavChild(anchor)) return true;
11311
11368
  const group = anchor.closest("[data-ohw-nav-group]");
11312
- return Boolean(group?.querySelector(":scope > [data-ohw-nav-children]"));
11369
+ const childrenRoot = group?.querySelector(":scope > [data-ohw-nav-children]");
11370
+ if (!childrenRoot) return false;
11371
+ return Array.from(childrenRoot.querySelectorAll(":scope > [data-ohw-href-key]")).some(
11372
+ isNavbarLinkItem
11373
+ );
11313
11374
  }
11314
11375
  function setNavGroupForceOpen(anchor, open) {
11315
11376
  document.querySelectorAll("[data-ohw-nav-force-open]").forEach((el) => {
@@ -11449,6 +11510,12 @@ function addNavbarSubitem(parentAnchor, href = "/", label = "New") {
11449
11510
  };
11450
11511
  }
11451
11512
  function reconcileNavbarItemsFromContent(content) {
11513
+ const openParentKeys = Array.from(
11514
+ document.querySelectorAll("[data-ohw-nav-group][data-ohw-nav-force-open]")
11515
+ ).map((group) => {
11516
+ const trigger = group.querySelector(":scope > [data-ohw-href-key]");
11517
+ return trigger?.getAttribute("data-ohw-href-key") ?? null;
11518
+ }).filter((key) => Boolean(key));
11452
11519
  const orderForest = parseNavOrderJson(content[NAV_ORDER_KEY]);
11453
11520
  if (orderForest?.length) {
11454
11521
  const allowed = new Set(flattenNavOrder(orderForest));
@@ -11504,6 +11571,12 @@ function reconcileNavbarItemsFromContent(content) {
11504
11571
  }
11505
11572
  pruneNavbarItemsNotInOrder(allowed);
11506
11573
  applyNavForest(orderForest);
11574
+ for (const parentKey of openParentKeys) {
11575
+ const trigger = document.querySelector(
11576
+ `[data-ohw-href-key="${CSS.escape(parentKey)}"]`
11577
+ );
11578
+ if (trigger) setNavGroupForceOpen(trigger, true);
11579
+ }
11507
11580
  return;
11508
11581
  }
11509
11582
  const indices = collectNavbarIndicesFromContent(content);
@@ -11514,6 +11587,12 @@ function reconcileNavbarItemsFromContent(content) {
11514
11587
  if (!href && !label) continue;
11515
11588
  insertNavbarItemDom(index, href ?? "/", label ?? "Untitled", null);
11516
11589
  }
11590
+ for (const parentKey of openParentKeys) {
11591
+ const trigger = document.querySelector(
11592
+ `[data-ohw-href-key="${CSS.escape(parentKey)}"]`
11593
+ );
11594
+ if (trigger) setNavGroupForceOpen(trigger, true);
11595
+ }
11517
11596
  }
11518
11597
  function pruneNavbarItemsNotInOrder(allowed) {
11519
11598
  const roots = [getNavbarDesktopContainer(), getNavbarDrawerContainer()].filter(
@@ -11862,19 +11941,31 @@ function deleteNavbarItem(sourceAnchor) {
11862
11941
 
11863
11942
  // src/lib/icon-markup.ts
11864
11943
  var GLYPH_SELECTOR = "svg, img";
11944
+ function squareIconSide(width, height) {
11945
+ if (!(width > 0) || !(height > 0)) return Math.max(width, height, 0);
11946
+ const ratio = width / height;
11947
+ if (ratio > 1.35 || ratio < 1 / 1.35) return Math.min(width, height);
11948
+ return (width + height) / 2;
11949
+ }
11865
11950
  function referenceBox(slot) {
11866
11951
  const row = slot.closest("[data-ohw-socials-row]") ?? slot.closest("a")?.parentElement ?? null;
11867
11952
  const neighbour = row ? Array.from(row.querySelectorAll('[data-ohw-editable="icon"]')).find(
11868
11953
  (el) => el !== slot && !el.hasAttribute("data-ohw-social-icon-placeholder")
11869
11954
  ) : null;
11955
+ const fromRect = (box) => {
11956
+ if (!box?.width || !box.height) return null;
11957
+ const side = Math.round(squareIconSide(box.width, box.height));
11958
+ return side > 0 ? { width: side, height: side } : null;
11959
+ };
11870
11960
  if (neighbour) {
11871
- const box2 = neighbour.querySelector(GLYPH_SELECTOR)?.getBoundingClientRect();
11872
- if (box2?.width && box2.height) return box2;
11961
+ const sized = fromRect(
11962
+ neighbour.querySelector(GLYPH_SELECTOR)?.getBoundingClientRect()
11963
+ );
11964
+ if (sized) return sized;
11873
11965
  }
11874
- const own = slot.getBoundingClientRect();
11875
- if (own.width && own.height) return own;
11876
- const box = slot.querySelector(GLYPH_SELECTOR)?.getBoundingClientRect() ?? null;
11877
- return box?.width && box.height ? box : null;
11966
+ const own = fromRect(slot.getBoundingClientRect());
11967
+ if (own) return own;
11968
+ return fromRect(slot.querySelector(GLYPH_SELECTOR)?.getBoundingClientRect());
11878
11969
  }
11879
11970
  function iconMarkupSizedFor(slot, markup) {
11880
11971
  const box = referenceBox(slot);
@@ -11888,8 +11979,8 @@ function iconMarkupSizedFor(slot, markup) {
11888
11979
  glyph.style.height = "1.5em";
11889
11980
  return holder.innerHTML;
11890
11981
  }
11891
- glyph.style.width = `${Math.round(box.width)}px`;
11892
- glyph.style.height = `${Math.round(box.height)}px`;
11982
+ glyph.style.width = `${box.width}px`;
11983
+ glyph.style.height = `${box.height}px`;
11893
11984
  return holder.innerHTML;
11894
11985
  }
11895
11986
  var ICON_SOURCE_ATTR = "data-ohw-icon-source";
@@ -11908,16 +11999,6 @@ function applyIconMarkup(slot, markup) {
11908
11999
  });
11909
12000
  }
11910
12001
  }
11911
- function detectIconStyle(el) {
11912
- const row = el.closest("[data-ohw-socials-row]");
11913
- const glyphs = Array.from((row ?? el).querySelectorAll("svg"));
11914
- const outlined = glyphs.some((svg) => {
11915
- return Array.from(svg.querySelectorAll("*")).some((node) => {
11916
- return node.getAttribute("stroke") !== null && node.getAttribute("stroke") !== "none";
11917
- });
11918
- });
11919
- return outlined ? "outline" : "fill";
11920
- }
11921
12002
  function iconMarkupInheritingColour(markup) {
11922
12003
  const holder = document.createElement("div");
11923
12004
  holder.innerHTML = markup;
@@ -11940,6 +12021,9 @@ var SOCIAL_KEY_RE = /(^|-)social(s)?(-|$)/i;
11940
12021
  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;
11941
12022
  var SOCIALS_ROW_ATTR = "data-ohw-socials-row";
11942
12023
  var SOCIALS_ITEM_ATTR = "data-ohw-social-item";
12024
+ var SOCIALS_ICONS_ATTR = "data-ohw-socials-icons";
12025
+ var SOCIALS_TEXT_ATTR = "data-ohw-socials-text";
12026
+ var SOCIALS_DISPLAY_STYLE_ID = "ohw-socials-display-style";
11943
12027
  function isSocialItem(el) {
11944
12028
  if (!el) return false;
11945
12029
  const anchor = el instanceof HTMLAnchorElement ? el : el.closest("a");
@@ -12046,9 +12130,11 @@ var SOCIALS_EMPTY_LABEL_ATTR = "data-ohw-empty-label";
12046
12130
  var EMPTY_LABEL_WIDTH = "8ch";
12047
12131
  function markEmptySocialLabels(root = document, skip) {
12048
12132
  root.querySelectorAll(`[${SOCIALS_ROW_ATTR}]`).forEach((row) => {
12133
+ if (row.getAttribute(SOCIALS_TEXT_ATTR) === "off") return;
12049
12134
  listSocialItems(row).forEach((item) => {
12050
12135
  const label = socialLabelElement(item);
12051
12136
  if (!label || label === skip) return;
12137
+ if (label.hasAttribute("data-ohw-hidden")) return;
12052
12138
  const empty = !label.textContent?.trim();
12053
12139
  if (empty === label.hasAttribute(SOCIALS_EMPTY_LABEL_ATTR)) return;
12054
12140
  if (empty) {
@@ -12375,6 +12461,11 @@ function planSocialMove(hrefKey, insertIndex, root = document) {
12375
12461
  }
12376
12462
  var SOCIALS_DISPLAY_KEY = "__ohw_socials_display";
12377
12463
  function readSocialsDisplay(row) {
12464
+ const iconsAttr = row.getAttribute(SOCIALS_ICONS_ATTR);
12465
+ const textAttr = row.getAttribute(SOCIALS_TEXT_ATTR);
12466
+ if ((iconsAttr === "on" || iconsAttr === "off") && (textAttr === "on" || textAttr === "off")) {
12467
+ return { text: textAttr === "on", icon: iconsAttr === "on" };
12468
+ }
12378
12469
  const items = listSocialItems(row);
12379
12470
  const visible = (el) => Boolean(el) && el.style.display !== "none" && el.getAttribute("data-ohw-hidden") === null;
12380
12471
  const drawn = (el) => Boolean(el && visible(el) && el.innerHTML.trim());
@@ -12399,15 +12490,48 @@ function socialsDisplayWith(row, display, content) {
12399
12490
  return { ...parseSocialsDisplay(content[SOCIALS_DISPLAY_KEY]) ?? {}, [rowKeyOf(row)]: display };
12400
12491
  }
12401
12492
  function applySocialsDisplayToRow(row, display) {
12493
+ ensureSocialsDisplayStyles(row.ownerDocument);
12494
+ row.setAttribute(SOCIALS_ICONS_ATTR, display.icon ? "on" : "off");
12495
+ row.setAttribute(SOCIALS_TEXT_ATTR, display.text ? "on" : "off");
12402
12496
  listSocialItems(row).forEach((item) => {
12403
12497
  const label = socialLabelElement(item);
12404
12498
  const icon = item.querySelector(ICON_SELECTOR);
12405
- if (label) label.style.display = display.text ? "" : "none";
12406
- if (icon) icon.style.display = display.icon ? "" : "none";
12499
+ setSocialSlotVisible(label, display.text);
12500
+ setSocialSlotVisible(icon, display.icon);
12407
12501
  layOutIconAndLabel(item, Boolean(display.text));
12408
12502
  });
12409
12503
  allowRowToWrap(row);
12410
12504
  }
12505
+ function setSocialSlotVisible(el, visible) {
12506
+ if (!el) return;
12507
+ if (visible) {
12508
+ el.removeAttribute("data-ohw-hidden");
12509
+ if (el.style.display === "none") el.style.display = "";
12510
+ } else {
12511
+ el.setAttribute("data-ohw-hidden", "");
12512
+ el.style.display = "none";
12513
+ }
12514
+ }
12515
+ function ensureSocialsDisplayStyles(doc) {
12516
+ if (!doc?.head) return;
12517
+ if (doc.getElementById(SOCIALS_DISPLAY_STYLE_ID)) return;
12518
+ const style = doc.createElement("style");
12519
+ style.id = SOCIALS_DISPLAY_STYLE_ID;
12520
+ style.textContent = `
12521
+ [${SOCIALS_ROW_ATTR}][${SOCIALS_ICONS_ATTR}="off"] [data-ohw-editable="icon"],
12522
+ [${SOCIALS_ROW_ATTR}][${SOCIALS_ICONS_ATTR}="off"] [data-ohw-editable="icon"] * {
12523
+ display: none !important;
12524
+ }
12525
+ [${SOCIALS_ROW_ATTR}][${SOCIALS_TEXT_ATTR}="off"] [${SOCIALS_LABEL_ATTR}],
12526
+ [${SOCIALS_ROW_ATTR}][${SOCIALS_TEXT_ATTR}="off"] [data-ohw-href-key] > [data-ohw-editable="text"],
12527
+ [${SOCIALS_ROW_ATTR}][${SOCIALS_TEXT_ATTR}="off"] [data-ohw-href-key] > [data-ohw-editable="plain"],
12528
+ [${SOCIALS_ROW_ATTR}][${SOCIALS_TEXT_ATTR}="off"] [data-ohw-social-item] [data-ohw-editable="text"],
12529
+ [${SOCIALS_ROW_ATTR}][${SOCIALS_TEXT_ATTR}="off"] [data-ohw-social-item] [data-ohw-editable="plain"] {
12530
+ display: none !important;
12531
+ }
12532
+ `;
12533
+ doc.head.appendChild(style);
12534
+ }
12411
12535
  function layOutIconAndLabel(item, on) {
12412
12536
  const hasBoth = Boolean(item.querySelector(ICON_SELECTOR)) && Boolean(socialLabelElement(item));
12413
12537
  if (!hasBoth) {
@@ -12827,15 +12951,6 @@ function setFooterColumnHeadingVisible(column, visible) {
12827
12951
  else column.prepend(heading);
12828
12952
  return { headingKey, text, visible: true };
12829
12953
  }
12830
- function ensureFooterColumnDefaultHeading(column, content) {
12831
- if (isFooterColumnHeadingVisible(column)) return null;
12832
- const headingKey = getFooterColumnHeadingKey(column);
12833
- if (!headingKey) return null;
12834
- if (content && content[headingKey] === "") return null;
12835
- const result = setFooterColumnHeadingVisible(column, true);
12836
- if (!result?.visible) return null;
12837
- return { headingKey: result.headingKey, text: result.text };
12838
- }
12839
12954
  function reconcileFooterHeadingVisibility(content) {
12840
12955
  for (const column of listFooterColumns()) {
12841
12956
  const headingKey = getFooterColumnHeadingKey(column);
@@ -13805,7 +13920,7 @@ import {
13805
13920
  useEffect as useEffect9,
13806
13921
  useLayoutEffect as useLayoutEffect4,
13807
13922
  useRef as useRef7,
13808
- useState as useState9
13923
+ useState as useState10
13809
13924
  } from "react";
13810
13925
  import { X as X5 } from "lucide-react";
13811
13926
  import { jsx as jsx27, jsxs as jsxs17 } from "react/jsx-runtime";
@@ -13855,7 +13970,7 @@ function FloatingPanel({
13855
13970
  bodyClassName
13856
13971
  }) {
13857
13972
  const panelRef = useRef7(null);
13858
- const [measured, setMeasured] = useState9({ w: PANEL_WIDTH, h: 280 });
13973
+ const [measured, setMeasured] = useState10({ w: PANEL_WIDTH, h: 280 });
13859
13974
  const dragRef = useRef7(null);
13860
13975
  const resolved = position ?? defaultFloatingPanelPosition(parentScroll, measured.h);
13861
13976
  const clamped = clampPosition(resolved, parentScroll, measured.w, measured.h);
@@ -14329,7 +14444,7 @@ function hitTestNavDropSlot(clientX, clientY, draggedHrefKey, draggedEl) {
14329
14444
  }
14330
14445
 
14331
14446
  // src/useNavItemDrag.ts
14332
- import { useCallback as useCallback6, useEffect as useEffect10, useRef as useRef8, useState as useState10 } from "react";
14447
+ import { useCallback as useCallback6, useEffect as useEffect10, useRef as useRef8, useState as useState11 } from "react";
14333
14448
  function useNavItemDrag({
14334
14449
  isEditMode,
14335
14450
  editContentRef,
@@ -14354,25 +14469,35 @@ function useNavItemDrag({
14354
14469
  isDragHandleDisabled: isDragHandleDisabled2
14355
14470
  }) {
14356
14471
  const navDragRef = useRef8(null);
14357
- const [navDropSlots, setNavDropSlots] = useState10([]);
14358
- const [activeNavDropIndex, setActiveNavDropIndex] = useState10(null);
14472
+ const [navDropSlots, setNavDropSlots] = useState11([]);
14473
+ const [activeNavDropIndex, setActiveNavDropIndex] = useState11(null);
14359
14474
  const navPointerDragRef = useRef8(null);
14360
14475
  const clearNavDragVisuals = useCallback6(() => {
14361
14476
  const session = navDragRef.current;
14362
- const keepOpenEl = session?.draggedEl?.closest("[data-ohw-nav-children]") != null ? session.draggedEl : null;
14477
+ const nestedHrefKey = session?.draggedEl?.closest("[data-ohw-nav-children]") != null ? session.hrefKey : null;
14363
14478
  navDragRef.current = null;
14364
14479
  setNavDropSlots([]);
14365
14480
  setActiveNavDropIndex(null);
14366
14481
  setDraggedItemRect(null);
14367
14482
  setSiblingHintRects([]);
14368
14483
  setIsItemDragging(false);
14369
- if (keepOpenEl?.isConnected) {
14370
- setNavGroupForceOpen(keepOpenEl, true);
14484
+ if (nestedHrefKey) {
14485
+ const reopen = () => {
14486
+ const desktop = document.querySelector("[data-ohw-nav-container]");
14487
+ const drawer = document.querySelector("[data-ohw-nav-drawer]");
14488
+ const link = desktop?.querySelector(
14489
+ `[data-ohw-href-key="${CSS.escape(nestedHrefKey)}"]`
14490
+ ) ?? drawer?.querySelector(
14491
+ `[data-ohw-href-key="${CSS.escape(nestedHrefKey)}"]`
14492
+ ) ?? document.querySelector(
14493
+ `[data-ohw-href-key="${CSS.escape(nestedHrefKey)}"]`
14494
+ );
14495
+ if (link) setNavGroupForceOpen(link, true);
14496
+ };
14497
+ reopen();
14371
14498
  requestAnimationFrame(() => {
14372
- if (keepOpenEl.isConnected) setNavGroupForceOpen(keepOpenEl, true);
14373
- requestAnimationFrame(() => {
14374
- if (keepOpenEl.isConnected) setNavGroupForceOpen(keepOpenEl, true);
14375
- });
14499
+ reopen();
14500
+ requestAnimationFrame(reopen);
14376
14501
  });
14377
14502
  } else {
14378
14503
  setNavGroupForceOpen(null, false);
@@ -14457,19 +14582,24 @@ function useNavItemDrag({
14457
14582
  const wasSelected = session.wasSelected;
14458
14583
  const hrefKey = session.hrefKey;
14459
14584
  const keepDropdownOpen = Boolean(session.draggedEl.closest("[data-ohw-nav-children]"));
14460
- const applySelectionAfterDrop = () => {
14461
- if (!wasSelected) {
14462
- deselectRef.current();
14463
- return;
14464
- }
14585
+ const findDroppedLink = () => {
14465
14586
  const desktop = document.querySelector("[data-ohw-nav-container]");
14466
14587
  const drawer = document.querySelector("[data-ohw-nav-drawer]");
14467
- 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)}"]`);
14468
- if (link) {
14588
+ 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)}"]`);
14589
+ };
14590
+ const reopenDropdown = () => {
14591
+ if (!keepDropdownOpen) return;
14592
+ const link = findDroppedLink();
14593
+ if (link) setNavGroupForceOpen(link, true);
14594
+ };
14595
+ const applySelectionAfterDrop = () => {
14596
+ const link = findDroppedLink();
14597
+ if (wasSelected && link) {
14469
14598
  selectRef.current(link);
14470
- return;
14599
+ } else {
14600
+ deselectRef.current();
14471
14601
  }
14472
- deselectRef.current();
14602
+ reopenDropdown();
14473
14603
  };
14474
14604
  if (planned) {
14475
14605
  editContentRef.current = {
@@ -14488,27 +14618,31 @@ function useNavItemDrag({
14488
14618
  type: "ow:change",
14489
14619
  nodes: [{ key: NAV_ORDER_KEY, text: planned.orderJson }]
14490
14620
  });
14621
+ reopenDropdown();
14491
14622
  applySelectionAfterDrop();
14492
14623
  clearNavDragVisuals();
14493
- if (keepDropdownOpen) {
14494
- requestAnimationFrame(() => {
14495
- const desktop = document.querySelector("[data-ohw-nav-container]");
14496
- const drawer = document.querySelector("[data-ohw-nav-drawer]");
14497
- 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)}"]`);
14498
- if (link) setNavGroupForceOpen(link, true);
14499
- });
14500
- }
14624
+ reopenDropdown();
14501
14625
  requestAnimationFrame(() => {
14502
14626
  if (editContentRef.current[NAV_ORDER_KEY] === planned.orderJson) {
14503
14627
  applyNavForest(planned.forest);
14504
14628
  }
14629
+ reopenDropdown();
14505
14630
  applySelectionAfterDrop();
14506
- requestAnimationFrame(applySelectionAfterDrop);
14631
+ requestAnimationFrame(() => {
14632
+ reopenDropdown();
14633
+ applySelectionAfterDrop();
14634
+ });
14635
+ window.setTimeout(reopenDropdown, 0);
14636
+ window.setTimeout(reopenDropdown, 50);
14637
+ window.setTimeout(reopenDropdown, 150);
14507
14638
  });
14508
14639
  return;
14509
14640
  }
14510
14641
  applySelectionAfterDrop();
14511
14642
  clearNavDragVisuals();
14643
+ reopenDropdown();
14644
+ window.setTimeout(reopenDropdown, 0);
14645
+ window.setTimeout(reopenDropdown, 50);
14512
14646
  },
14513
14647
  [clearNavDragVisuals, deselectRef, editContentRef, postToParentRef, selectRef]
14514
14648
  );
@@ -14600,7 +14734,7 @@ function useNavItemDrag({
14600
14734
  }
14601
14735
  if (linkPopoverOpenRef.current) setLinkPopover(null);
14602
14736
  const isNestedDrag = Boolean(pending.el.closest("[data-ohw-nav-children]"));
14603
- if (activeElRef.current && !isNestedDrag) deactivateRef.current();
14737
+ if (activeElRef.current) deactivateRef.current();
14604
14738
  const key = pending.el.getAttribute("data-ohw-href-key");
14605
14739
  if (!key) return;
14606
14740
  beginNavDragRef.current({
@@ -14611,9 +14745,7 @@ function useNavItemDrag({
14611
14745
  lastClientY: e.clientY,
14612
14746
  activeSlot: null
14613
14747
  });
14614
- if (activeElRef.current && isNestedDrag) {
14615
- deactivateRef.current();
14616
- }
14748
+ if (isNestedDrag) setNavGroupForceOpen(pending.el, true);
14617
14749
  };
14618
14750
  const endPointerDrag = (e) => {
14619
14751
  const pending = navPointerDragRef.current;
@@ -14704,7 +14836,7 @@ function useNavItemDrag({
14704
14836
  }
14705
14837
 
14706
14838
  // src/useSectionDrag.ts
14707
- import { useCallback as useCallback7, useEffect as useEffect11, useRef as useRef9, useState as useState11 } from "react";
14839
+ import { useCallback as useCallback7, useEffect as useEffect11, useRef as useRef9, useState as useState12 } from "react";
14708
14840
 
14709
14841
  // src/lib/section-dnd.ts
14710
14842
  function isFooterSection(el) {
@@ -14804,9 +14936,9 @@ function useSectionDrag({
14804
14936
  suppressClickUntilRef
14805
14937
  }) {
14806
14938
  const sectionDragRef = useRef9(null);
14807
- const [sectionDropSlots, setSectionDropSlots] = useState11([]);
14808
- const [activeSectionDropIndex, setActiveSectionDropIndex] = useState11(null);
14809
- const [isSectionDragging, setIsSectionDragging] = useState11(false);
14939
+ const [sectionDropSlots, setSectionDropSlots] = useState12([]);
14940
+ const [activeSectionDropIndex, setActiveSectionDropIndex] = useState12(null);
14941
+ const [isSectionDragging, setIsSectionDragging] = useState12(false);
14810
14942
  const sectionPointerDragRef = useRef9(null);
14811
14943
  const autoScrollRafRef = useRef9(null);
14812
14944
  const autoScrollDeltaRef = useRef9(0);
@@ -15086,7 +15218,7 @@ function FooterContainerChrome({
15086
15218
  }
15087
15219
 
15088
15220
  // src/lib/carousel.ts
15089
- import { useEffect as useEffect12, useState as useState12 } from "react";
15221
+ import { useEffect as useEffect12, useState as useState13 } from "react";
15090
15222
  var CAROUSEL_ATTR = "data-ohw-carousel";
15091
15223
  var CAROUSEL_VALUE_ATTR = "data-ohw-carousel-value";
15092
15224
  var CAROUSEL_SLIDE_ATTR = "data-ohw-carousel-slide";
@@ -15148,7 +15280,7 @@ function applyCarouselNode(key, val) {
15148
15280
  return true;
15149
15281
  }
15150
15282
  function useOhwCarousel(key, initial) {
15151
- const [images, setImages] = useState12(initial);
15283
+ const [images, setImages] = useState13(initial);
15152
15284
  useEffect12(() => {
15153
15285
  const el = document.querySelector(
15154
15286
  `[${CAROUSEL_ATTR}][data-ohw-key="${CSS.escape(key)}"]`
@@ -16171,14 +16303,18 @@ function isNavDropdownPanelOpen(childrenRoot) {
16171
16303
  }
16172
16304
  return true;
16173
16305
  }
16174
- function getOpenNavDropdownPanelRect(anchor) {
16306
+ function getOpenNavDropdownPanel(anchor) {
16175
16307
  const group = anchor.closest("[data-ohw-nav-group]");
16176
16308
  if (!group?.hasAttribute("data-ohw-nav-force-open")) return null;
16177
16309
  const panel = group.querySelector(":scope > [data-ohw-nav-children]");
16178
16310
  if (!panel || !isNavDropdownPanelOpen(panel)) return null;
16179
16311
  const panelRect = panel.getBoundingClientRect();
16180
16312
  if (panelRect.height < 2 || panelRect.width < 2) return null;
16181
- return panelRect;
16313
+ return panel;
16314
+ }
16315
+ function getOpenNavDropdownPanelRect(anchor) {
16316
+ const panel = getOpenNavDropdownPanel(anchor);
16317
+ return panel ? panel.getBoundingClientRect() : null;
16182
16318
  }
16183
16319
  function isNavItemPointerTarget(el) {
16184
16320
  const childrenRoot = el.closest("[data-ohw-nav-children]");
@@ -16214,7 +16350,7 @@ function requestSocialDialog(anchor, post, content) {
16214
16350
  hrefKey: item.getAttribute("data-ohw-href-key") ?? "",
16215
16351
  iconKey,
16216
16352
  url: getLinkHref4(item),
16217
- iconStyle: detectIconStyle(item),
16353
+ iconStyle: "outline",
16218
16354
  // What was chosen last time. Guessing from the address instead reads as "Website" for anything
16219
16355
  // unrecognised, and for an item with no address at all — so a deliberate choice looked lost.
16220
16356
  platformId: content[socialPlatformKey(iconKey)] ?? ""
@@ -16717,6 +16853,10 @@ function getIframeVisibleClip(parentScroll) {
16717
16853
  );
16718
16854
  return { top: clipTop, bottom: Math.max(clipTop, clipBottom) };
16719
16855
  }
16856
+ function isRectOutsideClip(rect, clip) {
16857
+ if (!clip) return false;
16858
+ return rect.bottom < clip.top || rect.top > clip.bottom;
16859
+ }
16720
16860
  function applyVisibleViewport(el, parentScroll) {
16721
16861
  const clip = getIframeVisibleClip(parentScroll);
16722
16862
  const top = clip?.top ?? 0;
@@ -17144,7 +17284,7 @@ function OhhwellsBridge() {
17144
17284
  const router = useRouter3();
17145
17285
  const searchParams = useSearchParams();
17146
17286
  const isEditMode = isEditSessionActive();
17147
- const [bridgeRoot, setBridgeRoot] = useState13(null);
17287
+ const [bridgeRoot, setBridgeRoot] = useState14(null);
17148
17288
  useEffect13(() => {
17149
17289
  const figtreeFontId = "ohw-figtree-font";
17150
17290
  if (!document.getElementById(figtreeFontId)) {
@@ -17179,8 +17319,8 @@ function OhhwellsBridge() {
17179
17319
  window.parent.postMessage(data, "*");
17180
17320
  }
17181
17321
  }, []);
17182
- const [fetchState, setFetchState] = useState13("idle");
17183
- const [showBranding, setShowBranding] = useState13(false);
17322
+ const [fetchState, setFetchState] = useState14("idle");
17323
+ const [showBranding, setShowBranding] = useState14(false);
17184
17324
  const autoSaveTimers = useRef10(/* @__PURE__ */ new Map());
17185
17325
  const activeElRef = useRef10(null);
17186
17326
  const pointerHeldRef = useRef10(false);
@@ -17191,7 +17331,7 @@ function OhhwellsBridge() {
17191
17331
  const activeStateElRef = useRef10(null);
17192
17332
  const parentScrollRef = useRef10(null);
17193
17333
  const visibleViewportRef = useRef10(null);
17194
- const [dialogPortalContainer, setDialogPortalContainer] = useState13(null);
17334
+ const [dialogPortalContainer, setDialogPortalContainer] = useState14(null);
17195
17335
  const attachVisibleViewport = useCallback8((node) => {
17196
17336
  visibleViewportRef.current = node;
17197
17337
  setDialogPortalContainer(node);
@@ -17202,8 +17342,8 @@ function OhhwellsBridge() {
17202
17342
  const hoveredImageRef = useRef10(null);
17203
17343
  const hoveredImageHasTextOverlapRef = useRef10(false);
17204
17344
  const dragOverElRef = useRef10(null);
17205
- const [mediaHover, setMediaHover] = useState13(null);
17206
- const [selectedMedia, setSelectedMedia] = useState13(null);
17345
+ const [mediaHover, setMediaHover] = useState14(null);
17346
+ const [selectedMedia, setSelectedMedia] = useState14(null);
17207
17347
  const selectedMediaElRef = useRef10(null);
17208
17348
  const clearMediaSelection = useCallback8(() => {
17209
17349
  const prev = selectedMediaElRef.current;
@@ -17267,8 +17407,8 @@ function OhhwellsBridge() {
17267
17407
  window.removeEventListener("resize", update);
17268
17408
  };
17269
17409
  }, [selectedMedia !== null]);
17270
- const [carouselHover, setCarouselHover] = useState13(null);
17271
- const [uploadingRects, setUploadingRects] = useState13({});
17410
+ const [carouselHover, setCarouselHover] = useState14(null);
17411
+ const [uploadingRects, setUploadingRects] = useState14({});
17272
17412
  const hoveredGapRef = useRef10(null);
17273
17413
  const imageUnhoverTimerRef = useRef10(null);
17274
17414
  const imageShowTimerRef = useRef10(null);
@@ -17303,17 +17443,17 @@ function OhhwellsBridge() {
17303
17443
  const aiSectionApiRef = useRef10(null);
17304
17444
  const sectionsLoadedRef = useRef10(false);
17305
17445
  const pendingScheduleConfigRequests = useRef10([]);
17306
- const [toolbarRect, setToolbarRect] = useState13(null);
17307
- const [formPickRect, setFormPickRect] = useState13(null);
17446
+ const [toolbarRect, setToolbarRect] = useState14(null);
17447
+ const [formPickRect, setFormPickRect] = useState14(null);
17308
17448
  const formPickElRef = useRef10(null);
17309
- const [formViewState, setFormViewStateUi] = useState13("default");
17310
- const [formPickCount, setFormPickCount] = useState13(null);
17311
- const [formHoverRect, setFormHoverRect] = useState13(null);
17449
+ const [formViewState, setFormViewStateUi] = useState14("default");
17450
+ const [formPickCount, setFormPickCount] = useState14(null);
17451
+ const [formHoverRect, setFormHoverRect] = useState14(null);
17312
17452
  const formHoverElRef = useRef10(null);
17313
- const [fieldPickRect, setFieldPickRect] = useState13(null);
17453
+ const [fieldPickRect, setFieldPickRect] = useState14(null);
17314
17454
  const fieldPickElRef = useRef10(null);
17315
- const [fieldPickState, setFieldPickState] = useState13(null);
17316
- const [fieldTypePickerOpen, setFieldTypePickerOpen] = useState13(false);
17455
+ const [fieldPickState, setFieldPickState] = useState14(null);
17456
+ const [fieldTypePickerOpen, setFieldTypePickerOpen] = useState14(false);
17317
17457
  const clearFormPick = useCallback8(() => {
17318
17458
  const form = formPickElRef.current;
17319
17459
  const editing = fieldPickElRef.current;
@@ -17457,9 +17597,9 @@ function OhhwellsBridge() {
17457
17597
  setFieldDropSlots([]);
17458
17598
  setFieldDragging(false);
17459
17599
  }, []);
17460
- const [fieldDropIndex, setFieldDropIndex] = useState13(null);
17461
- const [fieldDropSlots, setFieldDropSlots] = useState13([]);
17462
- const [fieldDragging, setFieldDragging] = useState13(false);
17600
+ const [fieldDropIndex, setFieldDropIndex] = useState14(null);
17601
+ const [fieldDropSlots, setFieldDropSlots] = useState14([]);
17602
+ const [fieldDragging, setFieldDragging] = useState14(false);
17463
17603
  const clearFormPickRef = useRef10(clearFormPick);
17464
17604
  clearFormPickRef.current = clearFormPick;
17465
17605
  useEffect13(() => {
@@ -17480,24 +17620,24 @@ function OhhwellsBridge() {
17480
17620
  observer.observe(el);
17481
17621
  return () => observer.disconnect();
17482
17622
  }, [formPickRect !== null, formViewState]);
17483
- const [toolbarVariant, setToolbarVariant] = useState13("none");
17623
+ const [toolbarVariant, setToolbarVariant] = useState14("none");
17484
17624
  const toolbarVariantRef = useRef10("none");
17485
17625
  toolbarVariantRef.current = toolbarVariant;
17486
- const [selectedIsCta, setSelectedIsCta] = useState13(false);
17487
- const [selectedIsSocial, setSelectedIsSocial] = useState13(false);
17488
- const [selectedIsSocialsRow, setSelectedIsSocialsRow] = useState13(false);
17489
- const [reorderHrefKey, setReorderHrefKey] = useState13(null);
17490
- const [reorderDragDisabled, setReorderDragDisabled] = useState13(false);
17491
- const [toggleState, setToggleState] = useState13(null);
17492
- const [maxBadge, setMaxBadge] = useState13(null);
17493
- const [activeCommands, setActiveCommands] = useState13(/* @__PURE__ */ new Set());
17494
- const [sectionGap, setSectionGap] = useState13(null);
17495
- const [toolbarShowEditLink, setToolbarShowEditLink] = useState13(false);
17626
+ const [selectedIsCta, setSelectedIsCta] = useState14(false);
17627
+ const [selectedIsSocial, setSelectedIsSocial] = useState14(false);
17628
+ const [selectedIsSocialsRow, setSelectedIsSocialsRow] = useState14(false);
17629
+ const [reorderHrefKey, setReorderHrefKey] = useState14(null);
17630
+ const [reorderDragDisabled, setReorderDragDisabled] = useState14(false);
17631
+ const [toggleState, setToggleState] = useState14(null);
17632
+ const [maxBadge, setMaxBadge] = useState14(null);
17633
+ const [activeCommands, setActiveCommands] = useState14(/* @__PURE__ */ new Set());
17634
+ const [sectionGap, setSectionGap] = useState14(null);
17635
+ const [toolbarShowEditLink, setToolbarShowEditLink] = useState14(false);
17496
17636
  const hoveredNavContainerRef = useRef10(null);
17497
- const [hoveredNavContainerRect, setHoveredNavContainerRect] = useState13(null);
17637
+ const [hoveredNavContainerRect, setHoveredNavContainerRect] = useState14(null);
17498
17638
  const hoveredItemElRef = useRef10(null);
17499
- const [hoveredItemRect, setHoveredItemRect] = useState13(null);
17500
- const [hoveredTextRect, setHoveredTextRect] = useState13(null);
17639
+ const [hoveredItemRect, setHoveredItemRect] = useState14(null);
17640
+ const [hoveredTextRect, setHoveredTextRect] = useState14(null);
17501
17641
  useEffect13(() => {
17502
17642
  const sync = () => {
17503
17643
  const el = document.querySelector(
@@ -17543,28 +17683,28 @@ function OhhwellsBridge() {
17543
17683
  return () => observer.disconnect();
17544
17684
  }, []);
17545
17685
  const siblingHintElRef = useRef10(null);
17546
- const [siblingHintRect, setSiblingHintRect] = useState13(null);
17547
- const [siblingHintRects, setSiblingHintRects] = useState13([]);
17548
- const [isItemDragging, setIsItemDragging] = useState13(false);
17549
- const [isFooterFrameSelection, setIsFooterFrameSelection] = useState13(false);
17686
+ const [siblingHintRect, setSiblingHintRect] = useState14(null);
17687
+ const [siblingHintRects, setSiblingHintRects] = useState14([]);
17688
+ const [isItemDragging, setIsItemDragging] = useState14(false);
17689
+ const [isFooterFrameSelection, setIsFooterFrameSelection] = useState14(false);
17550
17690
  isFooterFrameSelectionRef.current = isFooterFrameSelection;
17551
- const [floatingPanel, setFloatingPanel] = useState13(null);
17691
+ const [floatingPanel, setFloatingPanel] = useState14(null);
17552
17692
  const floatingPanelOpenRef = useRef10(false);
17553
17693
  floatingPanelOpenRef.current = floatingPanel !== null;
17554
- const [floatingPanelPos, setFloatingPanelPos] = useState13(null);
17555
- const [logoSizeDraft, setLogoSizeDraft] = useState13(null);
17556
- const [editorViewport, setEditorViewport] = useState13("desktop");
17557
- const [parentScrollSnap, setParentScrollSnap] = useState13(null);
17558
- const [navDropdownPreviewOpen, setNavDropdownPreviewOpen] = useState13(null);
17559
- const [footerHeadingVisible, setFooterHeadingVisible] = useState13(null);
17694
+ const [floatingPanelPos, setFloatingPanelPos] = useState14(null);
17695
+ const [logoSizeDraft, setLogoSizeDraft] = useState14(null);
17696
+ const [editorViewport, setEditorViewport] = useState14("desktop");
17697
+ const [parentScrollSnap, setParentScrollSnap] = useState14(null);
17698
+ const [navDropdownPreviewOpen, setNavDropdownPreviewOpen] = useState14(null);
17699
+ const [footerHeadingVisible, setFooterHeadingVisible] = useState14(null);
17560
17700
  const footerDragRef = useRef10(null);
17561
- const [footerDropSlots, setFooterDropSlots] = useState13([]);
17562
- const [activeFooterDropIndex, setActiveFooterDropIndex] = useState13(null);
17563
- const [draggedItemRect, setDraggedItemRect] = useState13(null);
17701
+ const [footerDropSlots, setFooterDropSlots] = useState14([]);
17702
+ const [activeFooterDropIndex, setActiveFooterDropIndex] = useState14(null);
17703
+ const [draggedItemRect, setDraggedItemRect] = useState14(null);
17564
17704
  const footerPointerDragRef = useRef10(null);
17565
17705
  const suppressNextClickRef = useRef10(false);
17566
17706
  const suppressClickUntilRef = useRef10(0);
17567
- const [linkPopover, setLinkPopover] = useState13(null);
17707
+ const [linkPopover, setLinkPopover] = useState14(null);
17568
17708
  const linkPopoverSessionRef = useRef10(null);
17569
17709
  const addNavAfterAnchorRef = useRef10(null);
17570
17710
  const editContentRef = useRef10({});
@@ -17572,8 +17712,8 @@ function OhhwellsBridge() {
17572
17712
  const brandKitRef = useRef10("");
17573
17713
  const stylesRef = useRef10("");
17574
17714
  const pendingDeleteUndoRef = useRef10(null);
17575
- const [sitePages, setSitePages] = useState13([]);
17576
- const [sectionsByPath, setSectionsByPath] = useState13({});
17715
+ const [sitePages, setSitePages] = useState14([]);
17716
+ const [sectionsByPath, setSectionsByPath] = useState14({});
17577
17717
  const sectionsPrefetchGenRef = useRef10(0);
17578
17718
  const setLinkPopoverRef = useRef10(setLinkPopover);
17579
17719
  const linkPopoverPanelRef = useRef10(null);
@@ -17786,11 +17926,16 @@ function OhhwellsBridge() {
17786
17926
  if (owner) persistFieldsRef.current(owner);
17787
17927
  }
17788
17928
  activeElRef.current = null;
17789
- const preserveNavDropdown = Boolean(navPointerDragRef.current?.el?.closest("[data-ohw-nav-children]")) || Boolean(navDragRef.current?.draggedEl?.closest("[data-ohw-nav-children]")) || Boolean(
17929
+ 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(
17790
17930
  selectedElRef.current?.closest("[data-ohw-nav-children]") && selectedElRef.current?.closest("[data-ohw-nav-group]")?.hasAttribute("data-ohw-nav-force-open")
17791
17931
  );
17792
17932
  if (!preserveNavDropdown) {
17793
17933
  setNavGroupForceOpen(null, false);
17934
+ } else {
17935
+ const keepAnchor = selectedElRef.current?.closest("[data-ohw-nav-children]") != null ? selectedElRef.current : el.closest("[data-ohw-href-key]") ?? el;
17936
+ if (keepAnchor.closest("[data-ohw-nav-children]")) {
17937
+ setNavGroupForceOpen(keepAnchor, true);
17938
+ }
17794
17939
  }
17795
17940
  setReorderHrefKey(null);
17796
17941
  setReorderDragDisabled(false);
@@ -17809,6 +17954,7 @@ function OhhwellsBridge() {
17809
17954
  });
17810
17955
  }, []);
17811
17956
  const deselect = useCallback8(() => {
17957
+ const nestedGroup = selectedElRef.current?.closest("[data-ohw-nav-children]") != null ? selectedElRef.current.closest("[data-ohw-nav-group]") : null;
17812
17958
  clearSelectedAttr();
17813
17959
  selectedElRef.current = null;
17814
17960
  selectedHrefKeyRef.current = null;
@@ -17832,7 +17978,11 @@ function OhhwellsBridge() {
17832
17978
  setFloatingPanel(null);
17833
17979
  setLogoSizeDraft(null);
17834
17980
  if (!activeElRef.current) {
17835
- setNavGroupForceOpen(null, false);
17981
+ if (nestedGroup?.isConnected) {
17982
+ nestedGroup.setAttribute("data-ohw-nav-force-open", "");
17983
+ } else {
17984
+ setNavGroupForceOpen(null, false);
17985
+ }
17836
17986
  setToolbarRect(null);
17837
17987
  setToolbarVariant("none");
17838
17988
  }
@@ -17913,10 +18063,7 @@ function OhhwellsBridge() {
17913
18063
  setSelectedIsSocialsRow(false);
17914
18064
  const isDropdownTrigger = !isNestedNavChild(navAnchor) && (navItemHasDropdownChildren(navAnchor) || navItemOwnsDropdownPanel(navAnchor));
17915
18065
  if (isNestedNavChild(navAnchor)) {
17916
- const group = navAnchor.closest("[data-ohw-nav-group]");
17917
- if (group?.hasAttribute("data-ohw-nav-force-open")) {
17918
- setNavGroupForceOpen(navAnchor, true);
17919
- }
18066
+ setNavGroupForceOpen(navAnchor, true);
17920
18067
  setNavDropdownPreviewOpen(null);
17921
18068
  } else if (isDropdownTrigger) {
17922
18069
  const group = navAnchor.closest("[data-ohw-nav-group]");
@@ -18068,7 +18215,7 @@ function OhhwellsBridge() {
18068
18215
  hrefKey: planned.hrefKey,
18069
18216
  iconKey: planned.iconKey,
18070
18217
  url: "",
18071
- iconStyle: detectIconStyle(getSocialItem(selected) ?? socialsRow),
18218
+ iconStyle: "outline",
18072
18219
  platformId: "",
18073
18220
  // Tells the editor this one is not on the page yet, so dismissing means "never mind".
18074
18221
  isNew: true
@@ -18150,8 +18297,10 @@ function OhhwellsBridge() {
18150
18297
  setNavDropdownPreviewOpen(true);
18151
18298
  setToolbarRect(selected.getBoundingClientRect());
18152
18299
  requestAnimationFrame(() => {
18153
- if (selected.isConnected) setToolbarRect(selected.getBoundingClientRect());
18154
- enterEditOnNewItem(result.anchor);
18300
+ requestAnimationFrame(() => {
18301
+ if (selected.isConnected) setToolbarRect(selected.getBoundingClientRect());
18302
+ enterEditOnNewItem(result.anchor);
18303
+ });
18155
18304
  });
18156
18305
  }, [enterEditOnNewItem, isFooterFrameSelection, maybeWarnNavLinkDropdownConflict, postToParent2]);
18157
18306
  const handleAddFooterColumn = useCallback8(() => {
@@ -18531,10 +18680,7 @@ function OhhwellsBridge() {
18531
18680
  clearHrefKeyHover(anchor);
18532
18681
  const isDropdownTrigger = !isNestedNavChild(anchor) && (navItemHasDropdownChildren(anchor) || navItemOwnsDropdownPanel(anchor));
18533
18682
  if (isNestedNavChild(anchor)) {
18534
- const group = anchor.closest("[data-ohw-nav-group]");
18535
- if (group?.hasAttribute("data-ohw-nav-force-open")) {
18536
- setNavGroupForceOpen(anchor, true);
18537
- }
18683
+ setNavGroupForceOpen(anchor, true);
18538
18684
  setNavDropdownPreviewOpen(null);
18539
18685
  } else if (isDropdownTrigger) {
18540
18686
  setNavGroupForceOpen(null, false);
@@ -18592,17 +18738,6 @@ function OhhwellsBridge() {
18592
18738
  setIsFooterFrameSelection(isFooterColumn);
18593
18739
  setNavDropdownPreviewOpen(null);
18594
18740
  if (isFooterColumn) {
18595
- const ensured = ensureFooterColumnDefaultHeading(el, editContentRef.current);
18596
- if (ensured) {
18597
- editContentRef.current = {
18598
- ...editContentRef.current,
18599
- [ensured.headingKey]: ensured.text
18600
- };
18601
- postToParent2({
18602
- type: "ow:change",
18603
- nodes: [{ key: ensured.headingKey, text: ensured.text }]
18604
- });
18605
- }
18606
18741
  setFooterHeadingVisible(isFooterColumnHeadingVisible(el));
18607
18742
  } else {
18608
18743
  setFooterHeadingVisible(null);
@@ -19446,8 +19581,10 @@ function OhhwellsBridge() {
19446
19581
  /* The glyph too, and this one mattered most: as a block it filled the whole width of its
19447
19582
  link and sat over the words, so every click meant for the text landed on the icon. */
19448
19583
  [data-ohw-socials-row] [data-ohw-editable="icon"] {
19449
- display: inline-flex;
19450
- flex: 0 0 auto;
19584
+ display: inline-flex !important;
19585
+ flex: 0 0 auto !important;
19586
+ width: auto !important;
19587
+ max-width: max-content !important;
19451
19588
  align-items: center;
19452
19589
  }
19453
19590
  [data-ohw-socials-row] a {
@@ -19526,9 +19663,24 @@ function OhhwellsBridge() {
19526
19663
  /* Somewhere to click the block itself, on every side (OHH-642) \u2014 editor only. */
19527
19664
  [data-ohw-editable="form"] {
19528
19665
  padding: 18px !important;
19666
+ /* Horizontal newsletter rows collapse added fields into pill-circles without wrap. */
19667
+ flex-wrap: wrap !important;
19668
+ align-items: flex-end !important;
19529
19669
  }
19670
+ [data-ohw-editable="form"] [data-ohw-form-field] {
19671
+ flex: 1 1 12rem !important;
19672
+ min-width: min(12rem, 100%) !important;
19673
+ max-width: 100% !important;
19674
+ }
19675
+ /* Placeholder text lives in the value while selected. currentColor inside color-mix
19676
+ resolves to the *inherited* color, so reverse-print footers washed it out on white
19677
+ inputs \u2014 pin to the control's own color captured in beginPlaceholderEdit. */
19530
19678
  [data-ohw-placeholder-edit] {
19531
- color: color-mix(in srgb, currentColor 55%, transparent) !important;
19679
+ color: color-mix(
19680
+ in srgb,
19681
+ var(--ohw-placeholder-edit-color, CanvasText) 55%,
19682
+ transparent
19683
+ ) !important;
19532
19684
  cursor: text !important;
19533
19685
  }
19534
19686
  /* Text hover chrome is drawn by the overlay (see hoveredTextRect) \u2014 the CSS outline
@@ -20804,6 +20956,7 @@ function OhhwellsBridge() {
20804
20956
  setHoveredItemRect(null);
20805
20957
  hoveredNavContainerRef.current = null;
20806
20958
  setHoveredNavContainerRect(null);
20959
+ dismissImageHover();
20807
20960
  return;
20808
20961
  }
20809
20962
  if (probeSocialsRowAt(clientX, clientY)) return;
@@ -22052,14 +22205,20 @@ function OhhwellsBridge() {
22052
22205
  };
22053
22206
  const applyToolbarPos = (rect) => {
22054
22207
  const ps = parentScrollRef.current;
22208
+ const hidden = isRectOutsideClip(rect, getIframeVisibleClip(ps));
22055
22209
  const measuredW = toolbarElRef.current?.offsetWidth || 330;
22056
22210
  if (toolbarElRef.current) {
22057
- const { top, left, transform } = calcToolbarPos(rect, ps, measuredW);
22058
- toolbarElRef.current.style.top = `${top}px`;
22059
- toolbarElRef.current.style.left = `${left}px`;
22060
- toolbarElRef.current.style.transform = transform;
22211
+ toolbarElRef.current.style.display = hidden ? "none" : "";
22212
+ if (!hidden) {
22213
+ const { top, left, transform } = calcToolbarPos(rect, ps, measuredW);
22214
+ toolbarElRef.current.style.top = `${top}px`;
22215
+ toolbarElRef.current.style.left = `${left}px`;
22216
+ toolbarElRef.current.style.transform = transform;
22217
+ }
22061
22218
  }
22062
22219
  if (glowElRef.current) {
22220
+ glowElRef.current.style.display = hidden ? "none" : "";
22221
+ if (hidden) return;
22063
22222
  const GAP = SELECTION_CHROME_GAP2;
22064
22223
  glowElRef.current.style.top = `${rect.top - GAP}px`;
22065
22224
  glowElRef.current.style.left = `${rect.left - GAP}px`;
@@ -22501,7 +22660,7 @@ function OhhwellsBridge() {
22501
22660
  postToParent2({
22502
22661
  type: "ow:ready",
22503
22662
  version: "1",
22504
- bridgeVersion: "0.1.107",
22663
+ bridgeVersion: "0.1.109",
22505
22664
  path: pathname,
22506
22665
  nodes: collectEditableNodes(editContentRef.current),
22507
22666
  sections
@@ -22965,7 +23124,7 @@ function OhhwellsBridge() {
22965
23124
  /* @__PURE__ */ jsx33("div", { id: "ohw-loader", suppressHydrationWarning: true, style: { ...OHW_LOADER_STYLE, display: "none" }, children: /* @__PURE__ */ jsx33(OhwLoaderSpinner, {}) }),
22966
23125
  /* @__PURE__ */ jsx33("script", { suppressHydrationWarning: true, dangerouslySetInnerHTML: { __html: OHW_LOADER_PREHYDRATE_SCRIPT } }),
22967
23126
  subdomain && !isEditMode && showBranding && /* @__PURE__ */ jsx33(MadeWithOhhWells, {}),
22968
- bridgeRoot ? createPortal2(
23127
+ bridgeRoot ? createPortal3(
22969
23128
  /* @__PURE__ */ jsxs20(Fragment8, { children: [
22970
23129
  /* @__PURE__ */ jsx33("div", { ref: attachVisibleViewport, "data-ohw-visible-viewport": "", "aria-hidden": true }),
22971
23130
  isEditMode && /* @__PURE__ */ jsx33(AiSectionOverlay, { postToParent: postToParent2, apiRef: aiSectionApiRef }),
@@ -23234,8 +23393,9 @@ function OhhwellsBridge() {
23234
23393
  {
23235
23394
  rect: isItemDragging && draggedItemRect && (footerDragRef.current?.wasSelected || navDragRef.current?.wasSelected) ? draggedItemRect : toolbarRect,
23236
23395
  toolbarBelowRect: selectedElRef.current && isNavigationItem2(selectedElRef.current) ? getOpenNavDropdownPanelRect(selectedElRef.current) : null,
23396
+ toolbarBelowEl: selectedElRef.current && isNavigationItem2(selectedElRef.current) ? getOpenNavDropdownPanel(selectedElRef.current) : null,
23237
23397
  elRef: glowElRef,
23238
- state: isItemDragging ? "dragging" : selectedElRef.current && isNavigationItem2(selectedElRef.current) && getOpenNavDropdownPanelRect(selectedElRef.current) ? "active-bottom" : resolveItemInteractionState(toolbarRect, parentScrollRef.current),
23398
+ state: isItemDragging ? "dragging" : selectedElRef.current && isNavigationItem2(selectedElRef.current) && getOpenNavDropdownPanel(selectedElRef.current) ? "active-bottom" : resolveItemInteractionState(toolbarRect, parentScrollRef.current),
23239
23399
  showHandle: toolbarVariant === "link-action" && Boolean(reorderHrefKey) || toolbarVariant === "select-frame" && isFooterFrameSelection,
23240
23400
  dragDisabled: reorderDragDisabled,
23241
23401
  dragHandleLabel: reorderHrefKey ? `Reorder ${reorderHrefKey}` : "Reorder item",
@@ -23288,7 +23448,7 @@ function OhhwellsBridge() {
23288
23448
  ) : void 0
23289
23449
  }
23290
23450
  ),
23291
- toolbarRect && toolbarVariant === "rich-text" && !linkPopover && /* @__PURE__ */ jsxs20(Fragment8, { children: [
23451
+ toolbarRect && toolbarVariant === "rich-text" && !linkPopover && !isRectOutsideClip(toolbarRect, getIframeVisibleClip(parentScrollRef.current)) && /* @__PURE__ */ jsxs20(Fragment8, { children: [
23292
23452
  /* @__PURE__ */ jsx33(
23293
23453
  EditGlowChrome,
23294
23454
  {