@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.cjs
CHANGED
|
@@ -2656,6 +2656,19 @@ function quotedFont(font) {
|
|
|
2656
2656
|
const cleaned = font.replace(/["']/g, "").trim();
|
|
2657
2657
|
return cleaned ? `"${cleaned}"` : "sans-serif";
|
|
2658
2658
|
}
|
|
2659
|
+
function themeFont(role, fallback) {
|
|
2660
|
+
const quoted = quotedFont(fallback);
|
|
2661
|
+
return role === "heading" ? `var(--brand-font-heading, var(--font-heading, var(--font-display, ${quoted})))` : `var(--brand-font-body, var(--font-body, ${quoted}))`;
|
|
2662
|
+
}
|
|
2663
|
+
function withThemeFonts(brand) {
|
|
2664
|
+
return {
|
|
2665
|
+
...brand,
|
|
2666
|
+
fonts: {
|
|
2667
|
+
heading: themeFont("heading", brand.fonts.heading),
|
|
2668
|
+
body: themeFont("body", brand.fonts.body)
|
|
2669
|
+
}
|
|
2670
|
+
};
|
|
2671
|
+
}
|
|
2659
2672
|
function footerLogoStyle(fallbackFont, fallbackColor) {
|
|
2660
2673
|
return {
|
|
2661
2674
|
fontFamily: `var(--brand-font-heading, var(--font-heading, var(--font-display, ${quotedFont(fallbackFont)})))`,
|
|
@@ -2727,7 +2740,7 @@ var AI_MOBILE_CSS = [
|
|
|
2727
2740
|
// page's first section. Top only (bottom needs no nav clearance); ~96px approximates the
|
|
2728
2741
|
// template nav's own height (measured ~94px) — there's no shared `--ohw-header-h` var to read
|
|
2729
2742
|
// an exact figure from (no live measurement exists), so this is a safe approximation, not a
|
|
2730
|
-
// pixel-exact fit. Horizontal spacing already comes from `data-ai-
|
|
2743
|
+
// pixel-exact fit. Horizontal spacing already comes from `data-ai-section-inner`.
|
|
2731
2744
|
'[data-ai-overlay-clearance] [data-ai-overlap-layer="overlay"]{padding-top:96px}',
|
|
2732
2745
|
// A full-bleed carousel's height is pure arithmetic: it spans the whole window, so 16/9 turns
|
|
2733
2746
|
// window width straight into height. Measured at 16/9 it came out ~90% of the viewport at EVERY
|
|
@@ -2743,8 +2756,10 @@ var AI_MOBILE_CSS = [
|
|
|
2743
2756
|
"[data-ai-section]{overflow-x:hidden}",
|
|
2744
2757
|
// `:not([data-ai-full-bleed])`: this `!important` gutter beat the inline `padding: 0` that a
|
|
2745
2758
|
// full-bleed section's container sets, so a carousel/media hero that is edge-to-edge on desktop
|
|
2746
|
-
// still got a 20px band of section background down both sides on a phone.
|
|
2747
|
-
|
|
2759
|
+
// still got a 20px band of section background down both sides on a phone. The footer's own
|
|
2760
|
+
// container keeps the unguarded rule below — `data-ai-full-bleed` can never appear on it.
|
|
2761
|
+
"[data-ai-section-inner]:not([data-ai-full-bleed]){padding:0 20px !important}",
|
|
2762
|
+
"[data-ai-container]{padding:0 20px !important}",
|
|
2748
2763
|
"[data-ai-row]{display:flex !important;flex-direction:column !important;align-items:stretch !important}",
|
|
2749
2764
|
"[data-ai-cell]{width:100%;min-width:0}",
|
|
2750
2765
|
// The rule above turns every row into a COLUMN flex container on phones, which silently breaks
|
|
@@ -2945,6 +2960,31 @@ function pricingCardEmphasis(featured, ctx, hasBg) {
|
|
|
2945
2960
|
function textAttrs(ctx, path) {
|
|
2946
2961
|
return ctx.keyFor ? { "data-ohw-key": ctx.keyFor(path), "data-ohw-editable": "text" } : {};
|
|
2947
2962
|
}
|
|
2963
|
+
var AI_RESPONSIVE_CSS = [
|
|
2964
|
+
"@media (max-width: 960px) {",
|
|
2965
|
+
" [data-ai-responsive] [data-ai-grid] { grid-template-columns: repeat(2, 1fr) !important; }",
|
|
2966
|
+
' [data-ai-responsive] [data-ai-grid="1"] { grid-template-columns: 1fr !important; }',
|
|
2967
|
+
"}",
|
|
2968
|
+
"@media (max-width: 640px) {",
|
|
2969
|
+
" [data-ai-responsive] [data-ai-grid] { grid-template-columns: 1fr !important; }",
|
|
2970
|
+
" [data-ai-responsive] [data-ai-columns] > * { grid-column: 1 / -1 !important; }",
|
|
2971
|
+
// Group containers flatten to a column on phones; span placements come along for free.
|
|
2972
|
+
// `:not([data-ai-group="overlap"])` for the same reason as the twin pair in AI_MOBILE_CSS — see
|
|
2973
|
+
// the comment there. This sheet's copy is the narrower selector, so without the exemption it
|
|
2974
|
+
// flattens an `overlap` hero below 640px even though the other rule stands down: measured a 390px
|
|
2975
|
+
// viewport with the heading/CTA in flow *under* the image, 219px of section background where the
|
|
2976
|
+
// layered text used to be.
|
|
2977
|
+
' [data-ai-responsive] [data-ai-group]:not([data-ai-group="overlap"]) { display: flex !important; flex-direction: column !important; }',
|
|
2978
|
+
' [data-ai-responsive] [data-ai-group]:not([data-ai-group="overlap"]) > * { grid-column: auto !important; }',
|
|
2979
|
+
// `:not([data-ai-full-bleed])` for the same reason as the twin rule in AI_MOBILE_CSS: this one
|
|
2980
|
+
// is narrower (0,2,0 vs 0,1,0) and also `!important`, so without the guard it wins outright and
|
|
2981
|
+
// a full-bleed hero gets its 20px side band back below 640px only — the one width where the
|
|
2982
|
+
// other rule had already been taught to stand down.
|
|
2983
|
+
" [data-ai-responsive] [data-ai-section-inner]:not([data-ai-full-bleed]) { padding-left: 20px !important; padding-right: 20px !important; }",
|
|
2984
|
+
" [data-ai-responsive] { overflow-x: hidden; }",
|
|
2985
|
+
" [data-ai-responsive] img { max-width: 100%; }",
|
|
2986
|
+
"}"
|
|
2987
|
+
].join("\n");
|
|
2948
2988
|
var TRANSPARENT_PX = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7";
|
|
2949
2989
|
function MediaBox({
|
|
2950
2990
|
refValue,
|
|
@@ -2965,9 +3005,9 @@ function MediaBox({
|
|
|
2965
3005
|
const url = refValue ? ctx.resolveMedia(refValue) : null;
|
|
2966
3006
|
const isIcon = /^(lucide|simple):/.test(refValue);
|
|
2967
3007
|
const aspectRatio = aspect && /^\d+:\d+$/.test(aspect) ? aspect.replace(":", " / ") : void 0;
|
|
2968
|
-
const editAttrs = ctx.keyFor && editPath
|
|
3008
|
+
const editAttrs = ctx.keyFor && editPath ? {
|
|
2969
3009
|
"data-ohw-key": ctx.keyFor(editPath),
|
|
2970
|
-
...genericImageEdit ? { "data-ohw-editable": "image" } : {}
|
|
3010
|
+
...isIcon ? { "data-ohw-editable": "icon" } : genericImageEdit ? { "data-ohw-editable": "image" } : {}
|
|
2971
3011
|
} : {};
|
|
2972
3012
|
if (isIcon) {
|
|
2973
3013
|
const Icon = refValue.startsWith("lucide:") ? lucideByName(refValue.slice(7)) : null;
|
|
@@ -2975,6 +3015,7 @@ function MediaBox({
|
|
|
2975
3015
|
"span",
|
|
2976
3016
|
{
|
|
2977
3017
|
"data-ai-icon": refValue,
|
|
3018
|
+
...editAttrs,
|
|
2978
3019
|
style: {
|
|
2979
3020
|
display: "inline-flex",
|
|
2980
3021
|
width: 48,
|
|
@@ -4468,7 +4509,7 @@ function CollectionBlock({ node, ctx, path }) {
|
|
|
4468
4509
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
4469
4510
|
"div",
|
|
4470
4511
|
{
|
|
4471
|
-
"data-ai-grid":
|
|
4512
|
+
"data-ai-grid": String(itemsPerRow),
|
|
4472
4513
|
"data-ohw-pricing-collection": isPricing ? "" : void 0,
|
|
4473
4514
|
style: {
|
|
4474
4515
|
display: "grid",
|
|
@@ -4728,7 +4769,7 @@ function renderNode(node, ctx, path, ambientAlign) {
|
|
|
4728
4769
|
},
|
|
4729
4770
|
children: [
|
|
4730
4771
|
i > 0 && ctx.heroOverlapFullBleed ? (
|
|
4731
|
-
// The section's `data-ai-
|
|
4772
|
+
// The section's `data-ai-section-inner` gave up its max-width/gutter so the base
|
|
4732
4773
|
// layer (this group's i===0 sibling) can span edge-to-edge — reintroduced here,
|
|
4733
4774
|
// scoped to just the overlay text, so a heading/copy/CTA stack doesn't stretch
|
|
4734
4775
|
// the full section width instead of reading at the usual content width.
|
|
@@ -5051,7 +5092,7 @@ function AiTreeRenderer({
|
|
|
5051
5092
|
if (!isRenderableTree(tree)) {
|
|
5052
5093
|
return null;
|
|
5053
5094
|
}
|
|
5054
|
-
const resolvedBrand = brand ?? AI_DEFAULT_BRAND;
|
|
5095
|
+
const resolvedBrand = withThemeFonts(brand ?? AI_DEFAULT_BRAND);
|
|
5055
5096
|
const band = (tree.settings ?? {}).sectionBackground === "accent" ? accentBandContext(resolvedBrand) : null;
|
|
5056
5097
|
const blockBrand = band?.brand ?? resolvedBrand;
|
|
5057
5098
|
const placeholderMap = buildPlaceholderMap(tree);
|
|
@@ -5121,6 +5162,7 @@ function AiTreeRenderer({
|
|
|
5121
5162
|
...fillHeight ? { "data-ai-fill-height": "" } : {},
|
|
5122
5163
|
...needsOverlayClearance ? { "data-ai-overlay-clearance": "" } : {},
|
|
5123
5164
|
...bgAttrs,
|
|
5165
|
+
"data-ai-responsive": "",
|
|
5124
5166
|
style: {
|
|
5125
5167
|
position: "relative",
|
|
5126
5168
|
padding: `${padCss} 0`,
|
|
@@ -5134,12 +5176,13 @@ function AiTreeRenderer({
|
|
|
5134
5176
|
...fillHeight ? { display: "grid" } : {}
|
|
5135
5177
|
},
|
|
5136
5178
|
children: [
|
|
5137
|
-
|
|
5179
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("style", { children: AI_RESPONSIVE_CSS }),
|
|
5138
5180
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("style", { children: AI_MOBILE_CSS }),
|
|
5181
|
+
isOverlay && backgroundUrl && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { position: "absolute", inset: 0, background: `rgba(255,255,255,${overlayAlpha})` } }),
|
|
5139
5182
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
5140
5183
|
"div",
|
|
5141
5184
|
{
|
|
5142
|
-
"data-ai-
|
|
5185
|
+
"data-ai-section-inner": "",
|
|
5143
5186
|
...fullBleedMedia ? { "data-ai-full-bleed": "" } : {},
|
|
5144
5187
|
style: {
|
|
5145
5188
|
position: "relative",
|
|
@@ -5156,7 +5199,7 @@ function AiTreeRenderer({
|
|
|
5156
5199
|
children: tree.rows.map((row, r2) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
5157
5200
|
"div",
|
|
5158
5201
|
{
|
|
5159
|
-
"data-ai-
|
|
5202
|
+
"data-ai-columns": "",
|
|
5160
5203
|
style: {
|
|
5161
5204
|
display: "grid",
|
|
5162
5205
|
gridTemplateColumns: "repeat(12, 1fr)",
|
|
@@ -5207,7 +5250,7 @@ function AiFooterRenderer({
|
|
|
5207
5250
|
if (!isRenderableFooterTree(tree)) {
|
|
5208
5251
|
return null;
|
|
5209
5252
|
}
|
|
5210
|
-
const resolvedBrand = brand ?? AI_DEFAULT_BRAND;
|
|
5253
|
+
const resolvedBrand = withThemeFonts(brand ?? AI_DEFAULT_BRAND);
|
|
5211
5254
|
const bandBg = surface?.background ?? resolvedBrand.palette.dark;
|
|
5212
5255
|
const bandText = surface?.text ?? resolvedBrand.palette.light;
|
|
5213
5256
|
const onDark = surface ? isDarkColor(surface.background) : true;
|
|
@@ -5812,9 +5855,10 @@ function applyAiSectionsToDom(state, options) {
|
|
|
5812
5855
|
if (existing && existing.serialized === serialized && existing.container.isConnected) {
|
|
5813
5856
|
continue;
|
|
5814
5857
|
}
|
|
5815
|
-
const isNewMount = !existing || !existing.container.isConnected;
|
|
5816
5858
|
let container = existing?.container;
|
|
5859
|
+
let isNewMount = false;
|
|
5817
5860
|
if (!container || !container.isConnected) {
|
|
5861
|
+
isNewMount = true;
|
|
5818
5862
|
existing?.root.unmount();
|
|
5819
5863
|
container?.remove();
|
|
5820
5864
|
container = document.createElement("div");
|
|
@@ -9030,7 +9074,7 @@ var isLabelWeight = (label) => label === "number" || label === "weight";
|
|
|
9030
9074
|
var isLabelShadow = (label) => label === "shadow";
|
|
9031
9075
|
var getDefaultConfig = () => {
|
|
9032
9076
|
const themeColor = fromTheme("color");
|
|
9033
|
-
const
|
|
9077
|
+
const themeFont2 = fromTheme("font");
|
|
9034
9078
|
const themeText = fromTheme("text");
|
|
9035
9079
|
const themeFontWeight = fromTheme("font-weight");
|
|
9036
9080
|
const themeTracking = fromTheme("tracking");
|
|
@@ -9952,7 +9996,7 @@ var getDefaultConfig = () => {
|
|
|
9952
9996
|
* @see https://tailwindcss.com/docs/font-family
|
|
9953
9997
|
*/
|
|
9954
9998
|
"font-family": [{
|
|
9955
|
-
font: [isArbitraryVariableFamilyName, isArbitraryFamilyName,
|
|
9999
|
+
font: [isArbitraryVariableFamilyName, isArbitraryFamilyName, themeFont2]
|
|
9956
10000
|
}],
|
|
9957
10001
|
/**
|
|
9958
10002
|
* Font Feature Settings
|
|
@@ -13449,6 +13493,7 @@ function MediaOverlay({
|
|
|
13449
13493
|
(prev) => prev && prev.fullWidth === width && prev.height === height ? prev : { fullWidth: width, height }
|
|
13450
13494
|
);
|
|
13451
13495
|
}, [isVideo]);
|
|
13496
|
+
const replaceLabel = isVideo ? "Replace video" : hover.elementType === "bg-image" ? "Replace background" : "Replace image";
|
|
13452
13497
|
const replaceMode = buttonSize ? replaceButtonMode({ width: rect.width, height: rect.height }, buttonSize) : "none";
|
|
13453
13498
|
const box = {
|
|
13454
13499
|
position: "fixed",
|
|
@@ -13547,11 +13592,10 @@ function MediaOverlay({
|
|
|
13547
13592
|
className: "flex items-center justify-center cursor-pointer",
|
|
13548
13593
|
style: {
|
|
13549
13594
|
...box,
|
|
13550
|
-
//
|
|
13551
|
-
//
|
|
13552
|
-
//
|
|
13553
|
-
|
|
13554
|
-
pointerEvents: hover.hasTextOverlap || cueOnly ? "none" : "auto",
|
|
13595
|
+
// Visual only. `pointer-events: auto` on this full-bleed rect covered the navbar
|
|
13596
|
+
// (hero bg includes the absolute TopNav) and swallowed CTA press-drag. Text overlay
|
|
13597
|
+
// and cueOnly also need clicks to fall through — Replace / video controls opt back in.
|
|
13598
|
+
pointerEvents: "none",
|
|
13555
13599
|
// Selected: a firm component ring with no wash, so the image reads as chosen rather
|
|
13556
13600
|
// than hovered. Hover keeps the existing tinted preview.
|
|
13557
13601
|
boxShadow: selected ? "inset 0 0 0 2px var(--color-bridge-primary)" : "inset 0 0 0 1.5px var(--color-bridge-primary)",
|
|
@@ -13578,17 +13622,17 @@ function MediaOverlay({
|
|
|
13578
13622
|
},
|
|
13579
13623
|
children: [
|
|
13580
13624
|
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 }),
|
|
13581
|
-
|
|
13625
|
+
replaceLabel
|
|
13582
13626
|
]
|
|
13583
13627
|
}
|
|
13584
13628
|
),
|
|
13585
|
-
replaceMode
|
|
13629
|
+
showChrome && replaceMode !== "none" && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
|
|
13586
13630
|
Button,
|
|
13587
13631
|
{
|
|
13588
13632
|
"data-ohw-media-overlay": "",
|
|
13589
13633
|
variant: "outline",
|
|
13590
13634
|
size: "sm",
|
|
13591
|
-
"aria-label":
|
|
13635
|
+
"aria-label": replaceLabel,
|
|
13592
13636
|
className: "gap-1.5 cursor-pointer hover:bg-background",
|
|
13593
13637
|
style: {
|
|
13594
13638
|
...OVERLAY_BUTTON_STYLE,
|
|
@@ -13611,7 +13655,7 @@ function MediaOverlay({
|
|
|
13611
13655
|
},
|
|
13612
13656
|
children: [
|
|
13613
13657
|
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 }),
|
|
13614
|
-
replaceMode === "full" ?
|
|
13658
|
+
replaceMode === "full" ? replaceLabel : null
|
|
13615
13659
|
]
|
|
13616
13660
|
}
|
|
13617
13661
|
)
|
|
@@ -19843,6 +19887,7 @@ function readLogoSizeState(content, placement) {
|
|
|
19843
19887
|
function getLogoElement(el) {
|
|
19844
19888
|
const marked = el.closest('[data-ohw-role="logo"], [data-ohw-logo]');
|
|
19845
19889
|
if (marked) return marked;
|
|
19890
|
+
if (el.closest('[data-ohw-editable="icon"]')) return null;
|
|
19846
19891
|
const root = el.closest("nav, [data-ohw-nav-root], footer");
|
|
19847
19892
|
if (!root) return null;
|
|
19848
19893
|
const anchor = el.closest("a");
|
|
@@ -23334,7 +23379,7 @@ function getNavigationSelectionParent(el) {
|
|
|
23334
23379
|
if (!isFooterLinksContainer(el) && (el.hasAttribute("data-ohw-footer-col") || el.hasAttribute("data-ohw-footer-column") || isInferredFooterGroup2(el))) {
|
|
23335
23380
|
return resolveFooterLinksContainerFrom(el);
|
|
23336
23381
|
}
|
|
23337
|
-
if (el.hasAttribute("data-ohw-nav-container") || el.hasAttribute("data-ohw-nav-drawer") || isFooterLinksContainer(el)) {
|
|
23382
|
+
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)) {
|
|
23338
23383
|
return getNavigationRoot(el);
|
|
23339
23384
|
}
|
|
23340
23385
|
return null;
|
|
@@ -23556,7 +23601,6 @@ var ICONS = {
|
|
|
23556
23601
|
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"/>',
|
|
23557
23602
|
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"/>'
|
|
23558
23603
|
};
|
|
23559
|
-
var HEIGHT_SETTLE_DELAYS = [150, 400, 800];
|
|
23560
23604
|
var SELECTION_CHROME_GAP2 = 4;
|
|
23561
23605
|
var TOOLBAR_STROKE_GAP2 = 4;
|
|
23562
23606
|
var TOOLBAR_OFFSET_FROM_ELEMENT = SELECTION_CHROME_GAP2 + TOOLBAR_STROKE_GAP2;
|
|
@@ -24536,21 +24580,6 @@ function OhhwellsBridge() {
|
|
|
24536
24580
|
const [isItemDragging, setIsItemDragging] = (0, import_react21.useState)(false);
|
|
24537
24581
|
const [isFooterFrameSelection, setIsFooterFrameSelection] = (0, import_react21.useState)(false);
|
|
24538
24582
|
isFooterFrameSelectionRef.current = isFooterFrameSelection;
|
|
24539
|
-
const [floatingPanel, setFloatingPanel] = (0, import_react21.useState)(null);
|
|
24540
|
-
const floatingPanelOpenRef = (0, import_react21.useRef)(false);
|
|
24541
|
-
floatingPanelOpenRef.current = floatingPanel !== null;
|
|
24542
|
-
const floatingPanelRef = (0, import_react21.useRef)(null);
|
|
24543
|
-
floatingPanelRef.current = floatingPanel;
|
|
24544
|
-
const [floatingPanelPos, setFloatingPanelPos] = (0, import_react21.useState)(null);
|
|
24545
|
-
const buttonCollectionDragRef = (0, import_react21.useRef)(null);
|
|
24546
|
-
const buttonDropInsertIndexRef = (0, import_react21.useRef)(null);
|
|
24547
|
-
const [buttonDropSlots, setButtonDropSlots] = (0, import_react21.useState)([]);
|
|
24548
|
-
const [activeButtonDropIndex, setActiveButtonDropIndex] = (0, import_react21.useState)(null);
|
|
24549
|
-
const buttonPointerDragRef = (0, import_react21.useRef)(null);
|
|
24550
|
-
const [buttonStyleTick, setButtonStyleTick] = (0, import_react21.useState)(0);
|
|
24551
|
-
const [logoSizeDraft, setLogoSizeDraft] = (0, import_react21.useState)(null);
|
|
24552
|
-
const [editorViewport, setEditorViewport] = (0, import_react21.useState)("desktop");
|
|
24553
|
-
const [parentScrollSnap, setParentScrollSnap] = (0, import_react21.useState)(null);
|
|
24554
24583
|
const [navDropdownPreviewOpen, setNavDropdownPreviewOpen] = (0, import_react21.useState)(null);
|
|
24555
24584
|
const [footerHeadingVisible, setFooterHeadingVisible] = (0, import_react21.useState)(null);
|
|
24556
24585
|
const footerDragRef = (0, import_react21.useRef)(null);
|
|
@@ -24576,6 +24605,21 @@ function OhhwellsBridge() {
|
|
|
24576
24605
|
const stylesRef = (0, import_react21.useRef)("");
|
|
24577
24606
|
const appliedDrawerRef = (0, import_react21.useRef)(null);
|
|
24578
24607
|
const pendingDeleteUndoRef = (0, import_react21.useRef)(null);
|
|
24608
|
+
const [floatingPanel, setFloatingPanel] = (0, import_react21.useState)(null);
|
|
24609
|
+
const floatingPanelOpenRef = (0, import_react21.useRef)(false);
|
|
24610
|
+
const floatingPanelRef = (0, import_react21.useRef)(null);
|
|
24611
|
+
floatingPanelRef.current = floatingPanel;
|
|
24612
|
+
const setFloatingPanelRef = (0, import_react21.useRef)(setFloatingPanel);
|
|
24613
|
+
const [floatingPanelPos, setFloatingPanelPos] = (0, import_react21.useState)(null);
|
|
24614
|
+
const buttonCollectionDragRef = (0, import_react21.useRef)(null);
|
|
24615
|
+
const buttonDropInsertIndexRef = (0, import_react21.useRef)(null);
|
|
24616
|
+
const [buttonDropSlots, setButtonDropSlots] = (0, import_react21.useState)([]);
|
|
24617
|
+
const [activeButtonDropIndex, setActiveButtonDropIndex] = (0, import_react21.useState)(null);
|
|
24618
|
+
const buttonPointerDragRef = (0, import_react21.useRef)(null);
|
|
24619
|
+
const [buttonStyleTick, setButtonStyleTick] = (0, import_react21.useState)(0);
|
|
24620
|
+
const [logoSizeDraft, setLogoSizeDraft] = (0, import_react21.useState)(null);
|
|
24621
|
+
const [editorViewport, setEditorViewport] = (0, import_react21.useState)("desktop");
|
|
24622
|
+
const [parentScrollSnap, setParentScrollSnap] = (0, import_react21.useState)(null);
|
|
24579
24623
|
const [sitePages, setSitePages] = (0, import_react21.useState)([]);
|
|
24580
24624
|
const [sectionsByPath, setSectionsByPath] = (0, import_react21.useState)({});
|
|
24581
24625
|
const sectionsPrefetchGenRef = (0, import_react21.useRef)(0);
|
|
@@ -24584,7 +24628,18 @@ function OhhwellsBridge() {
|
|
|
24584
24628
|
const linkPopoverOpenRef = (0, import_react21.useRef)(false);
|
|
24585
24629
|
const linkPopoverGraceUntilRef = (0, import_react21.useRef)(0);
|
|
24586
24630
|
setLinkPopoverRef.current = setLinkPopover;
|
|
24631
|
+
setFloatingPanelRef.current = setFloatingPanel;
|
|
24587
24632
|
linkPopoverSessionRef.current = linkPopover;
|
|
24633
|
+
floatingPanelOpenRef.current = Boolean(floatingPanel);
|
|
24634
|
+
(0, import_react21.useEffect)(() => {
|
|
24635
|
+
const syncViewport = () => {
|
|
24636
|
+
const next = window.innerWidth <= 480 ? "mobile" : "desktop";
|
|
24637
|
+
setEditorViewport((prev) => prev === next ? prev : next);
|
|
24638
|
+
};
|
|
24639
|
+
syncViewport();
|
|
24640
|
+
window.addEventListener("resize", syncViewport);
|
|
24641
|
+
return () => window.removeEventListener("resize", syncViewport);
|
|
24642
|
+
}, []);
|
|
24588
24643
|
(0, import_react21.useEffect)(() => {
|
|
24589
24644
|
setSectionOrderPersistHandler((entries) => {
|
|
24590
24645
|
const currentPath = window.location.pathname;
|
|
@@ -26263,6 +26318,7 @@ function OhhwellsBridge() {
|
|
|
26263
26318
|
applyAiFooterFromContent(content);
|
|
26264
26319
|
if (typeof content[STYLE_STORE_KEY] === "string") {
|
|
26265
26320
|
stylesRef.current = content[STYLE_STORE_KEY];
|
|
26321
|
+
document.querySelectorAll('[data-ohw-editable="form"]').forEach((f) => markFormFields(f));
|
|
26266
26322
|
applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
|
|
26267
26323
|
}
|
|
26268
26324
|
applyBrandChrome(content);
|
|
@@ -26272,12 +26328,12 @@ function OhhwellsBridge() {
|
|
|
26272
26328
|
if (key === "__ohw_sections") continue;
|
|
26273
26329
|
if (key === AI_SECTIONS_KEY) continue;
|
|
26274
26330
|
if (key === AI_FOOTER_KEY) continue;
|
|
26331
|
+
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
26332
|
+
if (LOGO_IMAGE_KEYS.includes(key)) continue;
|
|
26275
26333
|
if (key === BRAND_KIT_KEY) continue;
|
|
26276
26334
|
if (key === STYLE_STORE_KEY) continue;
|
|
26277
26335
|
if (BRAND_CHROME_KEYS.has(key)) continue;
|
|
26278
|
-
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
26279
26336
|
if (key === CUSTOM_CODE_AFTER_HEAD_KEY || key === CUSTOM_CODE_BEFORE_HEAD_KEY) continue;
|
|
26280
|
-
if (LOGO_IMAGE_KEYS.includes(key)) continue;
|
|
26281
26337
|
if (typeof content[AI_FOOTER_KEY] === "string" && content[AI_FOOTER_KEY] && isAiFooterOwnedContentKey(key)) {
|
|
26282
26338
|
continue;
|
|
26283
26339
|
}
|
|
@@ -26491,17 +26547,18 @@ function OhhwellsBridge() {
|
|
|
26491
26547
|
}
|
|
26492
26548
|
applyAiFooterFromContent(content);
|
|
26493
26549
|
if (typeof content[STYLE_STORE_KEY] === "string") {
|
|
26550
|
+
document.querySelectorAll('[data-ohw-editable="form"]').forEach((f) => markFormFields(f));
|
|
26494
26551
|
applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
|
|
26495
26552
|
}
|
|
26496
26553
|
for (const [key, val] of Object.entries(content)) {
|
|
26497
26554
|
if (key === "__ohw_sections") continue;
|
|
26498
26555
|
if (key === AI_SECTIONS_KEY) continue;
|
|
26499
26556
|
if (key === AI_FOOTER_KEY) continue;
|
|
26557
|
+
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
26558
|
+
if (LOGO_IMAGE_KEYS.includes(key)) continue;
|
|
26500
26559
|
if (key === BRAND_KIT_KEY) continue;
|
|
26501
26560
|
if (key === STYLE_STORE_KEY) continue;
|
|
26502
26561
|
if (BRAND_CHROME_KEYS.has(key)) continue;
|
|
26503
|
-
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
26504
|
-
if (LOGO_IMAGE_KEYS.includes(key)) continue;
|
|
26505
26562
|
if (typeof content[AI_FOOTER_KEY] === "string" && content[AI_FOOTER_KEY] && isAiFooterOwnedContentKey(key)) {
|
|
26506
26563
|
continue;
|
|
26507
26564
|
}
|
|
@@ -26757,26 +26814,11 @@ function OhhwellsBridge() {
|
|
|
26757
26814
|
const t2 = setTimeout(measure, 500);
|
|
26758
26815
|
const ro = new ResizeObserver(schedule);
|
|
26759
26816
|
ro.observe(document.body);
|
|
26760
|
-
let lastWidth = window.innerWidth;
|
|
26761
|
-
let resizeTimers = [];
|
|
26762
|
-
const clearResizeTimers = () => {
|
|
26763
|
-
resizeTimers.forEach(clearTimeout);
|
|
26764
|
-
resizeTimers = [];
|
|
26765
|
-
};
|
|
26766
|
-
const handleResize = () => {
|
|
26767
|
-
if (window.innerWidth === lastWidth) return;
|
|
26768
|
-
lastWidth = window.innerWidth;
|
|
26769
|
-
clearResizeTimers();
|
|
26770
|
-
resizeTimers = HEIGHT_SETTLE_DELAYS.map((delay) => setTimeout(measure, delay));
|
|
26771
|
-
};
|
|
26772
|
-
window.addEventListener("resize", handleResize);
|
|
26773
26817
|
return () => {
|
|
26774
26818
|
clearTimeout(t1);
|
|
26775
26819
|
clearTimeout(t2);
|
|
26776
26820
|
if (raf != null) cancelAnimationFrame(raf);
|
|
26777
26821
|
ro.disconnect();
|
|
26778
|
-
clearResizeTimers();
|
|
26779
|
-
window.removeEventListener("resize", handleResize);
|
|
26780
26822
|
};
|
|
26781
26823
|
}, [pathname, isEditMode, postToParent2]);
|
|
26782
26824
|
(0, import_react21.useEffect)(() => {
|
|
@@ -27071,6 +27113,13 @@ function OhhwellsBridge() {
|
|
|
27071
27113
|
if (target.closest("[data-ohw-state-toggle]")) return;
|
|
27072
27114
|
if (target.closest("[data-ohw-max-badge]")) return;
|
|
27073
27115
|
if (isInsideLinkEditor(target)) return;
|
|
27116
|
+
if (isInsideFloatingPanel(target)) return;
|
|
27117
|
+
if (target.closest("[data-ohw-form-toolbar]")) return;
|
|
27118
|
+
if (target.closest(
|
|
27119
|
+
'[data-ohw-field-toolbar], [data-ohw-field-type-picker], [data-radix-popper-content-wrapper], [role="menu"], [data-slot="dropdown-menu-content"]'
|
|
27120
|
+
)) {
|
|
27121
|
+
return;
|
|
27122
|
+
}
|
|
27074
27123
|
if (selectedMediaElRef.current && !selectedMediaElRef.current.contains(target) && !target.closest("[data-ohw-media-overlay], [data-ohw-edit-chrome], [data-ohw-item-interaction]")) {
|
|
27075
27124
|
clearMediaSelectionRef.current();
|
|
27076
27125
|
}
|
|
@@ -27091,13 +27140,6 @@ function OhhwellsBridge() {
|
|
|
27091
27140
|
return;
|
|
27092
27141
|
}
|
|
27093
27142
|
}
|
|
27094
|
-
if (isInsideFloatingPanel(target)) return;
|
|
27095
|
-
if (target.closest("[data-ohw-form-toolbar]")) return;
|
|
27096
|
-
if (target.closest(
|
|
27097
|
-
'[data-ohw-field-toolbar], [data-ohw-field-type-picker], [data-radix-popper-content-wrapper], [role="menu"], [data-slot="dropdown-menu-content"]'
|
|
27098
|
-
)) {
|
|
27099
|
-
return;
|
|
27100
|
-
}
|
|
27101
27143
|
{
|
|
27102
27144
|
const formEl = getFormElement(target);
|
|
27103
27145
|
const onSuccessText = target.closest(`[${SUCCESS_TEXT_ATTR}]`);
|
|
@@ -27477,6 +27519,9 @@ function OhhwellsBridge() {
|
|
|
27477
27519
|
setHoveredItemRect(null);
|
|
27478
27520
|
hoveredNavContainerRef.current = null;
|
|
27479
27521
|
setHoveredNavContainerRect(null);
|
|
27522
|
+
siblingHintElRef.current = null;
|
|
27523
|
+
setSiblingHintRect(null);
|
|
27524
|
+
setSiblingHintRects([]);
|
|
27480
27525
|
return;
|
|
27481
27526
|
}
|
|
27482
27527
|
{
|
|
@@ -27597,7 +27642,6 @@ function OhhwellsBridge() {
|
|
|
27597
27642
|
hoveredNavContainerRef.current = null;
|
|
27598
27643
|
setHoveredNavContainerRect(null);
|
|
27599
27644
|
hoveredItemElRef.current = editable;
|
|
27600
|
-
setHoveredItemRect(isSelectedForHoverRef.current(editable) ? null : editable.getBoundingClientRect());
|
|
27601
27645
|
}
|
|
27602
27646
|
}
|
|
27603
27647
|
}
|
|
@@ -28307,7 +28351,11 @@ function OhhwellsBridge() {
|
|
|
28307
28351
|
};
|
|
28308
28352
|
const handleMouseMove = (e) => {
|
|
28309
28353
|
const { clientX, clientY } = e;
|
|
28310
|
-
if (pointOwnedByFloatingPanel(clientX, clientY))
|
|
28354
|
+
if (pointOwnedByFloatingPanel(clientX, clientY)) {
|
|
28355
|
+
dismissImageHover();
|
|
28356
|
+
clearImageHover();
|
|
28357
|
+
return;
|
|
28358
|
+
}
|
|
28311
28359
|
if (isNavDrawerOpen() && isPointOutsideOpenDrawer(clientX, clientY)) {
|
|
28312
28360
|
document.querySelectorAll("[data-ohw-hovered]").forEach((el) => el.removeAttribute("data-ohw-hovered"));
|
|
28313
28361
|
formHoverElRef.current = null;
|
|
@@ -28336,7 +28384,12 @@ function OhhwellsBridge() {
|
|
|
28336
28384
|
setHoveredItemRect(null);
|
|
28337
28385
|
hoveredNavContainerRef.current = null;
|
|
28338
28386
|
setHoveredNavContainerRect(null);
|
|
28387
|
+
siblingHintElRef.current = null;
|
|
28388
|
+
setSiblingHintRect(null);
|
|
28389
|
+
setSiblingHintRects([]);
|
|
28339
28390
|
dismissImageHover();
|
|
28391
|
+
clearImageHover();
|
|
28392
|
+
setSectionGap(null);
|
|
28340
28393
|
return;
|
|
28341
28394
|
}
|
|
28342
28395
|
if (probeSocialsRowAt(clientX, clientY)) return;
|
|
@@ -28348,7 +28401,11 @@ function OhhwellsBridge() {
|
|
|
28348
28401
|
if (e.data?.type !== "ow:pointer-sync") return;
|
|
28349
28402
|
const { clientX, clientY } = e.data;
|
|
28350
28403
|
if (typeof clientX !== "number" || typeof clientY !== "number") return;
|
|
28351
|
-
if (pointOwnedByFloatingPanel(clientX, clientY))
|
|
28404
|
+
if (pointOwnedByFloatingPanel(clientX, clientY)) {
|
|
28405
|
+
dismissImageHover();
|
|
28406
|
+
clearImageHover();
|
|
28407
|
+
return;
|
|
28408
|
+
}
|
|
28352
28409
|
if (isNavDrawerOpen() && isPointOutsideOpenDrawer(clientX, clientY)) return;
|
|
28353
28410
|
if (probeSocialsRowAt(clientX, clientY)) return;
|
|
28354
28411
|
probeSectionGapAt(clientX, clientY);
|
|
@@ -28700,6 +28757,7 @@ function OhhwellsBridge() {
|
|
|
28700
28757
|
applyAiFooterFromContent(content);
|
|
28701
28758
|
if (typeof content[STYLE_STORE_KEY] === "string") {
|
|
28702
28759
|
stylesRef.current = content[STYLE_STORE_KEY];
|
|
28760
|
+
document.querySelectorAll('[data-ohw-editable="form"]').forEach((f) => markFormFields(f));
|
|
28703
28761
|
applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
|
|
28704
28762
|
}
|
|
28705
28763
|
applyBrandChrome(content);
|
|
@@ -28713,12 +28771,12 @@ function OhhwellsBridge() {
|
|
|
28713
28771
|
}
|
|
28714
28772
|
if (key === AI_SECTIONS_KEY) continue;
|
|
28715
28773
|
if (key === AI_FOOTER_KEY) continue;
|
|
28774
|
+
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
28775
|
+
if (LOGO_IMAGE_KEYS.includes(key) && !String(val ?? "").trim()) continue;
|
|
28716
28776
|
if (key === BRAND_KIT_KEY) continue;
|
|
28717
28777
|
if (key === STYLE_STORE_KEY) continue;
|
|
28718
28778
|
if (BRAND_CHROME_KEYS.has(key)) continue;
|
|
28719
|
-
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
28720
28779
|
if (key === CUSTOM_CODE_AFTER_HEAD_KEY || key === CUSTOM_CODE_BEFORE_HEAD_KEY) continue;
|
|
28721
|
-
if (LOGO_IMAGE_KEYS.includes(key) && !String(val ?? "").trim()) continue;
|
|
28722
28780
|
if (typeof content[AI_FOOTER_KEY] === "string" && content[AI_FOOTER_KEY] && isAiFooterOwnedContentKey(key)) {
|
|
28723
28781
|
continue;
|
|
28724
28782
|
}
|
|
@@ -29255,6 +29313,12 @@ function OhhwellsBridge() {
|
|
|
29255
29313
|
closeLinkPopoverRef.current();
|
|
29256
29314
|
return;
|
|
29257
29315
|
}
|
|
29316
|
+
if (floatingPanelOpenRef.current) {
|
|
29317
|
+
setFloatingPanelRef.current(null);
|
|
29318
|
+
deselectRef.current();
|
|
29319
|
+
deactivateRef.current();
|
|
29320
|
+
return;
|
|
29321
|
+
}
|
|
29258
29322
|
deselectRef.current();
|
|
29259
29323
|
deactivateRef.current();
|
|
29260
29324
|
clearMediaSelectionRef.current();
|
|
@@ -30017,10 +30081,10 @@ function OhhwellsBridge() {
|
|
|
30017
30081
|
window.removeEventListener("message", handleDeleteSection);
|
|
30018
30082
|
window.removeEventListener("message", handleDuplicateSection);
|
|
30019
30083
|
window.removeEventListener("message", handleDeactivate);
|
|
30020
|
-
document.documentElement.removeAttribute("data-ohw-panel-dragging");
|
|
30021
30084
|
window.removeEventListener("message", handleToastAction);
|
|
30022
30085
|
window.removeEventListener("message", handleFormCount);
|
|
30023
30086
|
window.removeEventListener("message", handleUiEscape);
|
|
30087
|
+
document.documentElement.removeAttribute("data-ohw-panel-dragging");
|
|
30024
30088
|
autoSaveTimers.current.forEach(clearTimeout);
|
|
30025
30089
|
autoSaveTimers.current.clear();
|
|
30026
30090
|
if (imageUnhoverTimerRef.current) clearTimeout(imageUnhoverTimerRef.current);
|
|
@@ -30314,7 +30378,7 @@ function OhhwellsBridge() {
|
|
|
30314
30378
|
postToParent2({
|
|
30315
30379
|
type: "ow:ready",
|
|
30316
30380
|
version: "1",
|
|
30317
|
-
bridgeVersion: "0.1.
|
|
30381
|
+
bridgeVersion: "0.1.134",
|
|
30318
30382
|
path: pathname,
|
|
30319
30383
|
nodes: collectEditableNodes(editContentRef.current),
|
|
30320
30384
|
sections
|