@ohhwells/bridge 0.1.133 → 0.1.134-next.362
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 +138 -74
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +138 -74
- 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.js
CHANGED
|
@@ -2564,6 +2564,19 @@ function quotedFont(font) {
|
|
|
2564
2564
|
const cleaned = font.replace(/["']/g, "").trim();
|
|
2565
2565
|
return cleaned ? `"${cleaned}"` : "sans-serif";
|
|
2566
2566
|
}
|
|
2567
|
+
function themeFont(role, fallback) {
|
|
2568
|
+
const quoted = quotedFont(fallback);
|
|
2569
|
+
return role === "heading" ? `var(--brand-font-heading, var(--font-heading, var(--font-display, ${quoted})))` : `var(--brand-font-body, var(--font-body, ${quoted}))`;
|
|
2570
|
+
}
|
|
2571
|
+
function withThemeFonts(brand) {
|
|
2572
|
+
return {
|
|
2573
|
+
...brand,
|
|
2574
|
+
fonts: {
|
|
2575
|
+
heading: themeFont("heading", brand.fonts.heading),
|
|
2576
|
+
body: themeFont("body", brand.fonts.body)
|
|
2577
|
+
}
|
|
2578
|
+
};
|
|
2579
|
+
}
|
|
2567
2580
|
function footerLogoStyle(fallbackFont, fallbackColor) {
|
|
2568
2581
|
return {
|
|
2569
2582
|
fontFamily: `var(--brand-font-heading, var(--font-heading, var(--font-display, ${quotedFont(fallbackFont)})))`,
|
|
@@ -2635,7 +2648,7 @@ var AI_MOBILE_CSS = [
|
|
|
2635
2648
|
// page's first section. Top only (bottom needs no nav clearance); ~96px approximates the
|
|
2636
2649
|
// template nav's own height (measured ~94px) — there's no shared `--ohw-header-h` var to read
|
|
2637
2650
|
// an exact figure from (no live measurement exists), so this is a safe approximation, not a
|
|
2638
|
-
// pixel-exact fit. Horizontal spacing already comes from `data-ai-
|
|
2651
|
+
// pixel-exact fit. Horizontal spacing already comes from `data-ai-section-inner`.
|
|
2639
2652
|
'[data-ai-overlay-clearance] [data-ai-overlap-layer="overlay"]{padding-top:96px}',
|
|
2640
2653
|
// A full-bleed carousel's height is pure arithmetic: it spans the whole window, so 16/9 turns
|
|
2641
2654
|
// window width straight into height. Measured at 16/9 it came out ~90% of the viewport at EVERY
|
|
@@ -2651,8 +2664,10 @@ var AI_MOBILE_CSS = [
|
|
|
2651
2664
|
"[data-ai-section]{overflow-x:hidden}",
|
|
2652
2665
|
// `:not([data-ai-full-bleed])`: this `!important` gutter beat the inline `padding: 0` that a
|
|
2653
2666
|
// full-bleed section's container sets, so a carousel/media hero that is edge-to-edge on desktop
|
|
2654
|
-
// still got a 20px band of section background down both sides on a phone.
|
|
2655
|
-
|
|
2667
|
+
// still got a 20px band of section background down both sides on a phone. The footer's own
|
|
2668
|
+
// container keeps the unguarded rule below — `data-ai-full-bleed` can never appear on it.
|
|
2669
|
+
"[data-ai-section-inner]:not([data-ai-full-bleed]){padding:0 20px !important}",
|
|
2670
|
+
"[data-ai-container]{padding:0 20px !important}",
|
|
2656
2671
|
"[data-ai-row]{display:flex !important;flex-direction:column !important;align-items:stretch !important}",
|
|
2657
2672
|
"[data-ai-cell]{width:100%;min-width:0}",
|
|
2658
2673
|
// The rule above turns every row into a COLUMN flex container on phones, which silently breaks
|
|
@@ -2853,6 +2868,31 @@ function pricingCardEmphasis(featured, ctx, hasBg) {
|
|
|
2853
2868
|
function textAttrs(ctx, path) {
|
|
2854
2869
|
return ctx.keyFor ? { "data-ohw-key": ctx.keyFor(path), "data-ohw-editable": "text" } : {};
|
|
2855
2870
|
}
|
|
2871
|
+
var AI_RESPONSIVE_CSS = [
|
|
2872
|
+
"@media (max-width: 960px) {",
|
|
2873
|
+
" [data-ai-responsive] [data-ai-grid] { grid-template-columns: repeat(2, 1fr) !important; }",
|
|
2874
|
+
' [data-ai-responsive] [data-ai-grid="1"] { grid-template-columns: 1fr !important; }',
|
|
2875
|
+
"}",
|
|
2876
|
+
"@media (max-width: 640px) {",
|
|
2877
|
+
" [data-ai-responsive] [data-ai-grid] { grid-template-columns: 1fr !important; }",
|
|
2878
|
+
" [data-ai-responsive] [data-ai-columns] > * { grid-column: 1 / -1 !important; }",
|
|
2879
|
+
// Group containers flatten to a column on phones; span placements come along for free.
|
|
2880
|
+
// `:not([data-ai-group="overlap"])` for the same reason as the twin pair in AI_MOBILE_CSS — see
|
|
2881
|
+
// the comment there. This sheet's copy is the narrower selector, so without the exemption it
|
|
2882
|
+
// flattens an `overlap` hero below 640px even though the other rule stands down: measured a 390px
|
|
2883
|
+
// viewport with the heading/CTA in flow *under* the image, 219px of section background where the
|
|
2884
|
+
// layered text used to be.
|
|
2885
|
+
' [data-ai-responsive] [data-ai-group]:not([data-ai-group="overlap"]) { display: flex !important; flex-direction: column !important; }',
|
|
2886
|
+
' [data-ai-responsive] [data-ai-group]:not([data-ai-group="overlap"]) > * { grid-column: auto !important; }',
|
|
2887
|
+
// `:not([data-ai-full-bleed])` for the same reason as the twin rule in AI_MOBILE_CSS: this one
|
|
2888
|
+
// is narrower (0,2,0 vs 0,1,0) and also `!important`, so without the guard it wins outright and
|
|
2889
|
+
// a full-bleed hero gets its 20px side band back below 640px only — the one width where the
|
|
2890
|
+
// other rule had already been taught to stand down.
|
|
2891
|
+
" [data-ai-responsive] [data-ai-section-inner]:not([data-ai-full-bleed]) { padding-left: 20px !important; padding-right: 20px !important; }",
|
|
2892
|
+
" [data-ai-responsive] { overflow-x: hidden; }",
|
|
2893
|
+
" [data-ai-responsive] img { max-width: 100%; }",
|
|
2894
|
+
"}"
|
|
2895
|
+
].join("\n");
|
|
2856
2896
|
var TRANSPARENT_PX = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7";
|
|
2857
2897
|
function MediaBox({
|
|
2858
2898
|
refValue,
|
|
@@ -2873,9 +2913,9 @@ function MediaBox({
|
|
|
2873
2913
|
const url = refValue ? ctx.resolveMedia(refValue) : null;
|
|
2874
2914
|
const isIcon = /^(lucide|simple):/.test(refValue);
|
|
2875
2915
|
const aspectRatio = aspect && /^\d+:\d+$/.test(aspect) ? aspect.replace(":", " / ") : void 0;
|
|
2876
|
-
const editAttrs = ctx.keyFor && editPath
|
|
2916
|
+
const editAttrs = ctx.keyFor && editPath ? {
|
|
2877
2917
|
"data-ohw-key": ctx.keyFor(editPath),
|
|
2878
|
-
...genericImageEdit ? { "data-ohw-editable": "image" } : {}
|
|
2918
|
+
...isIcon ? { "data-ohw-editable": "icon" } : genericImageEdit ? { "data-ohw-editable": "image" } : {}
|
|
2879
2919
|
} : {};
|
|
2880
2920
|
if (isIcon) {
|
|
2881
2921
|
const Icon = refValue.startsWith("lucide:") ? lucideByName(refValue.slice(7)) : null;
|
|
@@ -2883,6 +2923,7 @@ function MediaBox({
|
|
|
2883
2923
|
"span",
|
|
2884
2924
|
{
|
|
2885
2925
|
"data-ai-icon": refValue,
|
|
2926
|
+
...editAttrs,
|
|
2886
2927
|
style: {
|
|
2887
2928
|
display: "inline-flex",
|
|
2888
2929
|
width: 48,
|
|
@@ -4376,7 +4417,7 @@ function CollectionBlock({ node, ctx, path }) {
|
|
|
4376
4417
|
return /* @__PURE__ */ jsx(
|
|
4377
4418
|
"div",
|
|
4378
4419
|
{
|
|
4379
|
-
"data-ai-grid":
|
|
4420
|
+
"data-ai-grid": String(itemsPerRow),
|
|
4380
4421
|
"data-ohw-pricing-collection": isPricing ? "" : void 0,
|
|
4381
4422
|
style: {
|
|
4382
4423
|
display: "grid",
|
|
@@ -4636,7 +4677,7 @@ function renderNode(node, ctx, path, ambientAlign) {
|
|
|
4636
4677
|
},
|
|
4637
4678
|
children: [
|
|
4638
4679
|
i > 0 && ctx.heroOverlapFullBleed ? (
|
|
4639
|
-
// The section's `data-ai-
|
|
4680
|
+
// The section's `data-ai-section-inner` gave up its max-width/gutter so the base
|
|
4640
4681
|
// layer (this group's i===0 sibling) can span edge-to-edge — reintroduced here,
|
|
4641
4682
|
// scoped to just the overlay text, so a heading/copy/CTA stack doesn't stretch
|
|
4642
4683
|
// the full section width instead of reading at the usual content width.
|
|
@@ -4959,7 +5000,7 @@ function AiTreeRenderer({
|
|
|
4959
5000
|
if (!isRenderableTree(tree)) {
|
|
4960
5001
|
return null;
|
|
4961
5002
|
}
|
|
4962
|
-
const resolvedBrand = brand ?? AI_DEFAULT_BRAND;
|
|
5003
|
+
const resolvedBrand = withThemeFonts(brand ?? AI_DEFAULT_BRAND);
|
|
4963
5004
|
const band = (tree.settings ?? {}).sectionBackground === "accent" ? accentBandContext(resolvedBrand) : null;
|
|
4964
5005
|
const blockBrand = band?.brand ?? resolvedBrand;
|
|
4965
5006
|
const placeholderMap = buildPlaceholderMap(tree);
|
|
@@ -5029,6 +5070,7 @@ function AiTreeRenderer({
|
|
|
5029
5070
|
...fillHeight ? { "data-ai-fill-height": "" } : {},
|
|
5030
5071
|
...needsOverlayClearance ? { "data-ai-overlay-clearance": "" } : {},
|
|
5031
5072
|
...bgAttrs,
|
|
5073
|
+
"data-ai-responsive": "",
|
|
5032
5074
|
style: {
|
|
5033
5075
|
position: "relative",
|
|
5034
5076
|
padding: `${padCss} 0`,
|
|
@@ -5042,12 +5084,13 @@ function AiTreeRenderer({
|
|
|
5042
5084
|
...fillHeight ? { display: "grid" } : {}
|
|
5043
5085
|
},
|
|
5044
5086
|
children: [
|
|
5045
|
-
|
|
5087
|
+
/* @__PURE__ */ jsx("style", { children: AI_RESPONSIVE_CSS }),
|
|
5046
5088
|
/* @__PURE__ */ jsx("style", { children: AI_MOBILE_CSS }),
|
|
5089
|
+
isOverlay && backgroundUrl && /* @__PURE__ */ jsx("div", { style: { position: "absolute", inset: 0, background: `rgba(255,255,255,${overlayAlpha})` } }),
|
|
5047
5090
|
/* @__PURE__ */ jsx(
|
|
5048
5091
|
"div",
|
|
5049
5092
|
{
|
|
5050
|
-
"data-ai-
|
|
5093
|
+
"data-ai-section-inner": "",
|
|
5051
5094
|
...fullBleedMedia ? { "data-ai-full-bleed": "" } : {},
|
|
5052
5095
|
style: {
|
|
5053
5096
|
position: "relative",
|
|
@@ -5064,7 +5107,7 @@ function AiTreeRenderer({
|
|
|
5064
5107
|
children: tree.rows.map((row, r2) => /* @__PURE__ */ jsx(
|
|
5065
5108
|
"div",
|
|
5066
5109
|
{
|
|
5067
|
-
"data-ai-
|
|
5110
|
+
"data-ai-columns": "",
|
|
5068
5111
|
style: {
|
|
5069
5112
|
display: "grid",
|
|
5070
5113
|
gridTemplateColumns: "repeat(12, 1fr)",
|
|
@@ -5115,7 +5158,7 @@ function AiFooterRenderer({
|
|
|
5115
5158
|
if (!isRenderableFooterTree(tree)) {
|
|
5116
5159
|
return null;
|
|
5117
5160
|
}
|
|
5118
|
-
const resolvedBrand = brand ?? AI_DEFAULT_BRAND;
|
|
5161
|
+
const resolvedBrand = withThemeFonts(brand ?? AI_DEFAULT_BRAND);
|
|
5119
5162
|
const bandBg = surface?.background ?? resolvedBrand.palette.dark;
|
|
5120
5163
|
const bandText = surface?.text ?? resolvedBrand.palette.light;
|
|
5121
5164
|
const onDark = surface ? isDarkColor(surface.background) : true;
|
|
@@ -5720,9 +5763,10 @@ function applyAiSectionsToDom(state, options) {
|
|
|
5720
5763
|
if (existing && existing.serialized === serialized && existing.container.isConnected) {
|
|
5721
5764
|
continue;
|
|
5722
5765
|
}
|
|
5723
|
-
const isNewMount = !existing || !existing.container.isConnected;
|
|
5724
5766
|
let container = existing?.container;
|
|
5767
|
+
let isNewMount = false;
|
|
5725
5768
|
if (!container || !container.isConnected) {
|
|
5769
|
+
isNewMount = true;
|
|
5726
5770
|
existing?.root.unmount();
|
|
5727
5771
|
container?.remove();
|
|
5728
5772
|
container = document.createElement("div");
|
|
@@ -8938,7 +8982,7 @@ var isLabelWeight = (label) => label === "number" || label === "weight";
|
|
|
8938
8982
|
var isLabelShadow = (label) => label === "shadow";
|
|
8939
8983
|
var getDefaultConfig = () => {
|
|
8940
8984
|
const themeColor = fromTheme("color");
|
|
8941
|
-
const
|
|
8985
|
+
const themeFont2 = fromTheme("font");
|
|
8942
8986
|
const themeText = fromTheme("text");
|
|
8943
8987
|
const themeFontWeight = fromTheme("font-weight");
|
|
8944
8988
|
const themeTracking = fromTheme("tracking");
|
|
@@ -9860,7 +9904,7 @@ var getDefaultConfig = () => {
|
|
|
9860
9904
|
* @see https://tailwindcss.com/docs/font-family
|
|
9861
9905
|
*/
|
|
9862
9906
|
"font-family": [{
|
|
9863
|
-
font: [isArbitraryVariableFamilyName, isArbitraryFamilyName,
|
|
9907
|
+
font: [isArbitraryVariableFamilyName, isArbitraryFamilyName, themeFont2]
|
|
9864
9908
|
}],
|
|
9865
9909
|
/**
|
|
9866
9910
|
* Font Feature Settings
|
|
@@ -13357,6 +13401,7 @@ function MediaOverlay({
|
|
|
13357
13401
|
(prev) => prev && prev.fullWidth === width && prev.height === height ? prev : { fullWidth: width, height }
|
|
13358
13402
|
);
|
|
13359
13403
|
}, [isVideo]);
|
|
13404
|
+
const replaceLabel = isVideo ? "Replace video" : hover.elementType === "bg-image" ? "Replace background" : "Replace image";
|
|
13360
13405
|
const replaceMode = buttonSize ? replaceButtonMode({ width: rect.width, height: rect.height }, buttonSize) : "none";
|
|
13361
13406
|
const box = {
|
|
13362
13407
|
position: "fixed",
|
|
@@ -13455,11 +13500,10 @@ function MediaOverlay({
|
|
|
13455
13500
|
className: "flex items-center justify-center cursor-pointer",
|
|
13456
13501
|
style: {
|
|
13457
13502
|
...box,
|
|
13458
|
-
//
|
|
13459
|
-
//
|
|
13460
|
-
//
|
|
13461
|
-
|
|
13462
|
-
pointerEvents: hover.hasTextOverlap || cueOnly ? "none" : "auto",
|
|
13503
|
+
// Visual only. `pointer-events: auto` on this full-bleed rect covered the navbar
|
|
13504
|
+
// (hero bg includes the absolute TopNav) and swallowed CTA press-drag. Text overlay
|
|
13505
|
+
// and cueOnly also need clicks to fall through — Replace / video controls opt back in.
|
|
13506
|
+
pointerEvents: "none",
|
|
13463
13507
|
// Selected: a firm component ring with no wash, so the image reads as chosen rather
|
|
13464
13508
|
// than hovered. Hover keeps the existing tinted preview.
|
|
13465
13509
|
boxShadow: selected ? "inset 0 0 0 2px var(--color-bridge-primary)" : "inset 0 0 0 1.5px var(--color-bridge-primary)",
|
|
@@ -13486,17 +13530,17 @@ function MediaOverlay({
|
|
|
13486
13530
|
},
|
|
13487
13531
|
children: [
|
|
13488
13532
|
isVideo ? /* @__PURE__ */ jsx16(Film, { size: 14 }) : /* @__PURE__ */ jsx16(ImageIcon, { size: 14 }),
|
|
13489
|
-
|
|
13533
|
+
replaceLabel
|
|
13490
13534
|
]
|
|
13491
13535
|
}
|
|
13492
13536
|
),
|
|
13493
|
-
replaceMode
|
|
13537
|
+
showChrome && replaceMode !== "none" && /* @__PURE__ */ jsxs7(
|
|
13494
13538
|
Button,
|
|
13495
13539
|
{
|
|
13496
13540
|
"data-ohw-media-overlay": "",
|
|
13497
13541
|
variant: "outline",
|
|
13498
13542
|
size: "sm",
|
|
13499
|
-
"aria-label":
|
|
13543
|
+
"aria-label": replaceLabel,
|
|
13500
13544
|
className: "gap-1.5 cursor-pointer hover:bg-background",
|
|
13501
13545
|
style: {
|
|
13502
13546
|
...OVERLAY_BUTTON_STYLE,
|
|
@@ -13519,7 +13563,7 @@ function MediaOverlay({
|
|
|
13519
13563
|
},
|
|
13520
13564
|
children: [
|
|
13521
13565
|
isVideo ? /* @__PURE__ */ jsx16(Film, { size: 14 }) : /* @__PURE__ */ jsx16(ImageIcon, { size: 14 }),
|
|
13522
|
-
replaceMode === "full" ?
|
|
13566
|
+
replaceMode === "full" ? replaceLabel : null
|
|
13523
13567
|
]
|
|
13524
13568
|
}
|
|
13525
13569
|
)
|
|
@@ -19751,6 +19795,7 @@ function readLogoSizeState(content, placement) {
|
|
|
19751
19795
|
function getLogoElement(el) {
|
|
19752
19796
|
const marked = el.closest('[data-ohw-role="logo"], [data-ohw-logo]');
|
|
19753
19797
|
if (marked) return marked;
|
|
19798
|
+
if (el.closest('[data-ohw-editable="icon"]')) return null;
|
|
19754
19799
|
const root = el.closest("nav, [data-ohw-nav-root], footer");
|
|
19755
19800
|
if (!root) return null;
|
|
19756
19801
|
const anchor = el.closest("a");
|
|
@@ -23248,7 +23293,7 @@ function getNavigationSelectionParent(el) {
|
|
|
23248
23293
|
if (!isFooterLinksContainer(el) && (el.hasAttribute("data-ohw-footer-col") || el.hasAttribute("data-ohw-footer-column") || isInferredFooterGroup2(el))) {
|
|
23249
23294
|
return resolveFooterLinksContainerFrom(el);
|
|
23250
23295
|
}
|
|
23251
|
-
if (el.hasAttribute("data-ohw-nav-container") || el.hasAttribute("data-ohw-nav-drawer") || isFooterLinksContainer(el)) {
|
|
23296
|
+
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)) {
|
|
23252
23297
|
return getNavigationRoot(el);
|
|
23253
23298
|
}
|
|
23254
23299
|
return null;
|
|
@@ -23470,7 +23515,6 @@ var ICONS = {
|
|
|
23470
23515
|
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"/>',
|
|
23471
23516
|
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"/>'
|
|
23472
23517
|
};
|
|
23473
|
-
var HEIGHT_SETTLE_DELAYS = [150, 400, 800];
|
|
23474
23518
|
var SELECTION_CHROME_GAP2 = 4;
|
|
23475
23519
|
var TOOLBAR_STROKE_GAP2 = 4;
|
|
23476
23520
|
var TOOLBAR_OFFSET_FROM_ELEMENT = SELECTION_CHROME_GAP2 + TOOLBAR_STROKE_GAP2;
|
|
@@ -24450,21 +24494,6 @@ function OhhwellsBridge() {
|
|
|
24450
24494
|
const [isItemDragging, setIsItemDragging] = useState18(false);
|
|
24451
24495
|
const [isFooterFrameSelection, setIsFooterFrameSelection] = useState18(false);
|
|
24452
24496
|
isFooterFrameSelectionRef.current = isFooterFrameSelection;
|
|
24453
|
-
const [floatingPanel, setFloatingPanel] = useState18(null);
|
|
24454
|
-
const floatingPanelOpenRef = useRef14(false);
|
|
24455
|
-
floatingPanelOpenRef.current = floatingPanel !== null;
|
|
24456
|
-
const floatingPanelRef = useRef14(null);
|
|
24457
|
-
floatingPanelRef.current = floatingPanel;
|
|
24458
|
-
const [floatingPanelPos, setFloatingPanelPos] = useState18(null);
|
|
24459
|
-
const buttonCollectionDragRef = useRef14(null);
|
|
24460
|
-
const buttonDropInsertIndexRef = useRef14(null);
|
|
24461
|
-
const [buttonDropSlots, setButtonDropSlots] = useState18([]);
|
|
24462
|
-
const [activeButtonDropIndex, setActiveButtonDropIndex] = useState18(null);
|
|
24463
|
-
const buttonPointerDragRef = useRef14(null);
|
|
24464
|
-
const [buttonStyleTick, setButtonStyleTick] = useState18(0);
|
|
24465
|
-
const [logoSizeDraft, setLogoSizeDraft] = useState18(null);
|
|
24466
|
-
const [editorViewport, setEditorViewport] = useState18("desktop");
|
|
24467
|
-
const [parentScrollSnap, setParentScrollSnap] = useState18(null);
|
|
24468
24497
|
const [navDropdownPreviewOpen, setNavDropdownPreviewOpen] = useState18(null);
|
|
24469
24498
|
const [footerHeadingVisible, setFooterHeadingVisible] = useState18(null);
|
|
24470
24499
|
const footerDragRef = useRef14(null);
|
|
@@ -24490,6 +24519,21 @@ function OhhwellsBridge() {
|
|
|
24490
24519
|
const stylesRef = useRef14("");
|
|
24491
24520
|
const appliedDrawerRef = useRef14(null);
|
|
24492
24521
|
const pendingDeleteUndoRef = useRef14(null);
|
|
24522
|
+
const [floatingPanel, setFloatingPanel] = useState18(null);
|
|
24523
|
+
const floatingPanelOpenRef = useRef14(false);
|
|
24524
|
+
const floatingPanelRef = useRef14(null);
|
|
24525
|
+
floatingPanelRef.current = floatingPanel;
|
|
24526
|
+
const setFloatingPanelRef = useRef14(setFloatingPanel);
|
|
24527
|
+
const [floatingPanelPos, setFloatingPanelPos] = useState18(null);
|
|
24528
|
+
const buttonCollectionDragRef = useRef14(null);
|
|
24529
|
+
const buttonDropInsertIndexRef = useRef14(null);
|
|
24530
|
+
const [buttonDropSlots, setButtonDropSlots] = useState18([]);
|
|
24531
|
+
const [activeButtonDropIndex, setActiveButtonDropIndex] = useState18(null);
|
|
24532
|
+
const buttonPointerDragRef = useRef14(null);
|
|
24533
|
+
const [buttonStyleTick, setButtonStyleTick] = useState18(0);
|
|
24534
|
+
const [logoSizeDraft, setLogoSizeDraft] = useState18(null);
|
|
24535
|
+
const [editorViewport, setEditorViewport] = useState18("desktop");
|
|
24536
|
+
const [parentScrollSnap, setParentScrollSnap] = useState18(null);
|
|
24493
24537
|
const [sitePages, setSitePages] = useState18([]);
|
|
24494
24538
|
const [sectionsByPath, setSectionsByPath] = useState18({});
|
|
24495
24539
|
const sectionsPrefetchGenRef = useRef14(0);
|
|
@@ -24498,7 +24542,18 @@ function OhhwellsBridge() {
|
|
|
24498
24542
|
const linkPopoverOpenRef = useRef14(false);
|
|
24499
24543
|
const linkPopoverGraceUntilRef = useRef14(0);
|
|
24500
24544
|
setLinkPopoverRef.current = setLinkPopover;
|
|
24545
|
+
setFloatingPanelRef.current = setFloatingPanel;
|
|
24501
24546
|
linkPopoverSessionRef.current = linkPopover;
|
|
24547
|
+
floatingPanelOpenRef.current = Boolean(floatingPanel);
|
|
24548
|
+
useEffect17(() => {
|
|
24549
|
+
const syncViewport = () => {
|
|
24550
|
+
const next = window.innerWidth <= 480 ? "mobile" : "desktop";
|
|
24551
|
+
setEditorViewport((prev) => prev === next ? prev : next);
|
|
24552
|
+
};
|
|
24553
|
+
syncViewport();
|
|
24554
|
+
window.addEventListener("resize", syncViewport);
|
|
24555
|
+
return () => window.removeEventListener("resize", syncViewport);
|
|
24556
|
+
}, []);
|
|
24502
24557
|
useEffect17(() => {
|
|
24503
24558
|
setSectionOrderPersistHandler((entries) => {
|
|
24504
24559
|
const currentPath = window.location.pathname;
|
|
@@ -26177,6 +26232,7 @@ function OhhwellsBridge() {
|
|
|
26177
26232
|
applyAiFooterFromContent(content);
|
|
26178
26233
|
if (typeof content[STYLE_STORE_KEY] === "string") {
|
|
26179
26234
|
stylesRef.current = content[STYLE_STORE_KEY];
|
|
26235
|
+
document.querySelectorAll('[data-ohw-editable="form"]').forEach((f) => markFormFields(f));
|
|
26180
26236
|
applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
|
|
26181
26237
|
}
|
|
26182
26238
|
applyBrandChrome(content);
|
|
@@ -26186,12 +26242,12 @@ function OhhwellsBridge() {
|
|
|
26186
26242
|
if (key === "__ohw_sections") continue;
|
|
26187
26243
|
if (key === AI_SECTIONS_KEY) continue;
|
|
26188
26244
|
if (key === AI_FOOTER_KEY) continue;
|
|
26245
|
+
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
26246
|
+
if (LOGO_IMAGE_KEYS.includes(key)) continue;
|
|
26189
26247
|
if (key === BRAND_KIT_KEY) continue;
|
|
26190
26248
|
if (key === STYLE_STORE_KEY) continue;
|
|
26191
26249
|
if (BRAND_CHROME_KEYS.has(key)) continue;
|
|
26192
|
-
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
26193
26250
|
if (key === CUSTOM_CODE_AFTER_HEAD_KEY || key === CUSTOM_CODE_BEFORE_HEAD_KEY) continue;
|
|
26194
|
-
if (LOGO_IMAGE_KEYS.includes(key)) continue;
|
|
26195
26251
|
if (typeof content[AI_FOOTER_KEY] === "string" && content[AI_FOOTER_KEY] && isAiFooterOwnedContentKey(key)) {
|
|
26196
26252
|
continue;
|
|
26197
26253
|
}
|
|
@@ -26405,17 +26461,18 @@ function OhhwellsBridge() {
|
|
|
26405
26461
|
}
|
|
26406
26462
|
applyAiFooterFromContent(content);
|
|
26407
26463
|
if (typeof content[STYLE_STORE_KEY] === "string") {
|
|
26464
|
+
document.querySelectorAll('[data-ohw-editable="form"]').forEach((f) => markFormFields(f));
|
|
26408
26465
|
applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
|
|
26409
26466
|
}
|
|
26410
26467
|
for (const [key, val] of Object.entries(content)) {
|
|
26411
26468
|
if (key === "__ohw_sections") continue;
|
|
26412
26469
|
if (key === AI_SECTIONS_KEY) continue;
|
|
26413
26470
|
if (key === AI_FOOTER_KEY) continue;
|
|
26471
|
+
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
26472
|
+
if (LOGO_IMAGE_KEYS.includes(key)) continue;
|
|
26414
26473
|
if (key === BRAND_KIT_KEY) continue;
|
|
26415
26474
|
if (key === STYLE_STORE_KEY) continue;
|
|
26416
26475
|
if (BRAND_CHROME_KEYS.has(key)) continue;
|
|
26417
|
-
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
26418
|
-
if (LOGO_IMAGE_KEYS.includes(key)) continue;
|
|
26419
26476
|
if (typeof content[AI_FOOTER_KEY] === "string" && content[AI_FOOTER_KEY] && isAiFooterOwnedContentKey(key)) {
|
|
26420
26477
|
continue;
|
|
26421
26478
|
}
|
|
@@ -26671,26 +26728,11 @@ function OhhwellsBridge() {
|
|
|
26671
26728
|
const t2 = setTimeout(measure, 500);
|
|
26672
26729
|
const ro = new ResizeObserver(schedule);
|
|
26673
26730
|
ro.observe(document.body);
|
|
26674
|
-
let lastWidth = window.innerWidth;
|
|
26675
|
-
let resizeTimers = [];
|
|
26676
|
-
const clearResizeTimers = () => {
|
|
26677
|
-
resizeTimers.forEach(clearTimeout);
|
|
26678
|
-
resizeTimers = [];
|
|
26679
|
-
};
|
|
26680
|
-
const handleResize = () => {
|
|
26681
|
-
if (window.innerWidth === lastWidth) return;
|
|
26682
|
-
lastWidth = window.innerWidth;
|
|
26683
|
-
clearResizeTimers();
|
|
26684
|
-
resizeTimers = HEIGHT_SETTLE_DELAYS.map((delay) => setTimeout(measure, delay));
|
|
26685
|
-
};
|
|
26686
|
-
window.addEventListener("resize", handleResize);
|
|
26687
26731
|
return () => {
|
|
26688
26732
|
clearTimeout(t1);
|
|
26689
26733
|
clearTimeout(t2);
|
|
26690
26734
|
if (raf != null) cancelAnimationFrame(raf);
|
|
26691
26735
|
ro.disconnect();
|
|
26692
|
-
clearResizeTimers();
|
|
26693
|
-
window.removeEventListener("resize", handleResize);
|
|
26694
26736
|
};
|
|
26695
26737
|
}, [pathname, isEditMode, postToParent2]);
|
|
26696
26738
|
useEffect17(() => {
|
|
@@ -26985,6 +27027,13 @@ function OhhwellsBridge() {
|
|
|
26985
27027
|
if (target.closest("[data-ohw-state-toggle]")) return;
|
|
26986
27028
|
if (target.closest("[data-ohw-max-badge]")) return;
|
|
26987
27029
|
if (isInsideLinkEditor(target)) return;
|
|
27030
|
+
if (isInsideFloatingPanel(target)) return;
|
|
27031
|
+
if (target.closest("[data-ohw-form-toolbar]")) return;
|
|
27032
|
+
if (target.closest(
|
|
27033
|
+
'[data-ohw-field-toolbar], [data-ohw-field-type-picker], [data-radix-popper-content-wrapper], [role="menu"], [data-slot="dropdown-menu-content"]'
|
|
27034
|
+
)) {
|
|
27035
|
+
return;
|
|
27036
|
+
}
|
|
26988
27037
|
if (selectedMediaElRef.current && !selectedMediaElRef.current.contains(target) && !target.closest("[data-ohw-media-overlay], [data-ohw-edit-chrome], [data-ohw-item-interaction]")) {
|
|
26989
27038
|
clearMediaSelectionRef.current();
|
|
26990
27039
|
}
|
|
@@ -27005,13 +27054,6 @@ function OhhwellsBridge() {
|
|
|
27005
27054
|
return;
|
|
27006
27055
|
}
|
|
27007
27056
|
}
|
|
27008
|
-
if (isInsideFloatingPanel(target)) return;
|
|
27009
|
-
if (target.closest("[data-ohw-form-toolbar]")) return;
|
|
27010
|
-
if (target.closest(
|
|
27011
|
-
'[data-ohw-field-toolbar], [data-ohw-field-type-picker], [data-radix-popper-content-wrapper], [role="menu"], [data-slot="dropdown-menu-content"]'
|
|
27012
|
-
)) {
|
|
27013
|
-
return;
|
|
27014
|
-
}
|
|
27015
27057
|
{
|
|
27016
27058
|
const formEl = getFormElement(target);
|
|
27017
27059
|
const onSuccessText = target.closest(`[${SUCCESS_TEXT_ATTR}]`);
|
|
@@ -27391,6 +27433,9 @@ function OhhwellsBridge() {
|
|
|
27391
27433
|
setHoveredItemRect(null);
|
|
27392
27434
|
hoveredNavContainerRef.current = null;
|
|
27393
27435
|
setHoveredNavContainerRect(null);
|
|
27436
|
+
siblingHintElRef.current = null;
|
|
27437
|
+
setSiblingHintRect(null);
|
|
27438
|
+
setSiblingHintRects([]);
|
|
27394
27439
|
return;
|
|
27395
27440
|
}
|
|
27396
27441
|
{
|
|
@@ -27511,7 +27556,6 @@ function OhhwellsBridge() {
|
|
|
27511
27556
|
hoveredNavContainerRef.current = null;
|
|
27512
27557
|
setHoveredNavContainerRect(null);
|
|
27513
27558
|
hoveredItemElRef.current = editable;
|
|
27514
|
-
setHoveredItemRect(isSelectedForHoverRef.current(editable) ? null : editable.getBoundingClientRect());
|
|
27515
27559
|
}
|
|
27516
27560
|
}
|
|
27517
27561
|
}
|
|
@@ -28221,7 +28265,11 @@ function OhhwellsBridge() {
|
|
|
28221
28265
|
};
|
|
28222
28266
|
const handleMouseMove = (e) => {
|
|
28223
28267
|
const { clientX, clientY } = e;
|
|
28224
|
-
if (pointOwnedByFloatingPanel(clientX, clientY))
|
|
28268
|
+
if (pointOwnedByFloatingPanel(clientX, clientY)) {
|
|
28269
|
+
dismissImageHover();
|
|
28270
|
+
clearImageHover();
|
|
28271
|
+
return;
|
|
28272
|
+
}
|
|
28225
28273
|
if (isNavDrawerOpen() && isPointOutsideOpenDrawer(clientX, clientY)) {
|
|
28226
28274
|
document.querySelectorAll("[data-ohw-hovered]").forEach((el) => el.removeAttribute("data-ohw-hovered"));
|
|
28227
28275
|
formHoverElRef.current = null;
|
|
@@ -28250,7 +28298,12 @@ function OhhwellsBridge() {
|
|
|
28250
28298
|
setHoveredItemRect(null);
|
|
28251
28299
|
hoveredNavContainerRef.current = null;
|
|
28252
28300
|
setHoveredNavContainerRect(null);
|
|
28301
|
+
siblingHintElRef.current = null;
|
|
28302
|
+
setSiblingHintRect(null);
|
|
28303
|
+
setSiblingHintRects([]);
|
|
28253
28304
|
dismissImageHover();
|
|
28305
|
+
clearImageHover();
|
|
28306
|
+
setSectionGap(null);
|
|
28254
28307
|
return;
|
|
28255
28308
|
}
|
|
28256
28309
|
if (probeSocialsRowAt(clientX, clientY)) return;
|
|
@@ -28262,7 +28315,11 @@ function OhhwellsBridge() {
|
|
|
28262
28315
|
if (e.data?.type !== "ow:pointer-sync") return;
|
|
28263
28316
|
const { clientX, clientY } = e.data;
|
|
28264
28317
|
if (typeof clientX !== "number" || typeof clientY !== "number") return;
|
|
28265
|
-
if (pointOwnedByFloatingPanel(clientX, clientY))
|
|
28318
|
+
if (pointOwnedByFloatingPanel(clientX, clientY)) {
|
|
28319
|
+
dismissImageHover();
|
|
28320
|
+
clearImageHover();
|
|
28321
|
+
return;
|
|
28322
|
+
}
|
|
28266
28323
|
if (isNavDrawerOpen() && isPointOutsideOpenDrawer(clientX, clientY)) return;
|
|
28267
28324
|
if (probeSocialsRowAt(clientX, clientY)) return;
|
|
28268
28325
|
probeSectionGapAt(clientX, clientY);
|
|
@@ -28614,6 +28671,7 @@ function OhhwellsBridge() {
|
|
|
28614
28671
|
applyAiFooterFromContent(content);
|
|
28615
28672
|
if (typeof content[STYLE_STORE_KEY] === "string") {
|
|
28616
28673
|
stylesRef.current = content[STYLE_STORE_KEY];
|
|
28674
|
+
document.querySelectorAll('[data-ohw-editable="form"]').forEach((f) => markFormFields(f));
|
|
28617
28675
|
applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
|
|
28618
28676
|
}
|
|
28619
28677
|
applyBrandChrome(content);
|
|
@@ -28627,12 +28685,12 @@ function OhhwellsBridge() {
|
|
|
28627
28685
|
}
|
|
28628
28686
|
if (key === AI_SECTIONS_KEY) continue;
|
|
28629
28687
|
if (key === AI_FOOTER_KEY) continue;
|
|
28688
|
+
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
28689
|
+
if (LOGO_IMAGE_KEYS.includes(key) && !String(val ?? "").trim()) continue;
|
|
28630
28690
|
if (key === BRAND_KIT_KEY) continue;
|
|
28631
28691
|
if (key === STYLE_STORE_KEY) continue;
|
|
28632
28692
|
if (BRAND_CHROME_KEYS.has(key)) continue;
|
|
28633
|
-
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
28634
28693
|
if (key === CUSTOM_CODE_AFTER_HEAD_KEY || key === CUSTOM_CODE_BEFORE_HEAD_KEY) continue;
|
|
28635
|
-
if (LOGO_IMAGE_KEYS.includes(key) && !String(val ?? "").trim()) continue;
|
|
28636
28694
|
if (typeof content[AI_FOOTER_KEY] === "string" && content[AI_FOOTER_KEY] && isAiFooterOwnedContentKey(key)) {
|
|
28637
28695
|
continue;
|
|
28638
28696
|
}
|
|
@@ -29169,6 +29227,12 @@ function OhhwellsBridge() {
|
|
|
29169
29227
|
closeLinkPopoverRef.current();
|
|
29170
29228
|
return;
|
|
29171
29229
|
}
|
|
29230
|
+
if (floatingPanelOpenRef.current) {
|
|
29231
|
+
setFloatingPanelRef.current(null);
|
|
29232
|
+
deselectRef.current();
|
|
29233
|
+
deactivateRef.current();
|
|
29234
|
+
return;
|
|
29235
|
+
}
|
|
29172
29236
|
deselectRef.current();
|
|
29173
29237
|
deactivateRef.current();
|
|
29174
29238
|
clearMediaSelectionRef.current();
|
|
@@ -29931,10 +29995,10 @@ function OhhwellsBridge() {
|
|
|
29931
29995
|
window.removeEventListener("message", handleDeleteSection);
|
|
29932
29996
|
window.removeEventListener("message", handleDuplicateSection);
|
|
29933
29997
|
window.removeEventListener("message", handleDeactivate);
|
|
29934
|
-
document.documentElement.removeAttribute("data-ohw-panel-dragging");
|
|
29935
29998
|
window.removeEventListener("message", handleToastAction);
|
|
29936
29999
|
window.removeEventListener("message", handleFormCount);
|
|
29937
30000
|
window.removeEventListener("message", handleUiEscape);
|
|
30001
|
+
document.documentElement.removeAttribute("data-ohw-panel-dragging");
|
|
29938
30002
|
autoSaveTimers.current.forEach(clearTimeout);
|
|
29939
30003
|
autoSaveTimers.current.clear();
|
|
29940
30004
|
if (imageUnhoverTimerRef.current) clearTimeout(imageUnhoverTimerRef.current);
|
|
@@ -30228,7 +30292,7 @@ function OhhwellsBridge() {
|
|
|
30228
30292
|
postToParent2({
|
|
30229
30293
|
type: "ow:ready",
|
|
30230
30294
|
version: "1",
|
|
30231
|
-
bridgeVersion: "0.1.
|
|
30295
|
+
bridgeVersion: "0.1.134",
|
|
30232
30296
|
path: pathname,
|
|
30233
30297
|
nodes: collectEditableNodes(editContentRef.current),
|
|
30234
30298
|
sections
|