@ohhwells/bridge 0.1.138 → 0.1.139-next.373
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 +134 -71
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +134 -71
- package/dist/index.js.map +1 -1
- package/dist/pages.cjs +1 -1
- package/dist/pages.cjs.map +1 -1
- package/dist/pages.js +1 -1
- package/dist/pages.js.map +1 -1
- package/dist/styles.css +43 -0
- package/package.json +3 -3
package/dist/index.cjs
CHANGED
|
@@ -7279,7 +7279,7 @@ var AI_MOBILE_CSS = [
|
|
|
7279
7279
|
// page's first section. Top only (bottom needs no nav clearance); ~96px approximates the
|
|
7280
7280
|
// template nav's own height (measured ~94px) — there's no shared `--ohw-header-h` var to read
|
|
7281
7281
|
// an exact figure from (no live measurement exists), so this is a safe approximation, not a
|
|
7282
|
-
// pixel-exact fit. Horizontal spacing already comes from `data-ai-
|
|
7282
|
+
// pixel-exact fit. Horizontal spacing already comes from `data-ai-section-inner`.
|
|
7283
7283
|
'[data-ai-overlay-clearance] [data-ai-overlap-layer="overlay"]{padding-top:96px}',
|
|
7284
7284
|
// A full-bleed carousel's height is pure arithmetic: it spans the whole window, so 16/9 turns
|
|
7285
7285
|
// window width straight into height. Measured at 16/9 it came out ~90% of the viewport at EVERY
|
|
@@ -7295,8 +7295,10 @@ var AI_MOBILE_CSS = [
|
|
|
7295
7295
|
"[data-ai-section]{overflow-x:hidden}",
|
|
7296
7296
|
// `:not([data-ai-full-bleed])`: this `!important` gutter beat the inline `padding: 0` that a
|
|
7297
7297
|
// full-bleed section's container sets, so a carousel/media hero that is edge-to-edge on desktop
|
|
7298
|
-
// still got a 20px band of section background down both sides on a phone.
|
|
7299
|
-
|
|
7298
|
+
// still got a 20px band of section background down both sides on a phone. The footer's own
|
|
7299
|
+
// container keeps the unguarded rule below — `data-ai-full-bleed` can never appear on it.
|
|
7300
|
+
"[data-ai-section-inner]:not([data-ai-full-bleed]){padding:0 20px !important}",
|
|
7301
|
+
"[data-ai-container]{padding:0 20px !important}",
|
|
7300
7302
|
"[data-ai-row]{display:flex !important;flex-direction:column !important;align-items:stretch !important}",
|
|
7301
7303
|
"[data-ai-cell]{width:100%;min-width:0}",
|
|
7302
7304
|
// The rule above turns every row into a COLUMN flex container on phones, which silently breaks
|
|
@@ -7497,6 +7499,31 @@ function pricingCardEmphasis(featured, ctx, hasBg) {
|
|
|
7497
7499
|
function textAttrs(ctx, path) {
|
|
7498
7500
|
return ctx.keyFor ? { "data-ohw-key": ctx.keyFor(path), "data-ohw-editable": "text" } : {};
|
|
7499
7501
|
}
|
|
7502
|
+
var AI_RESPONSIVE_CSS = [
|
|
7503
|
+
"@media (max-width: 960px) {",
|
|
7504
|
+
" [data-ai-responsive] [data-ai-grid] { grid-template-columns: repeat(2, 1fr) !important; }",
|
|
7505
|
+
' [data-ai-responsive] [data-ai-grid="1"] { grid-template-columns: 1fr !important; }',
|
|
7506
|
+
"}",
|
|
7507
|
+
"@media (max-width: 640px) {",
|
|
7508
|
+
" [data-ai-responsive] [data-ai-grid] { grid-template-columns: 1fr !important; }",
|
|
7509
|
+
" [data-ai-responsive] [data-ai-columns] > * { grid-column: 1 / -1 !important; }",
|
|
7510
|
+
// Group containers flatten to a column on phones; span placements come along for free.
|
|
7511
|
+
// `:not([data-ai-group="overlap"])` for the same reason as the twin pair in AI_MOBILE_CSS — see
|
|
7512
|
+
// the comment there. This sheet's copy is the narrower selector, so without the exemption it
|
|
7513
|
+
// flattens an `overlap` hero below 640px even though the other rule stands down: measured a 390px
|
|
7514
|
+
// viewport with the heading/CTA in flow *under* the image, 219px of section background where the
|
|
7515
|
+
// layered text used to be.
|
|
7516
|
+
' [data-ai-responsive] [data-ai-group]:not([data-ai-group="overlap"]) { display: flex !important; flex-direction: column !important; }',
|
|
7517
|
+
' [data-ai-responsive] [data-ai-group]:not([data-ai-group="overlap"]) > * { grid-column: auto !important; }',
|
|
7518
|
+
// `:not([data-ai-full-bleed])` for the same reason as the twin rule in AI_MOBILE_CSS: this one
|
|
7519
|
+
// is narrower (0,2,0 vs 0,1,0) and also `!important`, so without the guard it wins outright and
|
|
7520
|
+
// a full-bleed hero gets its 20px side band back below 640px only — the one width where the
|
|
7521
|
+
// other rule had already been taught to stand down.
|
|
7522
|
+
" [data-ai-responsive] [data-ai-section-inner]:not([data-ai-full-bleed]) { padding-left: 20px !important; padding-right: 20px !important; }",
|
|
7523
|
+
" [data-ai-responsive] { overflow-x: hidden; }",
|
|
7524
|
+
" [data-ai-responsive] img { max-width: 100%; }",
|
|
7525
|
+
"}"
|
|
7526
|
+
].join("\n");
|
|
7500
7527
|
var TRANSPARENT_PX = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7";
|
|
7501
7528
|
function MediaBox({
|
|
7502
7529
|
refValue,
|
|
@@ -7517,9 +7544,9 @@ function MediaBox({
|
|
|
7517
7544
|
const url = refValue ? ctx.resolveMedia(refValue) : null;
|
|
7518
7545
|
const isIcon = /^(lucide|simple):/.test(refValue);
|
|
7519
7546
|
const aspectRatio = aspect && /^\d+:\d+$/.test(aspect) ? aspect.replace(":", " / ") : void 0;
|
|
7520
|
-
const editAttrs = ctx.keyFor && editPath
|
|
7547
|
+
const editAttrs = ctx.keyFor && editPath ? {
|
|
7521
7548
|
"data-ohw-key": ctx.keyFor(editPath),
|
|
7522
|
-
...genericImageEdit ? { "data-ohw-editable": "image" } : {}
|
|
7549
|
+
...isIcon ? { "data-ohw-editable": "icon" } : genericImageEdit ? { "data-ohw-editable": "image" } : {}
|
|
7523
7550
|
} : {};
|
|
7524
7551
|
if (isIcon) {
|
|
7525
7552
|
const Icon = refValue.startsWith("lucide:") ? lucideByName(refValue.slice(7)) : null;
|
|
@@ -7527,6 +7554,7 @@ function MediaBox({
|
|
|
7527
7554
|
"span",
|
|
7528
7555
|
{
|
|
7529
7556
|
"data-ai-icon": refValue,
|
|
7557
|
+
...editAttrs,
|
|
7530
7558
|
style: {
|
|
7531
7559
|
display: "inline-flex",
|
|
7532
7560
|
width: 48,
|
|
@@ -9034,7 +9062,7 @@ function CollectionBlock({ node, ctx, path }) {
|
|
|
9034
9062
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
9035
9063
|
"div",
|
|
9036
9064
|
{
|
|
9037
|
-
"data-ai-grid":
|
|
9065
|
+
"data-ai-grid": String(itemsPerRow),
|
|
9038
9066
|
"data-ohw-pricing-collection": isPricing ? "" : void 0,
|
|
9039
9067
|
style: {
|
|
9040
9068
|
display: "grid",
|
|
@@ -9294,7 +9322,7 @@ function renderNode(node, ctx, path, ambientAlign) {
|
|
|
9294
9322
|
},
|
|
9295
9323
|
children: [
|
|
9296
9324
|
i > 0 && ctx.heroOverlapFullBleed ? (
|
|
9297
|
-
// The section's `data-ai-
|
|
9325
|
+
// The section's `data-ai-section-inner` gave up its max-width/gutter so the base
|
|
9298
9326
|
// layer (this group's i===0 sibling) can span edge-to-edge — reintroduced here,
|
|
9299
9327
|
// scoped to just the overlay text, so a heading/copy/CTA stack doesn't stretch
|
|
9300
9328
|
// the full section width instead of reading at the usual content width.
|
|
@@ -9687,6 +9715,7 @@ function AiTreeRenderer({
|
|
|
9687
9715
|
...fillHeight ? { "data-ai-fill-height": "" } : {},
|
|
9688
9716
|
...needsOverlayClearance ? { "data-ai-overlay-clearance": "" } : {},
|
|
9689
9717
|
...bgAttrs,
|
|
9718
|
+
"data-ai-responsive": "",
|
|
9690
9719
|
style: {
|
|
9691
9720
|
position: "relative",
|
|
9692
9721
|
padding: `${padCss} 0`,
|
|
@@ -9700,12 +9729,13 @@ function AiTreeRenderer({
|
|
|
9700
9729
|
...fillHeight ? { display: "grid" } : {}
|
|
9701
9730
|
},
|
|
9702
9731
|
children: [
|
|
9703
|
-
|
|
9732
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("style", { children: AI_RESPONSIVE_CSS }),
|
|
9704
9733
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("style", { children: AI_MOBILE_CSS }),
|
|
9734
|
+
isOverlay && backgroundUrl && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { position: "absolute", inset: 0, background: `rgba(255,255,255,${overlayAlpha})` } }),
|
|
9705
9735
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
9706
9736
|
"div",
|
|
9707
9737
|
{
|
|
9708
|
-
"data-ai-
|
|
9738
|
+
"data-ai-section-inner": "",
|
|
9709
9739
|
...fullBleedMedia ? { "data-ai-full-bleed": "" } : {},
|
|
9710
9740
|
style: {
|
|
9711
9741
|
position: "relative",
|
|
@@ -9722,7 +9752,7 @@ function AiTreeRenderer({
|
|
|
9722
9752
|
children: tree.rows.map((row, r2) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
9723
9753
|
"div",
|
|
9724
9754
|
{
|
|
9725
|
-
"data-ai-
|
|
9755
|
+
"data-ai-columns": "",
|
|
9726
9756
|
style: {
|
|
9727
9757
|
display: "grid",
|
|
9728
9758
|
gridTemplateColumns: "repeat(12, 1fr)",
|
|
@@ -10378,9 +10408,10 @@ function applyAiSectionsToDom(state, options) {
|
|
|
10378
10408
|
if (existing && existing.serialized === serialized && existing.container.isConnected) {
|
|
10379
10409
|
continue;
|
|
10380
10410
|
}
|
|
10381
|
-
const isNewMount = !existing || !existing.container.isConnected;
|
|
10382
10411
|
let container = existing?.container;
|
|
10412
|
+
let isNewMount = false;
|
|
10383
10413
|
if (!container || !container.isConnected) {
|
|
10414
|
+
isNewMount = true;
|
|
10384
10415
|
existing?.root.unmount();
|
|
10385
10416
|
container?.remove();
|
|
10386
10417
|
container = document.createElement("div");
|
|
@@ -16822,6 +16853,7 @@ function MediaOverlay({
|
|
|
16822
16853
|
(prev) => prev && prev.fullWidth === width && prev.height === height ? prev : { fullWidth: width, height }
|
|
16823
16854
|
);
|
|
16824
16855
|
}, [isVideo]);
|
|
16856
|
+
const replaceLabel = isVideo ? "Replace video" : hover.elementType === "bg-image" ? "Replace background" : "Replace image";
|
|
16825
16857
|
const replaceMode = buttonSize ? replaceButtonMode({ width: rect.width, height: rect.height }, buttonSize) : "none";
|
|
16826
16858
|
const box = {
|
|
16827
16859
|
position: "fixed",
|
|
@@ -16920,11 +16952,10 @@ function MediaOverlay({
|
|
|
16920
16952
|
className: "flex items-center justify-center cursor-pointer",
|
|
16921
16953
|
style: {
|
|
16922
16954
|
...box,
|
|
16923
|
-
//
|
|
16924
|
-
//
|
|
16925
|
-
//
|
|
16926
|
-
|
|
16927
|
-
pointerEvents: hover.hasTextOverlap || cueOnly ? "none" : "auto",
|
|
16955
|
+
// Visual only. `pointer-events: auto` on this full-bleed rect covered the navbar
|
|
16956
|
+
// (hero bg includes the absolute TopNav) and swallowed CTA press-drag. Text overlay
|
|
16957
|
+
// and cueOnly also need clicks to fall through — Replace / video controls opt back in.
|
|
16958
|
+
pointerEvents: "none",
|
|
16928
16959
|
// Selected: a firm component ring with no wash, so the image reads as chosen rather
|
|
16929
16960
|
// than hovered. Hover keeps the existing tinted preview.
|
|
16930
16961
|
boxShadow: selected ? "inset 0 0 0 2px var(--color-bridge-primary)" : "inset 0 0 0 1.5px var(--color-bridge-primary)",
|
|
@@ -16951,17 +16982,17 @@ function MediaOverlay({
|
|
|
16951
16982
|
},
|
|
16952
16983
|
children: [
|
|
16953
16984
|
isVideo ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_lucide_react5.Film, { size: 14 }) : /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_lucide_react5.ImageIcon, { size: 14 }),
|
|
16954
|
-
|
|
16985
|
+
replaceLabel
|
|
16955
16986
|
]
|
|
16956
16987
|
}
|
|
16957
16988
|
),
|
|
16958
|
-
replaceMode
|
|
16989
|
+
showChrome && replaceMode !== "none" && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
|
|
16959
16990
|
Button,
|
|
16960
16991
|
{
|
|
16961
16992
|
"data-ohw-media-overlay": "",
|
|
16962
16993
|
variant: "outline",
|
|
16963
16994
|
size: "sm",
|
|
16964
|
-
"aria-label":
|
|
16995
|
+
"aria-label": replaceLabel,
|
|
16965
16996
|
className: "gap-1.5 cursor-pointer hover:bg-background",
|
|
16966
16997
|
style: {
|
|
16967
16998
|
...OVERLAY_BUTTON_STYLE,
|
|
@@ -16984,7 +17015,7 @@ function MediaOverlay({
|
|
|
16984
17015
|
},
|
|
16985
17016
|
children: [
|
|
16986
17017
|
isVideo ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_lucide_react5.Film, { size: 14 }) : /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_lucide_react5.ImageIcon, { size: 14 }),
|
|
16987
|
-
replaceMode === "full" ?
|
|
17018
|
+
replaceMode === "full" ? replaceLabel : null
|
|
16988
17019
|
]
|
|
16989
17020
|
}
|
|
16990
17021
|
)
|
|
@@ -18290,8 +18321,20 @@ function withPricingCollection(tree, mutate) {
|
|
|
18290
18321
|
const next = JSON.parse(JSON.stringify(tree));
|
|
18291
18322
|
const collection = findPricingCollection(next);
|
|
18292
18323
|
if (!collection || !collection.children) return null;
|
|
18324
|
+
for (const card of collection.children) {
|
|
18325
|
+
if (isPricingCard(card)) upgradeLegacyPricingSlots(card);
|
|
18326
|
+
}
|
|
18293
18327
|
return mutate(collection) ? next : null;
|
|
18294
18328
|
}
|
|
18329
|
+
function upgradeLegacyPricingSlots(card) {
|
|
18330
|
+
const slots = card.slots = card.slots ?? {};
|
|
18331
|
+
if (typeof slots.features === "string") {
|
|
18332
|
+
const rows = pricingFeatureList(card);
|
|
18333
|
+
if (rows.length > 0) slots.features = rows.slice(0, PRICING_FEATURES_MAX);
|
|
18334
|
+
}
|
|
18335
|
+
if (slots.featured === true) slots.featured = { enabled: true };
|
|
18336
|
+
else if (slots.featured === false) delete slots.featured;
|
|
18337
|
+
}
|
|
18295
18338
|
function addPricingTier(tree) {
|
|
18296
18339
|
return withPricingCollection(tree, (collection) => {
|
|
18297
18340
|
const children = collection.children;
|
|
@@ -18413,7 +18456,7 @@ function pricingFeatureList(target) {
|
|
|
18413
18456
|
}));
|
|
18414
18457
|
}
|
|
18415
18458
|
if (typeof raw === "string") {
|
|
18416
|
-
return raw.split(
|
|
18459
|
+
return raw.split(/\n|<br\s*\/?>/i).map((line) => line.replace(/<[^>]+>/g, "").replace(/^[-*•]\s*/, "").trim().slice(0, 120)).filter(Boolean).map((text) => ({ text }));
|
|
18417
18460
|
}
|
|
18418
18461
|
return [];
|
|
18419
18462
|
}
|
|
@@ -21407,6 +21450,7 @@ function shouldUseDevFixtures() {
|
|
|
21407
21450
|
function getLogoElement(el) {
|
|
21408
21451
|
const marked = el.closest('[data-ohw-role="logo"], [data-ohw-logo]');
|
|
21409
21452
|
if (marked) return marked;
|
|
21453
|
+
if (el.closest('[data-ohw-editable="icon"]')) return null;
|
|
21410
21454
|
const root = el.closest("nav, [data-ohw-nav-root], footer");
|
|
21411
21455
|
if (!root) return null;
|
|
21412
21456
|
const anchor = el.closest("a");
|
|
@@ -23970,7 +24014,7 @@ function getNavigationSelectionParent(el) {
|
|
|
23970
24014
|
if (!isFooterLinksContainer(el) && (el.hasAttribute("data-ohw-footer-col") || el.hasAttribute("data-ohw-footer-column") || isInferredFooterGroup2(el))) {
|
|
23971
24015
|
return resolveFooterLinksContainerFrom(el);
|
|
23972
24016
|
}
|
|
23973
|
-
if (el.hasAttribute("data-ohw-nav-container") || el.hasAttribute("data-ohw-nav-drawer") || isFooterLinksContainer(el)) {
|
|
24017
|
+
if (el.hasAttribute("data-ohw-nav-container") || el.hasAttribute("data-ohw-nav-drawer") || el.hasAttribute("data-ohw-footer-col") || el.hasAttribute("data-ohw-footer-column") || isFooterLinksContainer(el) || isInferredFooterGroup2(el)) {
|
|
23974
24018
|
return getNavigationRoot(el);
|
|
23975
24019
|
}
|
|
23976
24020
|
return null;
|
|
@@ -24192,7 +24236,6 @@ var ICONS = {
|
|
|
24192
24236
|
insertUnorderedList: '<line x1="8" y1="6" x2="21" y2="6"/><line x1="8" y1="12" x2="21" y2="12"/><line x1="8" y1="18" x2="21" y2="18"/><line x1="3" y1="6" x2="3.01" y2="6"/><line x1="3" y1="12" x2="3.01" y2="12"/><line x1="3" y1="18" x2="3.01" y2="18"/>',
|
|
24193
24237
|
insertOrderedList: '<line x1="10" y1="6" x2="21" y2="6"/><line x1="10" y1="12" x2="21" y2="12"/><line x1="10" y1="18" x2="21" y2="18"/><path d="M4 6h1v4"/><path d="M4 10h2"/><path d="M6 18H4c0-1 2-2 2-3s-1-1.5-2-1"/>'
|
|
24194
24238
|
};
|
|
24195
|
-
var HEIGHT_SETTLE_DELAYS = [150, 400, 800];
|
|
24196
24239
|
var SELECTION_CHROME_GAP2 = 4;
|
|
24197
24240
|
var TOOLBAR_STROKE_GAP2 = 4;
|
|
24198
24241
|
var TOOLBAR_OFFSET_FROM_ELEMENT = SELECTION_CHROME_GAP2 + TOOLBAR_STROKE_GAP2;
|
|
@@ -25172,21 +25215,6 @@ function OhhwellsBridge() {
|
|
|
25172
25215
|
const [isItemDragging, setIsItemDragging] = (0, import_react21.useState)(false);
|
|
25173
25216
|
const [isFooterFrameSelection, setIsFooterFrameSelection] = (0, import_react21.useState)(false);
|
|
25174
25217
|
isFooterFrameSelectionRef.current = isFooterFrameSelection;
|
|
25175
|
-
const [floatingPanel, setFloatingPanel] = (0, import_react21.useState)(null);
|
|
25176
|
-
const floatingPanelOpenRef = (0, import_react21.useRef)(false);
|
|
25177
|
-
floatingPanelOpenRef.current = floatingPanel !== null;
|
|
25178
|
-
const floatingPanelRef = (0, import_react21.useRef)(null);
|
|
25179
|
-
floatingPanelRef.current = floatingPanel;
|
|
25180
|
-
const [floatingPanelPos, setFloatingPanelPos] = (0, import_react21.useState)(null);
|
|
25181
|
-
const buttonCollectionDragRef = (0, import_react21.useRef)(null);
|
|
25182
|
-
const buttonDropInsertIndexRef = (0, import_react21.useRef)(null);
|
|
25183
|
-
const [buttonDropSlots, setButtonDropSlots] = (0, import_react21.useState)([]);
|
|
25184
|
-
const [activeButtonDropIndex, setActiveButtonDropIndex] = (0, import_react21.useState)(null);
|
|
25185
|
-
const buttonPointerDragRef = (0, import_react21.useRef)(null);
|
|
25186
|
-
const [buttonStyleTick, setButtonStyleTick] = (0, import_react21.useState)(0);
|
|
25187
|
-
const [logoSizeDraft, setLogoSizeDraft] = (0, import_react21.useState)(null);
|
|
25188
|
-
const [editorViewport, setEditorViewport] = (0, import_react21.useState)("desktop");
|
|
25189
|
-
const [parentScrollSnap, setParentScrollSnap] = (0, import_react21.useState)(null);
|
|
25190
25218
|
const [navDropdownPreviewOpen, setNavDropdownPreviewOpen] = (0, import_react21.useState)(null);
|
|
25191
25219
|
const [footerHeadingVisible, setFooterHeadingVisible] = (0, import_react21.useState)(null);
|
|
25192
25220
|
const footerDragRef = (0, import_react21.useRef)(null);
|
|
@@ -25212,6 +25240,21 @@ function OhhwellsBridge() {
|
|
|
25212
25240
|
const stylesRef = (0, import_react21.useRef)("");
|
|
25213
25241
|
const appliedDrawerRef = (0, import_react21.useRef)(null);
|
|
25214
25242
|
const pendingDeleteUndoRef = (0, import_react21.useRef)(null);
|
|
25243
|
+
const [floatingPanel, setFloatingPanel] = (0, import_react21.useState)(null);
|
|
25244
|
+
const floatingPanelOpenRef = (0, import_react21.useRef)(false);
|
|
25245
|
+
const floatingPanelRef = (0, import_react21.useRef)(null);
|
|
25246
|
+
floatingPanelRef.current = floatingPanel;
|
|
25247
|
+
const setFloatingPanelRef = (0, import_react21.useRef)(setFloatingPanel);
|
|
25248
|
+
const [floatingPanelPos, setFloatingPanelPos] = (0, import_react21.useState)(null);
|
|
25249
|
+
const buttonCollectionDragRef = (0, import_react21.useRef)(null);
|
|
25250
|
+
const buttonDropInsertIndexRef = (0, import_react21.useRef)(null);
|
|
25251
|
+
const [buttonDropSlots, setButtonDropSlots] = (0, import_react21.useState)([]);
|
|
25252
|
+
const [activeButtonDropIndex, setActiveButtonDropIndex] = (0, import_react21.useState)(null);
|
|
25253
|
+
const buttonPointerDragRef = (0, import_react21.useRef)(null);
|
|
25254
|
+
const [buttonStyleTick, setButtonStyleTick] = (0, import_react21.useState)(0);
|
|
25255
|
+
const [logoSizeDraft, setLogoSizeDraft] = (0, import_react21.useState)(null);
|
|
25256
|
+
const [editorViewport, setEditorViewport] = (0, import_react21.useState)("desktop");
|
|
25257
|
+
const [parentScrollSnap, setParentScrollSnap] = (0, import_react21.useState)(null);
|
|
25215
25258
|
const [sitePages, setSitePages] = (0, import_react21.useState)([]);
|
|
25216
25259
|
const [sectionsByPath, setSectionsByPath] = (0, import_react21.useState)({});
|
|
25217
25260
|
const sectionsPrefetchGenRef = (0, import_react21.useRef)(0);
|
|
@@ -25220,7 +25263,18 @@ function OhhwellsBridge() {
|
|
|
25220
25263
|
const linkPopoverOpenRef = (0, import_react21.useRef)(false);
|
|
25221
25264
|
const linkPopoverGraceUntilRef = (0, import_react21.useRef)(0);
|
|
25222
25265
|
setLinkPopoverRef.current = setLinkPopover;
|
|
25266
|
+
setFloatingPanelRef.current = setFloatingPanel;
|
|
25223
25267
|
linkPopoverSessionRef.current = linkPopover;
|
|
25268
|
+
floatingPanelOpenRef.current = Boolean(floatingPanel);
|
|
25269
|
+
(0, import_react21.useEffect)(() => {
|
|
25270
|
+
const syncViewport = () => {
|
|
25271
|
+
const next = window.innerWidth <= 480 ? "mobile" : "desktop";
|
|
25272
|
+
setEditorViewport((prev) => prev === next ? prev : next);
|
|
25273
|
+
};
|
|
25274
|
+
syncViewport();
|
|
25275
|
+
window.addEventListener("resize", syncViewport);
|
|
25276
|
+
return () => window.removeEventListener("resize", syncViewport);
|
|
25277
|
+
}, []);
|
|
25224
25278
|
(0, import_react21.useEffect)(() => {
|
|
25225
25279
|
setSectionOrderPersistHandler((entries) => {
|
|
25226
25280
|
const currentPath = window.location.pathname;
|
|
@@ -26899,6 +26953,7 @@ function OhhwellsBridge() {
|
|
|
26899
26953
|
applyAiFooterFromContent(content);
|
|
26900
26954
|
if (typeof content[STYLE_STORE_KEY] === "string") {
|
|
26901
26955
|
stylesRef.current = content[STYLE_STORE_KEY];
|
|
26956
|
+
document.querySelectorAll('[data-ohw-editable="form"]').forEach((f) => markFormFields(f));
|
|
26902
26957
|
applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
|
|
26903
26958
|
}
|
|
26904
26959
|
applyBrandChrome(content);
|
|
@@ -26909,12 +26964,12 @@ function OhhwellsBridge() {
|
|
|
26909
26964
|
if (key === "__ohw_sections") continue;
|
|
26910
26965
|
if (key === AI_SECTIONS_KEY) continue;
|
|
26911
26966
|
if (key === AI_FOOTER_KEY) continue;
|
|
26967
|
+
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
26968
|
+
if (LOGO_IMAGE_KEYS.includes(key)) continue;
|
|
26912
26969
|
if (key === BRAND_KIT_KEY) continue;
|
|
26913
26970
|
if (key === STYLE_STORE_KEY) continue;
|
|
26914
26971
|
if (BRAND_CHROME_KEYS.has(key)) continue;
|
|
26915
|
-
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
26916
26972
|
if (key === CUSTOM_CODE_AFTER_HEAD_KEY || key === CUSTOM_CODE_BEFORE_HEAD_KEY) continue;
|
|
26917
|
-
if (LOGO_IMAGE_KEYS.includes(key)) continue;
|
|
26918
26973
|
if (typeof content[AI_FOOTER_KEY] === "string" && content[AI_FOOTER_KEY] && isAiFooterOwnedContentKey(key)) {
|
|
26919
26974
|
continue;
|
|
26920
26975
|
}
|
|
@@ -27129,17 +27184,18 @@ function OhhwellsBridge() {
|
|
|
27129
27184
|
}
|
|
27130
27185
|
applyAiFooterFromContent(content);
|
|
27131
27186
|
if (typeof content[STYLE_STORE_KEY] === "string") {
|
|
27187
|
+
document.querySelectorAll('[data-ohw-editable="form"]').forEach((f) => markFormFields(f));
|
|
27132
27188
|
applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
|
|
27133
27189
|
}
|
|
27134
27190
|
for (const [key, val] of Object.entries(content)) {
|
|
27135
27191
|
if (key === "__ohw_sections") continue;
|
|
27136
27192
|
if (key === AI_SECTIONS_KEY) continue;
|
|
27137
27193
|
if (key === AI_FOOTER_KEY) continue;
|
|
27194
|
+
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
27195
|
+
if (LOGO_IMAGE_KEYS.includes(key)) continue;
|
|
27138
27196
|
if (key === BRAND_KIT_KEY) continue;
|
|
27139
27197
|
if (key === STYLE_STORE_KEY) continue;
|
|
27140
27198
|
if (BRAND_CHROME_KEYS.has(key)) continue;
|
|
27141
|
-
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
27142
|
-
if (LOGO_IMAGE_KEYS.includes(key)) continue;
|
|
27143
27199
|
if (typeof content[AI_FOOTER_KEY] === "string" && content[AI_FOOTER_KEY] && isAiFooterOwnedContentKey(key)) {
|
|
27144
27200
|
continue;
|
|
27145
27201
|
}
|
|
@@ -27396,26 +27452,11 @@ function OhhwellsBridge() {
|
|
|
27396
27452
|
const t2 = setTimeout(measure, 500);
|
|
27397
27453
|
const ro = new ResizeObserver(schedule);
|
|
27398
27454
|
ro.observe(document.body);
|
|
27399
|
-
let lastWidth = window.innerWidth;
|
|
27400
|
-
let resizeTimers = [];
|
|
27401
|
-
const clearResizeTimers = () => {
|
|
27402
|
-
resizeTimers.forEach(clearTimeout);
|
|
27403
|
-
resizeTimers = [];
|
|
27404
|
-
};
|
|
27405
|
-
const handleResize = () => {
|
|
27406
|
-
if (window.innerWidth === lastWidth) return;
|
|
27407
|
-
lastWidth = window.innerWidth;
|
|
27408
|
-
clearResizeTimers();
|
|
27409
|
-
resizeTimers = HEIGHT_SETTLE_DELAYS.map((delay) => setTimeout(measure, delay));
|
|
27410
|
-
};
|
|
27411
|
-
window.addEventListener("resize", handleResize);
|
|
27412
27455
|
return () => {
|
|
27413
27456
|
clearTimeout(t1);
|
|
27414
27457
|
clearTimeout(t2);
|
|
27415
27458
|
if (raf != null) cancelAnimationFrame(raf);
|
|
27416
27459
|
ro.disconnect();
|
|
27417
|
-
clearResizeTimers();
|
|
27418
|
-
window.removeEventListener("resize", handleResize);
|
|
27419
27460
|
};
|
|
27420
27461
|
}, [pathname, isEditMode, postToParent2]);
|
|
27421
27462
|
(0, import_react21.useEffect)(() => {
|
|
@@ -27710,6 +27751,13 @@ function OhhwellsBridge() {
|
|
|
27710
27751
|
if (target.closest("[data-ohw-state-toggle]")) return;
|
|
27711
27752
|
if (target.closest("[data-ohw-max-badge]")) return;
|
|
27712
27753
|
if (isInsideLinkEditor(target)) return;
|
|
27754
|
+
if (isInsideFloatingPanel(target)) return;
|
|
27755
|
+
if (target.closest("[data-ohw-form-toolbar]")) return;
|
|
27756
|
+
if (target.closest(
|
|
27757
|
+
'[data-ohw-field-toolbar], [data-ohw-field-type-picker], [data-radix-popper-content-wrapper], [role="menu"], [data-slot="dropdown-menu-content"]'
|
|
27758
|
+
)) {
|
|
27759
|
+
return;
|
|
27760
|
+
}
|
|
27713
27761
|
if (selectedMediaElRef.current && !selectedMediaElRef.current.contains(target) && !target.closest("[data-ohw-media-overlay], [data-ohw-edit-chrome], [data-ohw-item-interaction]")) {
|
|
27714
27762
|
clearMediaSelectionRef.current();
|
|
27715
27763
|
}
|
|
@@ -27730,13 +27778,6 @@ function OhhwellsBridge() {
|
|
|
27730
27778
|
return;
|
|
27731
27779
|
}
|
|
27732
27780
|
}
|
|
27733
|
-
if (isInsideFloatingPanel(target)) return;
|
|
27734
|
-
if (target.closest("[data-ohw-form-toolbar]")) return;
|
|
27735
|
-
if (target.closest(
|
|
27736
|
-
'[data-ohw-field-toolbar], [data-ohw-field-type-picker], [data-radix-popper-content-wrapper], [role="menu"], [data-slot="dropdown-menu-content"]'
|
|
27737
|
-
)) {
|
|
27738
|
-
return;
|
|
27739
|
-
}
|
|
27740
27781
|
{
|
|
27741
27782
|
const formEl = getFormElement(target);
|
|
27742
27783
|
const onSuccessText = target.closest(`[${SUCCESS_TEXT_ATTR}]`);
|
|
@@ -28116,6 +28157,9 @@ function OhhwellsBridge() {
|
|
|
28116
28157
|
setHoveredItemRect(null);
|
|
28117
28158
|
hoveredNavContainerRef.current = null;
|
|
28118
28159
|
setHoveredNavContainerRect(null);
|
|
28160
|
+
siblingHintElRef.current = null;
|
|
28161
|
+
setSiblingHintRect(null);
|
|
28162
|
+
setSiblingHintRects([]);
|
|
28119
28163
|
return;
|
|
28120
28164
|
}
|
|
28121
28165
|
{
|
|
@@ -28236,7 +28280,6 @@ function OhhwellsBridge() {
|
|
|
28236
28280
|
hoveredNavContainerRef.current = null;
|
|
28237
28281
|
setHoveredNavContainerRect(null);
|
|
28238
28282
|
hoveredItemElRef.current = editable;
|
|
28239
|
-
setHoveredItemRect(isSelectedForHoverRef.current(editable) ? null : editable.getBoundingClientRect());
|
|
28240
28283
|
}
|
|
28241
28284
|
}
|
|
28242
28285
|
}
|
|
@@ -28946,7 +28989,11 @@ function OhhwellsBridge() {
|
|
|
28946
28989
|
};
|
|
28947
28990
|
const handleMouseMove = (e) => {
|
|
28948
28991
|
const { clientX, clientY } = e;
|
|
28949
|
-
if (pointOwnedByFloatingPanel(clientX, clientY))
|
|
28992
|
+
if (pointOwnedByFloatingPanel(clientX, clientY)) {
|
|
28993
|
+
dismissImageHover();
|
|
28994
|
+
clearImageHover();
|
|
28995
|
+
return;
|
|
28996
|
+
}
|
|
28950
28997
|
if (isNavDrawerOpen() && isPointOutsideOpenDrawer(clientX, clientY)) {
|
|
28951
28998
|
document.querySelectorAll("[data-ohw-hovered]").forEach((el) => el.removeAttribute("data-ohw-hovered"));
|
|
28952
28999
|
formHoverElRef.current = null;
|
|
@@ -28975,7 +29022,12 @@ function OhhwellsBridge() {
|
|
|
28975
29022
|
setHoveredItemRect(null);
|
|
28976
29023
|
hoveredNavContainerRef.current = null;
|
|
28977
29024
|
setHoveredNavContainerRect(null);
|
|
29025
|
+
siblingHintElRef.current = null;
|
|
29026
|
+
setSiblingHintRect(null);
|
|
29027
|
+
setSiblingHintRects([]);
|
|
28978
29028
|
dismissImageHover();
|
|
29029
|
+
clearImageHover();
|
|
29030
|
+
setSectionGap(null);
|
|
28979
29031
|
return;
|
|
28980
29032
|
}
|
|
28981
29033
|
if (probeSocialsRowAt(clientX, clientY)) return;
|
|
@@ -28987,7 +29039,11 @@ function OhhwellsBridge() {
|
|
|
28987
29039
|
if (e.data?.type !== "ow:pointer-sync") return;
|
|
28988
29040
|
const { clientX, clientY } = e.data;
|
|
28989
29041
|
if (typeof clientX !== "number" || typeof clientY !== "number") return;
|
|
28990
|
-
if (pointOwnedByFloatingPanel(clientX, clientY))
|
|
29042
|
+
if (pointOwnedByFloatingPanel(clientX, clientY)) {
|
|
29043
|
+
dismissImageHover();
|
|
29044
|
+
clearImageHover();
|
|
29045
|
+
return;
|
|
29046
|
+
}
|
|
28991
29047
|
if (isNavDrawerOpen() && isPointOutsideOpenDrawer(clientX, clientY)) return;
|
|
28992
29048
|
if (probeSocialsRowAt(clientX, clientY)) return;
|
|
28993
29049
|
probeSectionGapAt(clientX, clientY);
|
|
@@ -29339,6 +29395,7 @@ function OhhwellsBridge() {
|
|
|
29339
29395
|
applyAiFooterFromContent(content);
|
|
29340
29396
|
if (typeof content[STYLE_STORE_KEY] === "string") {
|
|
29341
29397
|
stylesRef.current = content[STYLE_STORE_KEY];
|
|
29398
|
+
document.querySelectorAll('[data-ohw-editable="form"]').forEach((f) => markFormFields(f));
|
|
29342
29399
|
applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
|
|
29343
29400
|
}
|
|
29344
29401
|
applyBrandChrome(content);
|
|
@@ -29353,12 +29410,12 @@ function OhhwellsBridge() {
|
|
|
29353
29410
|
}
|
|
29354
29411
|
if (key === AI_SECTIONS_KEY) continue;
|
|
29355
29412
|
if (key === AI_FOOTER_KEY) continue;
|
|
29413
|
+
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
29414
|
+
if (LOGO_IMAGE_KEYS.includes(key) && !String(val ?? "").trim()) continue;
|
|
29356
29415
|
if (key === BRAND_KIT_KEY) continue;
|
|
29357
29416
|
if (key === STYLE_STORE_KEY) continue;
|
|
29358
29417
|
if (BRAND_CHROME_KEYS.has(key)) continue;
|
|
29359
|
-
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
29360
29418
|
if (key === CUSTOM_CODE_AFTER_HEAD_KEY || key === CUSTOM_CODE_BEFORE_HEAD_KEY) continue;
|
|
29361
|
-
if (LOGO_IMAGE_KEYS.includes(key) && !String(val ?? "").trim()) continue;
|
|
29362
29419
|
if (typeof content[AI_FOOTER_KEY] === "string" && content[AI_FOOTER_KEY] && isAiFooterOwnedContentKey(key)) {
|
|
29363
29420
|
continue;
|
|
29364
29421
|
}
|
|
@@ -29895,6 +29952,12 @@ function OhhwellsBridge() {
|
|
|
29895
29952
|
closeLinkPopoverRef.current();
|
|
29896
29953
|
return;
|
|
29897
29954
|
}
|
|
29955
|
+
if (floatingPanelOpenRef.current) {
|
|
29956
|
+
setFloatingPanelRef.current(null);
|
|
29957
|
+
deselectRef.current();
|
|
29958
|
+
deactivateRef.current();
|
|
29959
|
+
return;
|
|
29960
|
+
}
|
|
29898
29961
|
deselectRef.current();
|
|
29899
29962
|
deactivateRef.current();
|
|
29900
29963
|
clearMediaSelectionRef.current();
|
|
@@ -30708,10 +30771,10 @@ function OhhwellsBridge() {
|
|
|
30708
30771
|
window.removeEventListener("message", handleDeleteSection);
|
|
30709
30772
|
window.removeEventListener("message", handleDuplicateSection);
|
|
30710
30773
|
window.removeEventListener("message", handleDeactivate);
|
|
30711
|
-
document.documentElement.removeAttribute("data-ohw-panel-dragging");
|
|
30712
30774
|
window.removeEventListener("message", handleToastAction);
|
|
30713
30775
|
window.removeEventListener("message", handleFormCount);
|
|
30714
30776
|
window.removeEventListener("message", handleUiEscape);
|
|
30777
|
+
document.documentElement.removeAttribute("data-ohw-panel-dragging");
|
|
30715
30778
|
autoSaveTimers.current.forEach(clearTimeout);
|
|
30716
30779
|
autoSaveTimers.current.clear();
|
|
30717
30780
|
if (imageUnhoverTimerRef.current) clearTimeout(imageUnhoverTimerRef.current);
|
|
@@ -31005,7 +31068,7 @@ function OhhwellsBridge() {
|
|
|
31005
31068
|
postToParent2({
|
|
31006
31069
|
type: "ow:ready",
|
|
31007
31070
|
version: "1",
|
|
31008
|
-
bridgeVersion: "0.1.
|
|
31071
|
+
bridgeVersion: "0.1.139",
|
|
31009
31072
|
path: pathname,
|
|
31010
31073
|
nodes: collectEditableNodes(editContentRef.current),
|
|
31011
31074
|
sections
|