@ohhwells/bridge 0.1.131 → 0.1.132-next.358
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 +292 -87
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +292 -87
- 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
|
@@ -2727,7 +2727,7 @@ var AI_MOBILE_CSS = [
|
|
|
2727
2727
|
// page's first section. Top only (bottom needs no nav clearance); ~96px approximates the
|
|
2728
2728
|
// template nav's own height (measured ~94px) — there's no shared `--ohw-header-h` var to read
|
|
2729
2729
|
// 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-
|
|
2730
|
+
// pixel-exact fit. Horizontal spacing already comes from `data-ai-section-inner`.
|
|
2731
2731
|
'[data-ai-overlay-clearance] [data-ai-overlap-layer="overlay"]{padding-top:96px}',
|
|
2732
2732
|
// A full-bleed carousel's height is pure arithmetic: it spans the whole window, so 16/9 turns
|
|
2733
2733
|
// window width straight into height. Measured at 16/9 it came out ~90% of the viewport at EVERY
|
|
@@ -2743,8 +2743,10 @@ var AI_MOBILE_CSS = [
|
|
|
2743
2743
|
"[data-ai-section]{overflow-x:hidden}",
|
|
2744
2744
|
// `:not([data-ai-full-bleed])`: this `!important` gutter beat the inline `padding: 0` that a
|
|
2745
2745
|
// 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
|
-
|
|
2746
|
+
// still got a 20px band of section background down both sides on a phone. The footer's own
|
|
2747
|
+
// container keeps the unguarded rule below — `data-ai-full-bleed` can never appear on it.
|
|
2748
|
+
"[data-ai-section-inner]:not([data-ai-full-bleed]){padding:0 20px !important}",
|
|
2749
|
+
"[data-ai-container]{padding:0 20px !important}",
|
|
2748
2750
|
"[data-ai-row]{display:flex !important;flex-direction:column !important;align-items:stretch !important}",
|
|
2749
2751
|
"[data-ai-cell]{width:100%;min-width:0}",
|
|
2750
2752
|
// The rule above turns every row into a COLUMN flex container on phones, which silently breaks
|
|
@@ -2945,6 +2947,31 @@ function pricingCardEmphasis(featured, ctx, hasBg) {
|
|
|
2945
2947
|
function textAttrs(ctx, path) {
|
|
2946
2948
|
return ctx.keyFor ? { "data-ohw-key": ctx.keyFor(path), "data-ohw-editable": "text" } : {};
|
|
2947
2949
|
}
|
|
2950
|
+
var AI_RESPONSIVE_CSS = [
|
|
2951
|
+
"@media (max-width: 960px) {",
|
|
2952
|
+
" [data-ai-responsive] [data-ai-grid] { grid-template-columns: repeat(2, 1fr) !important; }",
|
|
2953
|
+
' [data-ai-responsive] [data-ai-grid="1"] { grid-template-columns: 1fr !important; }',
|
|
2954
|
+
"}",
|
|
2955
|
+
"@media (max-width: 640px) {",
|
|
2956
|
+
" [data-ai-responsive] [data-ai-grid] { grid-template-columns: 1fr !important; }",
|
|
2957
|
+
" [data-ai-responsive] [data-ai-columns] > * { grid-column: 1 / -1 !important; }",
|
|
2958
|
+
// Group containers flatten to a column on phones; span placements come along for free.
|
|
2959
|
+
// `:not([data-ai-group="overlap"])` for the same reason as the twin pair in AI_MOBILE_CSS — see
|
|
2960
|
+
// the comment there. This sheet's copy is the narrower selector, so without the exemption it
|
|
2961
|
+
// flattens an `overlap` hero below 640px even though the other rule stands down: measured a 390px
|
|
2962
|
+
// viewport with the heading/CTA in flow *under* the image, 219px of section background where the
|
|
2963
|
+
// layered text used to be.
|
|
2964
|
+
' [data-ai-responsive] [data-ai-group]:not([data-ai-group="overlap"]) { display: flex !important; flex-direction: column !important; }',
|
|
2965
|
+
' [data-ai-responsive] [data-ai-group]:not([data-ai-group="overlap"]) > * { grid-column: auto !important; }',
|
|
2966
|
+
// `:not([data-ai-full-bleed])` for the same reason as the twin rule in AI_MOBILE_CSS: this one
|
|
2967
|
+
// is narrower (0,2,0 vs 0,1,0) and also `!important`, so without the guard it wins outright and
|
|
2968
|
+
// a full-bleed hero gets its 20px side band back below 640px only — the one width where the
|
|
2969
|
+
// other rule had already been taught to stand down.
|
|
2970
|
+
" [data-ai-responsive] [data-ai-section-inner]:not([data-ai-full-bleed]) { padding-left: 20px !important; padding-right: 20px !important; }",
|
|
2971
|
+
" [data-ai-responsive] { overflow-x: hidden; }",
|
|
2972
|
+
" [data-ai-responsive] img { max-width: 100%; }",
|
|
2973
|
+
"}"
|
|
2974
|
+
].join("\n");
|
|
2948
2975
|
var TRANSPARENT_PX = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7";
|
|
2949
2976
|
function MediaBox({
|
|
2950
2977
|
refValue,
|
|
@@ -2965,9 +2992,9 @@ function MediaBox({
|
|
|
2965
2992
|
const url = refValue ? ctx.resolveMedia(refValue) : null;
|
|
2966
2993
|
const isIcon = /^(lucide|simple):/.test(refValue);
|
|
2967
2994
|
const aspectRatio = aspect && /^\d+:\d+$/.test(aspect) ? aspect.replace(":", " / ") : void 0;
|
|
2968
|
-
const editAttrs = ctx.keyFor && editPath
|
|
2995
|
+
const editAttrs = ctx.keyFor && editPath ? {
|
|
2969
2996
|
"data-ohw-key": ctx.keyFor(editPath),
|
|
2970
|
-
...genericImageEdit ? { "data-ohw-editable": "image" } : {}
|
|
2997
|
+
...isIcon ? { "data-ohw-editable": "icon" } : genericImageEdit ? { "data-ohw-editable": "image" } : {}
|
|
2971
2998
|
} : {};
|
|
2972
2999
|
if (isIcon) {
|
|
2973
3000
|
const Icon = refValue.startsWith("lucide:") ? lucideByName(refValue.slice(7)) : null;
|
|
@@ -2975,6 +3002,7 @@ function MediaBox({
|
|
|
2975
3002
|
"span",
|
|
2976
3003
|
{
|
|
2977
3004
|
"data-ai-icon": refValue,
|
|
3005
|
+
...editAttrs,
|
|
2978
3006
|
style: {
|
|
2979
3007
|
display: "inline-flex",
|
|
2980
3008
|
width: 48,
|
|
@@ -4461,7 +4489,7 @@ function CollectionBlock({ node, ctx, path }) {
|
|
|
4461
4489
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
4462
4490
|
"div",
|
|
4463
4491
|
{
|
|
4464
|
-
"data-ai-grid":
|
|
4492
|
+
"data-ai-grid": String(itemsPerRow),
|
|
4465
4493
|
"data-ohw-pricing-collection": isPricing ? "" : void 0,
|
|
4466
4494
|
style: {
|
|
4467
4495
|
display: "grid",
|
|
@@ -4721,7 +4749,7 @@ function renderNode(node, ctx, path, ambientAlign) {
|
|
|
4721
4749
|
},
|
|
4722
4750
|
children: [
|
|
4723
4751
|
i > 0 && ctx.heroOverlapFullBleed ? (
|
|
4724
|
-
// The section's `data-ai-
|
|
4752
|
+
// The section's `data-ai-section-inner` gave up its max-width/gutter so the base
|
|
4725
4753
|
// layer (this group's i===0 sibling) can span edge-to-edge — reintroduced here,
|
|
4726
4754
|
// scoped to just the overlay text, so a heading/copy/CTA stack doesn't stretch
|
|
4727
4755
|
// the full section width instead of reading at the usual content width.
|
|
@@ -5114,6 +5142,7 @@ function AiTreeRenderer({
|
|
|
5114
5142
|
...fillHeight ? { "data-ai-fill-height": "" } : {},
|
|
5115
5143
|
...needsOverlayClearance ? { "data-ai-overlay-clearance": "" } : {},
|
|
5116
5144
|
...bgAttrs,
|
|
5145
|
+
"data-ai-responsive": "",
|
|
5117
5146
|
style: {
|
|
5118
5147
|
position: "relative",
|
|
5119
5148
|
padding: `${padCss} 0`,
|
|
@@ -5127,12 +5156,13 @@ function AiTreeRenderer({
|
|
|
5127
5156
|
...fillHeight ? { display: "grid" } : {}
|
|
5128
5157
|
},
|
|
5129
5158
|
children: [
|
|
5130
|
-
|
|
5159
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("style", { children: AI_RESPONSIVE_CSS }),
|
|
5131
5160
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("style", { children: AI_MOBILE_CSS }),
|
|
5161
|
+
isOverlay && backgroundUrl && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { position: "absolute", inset: 0, background: `rgba(255,255,255,${overlayAlpha})` } }),
|
|
5132
5162
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
5133
5163
|
"div",
|
|
5134
5164
|
{
|
|
5135
|
-
"data-ai-
|
|
5165
|
+
"data-ai-section-inner": "",
|
|
5136
5166
|
...fullBleedMedia ? { "data-ai-full-bleed": "" } : {},
|
|
5137
5167
|
style: {
|
|
5138
5168
|
position: "relative",
|
|
@@ -5149,7 +5179,7 @@ function AiTreeRenderer({
|
|
|
5149
5179
|
children: tree.rows.map((row, r2) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
5150
5180
|
"div",
|
|
5151
5181
|
{
|
|
5152
|
-
"data-ai-
|
|
5182
|
+
"data-ai-columns": "",
|
|
5153
5183
|
style: {
|
|
5154
5184
|
display: "grid",
|
|
5155
5185
|
gridTemplateColumns: "repeat(12, 1fr)",
|
|
@@ -5805,9 +5835,10 @@ function applyAiSectionsToDom(state, options) {
|
|
|
5805
5835
|
if (existing && existing.serialized === serialized && existing.container.isConnected) {
|
|
5806
5836
|
continue;
|
|
5807
5837
|
}
|
|
5808
|
-
const isNewMount = !existing || !existing.container.isConnected;
|
|
5809
5838
|
let container = existing?.container;
|
|
5839
|
+
let isNewMount = false;
|
|
5810
5840
|
if (!container || !container.isConnected) {
|
|
5841
|
+
isNewMount = true;
|
|
5811
5842
|
existing?.root.unmount();
|
|
5812
5843
|
container?.remove();
|
|
5813
5844
|
container = document.createElement("div");
|
|
@@ -13375,17 +13406,9 @@ var Button = React7.forwardRef(
|
|
|
13375
13406
|
);
|
|
13376
13407
|
Button.displayName = "Button";
|
|
13377
13408
|
|
|
13378
|
-
// src/ui/
|
|
13379
|
-
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
13409
|
+
// src/ui/media-skeleton.ts
|
|
13380
13410
|
var MEDIA_UPLOAD_FADE_MS = 300;
|
|
13381
|
-
var
|
|
13382
|
-
var OVERLAY_BUTTON_STYLE = {
|
|
13383
|
-
pointerEvents: "auto",
|
|
13384
|
-
fontFamily: "Inter, sans-serif",
|
|
13385
|
-
fontSize: 12,
|
|
13386
|
-
color: "#000"
|
|
13387
|
-
};
|
|
13388
|
-
var SKELETON_CSS = `
|
|
13411
|
+
var MEDIA_SKELETON_CSS = `
|
|
13389
13412
|
@keyframes ohw-media-shimmer {
|
|
13390
13413
|
0% { transform: translateX(-100%); }
|
|
13391
13414
|
100% { transform: translateX(100%); }
|
|
@@ -13402,6 +13425,16 @@ var SKELETON_CSS = `
|
|
|
13402
13425
|
animation: ohw-media-shimmer 1.4s infinite;
|
|
13403
13426
|
}
|
|
13404
13427
|
`;
|
|
13428
|
+
|
|
13429
|
+
// src/ui/MediaOverlay.tsx
|
|
13430
|
+
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
13431
|
+
var VIDEO_SETTINGS_BAR_INSET = 8;
|
|
13432
|
+
var OVERLAY_BUTTON_STYLE = {
|
|
13433
|
+
pointerEvents: "auto",
|
|
13434
|
+
fontFamily: "Inter, sans-serif",
|
|
13435
|
+
fontSize: 12,
|
|
13436
|
+
color: "#000"
|
|
13437
|
+
};
|
|
13405
13438
|
var REPLACE_BUTTON_INSET = 12;
|
|
13406
13439
|
function replaceButtonMode(image, button) {
|
|
13407
13440
|
if (!button.fullWidth || !button.height) return "none";
|
|
@@ -13440,6 +13473,7 @@ function MediaOverlay({
|
|
|
13440
13473
|
(prev) => prev && prev.fullWidth === width && prev.height === height ? prev : { fullWidth: width, height }
|
|
13441
13474
|
);
|
|
13442
13475
|
}, [isVideo]);
|
|
13476
|
+
const replaceLabel = isVideo ? "Replace video" : hover.elementType === "bg-image" ? "Replace background" : "Replace image";
|
|
13443
13477
|
const replaceMode = buttonSize ? replaceButtonMode({ width: rect.width, height: rect.height }, buttonSize) : "none";
|
|
13444
13478
|
const box = {
|
|
13445
13479
|
position: "fixed",
|
|
@@ -13469,7 +13503,7 @@ function MediaOverlay({
|
|
|
13469
13503
|
"data-ohw-media-skeleton": "",
|
|
13470
13504
|
"aria-hidden": true,
|
|
13471
13505
|
style: { ...box, pointerEvents: "none" },
|
|
13472
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("style", { children:
|
|
13506
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("style", { children: MEDIA_SKELETON_CSS })
|
|
13473
13507
|
}
|
|
13474
13508
|
);
|
|
13475
13509
|
}
|
|
@@ -13538,11 +13572,10 @@ function MediaOverlay({
|
|
|
13538
13572
|
className: "flex items-center justify-center cursor-pointer",
|
|
13539
13573
|
style: {
|
|
13540
13574
|
...box,
|
|
13541
|
-
//
|
|
13542
|
-
//
|
|
13543
|
-
//
|
|
13544
|
-
|
|
13545
|
-
pointerEvents: hover.hasTextOverlap || cueOnly ? "none" : "auto",
|
|
13575
|
+
// Visual only. `pointer-events: auto` on this full-bleed rect covered the navbar
|
|
13576
|
+
// (hero bg includes the absolute TopNav) and swallowed CTA press-drag. Text overlay
|
|
13577
|
+
// and cueOnly also need clicks to fall through — Replace / video controls opt back in.
|
|
13578
|
+
pointerEvents: "none",
|
|
13546
13579
|
// Selected: a firm component ring with no wash, so the image reads as chosen rather
|
|
13547
13580
|
// than hovered. Hover keeps the existing tinted preview.
|
|
13548
13581
|
boxShadow: selected ? "inset 0 0 0 2px var(--color-bridge-primary)" : "inset 0 0 0 1.5px var(--color-bridge-primary)",
|
|
@@ -13569,17 +13602,17 @@ function MediaOverlay({
|
|
|
13569
13602
|
},
|
|
13570
13603
|
children: [
|
|
13571
13604
|
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 }),
|
|
13572
|
-
|
|
13605
|
+
replaceLabel
|
|
13573
13606
|
]
|
|
13574
13607
|
}
|
|
13575
13608
|
),
|
|
13576
|
-
replaceMode
|
|
13609
|
+
showChrome && replaceMode !== "none" && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
|
|
13577
13610
|
Button,
|
|
13578
13611
|
{
|
|
13579
13612
|
"data-ohw-media-overlay": "",
|
|
13580
13613
|
variant: "outline",
|
|
13581
13614
|
size: "sm",
|
|
13582
|
-
"aria-label":
|
|
13615
|
+
"aria-label": replaceLabel,
|
|
13583
13616
|
className: "gap-1.5 cursor-pointer hover:bg-background",
|
|
13584
13617
|
style: {
|
|
13585
13618
|
...OVERLAY_BUTTON_STYLE,
|
|
@@ -13602,7 +13635,7 @@ function MediaOverlay({
|
|
|
13602
13635
|
},
|
|
13603
13636
|
children: [
|
|
13604
13637
|
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 }),
|
|
13605
|
-
replaceMode === "full" ?
|
|
13638
|
+
replaceMode === "full" ? replaceLabel : null
|
|
13606
13639
|
]
|
|
13607
13640
|
}
|
|
13608
13641
|
)
|
|
@@ -15899,6 +15932,17 @@ function setCarouselSlideAsset(tree, index, assetId) {
|
|
|
15899
15932
|
return true;
|
|
15900
15933
|
});
|
|
15901
15934
|
}
|
|
15935
|
+
function carouselAutoplay(tree) {
|
|
15936
|
+
return findCarouselBlock(tree)?.slots?.autoplay === true;
|
|
15937
|
+
}
|
|
15938
|
+
function setCarouselAutoplay(tree, on) {
|
|
15939
|
+
return withCarousel(tree, (block) => {
|
|
15940
|
+
const slots = { ...block.slots, autoplay: on };
|
|
15941
|
+
if (!on) delete slots.interval;
|
|
15942
|
+
block.slots = slots;
|
|
15943
|
+
return true;
|
|
15944
|
+
});
|
|
15945
|
+
}
|
|
15902
15946
|
|
|
15903
15947
|
// src/ui/ai-section/AiFadeCarouselOverlay.tsx
|
|
15904
15948
|
var import_jsx_runtime22 = require("react/jsx-runtime");
|
|
@@ -16012,10 +16056,85 @@ function Pill4({ label, onClick, disabled }) {
|
|
|
16012
16056
|
}
|
|
16013
16057
|
);
|
|
16014
16058
|
}
|
|
16059
|
+
function TogglePill({
|
|
16060
|
+
label,
|
|
16061
|
+
on,
|
|
16062
|
+
onToggle,
|
|
16063
|
+
disabled
|
|
16064
|
+
}) {
|
|
16065
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
|
|
16066
|
+
"button",
|
|
16067
|
+
{
|
|
16068
|
+
type: "button",
|
|
16069
|
+
role: "switch",
|
|
16070
|
+
"aria-checked": on,
|
|
16071
|
+
onClick: onToggle,
|
|
16072
|
+
disabled,
|
|
16073
|
+
title: on ? `${label} on \u2014 click to turn off` : `${label} off \u2014 click to turn on`,
|
|
16074
|
+
style: {
|
|
16075
|
+
height: 28,
|
|
16076
|
+
padding: "0 8px 0 10px",
|
|
16077
|
+
display: "inline-flex",
|
|
16078
|
+
alignItems: "center",
|
|
16079
|
+
gap: 8,
|
|
16080
|
+
borderRadius: 999,
|
|
16081
|
+
border: "none",
|
|
16082
|
+
cursor: disabled ? "default" : "pointer",
|
|
16083
|
+
background: "#ffffff",
|
|
16084
|
+
color: OHW_BLUE_DARK4,
|
|
16085
|
+
opacity: disabled ? 0.4 : 1,
|
|
16086
|
+
fontSize: 12,
|
|
16087
|
+
lineHeight: "16px",
|
|
16088
|
+
fontFamily: "Figtree, ui-sans-serif, system-ui, sans-serif",
|
|
16089
|
+
whiteSpace: "nowrap",
|
|
16090
|
+
flex: "0 0 auto"
|
|
16091
|
+
},
|
|
16092
|
+
children: [
|
|
16093
|
+
label,
|
|
16094
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
16095
|
+
"span",
|
|
16096
|
+
{
|
|
16097
|
+
"aria-hidden": true,
|
|
16098
|
+
style: {
|
|
16099
|
+
position: "relative",
|
|
16100
|
+
width: 26,
|
|
16101
|
+
height: 15,
|
|
16102
|
+
borderRadius: 999,
|
|
16103
|
+
flex: "0 0 auto",
|
|
16104
|
+
// Off is a grey track, not a washed-out blue: the pill's own white background already
|
|
16105
|
+
// carries the brand colour in the text, and a pale blue track next to it read as
|
|
16106
|
+
// "disabled control" rather than "switch that is off".
|
|
16107
|
+
background: on ? OHW_BLUE_DARK4 : "#CBD5E1",
|
|
16108
|
+
transition: "background 120ms ease"
|
|
16109
|
+
},
|
|
16110
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
16111
|
+
"span",
|
|
16112
|
+
{
|
|
16113
|
+
style: {
|
|
16114
|
+
position: "absolute",
|
|
16115
|
+
top: 2,
|
|
16116
|
+
left: on ? 13 : 2,
|
|
16117
|
+
width: 11,
|
|
16118
|
+
height: 11,
|
|
16119
|
+
borderRadius: "50%",
|
|
16120
|
+
background: "#ffffff",
|
|
16121
|
+
boxShadow: "0 1px 2px rgba(0,0,0,0.3)",
|
|
16122
|
+
transition: "left 120ms ease"
|
|
16123
|
+
}
|
|
16124
|
+
}
|
|
16125
|
+
)
|
|
16126
|
+
}
|
|
16127
|
+
)
|
|
16128
|
+
]
|
|
16129
|
+
}
|
|
16130
|
+
);
|
|
16131
|
+
}
|
|
16015
16132
|
function CarouselSlideToolbar({
|
|
16016
16133
|
pending,
|
|
16017
16134
|
error,
|
|
16018
|
-
|
|
16135
|
+
autoplay,
|
|
16136
|
+
onChangeImage,
|
|
16137
|
+
onToggleAutoplay
|
|
16019
16138
|
}) {
|
|
16020
16139
|
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
|
|
16021
16140
|
"div",
|
|
@@ -16032,11 +16151,18 @@ function CarouselSlideToolbar({
|
|
|
16032
16151
|
padding: 8,
|
|
16033
16152
|
borderRadius: 12,
|
|
16034
16153
|
boxShadow: "0 8px 24px rgba(0,0,0,0.25)",
|
|
16035
|
-
|
|
16036
|
-
|
|
16154
|
+
// Not dimmed while pending, only inert. The toolbar used to drop to 0.6 opacity for the
|
|
16155
|
+
// length of the validate round-trip, which on a local backend is short enough that the
|
|
16156
|
+
// autoplay toggle just flashed — a dim and an un-dim with nothing in between. Progress is
|
|
16157
|
+
// reported where the change is: the switch moves at once (optimistically), and an image
|
|
16158
|
+
// swap raises the skeleton over the slide.
|
|
16159
|
+
pointerEvents: pending ? "none" : "auto"
|
|
16037
16160
|
},
|
|
16038
16161
|
children: [
|
|
16039
|
-
/* @__PURE__ */ (0, import_jsx_runtime22.
|
|
16162
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { style: { display: "flex", gap: 6, alignItems: "center" }, children: [
|
|
16163
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Pill4, { label: "Change Image", onClick: onChangeImage }),
|
|
16164
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(TogglePill, { label: "Autoplay", on: autoplay, onToggle: onToggleAutoplay })
|
|
16165
|
+
] }),
|
|
16040
16166
|
error && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: { color: "#FCA5A5", fontSize: 11, maxWidth: 220, textAlign: "center" }, children: error })
|
|
16041
16167
|
]
|
|
16042
16168
|
}
|
|
@@ -16052,8 +16178,24 @@ function AiFadeCarouselOverlay({
|
|
|
16052
16178
|
const [active, setActive] = (0, import_react12.useState)(null);
|
|
16053
16179
|
const [pending, setPending] = (0, import_react12.useState)(false);
|
|
16054
16180
|
const [error, setError] = (0, import_react12.useState)(null);
|
|
16181
|
+
const [autoplayOverride, setAutoplayOverride] = (0, import_react12.useState)(null);
|
|
16182
|
+
const [swapping, setSwapping] = (0, import_react12.useState)(null);
|
|
16183
|
+
const skeletonRef = (0, import_react12.useRef)(null);
|
|
16055
16184
|
const activeRef = (0, import_react12.useRef)(null);
|
|
16056
16185
|
activeRef.current = active;
|
|
16186
|
+
(0, import_react12.useEffect)(() => {
|
|
16187
|
+
setAutoplayOverride(null);
|
|
16188
|
+
}, [active?.sectionId, active?.index]);
|
|
16189
|
+
(0, import_react12.useEffect)(() => {
|
|
16190
|
+
if (!swapping?.fadingOut || !skeletonRef.current) return;
|
|
16191
|
+
const anim = skeletonRef.current.animate([{ opacity: 1 }, { opacity: 0 }], {
|
|
16192
|
+
duration: MEDIA_UPLOAD_FADE_MS,
|
|
16193
|
+
easing: "ease-out",
|
|
16194
|
+
fill: "forwards"
|
|
16195
|
+
});
|
|
16196
|
+
anim.finished.then(() => setSwapping(null)).catch(() => setSwapping(null));
|
|
16197
|
+
return () => anim.cancel();
|
|
16198
|
+
}, [swapping?.fadingOut]);
|
|
16057
16199
|
(0, import_react12.useEffect)(() => {
|
|
16058
16200
|
const onMove = (e) => {
|
|
16059
16201
|
const t = e.target;
|
|
@@ -16194,6 +16336,27 @@ function AiFadeCarouselOverlay({
|
|
|
16194
16336
|
children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react11.Star, { size: 14, style: { pointerEvents: "none" } })
|
|
16195
16337
|
}
|
|
16196
16338
|
),
|
|
16339
|
+
swapping && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
16340
|
+
"div",
|
|
16341
|
+
{
|
|
16342
|
+
ref: skeletonRef,
|
|
16343
|
+
"data-ohw-bridge": "",
|
|
16344
|
+
"data-ohw-media-skeleton": "",
|
|
16345
|
+
"aria-hidden": true,
|
|
16346
|
+
style: {
|
|
16347
|
+
position: "fixed",
|
|
16348
|
+
top: swapping.rect.top,
|
|
16349
|
+
left: swapping.rect.left,
|
|
16350
|
+
width: swapping.rect.width,
|
|
16351
|
+
height: swapping.rect.height,
|
|
16352
|
+
// Under the toolbar (2147483647) so its controls stay visible and clickable over the
|
|
16353
|
+
// slide being swapped, and inert so it cannot eat the click that dismisses them.
|
|
16354
|
+
zIndex: 2147483646,
|
|
16355
|
+
pointerEvents: "none"
|
|
16356
|
+
},
|
|
16357
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("style", { children: MEDIA_SKELETON_CSS })
|
|
16358
|
+
}
|
|
16359
|
+
),
|
|
16197
16360
|
activeItemRect && active && activeEntry && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
16198
16361
|
ItemInteractionLayer,
|
|
16199
16362
|
{
|
|
@@ -16204,14 +16367,36 @@ function AiFadeCarouselOverlay({
|
|
|
16204
16367
|
{
|
|
16205
16368
|
pending,
|
|
16206
16369
|
error,
|
|
16370
|
+
autoplay: autoplayOverride ?? carouselAutoplay(activeEntry.tree),
|
|
16371
|
+
onToggleAutoplay: () => {
|
|
16372
|
+
const next = !(autoplayOverride ?? carouselAutoplay(activeEntry.tree));
|
|
16373
|
+
setAutoplayOverride(next);
|
|
16374
|
+
void runMutation(active.sectionId, (tree) => setCarouselAutoplay(tree, next)).then(
|
|
16375
|
+
(ok) => {
|
|
16376
|
+
if (!ok) setAutoplayOverride(null);
|
|
16377
|
+
}
|
|
16378
|
+
);
|
|
16379
|
+
},
|
|
16207
16380
|
onChangeImage: () => {
|
|
16208
|
-
void requestAssetPick2(postToParent2).then((picked) => {
|
|
16381
|
+
void requestAssetPick2(postToParent2).then(async (picked) => {
|
|
16209
16382
|
if (!picked) return;
|
|
16210
|
-
|
|
16383
|
+
const slideRect = readRect5(active);
|
|
16384
|
+
if (slideRect) setSwapping({ rect: slideRect, fadingOut: false });
|
|
16385
|
+
const ok = await runMutation(
|
|
16211
16386
|
active.sectionId,
|
|
16212
16387
|
(tree) => setCarouselSlideAsset(tree, active.index, picked.assetId),
|
|
16213
16388
|
{ [picked.assetId]: picked.url }
|
|
16214
16389
|
);
|
|
16390
|
+
if (!ok) {
|
|
16391
|
+
setSwapping(null);
|
|
16392
|
+
return;
|
|
16393
|
+
}
|
|
16394
|
+
const preload = new Image();
|
|
16395
|
+
const done = () => setSwapping((s) => s ? { ...s, fadingOut: true } : s);
|
|
16396
|
+
preload.onload = done;
|
|
16397
|
+
preload.onerror = done;
|
|
16398
|
+
preload.src = picked.url;
|
|
16399
|
+
if (preload.complete) done();
|
|
16215
16400
|
});
|
|
16216
16401
|
}
|
|
16217
16402
|
}
|
|
@@ -19682,6 +19867,7 @@ function readLogoSizeState(content, placement) {
|
|
|
19682
19867
|
function getLogoElement(el) {
|
|
19683
19868
|
const marked = el.closest('[data-ohw-role="logo"], [data-ohw-logo]');
|
|
19684
19869
|
if (marked) return marked;
|
|
19870
|
+
if (el.closest('[data-ohw-editable="icon"]')) return null;
|
|
19685
19871
|
const root = el.closest("nav, [data-ohw-nav-root], footer");
|
|
19686
19872
|
if (!root) return null;
|
|
19687
19873
|
const anchor = el.closest("a");
|
|
@@ -23173,7 +23359,7 @@ function getNavigationSelectionParent(el) {
|
|
|
23173
23359
|
if (!isFooterLinksContainer(el) && (el.hasAttribute("data-ohw-footer-col") || el.hasAttribute("data-ohw-footer-column") || isInferredFooterGroup2(el))) {
|
|
23174
23360
|
return resolveFooterLinksContainerFrom(el);
|
|
23175
23361
|
}
|
|
23176
|
-
if (el.hasAttribute("data-ohw-nav-container") || el.hasAttribute("data-ohw-nav-drawer") || isFooterLinksContainer(el)) {
|
|
23362
|
+
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)) {
|
|
23177
23363
|
return getNavigationRoot(el);
|
|
23178
23364
|
}
|
|
23179
23365
|
return null;
|
|
@@ -23395,7 +23581,6 @@ var ICONS = {
|
|
|
23395
23581
|
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"/>',
|
|
23396
23582
|
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"/>'
|
|
23397
23583
|
};
|
|
23398
|
-
var HEIGHT_SETTLE_DELAYS = [150, 400, 800];
|
|
23399
23584
|
var SELECTION_CHROME_GAP2 = 4;
|
|
23400
23585
|
var TOOLBAR_STROKE_GAP2 = 4;
|
|
23401
23586
|
var TOOLBAR_OFFSET_FROM_ELEMENT = SELECTION_CHROME_GAP2 + TOOLBAR_STROKE_GAP2;
|
|
@@ -24375,21 +24560,6 @@ function OhhwellsBridge() {
|
|
|
24375
24560
|
const [isItemDragging, setIsItemDragging] = (0, import_react21.useState)(false);
|
|
24376
24561
|
const [isFooterFrameSelection, setIsFooterFrameSelection] = (0, import_react21.useState)(false);
|
|
24377
24562
|
isFooterFrameSelectionRef.current = isFooterFrameSelection;
|
|
24378
|
-
const [floatingPanel, setFloatingPanel] = (0, import_react21.useState)(null);
|
|
24379
|
-
const floatingPanelOpenRef = (0, import_react21.useRef)(false);
|
|
24380
|
-
floatingPanelOpenRef.current = floatingPanel !== null;
|
|
24381
|
-
const floatingPanelRef = (0, import_react21.useRef)(null);
|
|
24382
|
-
floatingPanelRef.current = floatingPanel;
|
|
24383
|
-
const [floatingPanelPos, setFloatingPanelPos] = (0, import_react21.useState)(null);
|
|
24384
|
-
const buttonCollectionDragRef = (0, import_react21.useRef)(null);
|
|
24385
|
-
const buttonDropInsertIndexRef = (0, import_react21.useRef)(null);
|
|
24386
|
-
const [buttonDropSlots, setButtonDropSlots] = (0, import_react21.useState)([]);
|
|
24387
|
-
const [activeButtonDropIndex, setActiveButtonDropIndex] = (0, import_react21.useState)(null);
|
|
24388
|
-
const buttonPointerDragRef = (0, import_react21.useRef)(null);
|
|
24389
|
-
const [buttonStyleTick, setButtonStyleTick] = (0, import_react21.useState)(0);
|
|
24390
|
-
const [logoSizeDraft, setLogoSizeDraft] = (0, import_react21.useState)(null);
|
|
24391
|
-
const [editorViewport, setEditorViewport] = (0, import_react21.useState)("desktop");
|
|
24392
|
-
const [parentScrollSnap, setParentScrollSnap] = (0, import_react21.useState)(null);
|
|
24393
24563
|
const [navDropdownPreviewOpen, setNavDropdownPreviewOpen] = (0, import_react21.useState)(null);
|
|
24394
24564
|
const [footerHeadingVisible, setFooterHeadingVisible] = (0, import_react21.useState)(null);
|
|
24395
24565
|
const footerDragRef = (0, import_react21.useRef)(null);
|
|
@@ -24415,6 +24585,21 @@ function OhhwellsBridge() {
|
|
|
24415
24585
|
const stylesRef = (0, import_react21.useRef)("");
|
|
24416
24586
|
const appliedDrawerRef = (0, import_react21.useRef)(null);
|
|
24417
24587
|
const pendingDeleteUndoRef = (0, import_react21.useRef)(null);
|
|
24588
|
+
const [floatingPanel, setFloatingPanel] = (0, import_react21.useState)(null);
|
|
24589
|
+
const floatingPanelOpenRef = (0, import_react21.useRef)(false);
|
|
24590
|
+
const floatingPanelRef = (0, import_react21.useRef)(null);
|
|
24591
|
+
floatingPanelRef.current = floatingPanel;
|
|
24592
|
+
const setFloatingPanelRef = (0, import_react21.useRef)(setFloatingPanel);
|
|
24593
|
+
const [floatingPanelPos, setFloatingPanelPos] = (0, import_react21.useState)(null);
|
|
24594
|
+
const buttonCollectionDragRef = (0, import_react21.useRef)(null);
|
|
24595
|
+
const buttonDropInsertIndexRef = (0, import_react21.useRef)(null);
|
|
24596
|
+
const [buttonDropSlots, setButtonDropSlots] = (0, import_react21.useState)([]);
|
|
24597
|
+
const [activeButtonDropIndex, setActiveButtonDropIndex] = (0, import_react21.useState)(null);
|
|
24598
|
+
const buttonPointerDragRef = (0, import_react21.useRef)(null);
|
|
24599
|
+
const [buttonStyleTick, setButtonStyleTick] = (0, import_react21.useState)(0);
|
|
24600
|
+
const [logoSizeDraft, setLogoSizeDraft] = (0, import_react21.useState)(null);
|
|
24601
|
+
const [editorViewport, setEditorViewport] = (0, import_react21.useState)("desktop");
|
|
24602
|
+
const [parentScrollSnap, setParentScrollSnap] = (0, import_react21.useState)(null);
|
|
24418
24603
|
const [sitePages, setSitePages] = (0, import_react21.useState)([]);
|
|
24419
24604
|
const [sectionsByPath, setSectionsByPath] = (0, import_react21.useState)({});
|
|
24420
24605
|
const sectionsPrefetchGenRef = (0, import_react21.useRef)(0);
|
|
@@ -24423,7 +24608,18 @@ function OhhwellsBridge() {
|
|
|
24423
24608
|
const linkPopoverOpenRef = (0, import_react21.useRef)(false);
|
|
24424
24609
|
const linkPopoverGraceUntilRef = (0, import_react21.useRef)(0);
|
|
24425
24610
|
setLinkPopoverRef.current = setLinkPopover;
|
|
24611
|
+
setFloatingPanelRef.current = setFloatingPanel;
|
|
24426
24612
|
linkPopoverSessionRef.current = linkPopover;
|
|
24613
|
+
floatingPanelOpenRef.current = Boolean(floatingPanel);
|
|
24614
|
+
(0, import_react21.useEffect)(() => {
|
|
24615
|
+
const syncViewport = () => {
|
|
24616
|
+
const next = window.innerWidth <= 480 ? "mobile" : "desktop";
|
|
24617
|
+
setEditorViewport((prev) => prev === next ? prev : next);
|
|
24618
|
+
};
|
|
24619
|
+
syncViewport();
|
|
24620
|
+
window.addEventListener("resize", syncViewport);
|
|
24621
|
+
return () => window.removeEventListener("resize", syncViewport);
|
|
24622
|
+
}, []);
|
|
24427
24623
|
(0, import_react21.useEffect)(() => {
|
|
24428
24624
|
setSectionOrderPersistHandler((entries) => {
|
|
24429
24625
|
const currentPath = window.location.pathname;
|
|
@@ -26102,6 +26298,7 @@ function OhhwellsBridge() {
|
|
|
26102
26298
|
applyAiFooterFromContent(content);
|
|
26103
26299
|
if (typeof content[STYLE_STORE_KEY] === "string") {
|
|
26104
26300
|
stylesRef.current = content[STYLE_STORE_KEY];
|
|
26301
|
+
document.querySelectorAll('[data-ohw-editable="form"]').forEach((f) => markFormFields(f));
|
|
26105
26302
|
applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
|
|
26106
26303
|
}
|
|
26107
26304
|
applyBrandChrome(content);
|
|
@@ -26111,12 +26308,12 @@ function OhhwellsBridge() {
|
|
|
26111
26308
|
if (key === "__ohw_sections") continue;
|
|
26112
26309
|
if (key === AI_SECTIONS_KEY) continue;
|
|
26113
26310
|
if (key === AI_FOOTER_KEY) continue;
|
|
26311
|
+
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
26312
|
+
if (LOGO_IMAGE_KEYS.includes(key)) continue;
|
|
26114
26313
|
if (key === BRAND_KIT_KEY) continue;
|
|
26115
26314
|
if (key === STYLE_STORE_KEY) continue;
|
|
26116
26315
|
if (BRAND_CHROME_KEYS.has(key)) continue;
|
|
26117
|
-
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
26118
26316
|
if (key === CUSTOM_CODE_AFTER_HEAD_KEY || key === CUSTOM_CODE_BEFORE_HEAD_KEY) continue;
|
|
26119
|
-
if (LOGO_IMAGE_KEYS.includes(key)) continue;
|
|
26120
26317
|
if (typeof content[AI_FOOTER_KEY] === "string" && content[AI_FOOTER_KEY] && isAiFooterOwnedContentKey(key)) {
|
|
26121
26318
|
continue;
|
|
26122
26319
|
}
|
|
@@ -26330,17 +26527,18 @@ function OhhwellsBridge() {
|
|
|
26330
26527
|
}
|
|
26331
26528
|
applyAiFooterFromContent(content);
|
|
26332
26529
|
if (typeof content[STYLE_STORE_KEY] === "string") {
|
|
26530
|
+
document.querySelectorAll('[data-ohw-editable="form"]').forEach((f) => markFormFields(f));
|
|
26333
26531
|
applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
|
|
26334
26532
|
}
|
|
26335
26533
|
for (const [key, val] of Object.entries(content)) {
|
|
26336
26534
|
if (key === "__ohw_sections") continue;
|
|
26337
26535
|
if (key === AI_SECTIONS_KEY) continue;
|
|
26338
26536
|
if (key === AI_FOOTER_KEY) continue;
|
|
26537
|
+
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
26538
|
+
if (LOGO_IMAGE_KEYS.includes(key)) continue;
|
|
26339
26539
|
if (key === BRAND_KIT_KEY) continue;
|
|
26340
26540
|
if (key === STYLE_STORE_KEY) continue;
|
|
26341
26541
|
if (BRAND_CHROME_KEYS.has(key)) continue;
|
|
26342
|
-
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
26343
|
-
if (LOGO_IMAGE_KEYS.includes(key)) continue;
|
|
26344
26542
|
if (typeof content[AI_FOOTER_KEY] === "string" && content[AI_FOOTER_KEY] && isAiFooterOwnedContentKey(key)) {
|
|
26345
26543
|
continue;
|
|
26346
26544
|
}
|
|
@@ -26596,26 +26794,11 @@ function OhhwellsBridge() {
|
|
|
26596
26794
|
const t2 = setTimeout(measure, 500);
|
|
26597
26795
|
const ro = new ResizeObserver(schedule);
|
|
26598
26796
|
ro.observe(document.body);
|
|
26599
|
-
let lastWidth = window.innerWidth;
|
|
26600
|
-
let resizeTimers = [];
|
|
26601
|
-
const clearResizeTimers = () => {
|
|
26602
|
-
resizeTimers.forEach(clearTimeout);
|
|
26603
|
-
resizeTimers = [];
|
|
26604
|
-
};
|
|
26605
|
-
const handleResize = () => {
|
|
26606
|
-
if (window.innerWidth === lastWidth) return;
|
|
26607
|
-
lastWidth = window.innerWidth;
|
|
26608
|
-
clearResizeTimers();
|
|
26609
|
-
resizeTimers = HEIGHT_SETTLE_DELAYS.map((delay) => setTimeout(measure, delay));
|
|
26610
|
-
};
|
|
26611
|
-
window.addEventListener("resize", handleResize);
|
|
26612
26797
|
return () => {
|
|
26613
26798
|
clearTimeout(t1);
|
|
26614
26799
|
clearTimeout(t2);
|
|
26615
26800
|
if (raf != null) cancelAnimationFrame(raf);
|
|
26616
26801
|
ro.disconnect();
|
|
26617
|
-
clearResizeTimers();
|
|
26618
|
-
window.removeEventListener("resize", handleResize);
|
|
26619
26802
|
};
|
|
26620
26803
|
}, [pathname, isEditMode, postToParent2]);
|
|
26621
26804
|
(0, import_react21.useEffect)(() => {
|
|
@@ -26910,6 +27093,13 @@ function OhhwellsBridge() {
|
|
|
26910
27093
|
if (target.closest("[data-ohw-state-toggle]")) return;
|
|
26911
27094
|
if (target.closest("[data-ohw-max-badge]")) return;
|
|
26912
27095
|
if (isInsideLinkEditor(target)) return;
|
|
27096
|
+
if (isInsideFloatingPanel(target)) return;
|
|
27097
|
+
if (target.closest("[data-ohw-form-toolbar]")) return;
|
|
27098
|
+
if (target.closest(
|
|
27099
|
+
'[data-ohw-field-toolbar], [data-ohw-field-type-picker], [data-radix-popper-content-wrapper], [role="menu"], [data-slot="dropdown-menu-content"]'
|
|
27100
|
+
)) {
|
|
27101
|
+
return;
|
|
27102
|
+
}
|
|
26913
27103
|
if (selectedMediaElRef.current && !selectedMediaElRef.current.contains(target) && !target.closest("[data-ohw-media-overlay], [data-ohw-edit-chrome], [data-ohw-item-interaction]")) {
|
|
26914
27104
|
clearMediaSelectionRef.current();
|
|
26915
27105
|
}
|
|
@@ -26930,13 +27120,6 @@ function OhhwellsBridge() {
|
|
|
26930
27120
|
return;
|
|
26931
27121
|
}
|
|
26932
27122
|
}
|
|
26933
|
-
if (isInsideFloatingPanel(target)) return;
|
|
26934
|
-
if (target.closest("[data-ohw-form-toolbar]")) return;
|
|
26935
|
-
if (target.closest(
|
|
26936
|
-
'[data-ohw-field-toolbar], [data-ohw-field-type-picker], [data-radix-popper-content-wrapper], [role="menu"], [data-slot="dropdown-menu-content"]'
|
|
26937
|
-
)) {
|
|
26938
|
-
return;
|
|
26939
|
-
}
|
|
26940
27123
|
{
|
|
26941
27124
|
const formEl = getFormElement(target);
|
|
26942
27125
|
const onSuccessText = target.closest(`[${SUCCESS_TEXT_ATTR}]`);
|
|
@@ -27316,6 +27499,9 @@ function OhhwellsBridge() {
|
|
|
27316
27499
|
setHoveredItemRect(null);
|
|
27317
27500
|
hoveredNavContainerRef.current = null;
|
|
27318
27501
|
setHoveredNavContainerRect(null);
|
|
27502
|
+
siblingHintElRef.current = null;
|
|
27503
|
+
setSiblingHintRect(null);
|
|
27504
|
+
setSiblingHintRects([]);
|
|
27319
27505
|
return;
|
|
27320
27506
|
}
|
|
27321
27507
|
{
|
|
@@ -27436,7 +27622,6 @@ function OhhwellsBridge() {
|
|
|
27436
27622
|
hoveredNavContainerRef.current = null;
|
|
27437
27623
|
setHoveredNavContainerRect(null);
|
|
27438
27624
|
hoveredItemElRef.current = editable;
|
|
27439
|
-
setHoveredItemRect(isSelectedForHoverRef.current(editable) ? null : editable.getBoundingClientRect());
|
|
27440
27625
|
}
|
|
27441
27626
|
}
|
|
27442
27627
|
}
|
|
@@ -28146,7 +28331,11 @@ function OhhwellsBridge() {
|
|
|
28146
28331
|
};
|
|
28147
28332
|
const handleMouseMove = (e) => {
|
|
28148
28333
|
const { clientX, clientY } = e;
|
|
28149
|
-
if (pointOwnedByFloatingPanel(clientX, clientY))
|
|
28334
|
+
if (pointOwnedByFloatingPanel(clientX, clientY)) {
|
|
28335
|
+
dismissImageHover();
|
|
28336
|
+
clearImageHover();
|
|
28337
|
+
return;
|
|
28338
|
+
}
|
|
28150
28339
|
if (isNavDrawerOpen() && isPointOutsideOpenDrawer(clientX, clientY)) {
|
|
28151
28340
|
document.querySelectorAll("[data-ohw-hovered]").forEach((el) => el.removeAttribute("data-ohw-hovered"));
|
|
28152
28341
|
formHoverElRef.current = null;
|
|
@@ -28175,7 +28364,12 @@ function OhhwellsBridge() {
|
|
|
28175
28364
|
setHoveredItemRect(null);
|
|
28176
28365
|
hoveredNavContainerRef.current = null;
|
|
28177
28366
|
setHoveredNavContainerRect(null);
|
|
28367
|
+
siblingHintElRef.current = null;
|
|
28368
|
+
setSiblingHintRect(null);
|
|
28369
|
+
setSiblingHintRects([]);
|
|
28178
28370
|
dismissImageHover();
|
|
28371
|
+
clearImageHover();
|
|
28372
|
+
setSectionGap(null);
|
|
28179
28373
|
return;
|
|
28180
28374
|
}
|
|
28181
28375
|
if (probeSocialsRowAt(clientX, clientY)) return;
|
|
@@ -28187,7 +28381,11 @@ function OhhwellsBridge() {
|
|
|
28187
28381
|
if (e.data?.type !== "ow:pointer-sync") return;
|
|
28188
28382
|
const { clientX, clientY } = e.data;
|
|
28189
28383
|
if (typeof clientX !== "number" || typeof clientY !== "number") return;
|
|
28190
|
-
if (pointOwnedByFloatingPanel(clientX, clientY))
|
|
28384
|
+
if (pointOwnedByFloatingPanel(clientX, clientY)) {
|
|
28385
|
+
dismissImageHover();
|
|
28386
|
+
clearImageHover();
|
|
28387
|
+
return;
|
|
28388
|
+
}
|
|
28191
28389
|
if (isNavDrawerOpen() && isPointOutsideOpenDrawer(clientX, clientY)) return;
|
|
28192
28390
|
if (probeSocialsRowAt(clientX, clientY)) return;
|
|
28193
28391
|
probeSectionGapAt(clientX, clientY);
|
|
@@ -28539,6 +28737,7 @@ function OhhwellsBridge() {
|
|
|
28539
28737
|
applyAiFooterFromContent(content);
|
|
28540
28738
|
if (typeof content[STYLE_STORE_KEY] === "string") {
|
|
28541
28739
|
stylesRef.current = content[STYLE_STORE_KEY];
|
|
28740
|
+
document.querySelectorAll('[data-ohw-editable="form"]').forEach((f) => markFormFields(f));
|
|
28542
28741
|
applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
|
|
28543
28742
|
}
|
|
28544
28743
|
applyBrandChrome(content);
|
|
@@ -28552,12 +28751,12 @@ function OhhwellsBridge() {
|
|
|
28552
28751
|
}
|
|
28553
28752
|
if (key === AI_SECTIONS_KEY) continue;
|
|
28554
28753
|
if (key === AI_FOOTER_KEY) continue;
|
|
28754
|
+
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
28755
|
+
if (LOGO_IMAGE_KEYS.includes(key) && !String(val ?? "").trim()) continue;
|
|
28555
28756
|
if (key === BRAND_KIT_KEY) continue;
|
|
28556
28757
|
if (key === STYLE_STORE_KEY) continue;
|
|
28557
28758
|
if (BRAND_CHROME_KEYS.has(key)) continue;
|
|
28558
|
-
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
28559
28759
|
if (key === CUSTOM_CODE_AFTER_HEAD_KEY || key === CUSTOM_CODE_BEFORE_HEAD_KEY) continue;
|
|
28560
|
-
if (LOGO_IMAGE_KEYS.includes(key) && !String(val ?? "").trim()) continue;
|
|
28561
28760
|
if (typeof content[AI_FOOTER_KEY] === "string" && content[AI_FOOTER_KEY] && isAiFooterOwnedContentKey(key)) {
|
|
28562
28761
|
continue;
|
|
28563
28762
|
}
|
|
@@ -29094,6 +29293,12 @@ function OhhwellsBridge() {
|
|
|
29094
29293
|
closeLinkPopoverRef.current();
|
|
29095
29294
|
return;
|
|
29096
29295
|
}
|
|
29296
|
+
if (floatingPanelOpenRef.current) {
|
|
29297
|
+
setFloatingPanelRef.current(null);
|
|
29298
|
+
deselectRef.current();
|
|
29299
|
+
deactivateRef.current();
|
|
29300
|
+
return;
|
|
29301
|
+
}
|
|
29097
29302
|
deselectRef.current();
|
|
29098
29303
|
deactivateRef.current();
|
|
29099
29304
|
clearMediaSelectionRef.current();
|
|
@@ -29856,10 +30061,10 @@ function OhhwellsBridge() {
|
|
|
29856
30061
|
window.removeEventListener("message", handleDeleteSection);
|
|
29857
30062
|
window.removeEventListener("message", handleDuplicateSection);
|
|
29858
30063
|
window.removeEventListener("message", handleDeactivate);
|
|
29859
|
-
document.documentElement.removeAttribute("data-ohw-panel-dragging");
|
|
29860
30064
|
window.removeEventListener("message", handleToastAction);
|
|
29861
30065
|
window.removeEventListener("message", handleFormCount);
|
|
29862
30066
|
window.removeEventListener("message", handleUiEscape);
|
|
30067
|
+
document.documentElement.removeAttribute("data-ohw-panel-dragging");
|
|
29863
30068
|
autoSaveTimers.current.forEach(clearTimeout);
|
|
29864
30069
|
autoSaveTimers.current.clear();
|
|
29865
30070
|
if (imageUnhoverTimerRef.current) clearTimeout(imageUnhoverTimerRef.current);
|
|
@@ -30153,7 +30358,7 @@ function OhhwellsBridge() {
|
|
|
30153
30358
|
postToParent2({
|
|
30154
30359
|
type: "ow:ready",
|
|
30155
30360
|
version: "1",
|
|
30156
|
-
bridgeVersion: "0.1.
|
|
30361
|
+
bridgeVersion: "0.1.132",
|
|
30157
30362
|
path: pathname,
|
|
30158
30363
|
nodes: collectEditableNodes(editContentRef.current),
|
|
30159
30364
|
sections
|