@ohhwells/bridge 0.1.114-next.309 → 0.1.114-next.310

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
@@ -11117,6 +11117,17 @@ import { useCallback as useCallback4, useEffect as useEffect7, useMemo as useMem
11117
11117
  import { createPortal as createPortal2 } from "react-dom";
11118
11118
  import { ArrowLeft as ArrowLeft2, Check as Check2 } from "lucide-react";
11119
11119
  import { usePathname, useRouter as useRouter2 } from "next/navigation";
11120
+
11121
+ // src/lib/parent-scroll.ts
11122
+ function getIframeVisibleClip(parentScroll) {
11123
+ if (!parentScroll) return null;
11124
+ const { iframeOffsetTop, headerH: visibleCanvasTop, canvasH, promptBarH = 0 } = parentScroll;
11125
+ const clipTop = Math.max(0, visibleCanvasTop - iframeOffsetTop);
11126
+ const clipBottom = Math.min(window.innerHeight, visibleCanvasTop + canvasH - iframeOffsetTop) - promptBarH;
11127
+ return { top: clipTop, bottom: Math.max(clipTop, clipBottom) };
11128
+ }
11129
+
11130
+ // src/ui/link-modal/SectionPickerOverlay.tsx
11120
11131
  import { jsx as jsx26, jsxs as jsxs16 } from "react/jsx-runtime";
11121
11132
  var DIM_OVERLAY = "rgba(0, 0, 0, 0.45)";
11122
11133
  function rectsEqual(a, b) {
@@ -11254,20 +11265,22 @@ function SectionPickerOverlay({
11254
11265
  []
11255
11266
  );
11256
11267
  useEffect7(() => {
11257
- const applyClip = (iframeOffsetTop, visibleCanvasTop, canvasH) => {
11258
- const top = Math.max(0, visibleCanvasTop - iframeOffsetTop);
11259
- const bottom = Math.min(
11260
- window.innerHeight,
11261
- visibleCanvasTop + canvasH - iframeOffsetTop
11262
- );
11268
+ const applyClip = (iframeOffsetTop, visibleCanvasTop, canvasH, promptBarH = 0) => {
11269
+ const next = getIframeVisibleClip({
11270
+ iframeOffsetTop,
11271
+ headerH: visibleCanvasTop,
11272
+ canvasH,
11273
+ promptBarH
11274
+ });
11275
+ if (!next) return;
11263
11276
  setChromeClip(
11264
- (prev) => prev.top === top && prev.bottom === bottom ? prev : { top, bottom: Math.max(top, bottom) }
11277
+ (prev) => prev.top === next.top && prev.bottom === next.bottom ? prev : next
11265
11278
  );
11266
11279
  };
11267
11280
  const onParentScroll = (e) => {
11268
11281
  if (e.data?.type !== "ow:parent-scroll") return;
11269
- const { iframeOffsetTop, headerH, canvasH } = e.data;
11270
- applyClip(iframeOffsetTop, headerH, canvasH);
11282
+ const { iframeOffsetTop, headerH, canvasH, promptBarH = 0 } = e.data;
11283
+ applyClip(iframeOffsetTop, headerH, canvasH, promptBarH);
11271
11284
  iframeOffsetTopRef.current = iframeOffsetTop;
11272
11285
  if (!pointerScreenRef.current && pointerRef.current) {
11273
11286
  pointerScreenRef.current = {
@@ -14941,13 +14954,11 @@ var EDGE_MARGIN = 16;
14941
14954
  function getVisibleClip(parentScroll) {
14942
14955
  const left = 0;
14943
14956
  const right = window.innerWidth;
14944
- if (!parentScroll) {
14957
+ const band = getIframeVisibleClip(parentScroll);
14958
+ if (!band) {
14945
14959
  return { top: 0, bottom: window.innerHeight, left, right };
14946
14960
  }
14947
- const { iframeOffsetTop, headerH: visibleCanvasTop, canvasH } = parentScroll;
14948
- const top = Math.max(0, visibleCanvasTop - iframeOffsetTop);
14949
- const bottom = Math.min(window.innerHeight, visibleCanvasTop + canvasH - iframeOffsetTop);
14950
- return { top, bottom: Math.max(top, bottom), left, right };
14961
+ return { ...band, left, right };
14951
14962
  }
14952
14963
  function defaultFloatingPanelPosition(parentScroll, panelHeight = 280) {
14953
14964
  const clip = getVisibleClip(parentScroll);
@@ -15823,7 +15834,10 @@ function assignmentFor(el, content, tokens) {
15823
15834
  function labelElement(el) {
15824
15835
  return el.querySelector('[data-ohw-editable="text"], [data-ohw-editable="plain"]') ?? (el.matches('[data-ohw-editable="text"], [data-ohw-editable="plain"]') ? el : null);
15825
15836
  }
15826
- function applyButtonStyle(el, assignment, tokens) {
15837
+ var paintLockByEl = /* @__PURE__ */ new WeakMap();
15838
+ var paintObserverByEl = /* @__PURE__ */ new WeakMap();
15839
+ var paintingButton = false;
15840
+ function paintButtonChrome(el, assignment, tokens) {
15827
15841
  const origin = captureButtonOrigin(el);
15828
15842
  const chrome = tokens.variants[assignment.variant];
15829
15843
  const originSlot = classifyHeight(origin.size.height);
@@ -15831,6 +15845,7 @@ function applyButtonStyle(el, assignment, tokens) {
15831
15845
  const { typography } = origin;
15832
15846
  el.setAttribute("data-ohw-btn-variant", assignment.variant);
15833
15847
  el.setAttribute("data-ohw-btn-size", assignment.size);
15848
+ el.style.transition = "none";
15834
15849
  el.style.boxSizing = "border-box";
15835
15850
  el.style.display = "inline-flex";
15836
15851
  el.style.alignItems = "center";
@@ -15857,6 +15872,26 @@ function applyButtonStyle(el, assignment, tokens) {
15857
15872
  const label = labelElement(el);
15858
15873
  if (label && label !== el) label.style.color = chrome.color;
15859
15874
  }
15875
+ function guardTemplateHover(el) {
15876
+ if (paintObserverByEl.has(el)) return;
15877
+ const observer = new MutationObserver(() => {
15878
+ if (paintingButton) return;
15879
+ const lock = paintLockByEl.get(el);
15880
+ if (!lock) return;
15881
+ paintingButton = true;
15882
+ paintButtonChrome(el, lock.assignment, lock.tokens);
15883
+ paintingButton = false;
15884
+ });
15885
+ observer.observe(el, { attributes: true, attributeFilter: ["style", "class"] });
15886
+ paintObserverByEl.set(el, observer);
15887
+ }
15888
+ function applyButtonStyle(el, assignment, tokens) {
15889
+ paintLockByEl.set(el, { assignment, tokens });
15890
+ paintingButton = true;
15891
+ paintButtonChrome(el, assignment, tokens);
15892
+ paintingButton = false;
15893
+ guardTemplateHover(el);
15894
+ }
15860
15895
  function applyButtonStylesFromContent(doc, content) {
15861
15896
  const assignments = readAssignments(content);
15862
15897
  for (const [id, assignment] of Object.entries(assignments)) {
@@ -16046,6 +16081,9 @@ function isLastNavbarButton(el) {
16046
16081
  function canDeleteButton(el) {
16047
16082
  return !isLastNavbarButton(el);
16048
16083
  }
16084
+ function canDuplicateButton(el) {
16085
+ return isNavbarCta(el);
16086
+ }
16049
16087
  function labelElement2(el) {
16050
16088
  return el.querySelector('[data-ohw-editable="text"], [data-ohw-editable="plain"]') ?? el.querySelector("[data-ohw-key]");
16051
16089
  }
@@ -16100,12 +16138,27 @@ function nextCollectionId(content, doc) {
16100
16138
  while (used.has(`bc-${n}`)) n += 1;
16101
16139
  return `bc-${n}`;
16102
16140
  }
16141
+ var COLLECTION_GAP_MAX_PX = 12;
16142
+ var COLLECTION_GAP_DEFAULT = "12px";
16143
+ function usableGap(value) {
16144
+ if (!value || value === "normal") return null;
16145
+ const n = parseFloat(value);
16146
+ if (!Number.isFinite(n) || n <= 0) return null;
16147
+ if (n > COLLECTION_GAP_MAX_PX) return COLLECTION_GAP_DEFAULT;
16148
+ return `${Math.round(n * 100) / 100}px`;
16149
+ }
16103
16150
  function collectionGap(el, tokens) {
16104
- if (tokens) return tokens.sizes.m.gap;
16151
+ const fromCollection = usableGap(buttonCollectionOf(el)?.style.gap);
16152
+ if (fromCollection) return fromCollection;
16105
16153
  const parent = el.parentElement;
16106
- if (!parent) return "12px";
16107
- const gap = getComputedStyle(parent).columnGap || getComputedStyle(parent).gap;
16108
- return gap && gap !== "normal" ? gap : "12px";
16154
+ if (parent) {
16155
+ const style = getComputedStyle(parent);
16156
+ const fromParent = usableGap(style.columnGap) ?? usableGap(style.gap);
16157
+ if (fromParent) return fromParent;
16158
+ }
16159
+ const fromTokens = usableGap(tokens?.sizes.m.gap);
16160
+ if (fromTokens) return fromTokens;
16161
+ return COLLECTION_GAP_DEFAULT;
16109
16162
  }
16110
16163
  function styleCollection(collection, gap) {
16111
16164
  collection.style.display = "inline-flex";
@@ -16153,6 +16206,7 @@ function findButton(doc, id) {
16153
16206
  return doc.querySelector(`[data-ohw-href-key="${CSS.escape(id)}"]`);
16154
16207
  }
16155
16208
  function duplicateButton(source, content) {
16209
+ if (!canDuplicateButton(source)) return null;
16156
16210
  const sourceId = buttonId(source);
16157
16211
  if (!sourceId) return null;
16158
16212
  const doc = source.ownerDocument;
@@ -16171,7 +16225,7 @@ function duplicateButton(source, content) {
16171
16225
  const collections = readCollections(content);
16172
16226
  let collectionId = collection?.getAttribute(COLLECTION_ATTR) ?? "";
16173
16227
  let members = collectionId && collections[collectionId] ? [...collections[collectionId].members] : [];
16174
- const gap = collection?.style.gap || collectionGap(source, tokens);
16228
+ const gap = collectionGap(source, tokens);
16175
16229
  if (!collection) {
16176
16230
  collectionId = nextCollectionId(content, doc);
16177
16231
  collection = createCollection(doc, collectionId, gap);
@@ -17157,12 +17211,6 @@ var SECTION_DRAG_EXCLUDED_SELECTOR = [
17157
17211
  "[data-ohw-media-overlay]",
17158
17212
  "[data-ohw-media-skeleton]"
17159
17213
  ].join(", ");
17160
- function visibleClip(ps) {
17161
- if (!ps) return null;
17162
- const top = Math.max(0, ps.headerH - ps.iframeOffsetTop);
17163
- const bottom = Math.min(window.innerHeight, ps.headerH + ps.canvasH - ps.iframeOffsetTop);
17164
- return { top, bottom: Math.max(top, bottom) };
17165
- }
17166
17214
  function useSectionDrag({
17167
17215
  isEditMode,
17168
17216
  editContentRef,
@@ -17199,7 +17247,7 @@ function useSectionDrag({
17199
17247
  }, [postToParentRef, stopAutoScroll]);
17200
17248
  const updateAutoScroll = useCallback8(
17201
17249
  (clientY) => {
17202
- const clip = visibleClip(parentScrollRef.current);
17250
+ const clip = getIframeVisibleClip(parentScrollRef.current);
17203
17251
  let delta = 0;
17204
17252
  if (clip) {
17205
17253
  const distTop = clientY - clip.top;
@@ -19108,16 +19156,6 @@ function EditGlowChrome({
19108
19156
  }
19109
19157
  );
19110
19158
  }
19111
- function getIframeVisibleClip(parentScroll) {
19112
- if (!parentScroll) return null;
19113
- const { iframeOffsetTop, headerH: visibleCanvasTop, canvasH } = parentScroll;
19114
- const clipTop = Math.max(0, visibleCanvasTop - iframeOffsetTop);
19115
- const clipBottom = Math.min(
19116
- window.innerHeight,
19117
- visibleCanvasTop + canvasH - iframeOffsetTop
19118
- );
19119
- return { top: clipTop, bottom: Math.max(clipTop, clipBottom) };
19120
- }
19121
19159
  function isRectOutsideClip(rect, clip) {
19122
19160
  if (!clip) return false;
19123
19161
  return rect.bottom < clip.top || rect.top > clip.bottom;
@@ -24866,10 +24904,10 @@ function OhhwellsBridge() {
24866
24904
  };
24867
24905
  const handleParentScroll = (e) => {
24868
24906
  if (e.data?.type !== "ow:parent-scroll") return;
24869
- const { iframeOffsetTop, headerH, canvasH } = e.data;
24870
- parentScrollRef.current = { iframeOffsetTop, headerH, canvasH };
24907
+ const { iframeOffsetTop, headerH, canvasH, promptBarH = 0 } = e.data;
24908
+ parentScrollRef.current = { iframeOffsetTop, headerH, canvasH, promptBarH };
24871
24909
  if (floatingPanelOpenRef.current) {
24872
- setParentScrollSnap({ iframeOffsetTop, headerH, canvasH });
24910
+ setParentScrollSnap({ iframeOffsetTop, headerH, canvasH, promptBarH });
24873
24911
  }
24874
24912
  if (visibleViewportRef.current) {
24875
24913
  applyVisibleViewport(visibleViewportRef.current, parentScrollRef.current);
@@ -26162,7 +26200,7 @@ function OhhwellsBridge() {
26162
26200
  const social = getSocialItem(selectedElRef.current);
26163
26201
  return social ? !canRemoveSocialItem(social) : false;
26164
26202
  })(),
26165
- duplicateDisabled: isFooterFrameSelection || selectedIsSocialsRow || selectedElRef.current !== null && (() => {
26203
+ duplicateDisabled: isFooterFrameSelection || selectedIsSocialsRow || selectedElRef.current !== null && isCtaButton(selectedElRef.current) && !canDuplicateButton(selectedElRef.current) || selectedElRef.current !== null && (() => {
26166
26204
  const social = getSocialItem(selectedElRef.current);
26167
26205
  const row = social ? findSocialsRow(social) : null;
26168
26206
  return row ? !canAddSocialItem(row) : false;