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