@ohhwells/bridge 0.1.60 → 0.1.61-next.173
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 +1557 -187
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +17 -3
- package/dist/index.d.ts +17 -3
- package/dist/index.js +1554 -185
- package/dist/index.js.map +1 -1
- package/dist/pages.cjs +141 -0
- package/dist/pages.cjs.map +1 -0
- package/dist/pages.d.cts +45 -0
- package/dist/pages.d.ts +45 -0
- package/dist/pages.js +107 -0
- package/dist/pages.js.map +1 -0
- package/dist/styles.css +61 -0
- package/package.json +6 -1
package/dist/index.js
CHANGED
|
@@ -96,6 +96,7 @@ function applyTreeToState(state, payload) {
|
|
|
96
96
|
const entry = {
|
|
97
97
|
id: payload.id,
|
|
98
98
|
label: payload.label ?? "Generated section",
|
|
99
|
+
...typeof payload.path === "string" && payload.path ? { path: payload.path } : {},
|
|
99
100
|
afterSection: payload.mode === "insert" && !insertBefore ? payload.targetSectionId ?? null : null,
|
|
100
101
|
...insertBefore && payload.targetSectionId ? { beforeSection: payload.targetSectionId } : {},
|
|
101
102
|
...payload.mode === "replace" && payload.targetSectionId ? { replaces: payload.targetSectionId } : {},
|
|
@@ -118,6 +119,287 @@ function deleteSectionFromState(state, sectionId) {
|
|
|
118
119
|
return { ...state, v: 1, sections: state.sections, removed: [...removed, sectionId] };
|
|
119
120
|
}
|
|
120
121
|
|
|
122
|
+
// src/lib/brand-chrome.ts
|
|
123
|
+
var BRAND_NAME_KEY = "__ohw_brand_name";
|
|
124
|
+
var BRAND_TITLE_KEY = "__ohw_site_title";
|
|
125
|
+
var BRAND_FAVICON_LETTER_KEY = "__ohw_favicon_letter";
|
|
126
|
+
var BRAND_CHROME_KEYS = /* @__PURE__ */ new Set([
|
|
127
|
+
BRAND_NAME_KEY,
|
|
128
|
+
BRAND_TITLE_KEY,
|
|
129
|
+
BRAND_FAVICON_LETTER_KEY
|
|
130
|
+
]);
|
|
131
|
+
function upsertMeta(selector, attr, token, value) {
|
|
132
|
+
let el = document.head.querySelector(selector);
|
|
133
|
+
if (!el) {
|
|
134
|
+
el = document.createElement("meta");
|
|
135
|
+
el.setAttribute(attr, token);
|
|
136
|
+
document.head.appendChild(el);
|
|
137
|
+
}
|
|
138
|
+
if (el.getAttribute("content") !== value) el.setAttribute("content", value);
|
|
139
|
+
}
|
|
140
|
+
function escapeXml(value) {
|
|
141
|
+
return value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
142
|
+
}
|
|
143
|
+
function applyLetterFavicon(letter) {
|
|
144
|
+
const svg = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><rect width="64" height="64" rx="12" fill="#111827"/><text x="32" y="46" font-family="system-ui,-apple-system,Segoe UI,sans-serif" font-size="40" font-weight="700" text-anchor="middle" fill="#ffffff">${escapeXml(letter)}</text></svg>`;
|
|
145
|
+
const href = `data:image/svg+xml,${encodeURIComponent(svg)}`;
|
|
146
|
+
let link = document.head.querySelector('link[rel="icon"]');
|
|
147
|
+
if (!link) {
|
|
148
|
+
link = document.createElement("link");
|
|
149
|
+
link.rel = "icon";
|
|
150
|
+
document.head.appendChild(link);
|
|
151
|
+
}
|
|
152
|
+
link.type = "image/svg+xml";
|
|
153
|
+
if (link.href !== href) link.href = href;
|
|
154
|
+
}
|
|
155
|
+
function applyBrandChrome(content) {
|
|
156
|
+
const name = content[BRAND_NAME_KEY];
|
|
157
|
+
if (typeof name === "string" && name.length > 0) {
|
|
158
|
+
document.querySelectorAll("[data-ohw-wordmark]").forEach((el) => {
|
|
159
|
+
if (el.textContent !== name) el.textContent = name;
|
|
160
|
+
if (el.getAttribute("title") !== name) el.setAttribute("title", name);
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
const title = content[BRAND_TITLE_KEY];
|
|
164
|
+
if (typeof title === "string" && title.length > 0) {
|
|
165
|
+
if (document.title !== title) document.title = title;
|
|
166
|
+
upsertMeta('meta[property="og:title"]', "property", "og:title", title);
|
|
167
|
+
upsertMeta('meta[name="twitter:title"]', "name", "twitter:title", title);
|
|
168
|
+
}
|
|
169
|
+
const letter = content[BRAND_FAVICON_LETTER_KEY];
|
|
170
|
+
if (typeof letter === "string" && letter.length > 0) {
|
|
171
|
+
applyLetterFavicon(letter);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// src/lib/brand-kit.ts
|
|
176
|
+
var BRAND_KIT_KEY = "__ohw_brand";
|
|
177
|
+
var BRAND_VAR_PREFIX = "--ohw-brand-";
|
|
178
|
+
var BRAND_VAR_NAMES = ["primary", "accent", "light", "dark", "surface", "border", "muted"].map(
|
|
179
|
+
(role) => `${BRAND_VAR_PREFIX}${role}`
|
|
180
|
+
);
|
|
181
|
+
var FONT_VARS = { heading: ["--font-heading", "--font-display"], body: ["--font-body"] };
|
|
182
|
+
var BRAND_FONT_LINK_ID = "ohw-brand-fonts";
|
|
183
|
+
function brandColorVars(kit) {
|
|
184
|
+
const { dark, primary, accent, light } = kit.palette;
|
|
185
|
+
const mix = (a, aPct, b) => `color-mix(in srgb, ${a} ${aPct}%, ${b})`;
|
|
186
|
+
return {
|
|
187
|
+
[`${BRAND_VAR_PREFIX}primary`]: primary,
|
|
188
|
+
[`${BRAND_VAR_PREFIX}accent`]: accent,
|
|
189
|
+
[`${BRAND_VAR_PREFIX}light`]: light,
|
|
190
|
+
[`${BRAND_VAR_PREFIX}dark`]: dark,
|
|
191
|
+
[`${BRAND_VAR_PREFIX}surface`]: mix(light, 95, dark),
|
|
192
|
+
[`${BRAND_VAR_PREFIX}border`]: mix(light, 85, dark),
|
|
193
|
+
[`${BRAND_VAR_PREFIX}muted`]: mix(dark, 62, light)
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
function parseBrandKit(raw) {
|
|
197
|
+
if (!raw) return null;
|
|
198
|
+
try {
|
|
199
|
+
const parsed = JSON.parse(raw);
|
|
200
|
+
const p = parsed?.palette;
|
|
201
|
+
const f = parsed?.fonts;
|
|
202
|
+
if (!p || !f || typeof p.dark !== "string" || typeof p.primary !== "string" || typeof p.accent !== "string" || typeof p.light !== "string" || typeof f.heading !== "string" || typeof f.body !== "string") {
|
|
203
|
+
return null;
|
|
204
|
+
}
|
|
205
|
+
return {
|
|
206
|
+
palette: { dark: p.dark, primary: p.primary, accent: p.accent, light: p.light },
|
|
207
|
+
fonts: { heading: f.heading, body: f.body }
|
|
208
|
+
};
|
|
209
|
+
} catch {
|
|
210
|
+
return null;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
function familyOf(stack) {
|
|
214
|
+
const first = stack.split(",")[0]?.trim() ?? "";
|
|
215
|
+
return first.replace(/^['"]|['"]$/g, "");
|
|
216
|
+
}
|
|
217
|
+
function loadBrandFonts(families) {
|
|
218
|
+
const unique = [...new Set(families.map((f) => f.trim()).filter(Boolean))];
|
|
219
|
+
if (unique.length === 0) return;
|
|
220
|
+
const spec = unique.map((f) => `${f.replace(/ /g, "+")}:400,500,600,700`).join("|");
|
|
221
|
+
const href = `https://fonts.googleapis.com/css?family=${spec}&display=swap`;
|
|
222
|
+
let link = document.getElementById(BRAND_FONT_LINK_ID);
|
|
223
|
+
if (!link) {
|
|
224
|
+
link = document.createElement("link");
|
|
225
|
+
link.id = BRAND_FONT_LINK_ID;
|
|
226
|
+
link.rel = "stylesheet";
|
|
227
|
+
document.head.appendChild(link);
|
|
228
|
+
}
|
|
229
|
+
if (link.href !== href) link.href = href;
|
|
230
|
+
}
|
|
231
|
+
function applyBrandToDom(kit) {
|
|
232
|
+
const root = document.documentElement;
|
|
233
|
+
if (!kit) {
|
|
234
|
+
for (const name of BRAND_VAR_NAMES) root.style.removeProperty(name);
|
|
235
|
+
for (const name of [...FONT_VARS.heading, ...FONT_VARS.body]) root.style.removeProperty(name);
|
|
236
|
+
document.getElementById(BRAND_FONT_LINK_ID)?.remove();
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
for (const [name, value] of Object.entries(brandColorVars(kit))) root.style.setProperty(name, value);
|
|
240
|
+
for (const name of FONT_VARS.heading) root.style.setProperty(name, kit.fonts.heading);
|
|
241
|
+
for (const name of FONT_VARS.body) root.style.setProperty(name, kit.fonts.body);
|
|
242
|
+
loadBrandFonts([familyOf(kit.fonts.heading), familyOf(kit.fonts.body)]);
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
// src/lib/section-styles.ts
|
|
246
|
+
var STYLE_STORE_KEY = "__ohw_styles";
|
|
247
|
+
var STYLE_SHEET_ID = "ohw-section-styles";
|
|
248
|
+
function parseStyleStore(raw) {
|
|
249
|
+
if (!raw) return null;
|
|
250
|
+
try {
|
|
251
|
+
const parsed = JSON.parse(raw);
|
|
252
|
+
if (parsed?.v !== 1) return null;
|
|
253
|
+
return {
|
|
254
|
+
v: 1,
|
|
255
|
+
sections: typeof parsed.sections === "object" && parsed.sections ? parsed.sections : {},
|
|
256
|
+
nodes: typeof parsed.nodes === "object" && parsed.nodes ? parsed.nodes : {}
|
|
257
|
+
};
|
|
258
|
+
} catch {
|
|
259
|
+
return null;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
var BG_VALUES = {
|
|
263
|
+
surface: "color-mix(in srgb, var(--ohw-brand-light, var(--color-light, #ECECEB)) 94%, var(--ohw-brand-dark, var(--color-dark, #0C0A09)))",
|
|
264
|
+
accent: "var(--ohw-brand-primary, var(--color-primary, #0078E5))",
|
|
265
|
+
"accent-soft": "color-mix(in srgb, var(--ohw-brand-primary, var(--color-primary, #0078E5)) 12%, var(--ohw-brand-light, var(--color-light, #FFFFFF)))"
|
|
266
|
+
};
|
|
267
|
+
var HEADLINE_SIZES = { md: 24, lg: 32, xl: 40, display: 56 };
|
|
268
|
+
function styleSheetCss() {
|
|
269
|
+
const rules = [];
|
|
270
|
+
for (const [tone, value] of Object.entries(BG_VALUES)) {
|
|
271
|
+
rules.push(`[data-ohw-style-bg="${tone}"] { background: ${value} !important; }`);
|
|
272
|
+
}
|
|
273
|
+
rules.push(
|
|
274
|
+
`[data-ohw-style-bg="accent"] { color: var(--ohw-brand-light, var(--color-light, #FFFFFF)) !important; }`
|
|
275
|
+
);
|
|
276
|
+
rules.push(
|
|
277
|
+
`[data-ohw-style-distribution="space-between"] { display: flex !important; flex-direction: column; justify-content: space-between; }`,
|
|
278
|
+
`[data-ohw-style-distribution="center"] { display: flex !important; flex-direction: column; justify-content: center; }`
|
|
279
|
+
);
|
|
280
|
+
for (const [scale, size] of Object.entries(HEADLINE_SIZES)) {
|
|
281
|
+
rules.push(
|
|
282
|
+
`[data-ohw-style-headline="${scale}"] :is(h1, h2, h3) { font-size: ${size}px !important; line-height: 1.15 !important; }`
|
|
283
|
+
);
|
|
284
|
+
}
|
|
285
|
+
rules.push(
|
|
286
|
+
`[data-ohw-style-aspect="fill-height"] img { height: 100% !important; aspect-ratio: auto !important; object-fit: cover; }`
|
|
287
|
+
);
|
|
288
|
+
for (const aspect of ["1:1", "4:5", "3:4", "3:2", "16:9", "2:1", "3:1"]) {
|
|
289
|
+
rules.push(
|
|
290
|
+
`[data-ohw-style-aspect="${aspect.replace(":", "-")}"] img { aspect-ratio: ${aspect.replace(":", " / ")} !important; height: auto !important; object-fit: cover; }`
|
|
291
|
+
);
|
|
292
|
+
}
|
|
293
|
+
const pad = { tight: 40, balanced: 64, airy: 96 };
|
|
294
|
+
for (const [spacing, px] of Object.entries(pad)) {
|
|
295
|
+
rules.push(
|
|
296
|
+
`[data-ohw-style-spacing="${spacing}"] { padding-top: ${px}px !important; padding-bottom: ${px}px !important; }`
|
|
297
|
+
);
|
|
298
|
+
}
|
|
299
|
+
return rules.join("\n");
|
|
300
|
+
}
|
|
301
|
+
var SECTION_ATTRS = {
|
|
302
|
+
sectionBackground: "data-ohw-style-bg",
|
|
303
|
+
textDistribution: "data-ohw-style-distribution",
|
|
304
|
+
headlineScale: "data-ohw-style-headline",
|
|
305
|
+
imageAspect: "data-ohw-style-aspect",
|
|
306
|
+
spacing: "data-ohw-style-spacing"
|
|
307
|
+
};
|
|
308
|
+
var NODE_WROTE_ATTR = "data-ohw-style-node";
|
|
309
|
+
var NODE_PROPS = ["color", "font-size", "background"];
|
|
310
|
+
function saveInline(el, prop) {
|
|
311
|
+
const attr = `data-ohw-style-prev-${prop}`;
|
|
312
|
+
if (!el.hasAttribute(attr)) el.setAttribute(attr, el.style.getPropertyValue(prop));
|
|
313
|
+
}
|
|
314
|
+
function restoreInline(el, prop) {
|
|
315
|
+
const attr = `data-ohw-style-prev-${prop}`;
|
|
316
|
+
if (!el.hasAttribute(attr)) return;
|
|
317
|
+
const prev = el.getAttribute(attr) ?? "";
|
|
318
|
+
if (prev) el.style.setProperty(prop, prev);
|
|
319
|
+
else el.style.removeProperty(prop);
|
|
320
|
+
el.removeAttribute(attr);
|
|
321
|
+
}
|
|
322
|
+
function ensureStyleSheet() {
|
|
323
|
+
let el = document.getElementById(STYLE_SHEET_ID);
|
|
324
|
+
if (!el) {
|
|
325
|
+
el = document.createElement("style");
|
|
326
|
+
el.id = STYLE_SHEET_ID;
|
|
327
|
+
document.head.appendChild(el);
|
|
328
|
+
}
|
|
329
|
+
const css = styleSheetCss();
|
|
330
|
+
if (el.textContent !== css) el.textContent = css;
|
|
331
|
+
}
|
|
332
|
+
function clearSectionAttrs(root) {
|
|
333
|
+
for (const attr of Object.values(SECTION_ATTRS)) {
|
|
334
|
+
for (const el of Array.from(root.querySelectorAll(`[${attr}]`))) el.removeAttribute(attr);
|
|
335
|
+
}
|
|
336
|
+
for (const el of Array.from(root.querySelectorAll("[data-ohw-style-bgcolor]"))) {
|
|
337
|
+
restoreInline(el, "background");
|
|
338
|
+
el.removeAttribute("data-ohw-style-bgcolor");
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
function clearNodeProps(root) {
|
|
342
|
+
for (const el of Array.from(root.querySelectorAll(`[${NODE_WROTE_ATTR}]`))) {
|
|
343
|
+
const h = el;
|
|
344
|
+
for (const prop of NODE_PROPS) restoreInline(h, prop);
|
|
345
|
+
h.removeAttribute(NODE_WROTE_ATTR);
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
function buttonSurfaceOf(el) {
|
|
349
|
+
return el.closest("a, button") ?? el;
|
|
350
|
+
}
|
|
351
|
+
function applyStylesToDom(store) {
|
|
352
|
+
ensureStyleSheet();
|
|
353
|
+
clearSectionAttrs(document);
|
|
354
|
+
clearNodeProps(document);
|
|
355
|
+
if (!store) return;
|
|
356
|
+
for (const [sectionId, override] of Object.entries(store.sections)) {
|
|
357
|
+
const sections = document.querySelectorAll(
|
|
358
|
+
`[data-ohw-section="${CSS.escape(sectionId)}"]`
|
|
359
|
+
);
|
|
360
|
+
for (const section of Array.from(sections)) {
|
|
361
|
+
for (const [prop, attr] of Object.entries(SECTION_ATTRS)) {
|
|
362
|
+
const value = override[prop];
|
|
363
|
+
if (value === void 0) continue;
|
|
364
|
+
if (prop === "sectionBackground" && override.sectionBackgroundColor !== void 0) continue;
|
|
365
|
+
section.setAttribute(attr, String(value).replace(":", "-"));
|
|
366
|
+
}
|
|
367
|
+
if (override.sectionBackgroundColor !== void 0) {
|
|
368
|
+
saveInline(section, "background");
|
|
369
|
+
section.style.setProperty("background", override.sectionBackgroundColor, "important");
|
|
370
|
+
section.setAttribute("data-ohw-style-bgcolor", "");
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
for (const [key, override] of Object.entries(store.nodes)) {
|
|
375
|
+
const nodes = document.querySelectorAll(`[data-ohw-key="${CSS.escape(key)}"]`);
|
|
376
|
+
for (const el of Array.from(nodes)) {
|
|
377
|
+
if (override.color !== void 0) {
|
|
378
|
+
saveInline(el, "color");
|
|
379
|
+
el.style.setProperty("color", override.color, "important");
|
|
380
|
+
el.setAttribute(NODE_WROTE_ATTR, "");
|
|
381
|
+
}
|
|
382
|
+
if (override.fontSize !== void 0) {
|
|
383
|
+
saveInline(el, "font-size");
|
|
384
|
+
el.style.setProperty("font-size", `${override.fontSize}px`, "important");
|
|
385
|
+
el.setAttribute(NODE_WROTE_ATTR, "");
|
|
386
|
+
}
|
|
387
|
+
if (override.buttonBackground !== void 0 || override.buttonText !== void 0) {
|
|
388
|
+
const surface = buttonSurfaceOf(el);
|
|
389
|
+
if (override.buttonBackground !== void 0) {
|
|
390
|
+
saveInline(surface, "background");
|
|
391
|
+
surface.style.setProperty("background", override.buttonBackground, "important");
|
|
392
|
+
}
|
|
393
|
+
if (override.buttonText !== void 0) {
|
|
394
|
+
saveInline(surface, "color");
|
|
395
|
+
surface.style.setProperty("color", override.buttonText, "important");
|
|
396
|
+
}
|
|
397
|
+
surface.setAttribute(NODE_WROTE_ATTR, "");
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
|
|
121
403
|
// src/ui/ai-tree/aiSectionsManager.tsx
|
|
122
404
|
import { flushSync } from "react-dom";
|
|
123
405
|
import { createRoot } from "react-dom/client";
|
|
@@ -132,7 +414,8 @@ function lucideByName(name) {
|
|
|
132
414
|
}
|
|
133
415
|
var typeStyle = (spec, font) => ({
|
|
134
416
|
fontFamily: font,
|
|
135
|
-
|
|
417
|
+
// Headings shrink with the viewport (reaching full size around ~900px wide); body copy stays put.
|
|
418
|
+
fontSize: spec.size >= 24 ? `clamp(${Math.max(18, Math.round(spec.size * 0.6))}px, ${(spec.size / 9).toFixed(2)}vw, ${spec.size}px)` : spec.size,
|
|
136
419
|
lineHeight: spec.line,
|
|
137
420
|
fontWeight: spec.weight
|
|
138
421
|
});
|
|
@@ -159,6 +442,8 @@ var AI_RESPONSIVE_CSS = [
|
|
|
159
442
|
" [data-ai-responsive] [data-ai-grid] { grid-template-columns: 1fr !important; }",
|
|
160
443
|
" [data-ai-responsive] [data-ai-columns] > * { grid-column: 1 / -1 !important; }",
|
|
161
444
|
" [data-ai-responsive] [data-ai-section-inner] { padding-left: 20px !important; padding-right: 20px !important; }",
|
|
445
|
+
" [data-ai-responsive] { overflow-x: hidden; }",
|
|
446
|
+
" [data-ai-responsive] img { max-width: 100%; }",
|
|
162
447
|
"}"
|
|
163
448
|
].join("\n");
|
|
164
449
|
var TRANSPARENT_PX = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7";
|
|
@@ -1166,6 +1451,20 @@ function AiTreeRenderer({ tree, brand, resolveMedia, editKeyPrefix }) {
|
|
|
1166
1451
|
const overlayAlpha = { low: 0.25, medium: 0.45, high: 0.65 }[settings.overlayIntensity ?? "medium"];
|
|
1167
1452
|
const backgroundUrl = isOverlay && settings.backgroundMedia ? ctx.resolveMedia(settings.backgroundMedia) : null;
|
|
1168
1453
|
const bgAttrs = ctx.keyFor && isOverlay && settings.backgroundMedia ? { "data-ohw-key": ctx.keyFor("settings.backgroundMedia"), "data-ohw-editable": "bg-image" } : {};
|
|
1454
|
+
const toneBackground = (() => {
|
|
1455
|
+
const { dark, primary, light } = resolvedBrand.palette;
|
|
1456
|
+
switch (settings.sectionBackground) {
|
|
1457
|
+
case "surface":
|
|
1458
|
+
return `color-mix(in srgb, ${light} 94%, ${dark})`;
|
|
1459
|
+
case "accent":
|
|
1460
|
+
return primary;
|
|
1461
|
+
case "accent-soft":
|
|
1462
|
+
return `color-mix(in srgb, ${primary} 12%, ${light})`;
|
|
1463
|
+
default:
|
|
1464
|
+
return void 0;
|
|
1465
|
+
}
|
|
1466
|
+
})();
|
|
1467
|
+
const distributed = !isOverlay && settings.textDistribution;
|
|
1169
1468
|
return /* @__PURE__ */ jsxs(
|
|
1170
1469
|
"section",
|
|
1171
1470
|
{
|
|
@@ -1175,10 +1474,11 @@ function AiTreeRenderer({ tree, brand, resolveMedia, editKeyPrefix }) {
|
|
|
1175
1474
|
style: {
|
|
1176
1475
|
position: "relative",
|
|
1177
1476
|
padding: `${pad}px 0`,
|
|
1178
|
-
background: isOverlay && !backgroundUrl ? "#DBEAFE" : void 0,
|
|
1477
|
+
background: toneBackground ?? (isOverlay && !backgroundUrl ? "#DBEAFE" : void 0),
|
|
1179
1478
|
backgroundImage: backgroundUrl ? `url(${backgroundUrl})` : void 0,
|
|
1180
1479
|
backgroundSize: "cover",
|
|
1181
|
-
backgroundPosition: "center"
|
|
1480
|
+
backgroundPosition: "center",
|
|
1481
|
+
color: settings.sectionBackground === "accent" ? resolvedBrand.palette.light : void 0
|
|
1182
1482
|
},
|
|
1183
1483
|
children: [
|
|
1184
1484
|
/* @__PURE__ */ jsx("style", { children: AI_RESPONSIVE_CSS }),
|
|
@@ -1202,10 +1502,24 @@ function AiTreeRenderer({ tree, brand, resolveMedia, editKeyPrefix }) {
|
|
|
1202
1502
|
display: "grid",
|
|
1203
1503
|
gridTemplateColumns: "repeat(12, 1fr)",
|
|
1204
1504
|
gap: AI_TREE_TOKENS.spacing6,
|
|
1205
|
-
alignItems: settings.verticalPosition === "top" ? "start" : "center",
|
|
1505
|
+
alignItems: distributed === "space-between" ? "stretch" : (distributed ?? settings.verticalPosition) === "top" ? "start" : "center",
|
|
1206
1506
|
marginTop: r2 > 0 ? AI_TREE_TOKENS.spacing8 : 0
|
|
1207
1507
|
},
|
|
1208
|
-
children: (row.blocks ?? []).map((block, b) => /* @__PURE__ */ jsx(
|
|
1508
|
+
children: (row.blocks ?? []).map((block, b) => /* @__PURE__ */ jsx(
|
|
1509
|
+
"div",
|
|
1510
|
+
{
|
|
1511
|
+
"data-ai-cell": "",
|
|
1512
|
+
style: {
|
|
1513
|
+
gridColumn: `span ${Math.min(12, Math.max(1, block.span))}`,
|
|
1514
|
+
minWidth: 0,
|
|
1515
|
+
// space-between: each column becomes a flex column whose content spreads over
|
|
1516
|
+
// the full row height instead of clumping at the top.
|
|
1517
|
+
...distributed === "space-between" ? { display: "flex", flexDirection: "column", justifyContent: "space-between" } : {}
|
|
1518
|
+
},
|
|
1519
|
+
children: renderNode(block, ctx, `r${r2}.b${b}`)
|
|
1520
|
+
},
|
|
1521
|
+
b
|
|
1522
|
+
))
|
|
1209
1523
|
},
|
|
1210
1524
|
r2
|
|
1211
1525
|
))
|
|
@@ -1221,17 +1535,34 @@ import { jsx as jsx2 } from "react/jsx-runtime";
|
|
|
1221
1535
|
var CONTAINER_ATTR = "data-ohw-ai-generated";
|
|
1222
1536
|
var REPLACED_ATTR = "data-ohw-ai-replaced-by";
|
|
1223
1537
|
var REMOVED_ATTR = "data-ohw-ai-removed";
|
|
1538
|
+
function readRootVar(name) {
|
|
1539
|
+
if (typeof document === "undefined") return "";
|
|
1540
|
+
return getComputedStyle(document.documentElement).getPropertyValue(name).trim();
|
|
1541
|
+
}
|
|
1542
|
+
function deriveBrandOverride() {
|
|
1543
|
+
const dark = readRootVar("--ohw-brand-dark");
|
|
1544
|
+
const primary = readRootVar("--ohw-brand-primary");
|
|
1545
|
+
const light = readRootVar("--ohw-brand-light");
|
|
1546
|
+
if (!dark || !primary || !light) return null;
|
|
1547
|
+
const accent = readRootVar("--ohw-brand-accent");
|
|
1548
|
+
const heading = readRootVar("--font-heading") || readRootVar("--font-display");
|
|
1549
|
+
const body = readRootVar("--font-body");
|
|
1550
|
+
return {
|
|
1551
|
+
palette: { dark, primary, accent: accent || dark, light },
|
|
1552
|
+
fonts: {
|
|
1553
|
+
heading: heading || AI_DEFAULT_BRAND.fonts.heading,
|
|
1554
|
+
body: body || AI_DEFAULT_BRAND.fonts.body
|
|
1555
|
+
}
|
|
1556
|
+
};
|
|
1557
|
+
}
|
|
1224
1558
|
function deriveTemplateBrand() {
|
|
1225
|
-
|
|
1226
|
-
const
|
|
1227
|
-
const
|
|
1228
|
-
const dark = read("--color-dark");
|
|
1229
|
-
const primary = read("--color-primary");
|
|
1230
|
-
const light = read("--color-light");
|
|
1559
|
+
const dark = readRootVar("--color-dark");
|
|
1560
|
+
const primary = readRootVar("--color-primary");
|
|
1561
|
+
const light = readRootVar("--color-light");
|
|
1231
1562
|
if (!dark || !primary || !light) return null;
|
|
1232
|
-
const accent =
|
|
1233
|
-
const heading =
|
|
1234
|
-
const body =
|
|
1563
|
+
const accent = readRootVar("--color-accent");
|
|
1564
|
+
const heading = readRootVar("--font-heading") || readRootVar("--font-display");
|
|
1565
|
+
const body = readRootVar("--font-body");
|
|
1235
1566
|
return {
|
|
1236
1567
|
palette: { dark, primary, accent: accent || dark, light },
|
|
1237
1568
|
fonts: {
|
|
@@ -1323,8 +1654,12 @@ function syncReplacedOriginals(state) {
|
|
|
1323
1654
|
}
|
|
1324
1655
|
function applyAiSectionsToDom(state, options) {
|
|
1325
1656
|
if (typeof document === "undefined") return;
|
|
1657
|
+
const brandOverride = deriveBrandOverride();
|
|
1326
1658
|
const templateBrand = deriveTemplateBrand();
|
|
1327
|
-
const
|
|
1659
|
+
const brandKey = brandOverride ? JSON.stringify(brandOverride) : "";
|
|
1660
|
+
const pagePath = window.location.pathname;
|
|
1661
|
+
const pageSections = state.sections.filter((entry) => !entry.path || entry.path === pagePath);
|
|
1662
|
+
const activeIds = new Set(pageSections.map((entry) => entry.id));
|
|
1328
1663
|
for (const [id, section] of mounted) {
|
|
1329
1664
|
if (!activeIds.has(id)) {
|
|
1330
1665
|
section.root.unmount();
|
|
@@ -1332,8 +1667,8 @@ function applyAiSectionsToDom(state, options) {
|
|
|
1332
1667
|
mounted.delete(id);
|
|
1333
1668
|
}
|
|
1334
1669
|
}
|
|
1335
|
-
for (const entry of
|
|
1336
|
-
const serialized = JSON.stringify(entry);
|
|
1670
|
+
for (const entry of pageSections) {
|
|
1671
|
+
const serialized = JSON.stringify(entry) + brandKey;
|
|
1337
1672
|
const existing = mounted.get(entry.id);
|
|
1338
1673
|
if (existing && existing.serialized === serialized && existing.container.isConnected) {
|
|
1339
1674
|
continue;
|
|
@@ -1347,6 +1682,7 @@ function applyAiSectionsToDom(state, options) {
|
|
|
1347
1682
|
mounted.delete(entry.id);
|
|
1348
1683
|
}
|
|
1349
1684
|
container.setAttribute("data-ohw-section", entry.id);
|
|
1685
|
+
container.setAttribute("data-ohw-instance", entry.id);
|
|
1350
1686
|
container.setAttribute("data-ohw-section-label", entry.label);
|
|
1351
1687
|
placeContainer(container, entry);
|
|
1352
1688
|
const root = mounted.get(entry.id)?.root ?? createRoot(container);
|
|
@@ -1357,7 +1693,7 @@ function applyAiSectionsToDom(state, options) {
|
|
|
1357
1693
|
AiTreeRenderer,
|
|
1358
1694
|
{
|
|
1359
1695
|
tree: entry.tree,
|
|
1360
|
-
brand: entry.brand ?? options?.brand ?? templateBrand ?? void 0,
|
|
1696
|
+
brand: brandOverride ?? entry.brand ?? options?.brand ?? templateBrand ?? void 0,
|
|
1361
1697
|
resolveMedia,
|
|
1362
1698
|
editKeyPrefix: `ai.${entry.id}`
|
|
1363
1699
|
}
|
|
@@ -1974,7 +2310,7 @@ function SchedulingWidget({ notifyOnConnect = false, initialScheduleId, insertAf
|
|
|
1974
2310
|
const autoId = useId();
|
|
1975
2311
|
const insertAfter = insertAfterProp ?? autoId;
|
|
1976
2312
|
const [schedule, setSchedule] = useState2(null);
|
|
1977
|
-
const [loading, setLoading] = useState2(
|
|
2313
|
+
const [loading, setLoading] = useState2(initialScheduleId !== null);
|
|
1978
2314
|
const [inEditor, setInEditor] = useState2(false);
|
|
1979
2315
|
const [isHovered, setIsHovered] = useState2(false);
|
|
1980
2316
|
const [modalState, setModalState] = useState2(null);
|
|
@@ -2148,8 +2484,10 @@ function SchedulingWidget({ notifyOnConnect = false, initialScheduleId, insertAf
|
|
|
2148
2484
|
"*"
|
|
2149
2485
|
);
|
|
2150
2486
|
};
|
|
2151
|
-
if (!inEditor && !loading && !schedule) return null;
|
|
2152
2487
|
const sectionId = `scheduling-${insertAfter}`;
|
|
2488
|
+
if (!inEditor && !loading && !schedule) {
|
|
2489
|
+
return /* @__PURE__ */ jsx4("section", { "data-ohw-section": sectionId, "data-ohw-scheduling-anchor": insertAfter, style: { display: "none" } });
|
|
2490
|
+
}
|
|
2153
2491
|
return /* @__PURE__ */ jsxs3(
|
|
2154
2492
|
"section",
|
|
2155
2493
|
{
|
|
@@ -6668,8 +7006,12 @@ function parseSectionsFromHtml(html) {
|
|
|
6668
7006
|
|
|
6669
7007
|
// src/ui/ai-section/AiSectionOverlay.tsx
|
|
6670
7008
|
import { Fragment as Fragment5, jsx as jsx16, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
6671
|
-
function
|
|
6672
|
-
const
|
|
7009
|
+
function findSectionElement(instanceId) {
|
|
7010
|
+
const escaped = CSS.escape(instanceId);
|
|
7011
|
+
return document.querySelector(`[data-ohw-instance="${escaped}"]`) ?? document.querySelector(`[data-ohw-section="${escaped}"]:not([data-ohw-instance])`);
|
|
7012
|
+
}
|
|
7013
|
+
function readRect(instanceId) {
|
|
7014
|
+
const el = findSectionElement(instanceId);
|
|
6673
7015
|
if (!el) return null;
|
|
6674
7016
|
const r2 = el.getBoundingClientRect();
|
|
6675
7017
|
if (r2.width <= 0 || r2.height <= 0) return null;
|
|
@@ -6692,7 +7034,7 @@ function useLiveSectionRect(sectionId) {
|
|
|
6692
7034
|
const opts = { capture: true, passive: true };
|
|
6693
7035
|
window.addEventListener("scroll", update, opts);
|
|
6694
7036
|
window.addEventListener("resize", update);
|
|
6695
|
-
const el =
|
|
7037
|
+
const el = findSectionElement(sectionId);
|
|
6696
7038
|
const ro = el ? new ResizeObserver(update) : null;
|
|
6697
7039
|
if (el && ro) ro.observe(el);
|
|
6698
7040
|
const interval = setInterval(update, 500);
|
|
@@ -6705,6 +7047,14 @@ function useLiveSectionRect(sectionId) {
|
|
|
6705
7047
|
}, [sectionId]);
|
|
6706
7048
|
return rect;
|
|
6707
7049
|
}
|
|
7050
|
+
function computeSectionBoundaryFlags(instanceId) {
|
|
7051
|
+
const topLevel = Array.from(document.querySelectorAll("[data-ohw-section]")).filter(
|
|
7052
|
+
(el) => !el.parentElement?.closest("[data-ohw-section]")
|
|
7053
|
+
);
|
|
7054
|
+
const index = topLevel.findIndex((el) => (el.dataset.ohwInstance ?? el.dataset.ohwSection) === instanceId);
|
|
7055
|
+
if (index === -1) return { isFirst: true, isLast: true };
|
|
7056
|
+
return { isFirst: index === 0, isLast: index === topLevel.length - 1 };
|
|
7057
|
+
}
|
|
6708
7058
|
var PRIMARY2 = "#0885FE";
|
|
6709
7059
|
function edgeAwareRadius(rect) {
|
|
6710
7060
|
const container = window.innerWidth <= 480 ? 16 : 24;
|
|
@@ -6778,6 +7128,7 @@ function AiSectionOverlay({
|
|
|
6778
7128
|
}) {
|
|
6779
7129
|
const [selectedId, setSelectedId] = useState4(null);
|
|
6780
7130
|
const [reviewId, setReviewId] = useState4(null);
|
|
7131
|
+
const [reviewButtonsHidden, setReviewButtonsHidden] = useState4(false);
|
|
6781
7132
|
const reviewIdRef = useRef4(null);
|
|
6782
7133
|
reviewIdRef.current = reviewId;
|
|
6783
7134
|
const selectedIdRef = useRef4(null);
|
|
@@ -6786,7 +7137,7 @@ function AiSectionOverlay({
|
|
|
6786
7137
|
(el) => {
|
|
6787
7138
|
postToParent2({
|
|
6788
7139
|
type: "ow:section-selected",
|
|
6789
|
-
sectionId: el
|
|
7140
|
+
sectionId: el ? el.dataset.ohwInstance ?? el.dataset.ohwSection ?? null : null,
|
|
6790
7141
|
sectionLabel: el ? el.dataset.ohwSectionLabel ?? titleCaseSectionId(el.dataset.ohwSection ?? "") : null
|
|
6791
7142
|
});
|
|
6792
7143
|
},
|
|
@@ -6795,7 +7146,7 @@ function AiSectionOverlay({
|
|
|
6795
7146
|
const selectFromElement = useCallback2(
|
|
6796
7147
|
(el, options) => {
|
|
6797
7148
|
const sectionEl = el?.closest("[data-ohw-section]") ?? null;
|
|
6798
|
-
const id = sectionEl
|
|
7149
|
+
const id = sectionEl ? sectionEl.dataset.ohwInstance ?? sectionEl.dataset.ohwSection ?? null : null;
|
|
6799
7150
|
if (id === selectedIdRef.current) return;
|
|
6800
7151
|
setSelectedId(id);
|
|
6801
7152
|
if (options?.report !== false) report(sectionEl);
|
|
@@ -6836,9 +7187,10 @@ function AiSectionOverlay({
|
|
|
6836
7187
|
}
|
|
6837
7188
|
const found = readRect(sectionId) != null;
|
|
6838
7189
|
setReviewId(found ? sectionId : null);
|
|
7190
|
+
setReviewButtonsHidden(e.data.hideButtons === true);
|
|
6839
7191
|
postToParent2({ type: "ow:ai-review-started", sectionId, found });
|
|
6840
7192
|
if (found) {
|
|
6841
|
-
document.querySelector(`[data-ohw-
|
|
7193
|
+
document.querySelector(`[data-ohw-instance="${CSS.escape(sectionId)}"]`)?.scrollIntoView({ behavior: "smooth", block: "nearest" });
|
|
6842
7194
|
}
|
|
6843
7195
|
}
|
|
6844
7196
|
};
|
|
@@ -6857,7 +7209,7 @@ function AiSectionOverlay({
|
|
|
6857
7209
|
return;
|
|
6858
7210
|
}
|
|
6859
7211
|
const sec = t.closest("[data-ohw-section]");
|
|
6860
|
-
setHoveredId(sec
|
|
7212
|
+
setHoveredId(sec ? sec.dataset.ohwInstance ?? sec.dataset.ohwSection ?? null : null);
|
|
6861
7213
|
};
|
|
6862
7214
|
const onLeave = () => setHoveredId(null);
|
|
6863
7215
|
document.addEventListener("mousemove", onMove, { passive: true });
|
|
@@ -6889,9 +7241,29 @@ function AiSectionOverlay({
|
|
|
6889
7241
|
},
|
|
6890
7242
|
[postToParent2]
|
|
6891
7243
|
);
|
|
6892
|
-
const
|
|
7244
|
+
const activeSelectionId = reviewId ? null : selectedId;
|
|
7245
|
+
const selectionRect = useLiveSectionRect(activeSelectionId);
|
|
6893
7246
|
const reviewRect = useLiveSectionRect(reviewId);
|
|
6894
7247
|
const hoverRect = useLiveSectionRect(reviewId || hoveredId === selectedId ? null : hoveredId);
|
|
7248
|
+
useEffect4(() => {
|
|
7249
|
+
if (!activeSelectionId || !selectionRect) {
|
|
7250
|
+
postToParent2({ type: "ow:section-rect", instanceId: null, rect: null });
|
|
7251
|
+
return;
|
|
7252
|
+
}
|
|
7253
|
+
const { isFirst, isLast } = computeSectionBoundaryFlags(activeSelectionId);
|
|
7254
|
+
postToParent2({
|
|
7255
|
+
type: "ow:section-rect",
|
|
7256
|
+
instanceId: activeSelectionId,
|
|
7257
|
+
rect: {
|
|
7258
|
+
top: selectionRect.top + window.scrollY,
|
|
7259
|
+
left: selectionRect.left + window.scrollX,
|
|
7260
|
+
width: selectionRect.width,
|
|
7261
|
+
height: selectionRect.height
|
|
7262
|
+
},
|
|
7263
|
+
isFirst,
|
|
7264
|
+
isLast
|
|
7265
|
+
});
|
|
7266
|
+
}, [activeSelectionId, selectionRect, postToParent2]);
|
|
6895
7267
|
return /* @__PURE__ */ jsxs8(Fragment5, { children: [
|
|
6896
7268
|
hoverRect && /* @__PURE__ */ jsx16(
|
|
6897
7269
|
"div",
|
|
@@ -6942,13 +7314,16 @@ function AiSectionOverlay({
|
|
|
6942
7314
|
border: `2px solid ${PRIMARY2}`,
|
|
6943
7315
|
borderRadius: edgeAwareRadius(reviewRect),
|
|
6944
7316
|
zIndex: 2147483200,
|
|
6945
|
-
// The veil itself: swallows clicks so the section stays locked until decided.
|
|
7317
|
+
// The veil itself: swallows clicks so the section stays locked until decided. This
|
|
7318
|
+
// stopPropagation only guards the bubble phase; the bridge's capture-phase click
|
|
7319
|
+
// handlers additionally bail on `[data-ohw-ai-review]`, without which a click on
|
|
7320
|
+
// Accept/Discard resolves to the media beneath and opens the file picker.
|
|
6946
7321
|
background: "rgba(8, 133, 254, 0.04)",
|
|
6947
7322
|
pointerEvents: "auto",
|
|
6948
7323
|
cursor: "default"
|
|
6949
7324
|
},
|
|
6950
7325
|
onClick: (e) => e.stopPropagation(),
|
|
6951
|
-
children: /* @__PURE__ */ jsxs8(
|
|
7326
|
+
children: !reviewButtonsHidden && /* @__PURE__ */ jsxs8(
|
|
6952
7327
|
"div",
|
|
6953
7328
|
{
|
|
6954
7329
|
style: {
|
|
@@ -10848,6 +11223,329 @@ function deleteFooterColumn(column) {
|
|
|
10848
11223
|
};
|
|
10849
11224
|
}
|
|
10850
11225
|
|
|
11226
|
+
// src/lib/logo-identity.ts
|
|
11227
|
+
var LOGO_TEXT_KEYS = ["nav-logo-text", "footer-logo-text", "logo-text"];
|
|
11228
|
+
var LOGO_IMAGE_KEYS = ["nav-logo-image", "footer-logo", "footer-logo-image"];
|
|
11229
|
+
var LOGO_HREF_KEYS = ["nav-logo-href", "footer-logo-href", "logo-href"];
|
|
11230
|
+
var LOGO_PLACEHOLDER_KEY = "logo-is-placeholder";
|
|
11231
|
+
var LOGO_ALT_KEY = "logo-alt";
|
|
11232
|
+
var LOGO_IMAGE_URL_KEY = "nav-logo-image";
|
|
11233
|
+
var PLACEHOLDER_BUSINESS_NAME = "Business name";
|
|
11234
|
+
function resolveLogoDisplayText(text) {
|
|
11235
|
+
const trimmed = (text ?? "").trim();
|
|
11236
|
+
return trimmed || PLACEHOLDER_BUSINESS_NAME;
|
|
11237
|
+
}
|
|
11238
|
+
function isFooterLogoRoot(root) {
|
|
11239
|
+
return Boolean(root.closest("footer") || root.closest('[data-ohw-section="footer"]'));
|
|
11240
|
+
}
|
|
11241
|
+
function imageKeyForRoot(root) {
|
|
11242
|
+
return isFooterLogoRoot(root) ? "footer-logo" : "nav-logo-image";
|
|
11243
|
+
}
|
|
11244
|
+
function textKeyForRoot(root) {
|
|
11245
|
+
return isFooterLogoRoot(root) ? "footer-logo-text" : "nav-logo-text";
|
|
11246
|
+
}
|
|
11247
|
+
function ensureLogoHrefKey(root) {
|
|
11248
|
+
if (!(root instanceof HTMLAnchorElement)) return;
|
|
11249
|
+
if (root.hasAttribute("data-ohw-href-key")) return;
|
|
11250
|
+
root.setAttribute("data-ohw-href-key", isFooterLogoRoot(root) ? "footer-logo-href" : "nav-logo-href");
|
|
11251
|
+
}
|
|
11252
|
+
function applyLogoIdentity(text, isPlaceholder) {
|
|
11253
|
+
const display = resolveLogoDisplayText(text);
|
|
11254
|
+
const placeholder = isPlaceholder || !text.trim() || display === PLACEHOLDER_BUSINESS_NAME;
|
|
11255
|
+
for (const key of LOGO_TEXT_KEYS) {
|
|
11256
|
+
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
11257
|
+
if (el.textContent !== display) el.textContent = display;
|
|
11258
|
+
});
|
|
11259
|
+
}
|
|
11260
|
+
for (const key of LOGO_IMAGE_KEYS) {
|
|
11261
|
+
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
11262
|
+
const img = el instanceof HTMLImageElement ? el : el.querySelector("img");
|
|
11263
|
+
if (img) img.alt = display;
|
|
11264
|
+
});
|
|
11265
|
+
}
|
|
11266
|
+
document.querySelectorAll('[data-ohw-role="logo"], [data-ohw-logo]').forEach((el) => {
|
|
11267
|
+
if (placeholder) el.setAttribute("data-ohw-placeholder", "");
|
|
11268
|
+
else el.removeAttribute("data-ohw-placeholder");
|
|
11269
|
+
});
|
|
11270
|
+
return display;
|
|
11271
|
+
}
|
|
11272
|
+
function applyLogoImage(url, alt) {
|
|
11273
|
+
const displayAlt = resolveLogoDisplayText(alt);
|
|
11274
|
+
document.querySelectorAll('[data-ohw-role="logo"], [data-ohw-logo]').forEach((root) => {
|
|
11275
|
+
ensureLogoHrefKey(root);
|
|
11276
|
+
const imageKey = imageKeyForRoot(root);
|
|
11277
|
+
const textKey = textKeyForRoot(root);
|
|
11278
|
+
let img = root.querySelector(`img[data-ohw-key="${imageKey}"]`) ?? (root.querySelector(`[data-ohw-key="${imageKey}"]`) instanceof HTMLImageElement ? root.querySelector(`[data-ohw-key="${imageKey}"]`) : null) ?? root.querySelector("img");
|
|
11279
|
+
let textEl = root.querySelector(`[data-ohw-key="${textKey}"]`) ?? root.querySelector('[data-ohw-key="logo-text"]');
|
|
11280
|
+
if (url) {
|
|
11281
|
+
if (!img) {
|
|
11282
|
+
img = document.createElement("img");
|
|
11283
|
+
img.setAttribute("data-ohw-editable", "image");
|
|
11284
|
+
img.setAttribute("data-ohw-key", imageKey);
|
|
11285
|
+
img.alt = displayAlt;
|
|
11286
|
+
img.style.height = "";
|
|
11287
|
+
img.style.maxHeight = "none";
|
|
11288
|
+
img.style.width = "auto";
|
|
11289
|
+
img.style.display = "block";
|
|
11290
|
+
img.style.objectFit = "contain";
|
|
11291
|
+
root.insertBefore(img, root.firstChild);
|
|
11292
|
+
} else {
|
|
11293
|
+
img.setAttribute("data-ohw-editable", "image");
|
|
11294
|
+
img.setAttribute("data-ohw-key", imageKey);
|
|
11295
|
+
}
|
|
11296
|
+
img.removeAttribute("srcset");
|
|
11297
|
+
img.removeAttribute("sizes");
|
|
11298
|
+
img.src = url;
|
|
11299
|
+
img.alt = displayAlt;
|
|
11300
|
+
img.style.display = "block";
|
|
11301
|
+
if (textEl) textEl.style.display = "none";
|
|
11302
|
+
root.removeAttribute("data-ohw-placeholder");
|
|
11303
|
+
return;
|
|
11304
|
+
}
|
|
11305
|
+
if (img) {
|
|
11306
|
+
img.removeAttribute("src");
|
|
11307
|
+
img.removeAttribute("srcset");
|
|
11308
|
+
img.removeAttribute("sizes");
|
|
11309
|
+
img.alt = displayAlt;
|
|
11310
|
+
img.style.display = "none";
|
|
11311
|
+
}
|
|
11312
|
+
if (!textEl) {
|
|
11313
|
+
textEl = document.createElement("span");
|
|
11314
|
+
textEl.setAttribute("data-ohw-editable", "plain");
|
|
11315
|
+
textEl.setAttribute("data-ohw-key", textKey);
|
|
11316
|
+
root.appendChild(textEl);
|
|
11317
|
+
}
|
|
11318
|
+
textEl.style.display = "";
|
|
11319
|
+
if (textEl.textContent !== displayAlt) textEl.textContent = displayAlt;
|
|
11320
|
+
if (!displayAlt.trim() || displayAlt === PLACEHOLDER_BUSINESS_NAME) {
|
|
11321
|
+
root.setAttribute("data-ohw-placeholder", "");
|
|
11322
|
+
} else {
|
|
11323
|
+
root.removeAttribute("data-ohw-placeholder");
|
|
11324
|
+
}
|
|
11325
|
+
});
|
|
11326
|
+
}
|
|
11327
|
+
function applyLogoHref(href) {
|
|
11328
|
+
const target = href.trim() || "/";
|
|
11329
|
+
document.querySelectorAll('[data-ohw-role="logo"], [data-ohw-logo]').forEach((root) => {
|
|
11330
|
+
ensureLogoHrefKey(root);
|
|
11331
|
+
if (root instanceof HTMLAnchorElement) {
|
|
11332
|
+
root.setAttribute("href", target);
|
|
11333
|
+
}
|
|
11334
|
+
});
|
|
11335
|
+
for (const key of LOGO_HREF_KEYS) setStoredLinkHref(key, target);
|
|
11336
|
+
}
|
|
11337
|
+
function readLogoIdentityFromDom() {
|
|
11338
|
+
let imageUrl = null;
|
|
11339
|
+
for (const key of LOGO_IMAGE_KEYS) {
|
|
11340
|
+
const el = document.querySelector(`[data-ohw-key="${key}"]`);
|
|
11341
|
+
const img = el instanceof HTMLImageElement ? el : el?.querySelector("img");
|
|
11342
|
+
const attrSrc = img?.getAttribute("src")?.trim() ?? "";
|
|
11343
|
+
if (attrSrc && !attrSrc.startsWith("data:") && img && img.style.display !== "none") {
|
|
11344
|
+
imageUrl = img.currentSrc || img.src;
|
|
11345
|
+
break;
|
|
11346
|
+
}
|
|
11347
|
+
}
|
|
11348
|
+
let text = PLACEHOLDER_BUSINESS_NAME;
|
|
11349
|
+
let isPlaceholder = true;
|
|
11350
|
+
for (const key of LOGO_TEXT_KEYS) {
|
|
11351
|
+
const el = document.querySelector(`[data-ohw-key="${key}"]`);
|
|
11352
|
+
if (el?.textContent?.trim()) {
|
|
11353
|
+
text = el.textContent.trim();
|
|
11354
|
+
const logoRoot2 = el.closest('[data-ohw-role="logo"], [data-ohw-logo]');
|
|
11355
|
+
isPlaceholder = logoRoot2?.hasAttribute("data-ohw-placeholder") === true || text === PLACEHOLDER_BUSINESS_NAME;
|
|
11356
|
+
break;
|
|
11357
|
+
}
|
|
11358
|
+
}
|
|
11359
|
+
if (imageUrl) {
|
|
11360
|
+
const logoImg = document.querySelector(
|
|
11361
|
+
'[data-ohw-key="nav-logo-image"], [data-ohw-key="footer-logo"]'
|
|
11362
|
+
);
|
|
11363
|
+
const alt = logoImg?.alt?.trim() || text;
|
|
11364
|
+
isPlaceholder = false;
|
|
11365
|
+
const hrefEl = document.querySelector(
|
|
11366
|
+
'a[data-ohw-role="logo"], a[data-ohw-logo], [data-ohw-role="logo"]'
|
|
11367
|
+
);
|
|
11368
|
+
const href2 = (hrefEl instanceof HTMLAnchorElement ? hrefEl.getAttribute("href") : null) || hrefEl?.closest("a")?.getAttribute("href") || "/";
|
|
11369
|
+
return { text, isPlaceholder, imageUrl, href: href2, alt };
|
|
11370
|
+
}
|
|
11371
|
+
const logoRoot = document.querySelector('[data-ohw-role="logo"], [data-ohw-logo]');
|
|
11372
|
+
const href = (logoRoot instanceof HTMLAnchorElement ? logoRoot.getAttribute("href") : null) || logoRoot?.closest("a")?.getAttribute("href") || "/";
|
|
11373
|
+
return { text, isPlaceholder, imageUrl: null, href, alt: text };
|
|
11374
|
+
}
|
|
11375
|
+
function applyLogoFromContent(content) {
|
|
11376
|
+
const hasLogoIdentity = LOGO_PLACEHOLDER_KEY in content || LOGO_TEXT_KEYS.some((key) => key in content) || LOGO_IMAGE_KEYS.some((key) => key in content) || LOGO_ALT_KEY in content || LOGO_HREF_KEYS.some((key) => key in content);
|
|
11377
|
+
if (!hasLogoIdentity) return false;
|
|
11378
|
+
const logoText = content[LOGO_TEXT_KEYS[0]] ?? content[LOGO_TEXT_KEYS[1]] ?? readLogoIdentityFromDom().text;
|
|
11379
|
+
const logoAlt = content[LOGO_ALT_KEY] ?? logoText;
|
|
11380
|
+
const rawLogoImage = content[LOGO_IMAGE_URL_KEY] ?? content["footer-logo"] ?? content["footer-logo-image"] ?? null;
|
|
11381
|
+
const logoImageUrl = typeof rawLogoImage === "string" && rawLogoImage.trim() ? rawLogoImage.trim() : null;
|
|
11382
|
+
const imageExplicitlyCleared = LOGO_IMAGE_KEYS.some((key) => key in content) && !logoImageUrl;
|
|
11383
|
+
const logoIsPlaceholder = LOGO_PLACEHOLDER_KEY in content ? content[LOGO_PLACEHOLDER_KEY] !== "false" : !logoImageUrl && (!logoText.trim() || logoText === PLACEHOLDER_BUSINESS_NAME);
|
|
11384
|
+
if (logoImageUrl) {
|
|
11385
|
+
applyLogoImage(logoImageUrl, logoAlt);
|
|
11386
|
+
} else {
|
|
11387
|
+
if (imageExplicitlyCleared) applyLogoImage(null, logoAlt);
|
|
11388
|
+
applyLogoIdentity(logoText, logoIsPlaceholder);
|
|
11389
|
+
}
|
|
11390
|
+
const logoHref = content["nav-logo-href"] ?? content["footer-logo-href"] ?? content["logo-href"];
|
|
11391
|
+
if (typeof logoHref === "string" && logoHref.trim()) {
|
|
11392
|
+
applyLogoHref(logoHref);
|
|
11393
|
+
}
|
|
11394
|
+
return true;
|
|
11395
|
+
}
|
|
11396
|
+
|
|
11397
|
+
// src/lib/logo-size.ts
|
|
11398
|
+
var LOGO_SIZE_DEFAULTS = {
|
|
11399
|
+
navbar: 28,
|
|
11400
|
+
footer: 32
|
|
11401
|
+
};
|
|
11402
|
+
var LOGO_SIZE_MIN = 16;
|
|
11403
|
+
var LOGO_SIZE_MAX = 80;
|
|
11404
|
+
var LOGO_SIZE_DESKTOP_KEYS = {
|
|
11405
|
+
navbar: "nav-logo-size",
|
|
11406
|
+
footer: "footer-logo-size"
|
|
11407
|
+
};
|
|
11408
|
+
var LOGO_SIZE_MOBILE_KEYS = {
|
|
11409
|
+
navbar: "nav-logo-size-mobile",
|
|
11410
|
+
footer: "footer-logo-size-mobile"
|
|
11411
|
+
};
|
|
11412
|
+
var LOGO_SIZE_KEYS = [
|
|
11413
|
+
LOGO_SIZE_DESKTOP_KEYS.navbar,
|
|
11414
|
+
LOGO_SIZE_DESKTOP_KEYS.footer,
|
|
11415
|
+
LOGO_SIZE_MOBILE_KEYS.navbar,
|
|
11416
|
+
LOGO_SIZE_MOBILE_KEYS.footer
|
|
11417
|
+
];
|
|
11418
|
+
function isFooterLogoRoot2(root) {
|
|
11419
|
+
return Boolean(root.closest("footer") || root.closest('[data-ohw-section="footer"]'));
|
|
11420
|
+
}
|
|
11421
|
+
function getLogoPlacement(root) {
|
|
11422
|
+
return isFooterLogoRoot2(root) ? "footer" : "navbar";
|
|
11423
|
+
}
|
|
11424
|
+
function parseLogoSizePx(raw, fallback) {
|
|
11425
|
+
if (raw == null || raw === "") return fallback;
|
|
11426
|
+
const n = Number.parseFloat(raw);
|
|
11427
|
+
if (!Number.isFinite(n)) return fallback;
|
|
11428
|
+
return Math.min(LOGO_SIZE_MAX, Math.max(LOGO_SIZE_MIN, Math.round(n)));
|
|
11429
|
+
}
|
|
11430
|
+
function isMobileLogoSizeFollowing(content, placement) {
|
|
11431
|
+
const raw = content[LOGO_SIZE_MOBILE_KEYS[placement]];
|
|
11432
|
+
return raw == null || raw.trim() === "";
|
|
11433
|
+
}
|
|
11434
|
+
function resolveDesktopLogoSize(content, placement) {
|
|
11435
|
+
return parseLogoSizePx(content[LOGO_SIZE_DESKTOP_KEYS[placement]], LOGO_SIZE_DEFAULTS[placement]);
|
|
11436
|
+
}
|
|
11437
|
+
function resolveMobileLogoSize(content, placement) {
|
|
11438
|
+
if (isMobileLogoSizeFollowing(content, placement)) {
|
|
11439
|
+
return resolveDesktopLogoSize(content, placement);
|
|
11440
|
+
}
|
|
11441
|
+
return parseLogoSizePx(
|
|
11442
|
+
content[LOGO_SIZE_MOBILE_KEYS[placement]],
|
|
11443
|
+
resolveDesktopLogoSize(content, placement)
|
|
11444
|
+
);
|
|
11445
|
+
}
|
|
11446
|
+
function setRootSizeVars(root, desktopPx, mobilePx, following) {
|
|
11447
|
+
root.style.setProperty("--ohw-logo-size", `${desktopPx}px`);
|
|
11448
|
+
if (following) {
|
|
11449
|
+
root.style.removeProperty("--ohw-logo-size-mobile");
|
|
11450
|
+
} else {
|
|
11451
|
+
root.style.setProperty("--ohw-logo-size-mobile", `${mobilePx}px`);
|
|
11452
|
+
}
|
|
11453
|
+
root.querySelectorAll("img").forEach((img) => {
|
|
11454
|
+
img.style.height = "";
|
|
11455
|
+
img.style.maxHeight = "none";
|
|
11456
|
+
img.style.width = "auto";
|
|
11457
|
+
img.style.objectFit = "contain";
|
|
11458
|
+
});
|
|
11459
|
+
}
|
|
11460
|
+
function applyLogoSizes(content) {
|
|
11461
|
+
document.querySelectorAll('[data-ohw-role="logo"], [data-ohw-logo]').forEach((root) => {
|
|
11462
|
+
const placement = getLogoPlacement(root);
|
|
11463
|
+
const desktop = resolveDesktopLogoSize(content, placement);
|
|
11464
|
+
const following = isMobileLogoSizeFollowing(content, placement);
|
|
11465
|
+
const mobile = following ? desktop : resolveMobileLogoSize(content, placement);
|
|
11466
|
+
setRootSizeVars(root, desktop, mobile, following);
|
|
11467
|
+
});
|
|
11468
|
+
}
|
|
11469
|
+
function applyLogoSizeToPlacement(placement, desktopPx, mobilePx, following) {
|
|
11470
|
+
document.querySelectorAll('[data-ohw-role="logo"], [data-ohw-logo]').forEach((root) => {
|
|
11471
|
+
if (getLogoPlacement(root) !== placement) return;
|
|
11472
|
+
setRootSizeVars(root, desktopPx, mobilePx, following);
|
|
11473
|
+
});
|
|
11474
|
+
}
|
|
11475
|
+
function logoHasUploadedImage(logoEl) {
|
|
11476
|
+
if (logoEl.hasAttribute("data-ohw-placeholder")) return false;
|
|
11477
|
+
const img = logoEl.querySelector('img[data-ohw-key="nav-logo-image"], img[data-ohw-key="footer-logo"], img[data-ohw-key="footer-logo-image"]') ?? logoEl.querySelector("img");
|
|
11478
|
+
if (!img) return false;
|
|
11479
|
+
const src = img.getAttribute("src")?.trim() ?? "";
|
|
11480
|
+
if (!src || src.startsWith("data:")) return false;
|
|
11481
|
+
if (img.style.display === "none") return false;
|
|
11482
|
+
return true;
|
|
11483
|
+
}
|
|
11484
|
+
function getLogoInteractionRect(logoEl) {
|
|
11485
|
+
if (logoHasUploadedImage(logoEl)) {
|
|
11486
|
+
const img = logoEl.querySelector('img[data-ohw-key="nav-logo-image"], img[data-ohw-key="footer-logo"], img[data-ohw-key="footer-logo-image"]') ?? logoEl.querySelector("img");
|
|
11487
|
+
if (img) {
|
|
11488
|
+
const r2 = img.getBoundingClientRect();
|
|
11489
|
+
if (r2.width > 0 && r2.height > 0) return r2;
|
|
11490
|
+
}
|
|
11491
|
+
}
|
|
11492
|
+
const text = logoEl.querySelector(
|
|
11493
|
+
'[data-ohw-key="nav-logo-text"], [data-ohw-key="footer-logo-text"]'
|
|
11494
|
+
);
|
|
11495
|
+
if (text) {
|
|
11496
|
+
const style = window.getComputedStyle(text);
|
|
11497
|
+
if (style.display !== "none" && style.visibility !== "hidden") {
|
|
11498
|
+
const r2 = text.getBoundingClientRect();
|
|
11499
|
+
if (r2.width > 0 && r2.height > 0) return r2;
|
|
11500
|
+
}
|
|
11501
|
+
}
|
|
11502
|
+
return logoEl.getBoundingClientRect();
|
|
11503
|
+
}
|
|
11504
|
+
function readLogoSizeState(content, placement) {
|
|
11505
|
+
const desktopPx = resolveDesktopLogoSize(content, placement);
|
|
11506
|
+
const mobileFollowing = isMobileLogoSizeFollowing(content, placement);
|
|
11507
|
+
const mobilePx = mobileFollowing ? desktopPx : resolveMobileLogoSize(content, placement);
|
|
11508
|
+
return { desktopPx, mobilePx, mobileFollowing };
|
|
11509
|
+
}
|
|
11510
|
+
|
|
11511
|
+
// src/lib/site-wide-scope.ts
|
|
11512
|
+
function getLogoElement(el) {
|
|
11513
|
+
const marked = el.closest('[data-ohw-role="logo"], [data-ohw-logo]');
|
|
11514
|
+
if (marked) return marked;
|
|
11515
|
+
if (el.closest('[data-ohw-editable="icon"]')) return null;
|
|
11516
|
+
const root = el.closest("nav, [data-ohw-nav-root], footer");
|
|
11517
|
+
if (!root) return null;
|
|
11518
|
+
const anchor = el.closest("a");
|
|
11519
|
+
if (anchor && root.contains(anchor) && !anchor.hasAttribute("data-ohw-href-key") && !anchor.closest("[data-ohw-nav-container]") && Boolean(anchor.querySelector("img") || anchor.matches("img"))) {
|
|
11520
|
+
return anchor;
|
|
11521
|
+
}
|
|
11522
|
+
const img = el.matches("img") ? el : null;
|
|
11523
|
+
if (img && !img.closest("[data-ohw-href-key]") && !img.closest("[data-ohw-nav-container]") && (img.closest("footer") || img.closest("nav, [data-ohw-nav-root]"))) {
|
|
11524
|
+
return img;
|
|
11525
|
+
}
|
|
11526
|
+
return null;
|
|
11527
|
+
}
|
|
11528
|
+
function isInFooter(el) {
|
|
11529
|
+
if (!el) return false;
|
|
11530
|
+
return Boolean(el.closest("footer") || el.closest('[data-ohw-section="footer"]'));
|
|
11531
|
+
}
|
|
11532
|
+
function isSiteWideElement(el) {
|
|
11533
|
+
if (!el) return false;
|
|
11534
|
+
if (getLogoElement(el)) return true;
|
|
11535
|
+
if (isInFooter(el)) return true;
|
|
11536
|
+
if (el.hasAttribute("data-ohw-nav-container") || el.hasAttribute("data-ohw-nav-root")) {
|
|
11537
|
+
return true;
|
|
11538
|
+
}
|
|
11539
|
+
if (el.hasAttribute("data-ohw-href-key") && el.closest("nav, [data-ohw-nav-root], [data-ohw-nav-drawer], aside")) {
|
|
11540
|
+
return true;
|
|
11541
|
+
}
|
|
11542
|
+
if (el.closest('[data-ohw-role="navbar-button"]')) return true;
|
|
11543
|
+
return false;
|
|
11544
|
+
}
|
|
11545
|
+
function isSiteWideScopeActive(args) {
|
|
11546
|
+
return isSiteWideElement(args.selected) || isSiteWideElement(args.hoveredItem) || isSiteWideElement(args.hoveredNavContainer) || isSiteWideElement(args.active);
|
|
11547
|
+
}
|
|
11548
|
+
|
|
10851
11549
|
// src/lib/add-footer-column.ts
|
|
10852
11550
|
function buildFooterColumnEditContentPatch(result) {
|
|
10853
11551
|
return {
|
|
@@ -11069,16 +11767,127 @@ function FloatingPanel({
|
|
|
11069
11767
|
);
|
|
11070
11768
|
}
|
|
11071
11769
|
|
|
11072
|
-
// src/ui/
|
|
11770
|
+
// src/ui/logo-size-panel.tsx
|
|
11771
|
+
import { ArrowUpRight, Link as Link2 } from "lucide-react";
|
|
11073
11772
|
import { jsx as jsx27, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
11773
|
+
function SizeSlider({
|
|
11774
|
+
value,
|
|
11775
|
+
onChange
|
|
11776
|
+
}) {
|
|
11777
|
+
const pct = (value - LOGO_SIZE_MIN) / (LOGO_SIZE_MAX - LOGO_SIZE_MIN) * 100;
|
|
11778
|
+
return /* @__PURE__ */ jsxs17("div", { className: "flex w-full flex-col gap-3", children: [
|
|
11779
|
+
/* @__PURE__ */ jsxs17("div", { className: "flex w-full items-center gap-2 text-sm font-medium leading-5", children: [
|
|
11780
|
+
/* @__PURE__ */ jsx27("span", { className: "min-w-0 flex-1 text-foreground", children: "Size" }),
|
|
11781
|
+
/* @__PURE__ */ jsxs17("span", { className: "shrink-0 whitespace-nowrap text-muted-foreground", children: [
|
|
11782
|
+
value,
|
|
11783
|
+
" px"
|
|
11784
|
+
] })
|
|
11785
|
+
] }),
|
|
11786
|
+
/* @__PURE__ */ jsxs17("div", { className: "relative h-2 w-full rounded-full bg-primary-50", children: [
|
|
11787
|
+
/* @__PURE__ */ jsx27(
|
|
11788
|
+
"div",
|
|
11789
|
+
{
|
|
11790
|
+
className: "absolute inset-y-0 left-0 rounded-full bg-primary",
|
|
11791
|
+
style: { width: `${pct}%` }
|
|
11792
|
+
}
|
|
11793
|
+
),
|
|
11794
|
+
/* @__PURE__ */ jsx27(
|
|
11795
|
+
"input",
|
|
11796
|
+
{
|
|
11797
|
+
type: "range",
|
|
11798
|
+
min: LOGO_SIZE_MIN,
|
|
11799
|
+
max: LOGO_SIZE_MAX,
|
|
11800
|
+
step: 1,
|
|
11801
|
+
value,
|
|
11802
|
+
"aria-label": "Logo size",
|
|
11803
|
+
className: cn(
|
|
11804
|
+
"absolute inset-0 h-full w-full cursor-pointer appearance-none bg-transparent",
|
|
11805
|
+
"[&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:size-5",
|
|
11806
|
+
"[&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:border-2",
|
|
11807
|
+
"[&::-webkit-slider-thumb]:border-primary [&::-webkit-slider-thumb]:bg-background",
|
|
11808
|
+
"[&::-moz-range-thumb]:size-5 [&::-moz-range-thumb]:rounded-full",
|
|
11809
|
+
"[&::-moz-range-thumb]:border-2 [&::-moz-range-thumb]:border-primary",
|
|
11810
|
+
"[&::-moz-range-thumb]:bg-background"
|
|
11811
|
+
),
|
|
11812
|
+
onChange: (e) => onChange(Number(e.target.value))
|
|
11813
|
+
}
|
|
11814
|
+
)
|
|
11815
|
+
] })
|
|
11816
|
+
] });
|
|
11817
|
+
}
|
|
11818
|
+
function LogoSizePanel({
|
|
11819
|
+
viewport,
|
|
11820
|
+
sizePx,
|
|
11821
|
+
mobileFollowing = true,
|
|
11822
|
+
onSizeChange,
|
|
11823
|
+
onCustomizeMobile,
|
|
11824
|
+
onResetMobile,
|
|
11825
|
+
onUpdateEverywhere,
|
|
11826
|
+
className
|
|
11827
|
+
}) {
|
|
11828
|
+
const showFollowing = viewport === "mobile" && mobileFollowing;
|
|
11829
|
+
const showMobileSlider = viewport === "mobile" && !mobileFollowing;
|
|
11830
|
+
const showDesktopSlider = viewport === "desktop";
|
|
11831
|
+
return /* @__PURE__ */ jsxs17("div", { className: cn("flex w-full flex-col gap-4", className), children: [
|
|
11832
|
+
showFollowing ? /* @__PURE__ */ jsxs17("div", { className: "flex w-full flex-col gap-2", children: [
|
|
11833
|
+
/* @__PURE__ */ jsxs17("div", { className: "flex items-start gap-1", children: [
|
|
11834
|
+
/* @__PURE__ */ jsx27(Link2, { size: 16, className: "mt-0.5 shrink-0 text-foreground", "aria-hidden": true }),
|
|
11835
|
+
/* @__PURE__ */ jsx27("p", { className: "text-sm font-semibold leading-5 text-foreground", children: "Following desktop size" })
|
|
11836
|
+
] }),
|
|
11837
|
+
/* @__PURE__ */ jsx27("p", { className: "text-sm leading-5 text-muted-foreground", children: "Mobile uses the desktop size until you customize it. Change the desktop size and it follows automatically." }),
|
|
11838
|
+
/* @__PURE__ */ jsx27(
|
|
11839
|
+
Button,
|
|
11840
|
+
{
|
|
11841
|
+
type: "button",
|
|
11842
|
+
variant: "outline",
|
|
11843
|
+
size: "sm",
|
|
11844
|
+
className: "h-9 w-full min-w-0 cursor-pointer",
|
|
11845
|
+
onClick: onCustomizeMobile,
|
|
11846
|
+
children: "Customize for mobile"
|
|
11847
|
+
}
|
|
11848
|
+
)
|
|
11849
|
+
] }) : null,
|
|
11850
|
+
showDesktopSlider || showMobileSlider ? /* @__PURE__ */ jsx27(SizeSlider, { value: sizePx, onChange: onSizeChange }) : null,
|
|
11851
|
+
showMobileSlider ? /* @__PURE__ */ jsx27(
|
|
11852
|
+
Button,
|
|
11853
|
+
{
|
|
11854
|
+
type: "button",
|
|
11855
|
+
variant: "outline",
|
|
11856
|
+
size: "sm",
|
|
11857
|
+
className: "h-9 w-full min-w-0 cursor-pointer",
|
|
11858
|
+
onClick: onResetMobile,
|
|
11859
|
+
children: "Reset to desktop size"
|
|
11860
|
+
}
|
|
11861
|
+
) : null,
|
|
11862
|
+
/* @__PURE__ */ jsx27("div", { className: "h-px w-full bg-border", role: "separator" }),
|
|
11863
|
+
/* @__PURE__ */ jsxs17(
|
|
11864
|
+
Button,
|
|
11865
|
+
{
|
|
11866
|
+
type: "button",
|
|
11867
|
+
variant: "outline",
|
|
11868
|
+
size: "sm",
|
|
11869
|
+
className: "h-9 w-full min-w-0 cursor-pointer gap-1",
|
|
11870
|
+
onClick: onUpdateEverywhere,
|
|
11871
|
+
children: [
|
|
11872
|
+
"Update logo everywhere",
|
|
11873
|
+
/* @__PURE__ */ jsx27(ArrowUpRight, { size: 16, "aria-hidden": true })
|
|
11874
|
+
]
|
|
11875
|
+
}
|
|
11876
|
+
),
|
|
11877
|
+
/* @__PURE__ */ jsx27("p", { className: "text-sm leading-5 text-muted-foreground", children: "Matches the right version to your background." })
|
|
11878
|
+
] });
|
|
11879
|
+
}
|
|
11880
|
+
|
|
11881
|
+
// src/ui/socials-display-panel.tsx
|
|
11882
|
+
import { jsx as jsx28, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
11074
11883
|
function DisplaySwitch({
|
|
11075
11884
|
label,
|
|
11076
11885
|
checked,
|
|
11077
11886
|
disabled,
|
|
11078
11887
|
onChange
|
|
11079
11888
|
}) {
|
|
11080
|
-
return /* @__PURE__ */
|
|
11081
|
-
/* @__PURE__ */
|
|
11889
|
+
return /* @__PURE__ */ jsxs18("div", { className: "flex w-full items-center gap-2", children: [
|
|
11890
|
+
/* @__PURE__ */ jsx28(
|
|
11082
11891
|
"span",
|
|
11083
11892
|
{
|
|
11084
11893
|
className: cn(
|
|
@@ -11088,7 +11897,7 @@ function DisplaySwitch({
|
|
|
11088
11897
|
children: label
|
|
11089
11898
|
}
|
|
11090
11899
|
),
|
|
11091
|
-
/* @__PURE__ */
|
|
11900
|
+
/* @__PURE__ */ jsx28(
|
|
11092
11901
|
"button",
|
|
11093
11902
|
{
|
|
11094
11903
|
type: "button",
|
|
@@ -11102,7 +11911,7 @@ function DisplaySwitch({
|
|
|
11102
11911
|
checked ? "bg-primary" : "bg-primary-50",
|
|
11103
11912
|
disabled ? "cursor-default opacity-50" : "cursor-pointer"
|
|
11104
11913
|
),
|
|
11105
|
-
children: /* @__PURE__ */
|
|
11914
|
+
children: /* @__PURE__ */ jsx28(
|
|
11106
11915
|
"span",
|
|
11107
11916
|
{
|
|
11108
11917
|
className: cn(
|
|
@@ -11116,8 +11925,8 @@ function DisplaySwitch({
|
|
|
11116
11925
|
] });
|
|
11117
11926
|
}
|
|
11118
11927
|
function SocialsDisplayPanel({ display, onChange, className }) {
|
|
11119
|
-
return /* @__PURE__ */
|
|
11120
|
-
/* @__PURE__ */
|
|
11928
|
+
return /* @__PURE__ */ jsxs18("div", { className: cn("flex w-full flex-col gap-3", className), children: [
|
|
11929
|
+
/* @__PURE__ */ jsx28(
|
|
11121
11930
|
DisplaySwitch,
|
|
11122
11931
|
{
|
|
11123
11932
|
label: "Text",
|
|
@@ -11126,7 +11935,7 @@ function SocialsDisplayPanel({ display, onChange, className }) {
|
|
|
11126
11935
|
onChange: (text) => onChange({ ...display, text })
|
|
11127
11936
|
}
|
|
11128
11937
|
),
|
|
11129
|
-
/* @__PURE__ */
|
|
11938
|
+
/* @__PURE__ */ jsx28(
|
|
11130
11939
|
DisplaySwitch,
|
|
11131
11940
|
{
|
|
11132
11941
|
label: "Icon",
|
|
@@ -11687,7 +12496,7 @@ function useNavItemDrag({
|
|
|
11687
12496
|
|
|
11688
12497
|
// src/ui/footer-container-chrome.tsx
|
|
11689
12498
|
import { Plus as Plus2 } from "lucide-react";
|
|
11690
|
-
import { jsx as
|
|
12499
|
+
import { jsx as jsx29, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
11691
12500
|
function FooterContainerChrome({
|
|
11692
12501
|
rect,
|
|
11693
12502
|
onAdd,
|
|
@@ -11695,7 +12504,7 @@ function FooterContainerChrome({
|
|
|
11695
12504
|
}) {
|
|
11696
12505
|
const chromeGap = 6;
|
|
11697
12506
|
const buttonMargin = 7;
|
|
11698
|
-
return /* @__PURE__ */
|
|
12507
|
+
return /* @__PURE__ */ jsx29(TooltipProvider, { delayDuration: 0, children: /* @__PURE__ */ jsx29(
|
|
11699
12508
|
"div",
|
|
11700
12509
|
{
|
|
11701
12510
|
"data-ohw-footer-container-chrome": "",
|
|
@@ -11707,8 +12516,8 @@ function FooterContainerChrome({
|
|
|
11707
12516
|
width: rect.width + chromeGap * 2,
|
|
11708
12517
|
height: rect.height + chromeGap * 2
|
|
11709
12518
|
},
|
|
11710
|
-
children: /* @__PURE__ */
|
|
11711
|
-
/* @__PURE__ */
|
|
12519
|
+
children: /* @__PURE__ */ jsxs19(Tooltip, { children: [
|
|
12520
|
+
/* @__PURE__ */ jsx29(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx29(
|
|
11712
12521
|
"button",
|
|
11713
12522
|
{
|
|
11714
12523
|
type: "button",
|
|
@@ -11727,10 +12536,10 @@ function FooterContainerChrome({
|
|
|
11727
12536
|
if (addDisabled) return;
|
|
11728
12537
|
onAdd();
|
|
11729
12538
|
},
|
|
11730
|
-
children: /* @__PURE__ */
|
|
12539
|
+
children: /* @__PURE__ */ jsx29(Plus2, { className: "size-4 shrink-0 text-foreground", "aria-hidden": true })
|
|
11731
12540
|
}
|
|
11732
12541
|
) }),
|
|
11733
|
-
/* @__PURE__ */
|
|
12542
|
+
/* @__PURE__ */ jsx29(TooltipContent, { side: "bottom", sideOffset: 9, children: addDisabled ? "Maximum columns reached" : "Add item" })
|
|
11734
12543
|
] })
|
|
11735
12544
|
}
|
|
11736
12545
|
) });
|
|
@@ -11913,6 +12722,18 @@ function collectEditableNodes(extraContent, root = document) {
|
|
|
11913
12722
|
}
|
|
11914
12723
|
if (extraContent && !isScoped) {
|
|
11915
12724
|
applyNavFooterDeleteOverrides(byKey, extraContent);
|
|
12725
|
+
for (const key of LOGO_IMAGE_KEYS) {
|
|
12726
|
+
if (!(key in extraContent)) continue;
|
|
12727
|
+
byKey.set(key, { key, type: "image", text: extraContent[key] ?? "" });
|
|
12728
|
+
}
|
|
12729
|
+
for (const key of [LOGO_PLACEHOLDER_KEY, LOGO_ALT_KEY]) {
|
|
12730
|
+
if (!(key in extraContent)) continue;
|
|
12731
|
+
byKey.set(key, { key, type: "meta", text: extraContent[key] ?? "" });
|
|
12732
|
+
}
|
|
12733
|
+
for (const key of LOGO_SIZE_KEYS) {
|
|
12734
|
+
if (!(key in extraContent)) continue;
|
|
12735
|
+
byKey.set(key, { key, type: "meta", text: extraContent[key] ?? "" });
|
|
12736
|
+
}
|
|
11916
12737
|
}
|
|
11917
12738
|
return Array.from(byKey.values());
|
|
11918
12739
|
}
|
|
@@ -12179,13 +13000,13 @@ function deleteSelectedNavFooterItem(deps) {
|
|
|
12179
13000
|
|
|
12180
13001
|
// src/ui/navbar-container-chrome.tsx
|
|
12181
13002
|
import { Plus as Plus3 } from "lucide-react";
|
|
12182
|
-
import { jsx as
|
|
13003
|
+
import { jsx as jsx30 } from "react/jsx-runtime";
|
|
12183
13004
|
function NavbarContainerChrome({
|
|
12184
13005
|
rect,
|
|
12185
13006
|
onAdd
|
|
12186
13007
|
}) {
|
|
12187
13008
|
const chromeGap = 6;
|
|
12188
|
-
return /* @__PURE__ */
|
|
13009
|
+
return /* @__PURE__ */ jsx30(
|
|
12189
13010
|
"div",
|
|
12190
13011
|
{
|
|
12191
13012
|
"data-ohw-navbar-container-chrome": "",
|
|
@@ -12197,7 +13018,7 @@ function NavbarContainerChrome({
|
|
|
12197
13018
|
width: rect.width + chromeGap * 2,
|
|
12198
13019
|
height: rect.height + chromeGap * 2
|
|
12199
13020
|
},
|
|
12200
|
-
children: /* @__PURE__ */
|
|
13021
|
+
children: /* @__PURE__ */ jsx30(
|
|
12201
13022
|
"button",
|
|
12202
13023
|
{
|
|
12203
13024
|
type: "button",
|
|
@@ -12214,7 +13035,7 @@ function NavbarContainerChrome({
|
|
|
12214
13035
|
e.stopPropagation();
|
|
12215
13036
|
onAdd();
|
|
12216
13037
|
},
|
|
12217
|
-
children: /* @__PURE__ */
|
|
13038
|
+
children: /* @__PURE__ */ jsx30(Plus3, { className: "size-4 shrink-0 text-foreground", "aria-hidden": true })
|
|
12218
13039
|
}
|
|
12219
13040
|
)
|
|
12220
13041
|
}
|
|
@@ -12223,7 +13044,7 @@ function NavbarContainerChrome({
|
|
|
12223
13044
|
|
|
12224
13045
|
// src/ui/drop-indicator.tsx
|
|
12225
13046
|
import * as React10 from "react";
|
|
12226
|
-
import { jsx as
|
|
13047
|
+
import { jsx as jsx31 } from "react/jsx-runtime";
|
|
12227
13048
|
var dropIndicatorVariants = cva(
|
|
12228
13049
|
"ov-gap-line pointer-events-none shrink-0 transition-opacity duration-150",
|
|
12229
13050
|
{
|
|
@@ -12247,7 +13068,7 @@ var dropIndicatorVariants = cva(
|
|
|
12247
13068
|
);
|
|
12248
13069
|
var DropIndicator = React10.forwardRef(
|
|
12249
13070
|
({ className, direction, state, ...props }, ref) => {
|
|
12250
|
-
return /* @__PURE__ */
|
|
13071
|
+
return /* @__PURE__ */ jsx31(
|
|
12251
13072
|
"div",
|
|
12252
13073
|
{
|
|
12253
13074
|
ref,
|
|
@@ -12264,7 +13085,7 @@ var DropIndicator = React10.forwardRef(
|
|
|
12264
13085
|
DropIndicator.displayName = "DropIndicator";
|
|
12265
13086
|
|
|
12266
13087
|
// src/ui/badge.tsx
|
|
12267
|
-
import { jsx as
|
|
13088
|
+
import { jsx as jsx32 } from "react/jsx-runtime";
|
|
12268
13089
|
var badgeVariants = cva(
|
|
12269
13090
|
"inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
|
|
12270
13091
|
{
|
|
@@ -12282,12 +13103,12 @@ var badgeVariants = cva(
|
|
|
12282
13103
|
}
|
|
12283
13104
|
);
|
|
12284
13105
|
function Badge({ className, variant, ...props }) {
|
|
12285
|
-
return /* @__PURE__ */
|
|
13106
|
+
return /* @__PURE__ */ jsx32("div", { className: cn(badgeVariants({ variant }), className), ...props });
|
|
12286
13107
|
}
|
|
12287
13108
|
|
|
12288
13109
|
// src/OhhwellsBridge.tsx
|
|
12289
|
-
import { Link as
|
|
12290
|
-
import { Fragment as Fragment8, jsx as
|
|
13110
|
+
import { Link as Link3 } from "lucide-react";
|
|
13111
|
+
import { Fragment as Fragment8, jsx as jsx33, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
12291
13112
|
var PRIMARY3 = "#0885FE";
|
|
12292
13113
|
var IMAGE_FADE_MS = 300;
|
|
12293
13114
|
function runOpacityFade(el, onDone) {
|
|
@@ -12381,21 +13202,10 @@ function parseSchedulingInsertAfter(insertAfter) {
|
|
|
12381
13202
|
insertBefore: insertAfter.slice(idx + INSERT_BEFORE_MARKER.length)
|
|
12382
13203
|
};
|
|
12383
13204
|
}
|
|
12384
|
-
function
|
|
12385
|
-
|
|
12386
|
-
const
|
|
12387
|
-
|
|
12388
|
-
return { effectiveInsertAfter, insertBefore };
|
|
12389
|
-
}
|
|
12390
|
-
function getSchedulingMountPoint(insertAfter) {
|
|
12391
|
-
const { anchor } = parseSchedulingInsertAfter(insertAfter);
|
|
12392
|
-
let anchorEl = document.querySelector(`[data-ohw-section="${anchor}"]`);
|
|
12393
|
-
if (!anchorEl && anchor === "scheduling") {
|
|
12394
|
-
const widgets = Array.from(document.querySelectorAll('[data-ohw-section^="scheduling-"]'));
|
|
12395
|
-
anchorEl = widgets.at(-1) ?? null;
|
|
12396
|
-
}
|
|
12397
|
-
if (!anchorEl) return null;
|
|
12398
|
-
return anchorEl.closest('[data-ohw-section-container="scheduling"]') ?? anchorEl;
|
|
13205
|
+
function resolveEntryAnchor(entry) {
|
|
13206
|
+
if (entry.anchorId !== void 0) return { anchorId: entry.anchorId, beforeId: entry.beforeId ?? null };
|
|
13207
|
+
const parsed = parseSchedulingInsertAfter(entry.insertAfter);
|
|
13208
|
+
return { anchorId: parsed.anchor, beforeId: parsed.insertBefore };
|
|
12399
13209
|
}
|
|
12400
13210
|
function schedulingMountDepth(insertAfter) {
|
|
12401
13211
|
if (!insertAfter.includes(INSERT_BEFORE_MARKER)) return 0;
|
|
@@ -12412,8 +13222,7 @@ function getPageSchedulingEntries(raw) {
|
|
|
12412
13222
|
}
|
|
12413
13223
|
}
|
|
12414
13224
|
function isSchedulingWidgetMissing(entry) {
|
|
12415
|
-
|
|
12416
|
-
return !document.querySelector(`[data-ohw-section="${schedulingSectionId(effectiveInsertAfter)}"]`);
|
|
13225
|
+
return !document.querySelector(`[data-ohw-section="${schedulingSectionId(entry.insertAfter)}"]`);
|
|
12417
13226
|
}
|
|
12418
13227
|
function hasMissingSchedulingWidgets(entries) {
|
|
12419
13228
|
return entries.some(isSchedulingWidgetMissing);
|
|
@@ -12443,16 +13252,17 @@ function initSectionsFromContent(content, removeExisting = false) {
|
|
|
12443
13252
|
} catch {
|
|
12444
13253
|
}
|
|
12445
13254
|
}
|
|
12446
|
-
function mountSchedulingWidget(
|
|
12447
|
-
const
|
|
12448
|
-
const sectionId = schedulingSectionId(
|
|
13255
|
+
function mountSchedulingWidget(anchorId, notifyOnConnect = false, scheduleId, beforeId, existingWidgetId) {
|
|
13256
|
+
const widgetId = existingWidgetId ?? (beforeId ? `${anchorId}${INSERT_BEFORE_MARKER}${beforeId}` : anchorId);
|
|
13257
|
+
const sectionId = schedulingSectionId(widgetId);
|
|
12449
13258
|
if (document.querySelector(`[data-ohw-section="${sectionId}"]`)) return false;
|
|
12450
|
-
const
|
|
12451
|
-
if (!
|
|
13259
|
+
const anchorEl = document.querySelector(`[data-ohw-section="${anchorId}"]`);
|
|
13260
|
+
if (!anchorEl) return false;
|
|
13261
|
+
const mountPoint = anchorEl.closest('[data-ohw-section-container="scheduling"]') ?? anchorEl;
|
|
12452
13262
|
const container = document.createElement("div");
|
|
12453
13263
|
container.dataset.ohwSectionContainer = "scheduling";
|
|
12454
|
-
if (
|
|
12455
|
-
const beforeAnchor = document.querySelector(`[data-ohw-section="${
|
|
13264
|
+
if (beforeId) {
|
|
13265
|
+
const beforeAnchor = document.querySelector(`[data-ohw-section="${beforeId}"]`);
|
|
12456
13266
|
const beforePoint = beforeAnchor?.closest('[data-ohw-section-container="scheduling"]') ?? beforeAnchor;
|
|
12457
13267
|
if (!beforePoint) return false;
|
|
12458
13268
|
beforePoint.insertAdjacentElement("beforebegin", container);
|
|
@@ -12463,19 +13273,25 @@ function mountSchedulingWidget(insertAfter, notifyOnConnect = false, scheduleId,
|
|
|
12463
13273
|
}
|
|
12464
13274
|
tail.insertAdjacentElement("afterend", container);
|
|
12465
13275
|
}
|
|
12466
|
-
|
|
12467
|
-
|
|
12468
|
-
|
|
12469
|
-
|
|
12470
|
-
|
|
12471
|
-
|
|
12472
|
-
|
|
12473
|
-
|
|
12474
|
-
|
|
12475
|
-
|
|
12476
|
-
|
|
12477
|
-
|
|
12478
|
-
|
|
13276
|
+
try {
|
|
13277
|
+
const root = createRoot2(container);
|
|
13278
|
+
flushSync2(() => {
|
|
13279
|
+
root.render(
|
|
13280
|
+
/* @__PURE__ */ jsx33(
|
|
13281
|
+
SchedulingWidget,
|
|
13282
|
+
{
|
|
13283
|
+
notifyOnConnect,
|
|
13284
|
+
initialScheduleId: scheduleId,
|
|
13285
|
+
insertAfter: widgetId
|
|
13286
|
+
}
|
|
13287
|
+
)
|
|
13288
|
+
);
|
|
13289
|
+
});
|
|
13290
|
+
} catch (err) {
|
|
13291
|
+
console.error("[ow:scheduling] render threw", err);
|
|
13292
|
+
container.remove();
|
|
13293
|
+
return false;
|
|
13294
|
+
}
|
|
12479
13295
|
const tracker = getSectionsTracker();
|
|
12480
13296
|
let sections = [];
|
|
12481
13297
|
try {
|
|
@@ -12483,10 +13299,12 @@ function mountSchedulingWidget(insertAfter, notifyOnConnect = false, scheduleId,
|
|
|
12483
13299
|
} catch {
|
|
12484
13300
|
}
|
|
12485
13301
|
const inEditor = typeof window !== "undefined" && window.self !== window.top;
|
|
12486
|
-
if (inEditor && !sections.find((s) => s.type === "scheduling" && s.insertAfter ===
|
|
13302
|
+
if (inEditor && !sections.find((s) => s.type === "scheduling" && s.insertAfter === widgetId)) {
|
|
12487
13303
|
sections.push({
|
|
12488
13304
|
type: "scheduling",
|
|
12489
|
-
insertAfter:
|
|
13305
|
+
insertAfter: widgetId,
|
|
13306
|
+
anchorId,
|
|
13307
|
+
beforeId: beforeId ?? null,
|
|
12490
13308
|
pagePath: window.location.pathname,
|
|
12491
13309
|
...scheduleId ? { scheduleId } : {}
|
|
12492
13310
|
});
|
|
@@ -12500,7 +13318,8 @@ function mountSchedulingEntries(entries, notifyOnConnect = false) {
|
|
|
12500
13318
|
for (let i = pending.length - 1; i >= 0; i--) {
|
|
12501
13319
|
const entry = pending[i];
|
|
12502
13320
|
const shouldNotify = typeof notifyOnConnect === "function" ? notifyOnConnect(entry) : notifyOnConnect;
|
|
12503
|
-
|
|
13321
|
+
const { anchorId, beforeId } = resolveEntryAnchor(entry);
|
|
13322
|
+
if (mountSchedulingWidget(anchorId, shouldNotify, entry.scheduleId ?? null, beforeId, entry.insertAfter)) {
|
|
12504
13323
|
pending.splice(i, 1);
|
|
12505
13324
|
}
|
|
12506
13325
|
}
|
|
@@ -12644,6 +13463,13 @@ function isInsideLinkEditor(target) {
|
|
|
12644
13463
|
target.closest("[data-ohw-link-popover-root]") || target.closest("[data-ohw-link-modal-root]") || target.closest("[data-ohw-link-page-dropdown]") || target.closest("[data-ohw-section-picker]") || target.closest("[data-ohw-navbar-container-chrome]") || target.closest("[data-ohw-navbar-add-button]") || target.closest("[data-ohw-footer-container-chrome]") || target.closest("[data-ohw-footer-add-button]") || target.closest("[data-ohw-more-menu]") || target.closest('[data-slot="dropdown-menu-content"]') || target.closest('[data-slot="popover-content"]') || target.closest('[data-slot="dialog-content"]') || target.closest('[data-slot="dialog-overlay"]')
|
|
12645
13464
|
);
|
|
12646
13465
|
}
|
|
13466
|
+
function isInsideFloatingPanel(target) {
|
|
13467
|
+
return Boolean(target.closest("[data-ohw-floating-panel]"));
|
|
13468
|
+
}
|
|
13469
|
+
function isPointOverFloatingPanel(clientX, clientY) {
|
|
13470
|
+
const el = document.elementFromPoint(clientX, clientY);
|
|
13471
|
+
return Boolean(el instanceof Element && el.closest("[data-ohw-floating-panel]"));
|
|
13472
|
+
}
|
|
12647
13473
|
function getHrefKeyFromElement(el) {
|
|
12648
13474
|
if (!el) return null;
|
|
12649
13475
|
const anchor = el.closest("[data-ohw-href-key]");
|
|
@@ -12881,7 +13707,7 @@ function getNavigationSelectionParent(el) {
|
|
|
12881
13707
|
if (!isFooterLinksContainer(el) && (el.hasAttribute("data-ohw-footer-col") || el.hasAttribute("data-ohw-footer-column") || isInferredFooterGroup2(el))) {
|
|
12882
13708
|
return getFooterLinksContainer();
|
|
12883
13709
|
}
|
|
12884
|
-
if (el.hasAttribute("data-ohw-nav-container") || el.hasAttribute("data-ohw-nav-drawer") || isFooterLinksContainer(el)) {
|
|
13710
|
+
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)) {
|
|
12885
13711
|
return getNavigationRoot(el);
|
|
12886
13712
|
}
|
|
12887
13713
|
return null;
|
|
@@ -13127,7 +13953,7 @@ function EditGlowChrome({
|
|
|
13127
13953
|
hideHandle = false
|
|
13128
13954
|
}) {
|
|
13129
13955
|
const GAP = SELECTION_CHROME_GAP2;
|
|
13130
|
-
return /* @__PURE__ */
|
|
13956
|
+
return /* @__PURE__ */ jsxs20(
|
|
13131
13957
|
"div",
|
|
13132
13958
|
{
|
|
13133
13959
|
ref: elRef,
|
|
@@ -13142,7 +13968,7 @@ function EditGlowChrome({
|
|
|
13142
13968
|
zIndex: 2147483646
|
|
13143
13969
|
},
|
|
13144
13970
|
children: [
|
|
13145
|
-
/* @__PURE__ */
|
|
13971
|
+
/* @__PURE__ */ jsx33(
|
|
13146
13972
|
"div",
|
|
13147
13973
|
{
|
|
13148
13974
|
style: {
|
|
@@ -13155,7 +13981,7 @@ function EditGlowChrome({
|
|
|
13155
13981
|
}
|
|
13156
13982
|
}
|
|
13157
13983
|
),
|
|
13158
|
-
reorderHrefKey && !hideHandle && /* @__PURE__ */
|
|
13984
|
+
reorderHrefKey && !hideHandle && /* @__PURE__ */ jsx33(
|
|
13159
13985
|
"div",
|
|
13160
13986
|
{
|
|
13161
13987
|
"data-ohw-drag-handle-container": "",
|
|
@@ -13167,7 +13993,7 @@ function EditGlowChrome({
|
|
|
13167
13993
|
transform: "translate(calc(-100% - 7px), -50%)",
|
|
13168
13994
|
pointerEvents: dragDisabled ? "none" : "auto"
|
|
13169
13995
|
},
|
|
13170
|
-
children: /* @__PURE__ */
|
|
13996
|
+
children: /* @__PURE__ */ jsx33(
|
|
13171
13997
|
DragHandle,
|
|
13172
13998
|
{
|
|
13173
13999
|
"aria-label": `Reorder ${reorderHrefKey}`,
|
|
@@ -13377,7 +14203,7 @@ function FloatingToolbar({
|
|
|
13377
14203
|
return () => ro.disconnect();
|
|
13378
14204
|
}, [showEditLink, activeCommands]);
|
|
13379
14205
|
const { top, left, transform } = calcToolbarPos(rect, parentScroll, measuredW);
|
|
13380
|
-
return /* @__PURE__ */
|
|
14206
|
+
return /* @__PURE__ */ jsx33(
|
|
13381
14207
|
"div",
|
|
13382
14208
|
{
|
|
13383
14209
|
ref: setRefs,
|
|
@@ -13389,12 +14215,12 @@ function FloatingToolbar({
|
|
|
13389
14215
|
zIndex: 2147483647,
|
|
13390
14216
|
pointerEvents: "auto"
|
|
13391
14217
|
},
|
|
13392
|
-
children: /* @__PURE__ */
|
|
13393
|
-
TOOLBAR_GROUPS.map((btns, gi) => /* @__PURE__ */
|
|
13394
|
-
gi > 0 && /* @__PURE__ */
|
|
14218
|
+
children: /* @__PURE__ */ jsxs20(CustomToolbar, { children: [
|
|
14219
|
+
TOOLBAR_GROUPS.map((btns, gi) => /* @__PURE__ */ jsxs20(React11.Fragment, { children: [
|
|
14220
|
+
gi > 0 && /* @__PURE__ */ jsx33(CustomToolbarDivider, {}),
|
|
13395
14221
|
btns.map((btn) => {
|
|
13396
14222
|
const isActive = activeCommands.has(btn.cmd);
|
|
13397
|
-
return /* @__PURE__ */
|
|
14223
|
+
return /* @__PURE__ */ jsx33(
|
|
13398
14224
|
CustomToolbarButton,
|
|
13399
14225
|
{
|
|
13400
14226
|
title: btn.title,
|
|
@@ -13403,7 +14229,7 @@ function FloatingToolbar({
|
|
|
13403
14229
|
e.preventDefault();
|
|
13404
14230
|
onCommand(btn.cmd);
|
|
13405
14231
|
},
|
|
13406
|
-
children: /* @__PURE__ */
|
|
14232
|
+
children: /* @__PURE__ */ jsx33(
|
|
13407
14233
|
"svg",
|
|
13408
14234
|
{
|
|
13409
14235
|
width: "16",
|
|
@@ -13424,7 +14250,7 @@ function FloatingToolbar({
|
|
|
13424
14250
|
);
|
|
13425
14251
|
})
|
|
13426
14252
|
] }, gi)),
|
|
13427
|
-
showEditLink ? /* @__PURE__ */
|
|
14253
|
+
showEditLink ? /* @__PURE__ */ jsx33(
|
|
13428
14254
|
CustomToolbarButton,
|
|
13429
14255
|
{
|
|
13430
14256
|
type: "button",
|
|
@@ -13438,7 +14264,7 @@ function FloatingToolbar({
|
|
|
13438
14264
|
e.preventDefault();
|
|
13439
14265
|
e.stopPropagation();
|
|
13440
14266
|
},
|
|
13441
|
-
children: /* @__PURE__ */
|
|
14267
|
+
children: /* @__PURE__ */ jsx33(Link3, { className: "size-4 shrink-0", "aria-hidden": true })
|
|
13442
14268
|
}
|
|
13443
14269
|
) : null
|
|
13444
14270
|
] })
|
|
@@ -13455,7 +14281,7 @@ function StateToggle({
|
|
|
13455
14281
|
states,
|
|
13456
14282
|
onStateChange
|
|
13457
14283
|
}) {
|
|
13458
|
-
return /* @__PURE__ */
|
|
14284
|
+
return /* @__PURE__ */ jsx33(
|
|
13459
14285
|
ToggleGroup,
|
|
13460
14286
|
{
|
|
13461
14287
|
"data-ohw-state-toggle": "",
|
|
@@ -13469,11 +14295,12 @@ function StateToggle({
|
|
|
13469
14295
|
left: rect.right - 8,
|
|
13470
14296
|
transform: "translateX(-100%)"
|
|
13471
14297
|
},
|
|
13472
|
-
children: states.map((state) => /* @__PURE__ */
|
|
14298
|
+
children: states.map((state) => /* @__PURE__ */ jsx33(ToggleGroupItem, { value: state, size: "sm", children: state }, state))
|
|
13473
14299
|
}
|
|
13474
14300
|
);
|
|
13475
14301
|
}
|
|
13476
14302
|
var contentCache = /* @__PURE__ */ new Map();
|
|
14303
|
+
var fetchedContentPaths = /* @__PURE__ */ new Set();
|
|
13477
14304
|
function resolveSubdomain(subdomainFromQuery) {
|
|
13478
14305
|
if (subdomainFromQuery) return subdomainFromQuery;
|
|
13479
14306
|
if (typeof window !== "undefined") {
|
|
@@ -13568,8 +14395,14 @@ function OhhwellsBridge() {
|
|
|
13568
14395
|
});
|
|
13569
14396
|
const selectFrameRef = useRef9(() => {
|
|
13570
14397
|
});
|
|
14398
|
+
const selectLogoRef = useRef9(() => {
|
|
14399
|
+
});
|
|
14400
|
+
const openLogoSizePanelRef = useRef9(() => {
|
|
14401
|
+
});
|
|
13571
14402
|
const deselectRef = useRef9(() => {
|
|
13572
14403
|
});
|
|
14404
|
+
const closeFloatingPanelOnlyRef = useRef9(() => {
|
|
14405
|
+
});
|
|
13573
14406
|
const reselectNavigationItemRef = useRef9(() => {
|
|
13574
14407
|
});
|
|
13575
14408
|
const commitNavigationTextEditRef = useRef9(() => {
|
|
@@ -13630,11 +14463,6 @@ function OhhwellsBridge() {
|
|
|
13630
14463
|
const [isItemDragging, setIsItemDragging] = useState11(false);
|
|
13631
14464
|
const [isFooterFrameSelection, setIsFooterFrameSelection] = useState11(false);
|
|
13632
14465
|
isFooterFrameSelectionRef.current = isFooterFrameSelection;
|
|
13633
|
-
const [floatingPanel, setFloatingPanel] = useState11(null);
|
|
13634
|
-
const floatingPanelOpenRef = useRef9(false);
|
|
13635
|
-
floatingPanelOpenRef.current = floatingPanel !== null;
|
|
13636
|
-
const [floatingPanelPos, setFloatingPanelPos] = useState11(null);
|
|
13637
|
-
const [parentScrollSnap, setParentScrollSnap] = useState11(null);
|
|
13638
14466
|
const [navDropdownPreviewOpen, setNavDropdownPreviewOpen] = useState11(null);
|
|
13639
14467
|
const [footerHeadingVisible, setFooterHeadingVisible] = useState11(null);
|
|
13640
14468
|
const footerDragRef = useRef9(null);
|
|
@@ -13649,7 +14477,16 @@ function OhhwellsBridge() {
|
|
|
13649
14477
|
const addNavAfterAnchorRef = useRef9(null);
|
|
13650
14478
|
const editContentRef = useRef9({});
|
|
13651
14479
|
const aiSectionsRef = useRef9("");
|
|
14480
|
+
const brandKitRef = useRef9("");
|
|
14481
|
+
const stylesRef = useRef9("");
|
|
13652
14482
|
const pendingDeleteUndoRef = useRef9(null);
|
|
14483
|
+
const [floatingPanel, setFloatingPanel] = useState11(null);
|
|
14484
|
+
const floatingPanelOpenRef = useRef9(false);
|
|
14485
|
+
const setFloatingPanelRef = useRef9(setFloatingPanel);
|
|
14486
|
+
const [floatingPanelPos, setFloatingPanelPos] = useState11(null);
|
|
14487
|
+
const [logoSizeDraft, setLogoSizeDraft] = useState11(null);
|
|
14488
|
+
const [editorViewport, setEditorViewport] = useState11("desktop");
|
|
14489
|
+
const [parentScrollSnap, setParentScrollSnap] = useState11(null);
|
|
13653
14490
|
const [sitePages, setSitePages] = useState11([]);
|
|
13654
14491
|
const [sectionsByPath, setSectionsByPath] = useState11({});
|
|
13655
14492
|
const sectionsPrefetchGenRef = useRef9(0);
|
|
@@ -13658,7 +14495,18 @@ function OhhwellsBridge() {
|
|
|
13658
14495
|
const linkPopoverOpenRef = useRef9(false);
|
|
13659
14496
|
const linkPopoverGraceUntilRef = useRef9(0);
|
|
13660
14497
|
setLinkPopoverRef.current = setLinkPopover;
|
|
14498
|
+
setFloatingPanelRef.current = setFloatingPanel;
|
|
13661
14499
|
linkPopoverSessionRef.current = linkPopover;
|
|
14500
|
+
floatingPanelOpenRef.current = Boolean(floatingPanel);
|
|
14501
|
+
useEffect12(() => {
|
|
14502
|
+
const syncViewport = () => {
|
|
14503
|
+
const next = window.innerWidth <= 480 ? "mobile" : "desktop";
|
|
14504
|
+
setEditorViewport((prev) => prev === next ? prev : next);
|
|
14505
|
+
};
|
|
14506
|
+
syncViewport();
|
|
14507
|
+
window.addEventListener("resize", syncViewport);
|
|
14508
|
+
return () => window.removeEventListener("resize", syncViewport);
|
|
14509
|
+
}, []);
|
|
13662
14510
|
const {
|
|
13663
14511
|
navDragRef,
|
|
13664
14512
|
navDropSlots,
|
|
@@ -13881,6 +14729,10 @@ function OhhwellsBridge() {
|
|
|
13881
14729
|
setIsItemDragging(false);
|
|
13882
14730
|
hoveredNavContainerRef.current = null;
|
|
13883
14731
|
setHoveredNavContainerRect(null);
|
|
14732
|
+
hoveredItemElRef.current = null;
|
|
14733
|
+
setHoveredItemRect(null);
|
|
14734
|
+
setFloatingPanel(null);
|
|
14735
|
+
setLogoSizeDraft(null);
|
|
13884
14736
|
if (!activeElRef.current) {
|
|
13885
14737
|
setNavGroupForceOpen(null, false);
|
|
13886
14738
|
setToolbarRect(null);
|
|
@@ -14586,6 +15438,8 @@ function OhhwellsBridge() {
|
|
|
14586
15438
|
setToolbarRect(anchor.getBoundingClientRect());
|
|
14587
15439
|
setToolbarShowEditLink(false);
|
|
14588
15440
|
setActiveCommands(/* @__PURE__ */ new Set());
|
|
15441
|
+
setFloatingPanel(null);
|
|
15442
|
+
setLogoSizeDraft(null);
|
|
14589
15443
|
}, [deactivate, markSelected]);
|
|
14590
15444
|
const selectFrame = useCallback7((el) => {
|
|
14591
15445
|
if (!isNavigationContainer(el)) return;
|
|
@@ -14635,7 +15489,51 @@ function OhhwellsBridge() {
|
|
|
14635
15489
|
setToolbarRect(el.getBoundingClientRect());
|
|
14636
15490
|
setToolbarShowEditLink(false);
|
|
14637
15491
|
setActiveCommands(/* @__PURE__ */ new Set());
|
|
15492
|
+
setFloatingPanel(null);
|
|
15493
|
+
setLogoSizeDraft(null);
|
|
14638
15494
|
}, [deactivate, markSelected, postToParent2]);
|
|
15495
|
+
const selectLogo = useCallback7(
|
|
15496
|
+
(logoEl) => {
|
|
15497
|
+
if (activeElRef.current) deactivate();
|
|
15498
|
+
selectedElRef.current = logoEl;
|
|
15499
|
+
selectedHrefKeyRef.current = null;
|
|
15500
|
+
selectedFooterColAttrRef.current = null;
|
|
15501
|
+
markSelected(logoEl);
|
|
15502
|
+
setSelectedIsCta(false);
|
|
15503
|
+
setSelectedIsSocial(false);
|
|
15504
|
+
setSelectedIsSocialsRow(false);
|
|
15505
|
+
clearHrefKeyHover(logoEl);
|
|
15506
|
+
hoveredNavContainerRef.current = null;
|
|
15507
|
+
setHoveredNavContainerRect(null);
|
|
15508
|
+
setHoveredItemRect(null);
|
|
15509
|
+
hoveredItemElRef.current = null;
|
|
15510
|
+
siblingHintElRef.current = null;
|
|
15511
|
+
setSiblingHintRect(null);
|
|
15512
|
+
setSiblingHintRects([]);
|
|
15513
|
+
setIsItemDragging(false);
|
|
15514
|
+
setReorderHrefKey(null);
|
|
15515
|
+
setReorderDragDisabled(false);
|
|
15516
|
+
setIsFooterFrameSelection(false);
|
|
15517
|
+
setToolbarVariant("logo");
|
|
15518
|
+
setToolbarRect(getLogoInteractionRect(logoEl));
|
|
15519
|
+
setToolbarShowEditLink(false);
|
|
15520
|
+
setActiveCommands(/* @__PURE__ */ new Set());
|
|
15521
|
+
},
|
|
15522
|
+
[deactivate, markSelected]
|
|
15523
|
+
);
|
|
15524
|
+
const openLogoSizePanel = useCallback7((logoEl) => {
|
|
15525
|
+
const placement = getLogoPlacement(logoEl);
|
|
15526
|
+
const draft = readLogoSizeState(editContentRef.current, placement);
|
|
15527
|
+
setLogoSizeDraft(draft);
|
|
15528
|
+
setParentScrollSnap(parentScrollRef.current);
|
|
15529
|
+
setFloatingPanel({
|
|
15530
|
+
key: `logo-size:${placement}`,
|
|
15531
|
+
title: "Logo",
|
|
15532
|
+
context: placement === "navbar" ? "Navbar" : "Footer",
|
|
15533
|
+
kind: "logo-size",
|
|
15534
|
+
placement
|
|
15535
|
+
});
|
|
15536
|
+
}, []);
|
|
14639
15537
|
const openSocialsDisplayPanel = useCallback7((row) => {
|
|
14640
15538
|
setParentScrollSnap(parentScrollRef.current);
|
|
14641
15539
|
setFloatingPanel({
|
|
@@ -14671,13 +15569,53 @@ function OhhwellsBridge() {
|
|
|
14671
15569
|
);
|
|
14672
15570
|
const closeFloatingPanelOnly = useCallback7(() => {
|
|
14673
15571
|
setFloatingPanel(null);
|
|
15572
|
+
setLogoSizeDraft(null);
|
|
14674
15573
|
}, []);
|
|
14675
|
-
const closeFloatingPanelOnlyRef = useRef9(closeFloatingPanelOnly);
|
|
14676
|
-
closeFloatingPanelOnlyRef.current = closeFloatingPanelOnly;
|
|
14677
15574
|
const closeFloatingPanelAndDeselect = useCallback7(() => {
|
|
14678
15575
|
setFloatingPanel(null);
|
|
15576
|
+
setLogoSizeDraft(null);
|
|
14679
15577
|
deselectRef.current();
|
|
14680
15578
|
}, []);
|
|
15579
|
+
const persistLogoSizeDraft = useCallback7(
|
|
15580
|
+
(placement, draft) => {
|
|
15581
|
+
const desktopKey = LOGO_SIZE_DESKTOP_KEYS[placement];
|
|
15582
|
+
const mobileKey = LOGO_SIZE_MOBILE_KEYS[placement];
|
|
15583
|
+
const nodes = [
|
|
15584
|
+
{ key: desktopKey, text: String(draft.desktopPx) }
|
|
15585
|
+
];
|
|
15586
|
+
if (draft.mobileFollowing) {
|
|
15587
|
+
nodes.push({ key: mobileKey, text: "" });
|
|
15588
|
+
} else {
|
|
15589
|
+
nodes.push({ key: mobileKey, text: String(draft.mobilePx) });
|
|
15590
|
+
}
|
|
15591
|
+
editContentRef.current = {
|
|
15592
|
+
...editContentRef.current,
|
|
15593
|
+
[desktopKey]: String(draft.desktopPx),
|
|
15594
|
+
[mobileKey]: draft.mobileFollowing ? "" : String(draft.mobilePx)
|
|
15595
|
+
};
|
|
15596
|
+
applyLogoSizeToPlacement(
|
|
15597
|
+
placement,
|
|
15598
|
+
draft.desktopPx,
|
|
15599
|
+
draft.mobileFollowing ? draft.desktopPx : draft.mobilePx,
|
|
15600
|
+
draft.mobileFollowing
|
|
15601
|
+
);
|
|
15602
|
+
postToParent2({ type: "ow:change", nodes });
|
|
15603
|
+
requestAnimationFrame(() => {
|
|
15604
|
+
const selected = selectedElRef.current;
|
|
15605
|
+
if (!selected || toolbarVariantRef.current !== "logo") return;
|
|
15606
|
+
const rect = getLogoInteractionRect(selected);
|
|
15607
|
+
setToolbarRect(rect);
|
|
15608
|
+
if (glowElRef.current) {
|
|
15609
|
+
const GAP = SELECTION_CHROME_GAP2;
|
|
15610
|
+
glowElRef.current.style.top = `${rect.top - GAP}px`;
|
|
15611
|
+
glowElRef.current.style.left = `${rect.left - GAP}px`;
|
|
15612
|
+
glowElRef.current.style.width = `${rect.width + GAP * 2}px`;
|
|
15613
|
+
glowElRef.current.style.height = `${rect.height + GAP * 2}px`;
|
|
15614
|
+
}
|
|
15615
|
+
});
|
|
15616
|
+
},
|
|
15617
|
+
[postToParent2]
|
|
15618
|
+
);
|
|
14681
15619
|
const activate = useCallback7((el, options) => {
|
|
14682
15620
|
if (activeElRef.current === el) return;
|
|
14683
15621
|
if (isIconEditable(el)) return;
|
|
@@ -14758,7 +15696,37 @@ function OhhwellsBridge() {
|
|
|
14758
15696
|
deactivateRef.current = deactivate;
|
|
14759
15697
|
selectRef.current = select;
|
|
14760
15698
|
selectFrameRef.current = selectFrame;
|
|
15699
|
+
selectLogoRef.current = selectLogo;
|
|
15700
|
+
openLogoSizePanelRef.current = openLogoSizePanel;
|
|
14761
15701
|
deselectRef.current = deselect;
|
|
15702
|
+
closeFloatingPanelOnlyRef.current = closeFloatingPanelOnly;
|
|
15703
|
+
const lastSiteWideScopeRef = useRef9(null);
|
|
15704
|
+
useEffect12(() => {
|
|
15705
|
+
if (!isEditMode) {
|
|
15706
|
+
if (lastSiteWideScopeRef.current !== false) {
|
|
15707
|
+
lastSiteWideScopeRef.current = false;
|
|
15708
|
+
postToParent2({ type: "ow:site-wide-scope", active: false });
|
|
15709
|
+
}
|
|
15710
|
+
return;
|
|
15711
|
+
}
|
|
15712
|
+
const active = isSiteWideScopeActive({
|
|
15713
|
+
selected: selectedElRef.current,
|
|
15714
|
+
hoveredItem: hoveredItemElRef.current,
|
|
15715
|
+
hoveredNavContainer: hoveredNavContainerRef.current,
|
|
15716
|
+
active: activeElRef.current
|
|
15717
|
+
});
|
|
15718
|
+
if (lastSiteWideScopeRef.current === active) return;
|
|
15719
|
+
lastSiteWideScopeRef.current = active;
|
|
15720
|
+
postToParent2({ type: "ow:site-wide-scope", active });
|
|
15721
|
+
}, [
|
|
15722
|
+
isEditMode,
|
|
15723
|
+
hoveredItemRect,
|
|
15724
|
+
hoveredNavContainerRect,
|
|
15725
|
+
toolbarVariant,
|
|
15726
|
+
toolbarRect,
|
|
15727
|
+
isFooterFrameSelection,
|
|
15728
|
+
postToParent2
|
|
15729
|
+
]);
|
|
14762
15730
|
useLayoutEffect4(() => {
|
|
14763
15731
|
if (!subdomain || isEditMode) {
|
|
14764
15732
|
setFetchState("done");
|
|
@@ -14770,9 +15738,23 @@ function OhhwellsBridge() {
|
|
|
14770
15738
|
aiSectionsRef.current = content[AI_SECTIONS_KEY];
|
|
14771
15739
|
applyAiSectionsToDom(parseAiSectionsState(content[AI_SECTIONS_KEY]));
|
|
14772
15740
|
}
|
|
15741
|
+
if (typeof content[BRAND_KIT_KEY] === "string") {
|
|
15742
|
+
brandKitRef.current = content[BRAND_KIT_KEY];
|
|
15743
|
+
applyBrandToDom(parseBrandKit(content[BRAND_KIT_KEY]));
|
|
15744
|
+
}
|
|
15745
|
+
if (typeof content[STYLE_STORE_KEY] === "string") {
|
|
15746
|
+
stylesRef.current = content[STYLE_STORE_KEY];
|
|
15747
|
+
applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
|
|
15748
|
+
}
|
|
15749
|
+
applyBrandChrome(content);
|
|
14773
15750
|
for (const [key, val] of Object.entries(content)) {
|
|
14774
15751
|
if (key === "__ohw_sections") continue;
|
|
14775
15752
|
if (key === AI_SECTIONS_KEY) continue;
|
|
15753
|
+
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
15754
|
+
if (LOGO_IMAGE_KEYS.includes(key)) continue;
|
|
15755
|
+
if (key === BRAND_KIT_KEY) continue;
|
|
15756
|
+
if (key === STYLE_STORE_KEY) continue;
|
|
15757
|
+
if (BRAND_CHROME_KEYS.has(key)) continue;
|
|
14776
15758
|
if (applyVideoSettingNode(key, val)) continue;
|
|
14777
15759
|
if (applyCarouselNode(key, val)) continue;
|
|
14778
15760
|
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
@@ -14807,6 +15789,8 @@ function OhhwellsBridge() {
|
|
|
14807
15789
|
});
|
|
14808
15790
|
applyLinkByKey(key, val);
|
|
14809
15791
|
}
|
|
15792
|
+
applyLogoFromContent(content);
|
|
15793
|
+
applyLogoSizes(content);
|
|
14810
15794
|
reconcileNavbarItemsFromContent(content);
|
|
14811
15795
|
reconcileFooterOrderFromContent(content);
|
|
14812
15796
|
reconcileSocialsFromContent(content);
|
|
@@ -14827,7 +15811,9 @@ function OhhwellsBridge() {
|
|
|
14827
15811
|
let cancelled = false;
|
|
14828
15812
|
setFetchState("loading");
|
|
14829
15813
|
const apiUrl = process.env.NEXT_PUBLIC_FLOWOPS_API_URL ?? "https://flowops-backend-staging-2yfdh7pwpq-as.a.run.app";
|
|
14830
|
-
|
|
15814
|
+
const initialPath = pathname;
|
|
15815
|
+
fetchedContentPaths.add(`${subdomain}::${initialPath}`);
|
|
15816
|
+
fetch(`${apiUrl}/api/public/sites/${subdomain}/content?path=${encodeURIComponent(initialPath)}`, { cache: "no-store" }).then((r2) => r2.ok ? r2.json() : null).then((data) => {
|
|
14831
15817
|
if (cancelled) return;
|
|
14832
15818
|
const content = data?.content ?? {};
|
|
14833
15819
|
contentCache.set(subdomain, content);
|
|
@@ -14851,8 +15837,21 @@ function OhhwellsBridge() {
|
|
|
14851
15837
|
initSectionInstancesFromContent(content, window.location.pathname);
|
|
14852
15838
|
observer?.disconnect();
|
|
14853
15839
|
try {
|
|
15840
|
+
applyBrandChrome(content);
|
|
15841
|
+
if (typeof content[BRAND_KIT_KEY] === "string") {
|
|
15842
|
+
applyBrandToDom(parseBrandKit(content[BRAND_KIT_KEY]));
|
|
15843
|
+
}
|
|
15844
|
+
if (typeof content[STYLE_STORE_KEY] === "string") {
|
|
15845
|
+
applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
|
|
15846
|
+
}
|
|
14854
15847
|
for (const [key, val] of Object.entries(content)) {
|
|
14855
15848
|
if (key === "__ohw_sections") continue;
|
|
15849
|
+
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
15850
|
+
if (LOGO_IMAGE_KEYS.includes(key)) continue;
|
|
15851
|
+
if (key === BRAND_KIT_KEY) continue;
|
|
15852
|
+
if (key === STYLE_STORE_KEY) continue;
|
|
15853
|
+
if (key === STYLE_STORE_KEY) continue;
|
|
15854
|
+
if (BRAND_CHROME_KEYS.has(key)) continue;
|
|
14856
15855
|
if (applyVideoSettingNode(key, val)) continue;
|
|
14857
15856
|
if (applyCarouselNode(key, val)) continue;
|
|
14858
15857
|
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
@@ -14873,6 +15872,7 @@ function OhhwellsBridge() {
|
|
|
14873
15872
|
});
|
|
14874
15873
|
applyLinkByKey(key, val);
|
|
14875
15874
|
}
|
|
15875
|
+
applyLogoFromContent(content);
|
|
14876
15876
|
reconcileNavbarItemsFromContent(content);
|
|
14877
15877
|
reconcileFooterOrderFromContent(content);
|
|
14878
15878
|
reconcileSocialsFromContent(content);
|
|
@@ -14887,6 +15887,17 @@ function OhhwellsBridge() {
|
|
|
14887
15887
|
debounceTimer = setTimeout(applyFromCache, 150);
|
|
14888
15888
|
};
|
|
14889
15889
|
applyFromCache();
|
|
15890
|
+
const pathCacheKey = `${subdomain}::${pathname}`;
|
|
15891
|
+
if (!fetchedContentPaths.has(pathCacheKey)) {
|
|
15892
|
+
fetchedContentPaths.add(pathCacheKey);
|
|
15893
|
+
const apiUrl = process.env.NEXT_PUBLIC_FLOWOPS_API_URL ?? "https://flowops-backend-staging-2yfdh7pwpq-as.a.run.app";
|
|
15894
|
+
fetch(`${apiUrl}/api/public/sites/${subdomain}/content?path=${encodeURIComponent(pathname)}`, { cache: "no-store" }).then((r2) => r2.ok ? r2.json() : null).then((data) => {
|
|
15895
|
+
if (!data?.content) return;
|
|
15896
|
+
contentCache.set(subdomain, data.content);
|
|
15897
|
+
applyFromCache();
|
|
15898
|
+
}).catch(() => {
|
|
15899
|
+
});
|
|
15900
|
+
}
|
|
14890
15901
|
observer = new MutationObserver(scheduleApply);
|
|
14891
15902
|
observer.observe(document.body, { childList: true, subtree: true });
|
|
14892
15903
|
return () => {
|
|
@@ -14980,26 +15991,31 @@ function OhhwellsBridge() {
|
|
|
14980
15991
|
}, [isEditMode, pathname, subdomain, fetchState, resyncSelectedNavigationItem]);
|
|
14981
15992
|
useEffect12(() => {
|
|
14982
15993
|
if (!isEditMode) return;
|
|
15994
|
+
let lastPosted = 0;
|
|
14983
15995
|
const measure = () => {
|
|
14984
15996
|
const h = document.body.scrollHeight;
|
|
14985
|
-
if (h > 50
|
|
15997
|
+
if (h > 50 && Math.abs(h - lastPosted) > 1) {
|
|
15998
|
+
lastPosted = h;
|
|
15999
|
+
postToParent2({ type: "ow:height", height: h });
|
|
16000
|
+
}
|
|
16001
|
+
};
|
|
16002
|
+
let raf = null;
|
|
16003
|
+
const schedule = () => {
|
|
16004
|
+
if (raf != null) return;
|
|
16005
|
+
raf = requestAnimationFrame(() => {
|
|
16006
|
+
raf = null;
|
|
16007
|
+
measure();
|
|
16008
|
+
});
|
|
14986
16009
|
};
|
|
14987
16010
|
const t1 = setTimeout(measure, 50);
|
|
14988
16011
|
const t2 = setTimeout(measure, 500);
|
|
14989
|
-
|
|
14990
|
-
|
|
14991
|
-
const handleResize = () => {
|
|
14992
|
-
if (window.innerWidth === lastWidth) return;
|
|
14993
|
-
lastWidth = window.innerWidth;
|
|
14994
|
-
if (resizeTimer) clearTimeout(resizeTimer);
|
|
14995
|
-
resizeTimer = setTimeout(measure, 150);
|
|
14996
|
-
};
|
|
14997
|
-
window.addEventListener("resize", handleResize);
|
|
16012
|
+
const ro = new ResizeObserver(schedule);
|
|
16013
|
+
ro.observe(document.body);
|
|
14998
16014
|
return () => {
|
|
14999
16015
|
clearTimeout(t1);
|
|
15000
16016
|
clearTimeout(t2);
|
|
15001
|
-
if (
|
|
15002
|
-
|
|
16017
|
+
if (raf != null) cancelAnimationFrame(raf);
|
|
16018
|
+
ro.disconnect();
|
|
15003
16019
|
};
|
|
15004
16020
|
}, [pathname, isEditMode, postToParent2]);
|
|
15005
16021
|
useEffect12(() => {
|
|
@@ -15149,10 +16165,12 @@ function OhhwellsBridge() {
|
|
|
15149
16165
|
return;
|
|
15150
16166
|
}
|
|
15151
16167
|
const target = e.target;
|
|
16168
|
+
if (target.closest("[data-ohw-ai-review]")) return;
|
|
15152
16169
|
if (target.closest("[data-ohw-toolbar]")) return;
|
|
15153
16170
|
if (target.closest("[data-ohw-state-toggle]")) return;
|
|
15154
16171
|
if (target.closest("[data-ohw-max-badge]")) return;
|
|
15155
16172
|
if (isInsideLinkEditor(target)) return;
|
|
16173
|
+
if (isInsideFloatingPanel(target)) return;
|
|
15156
16174
|
if (target.closest('[data-ohw-edit-chrome], [data-ohw-item-interaction], [data-ohw-drag-handle-container], [data-slot="drag-handle"]')) {
|
|
15157
16175
|
const beneath = document.elementsFromPoint(e.clientX, e.clientY).find(
|
|
15158
16176
|
(el) => el instanceof HTMLElement && !el.closest("[data-ohw-bridge-root]") && el.closest("[data-ohw-section]") != null
|
|
@@ -15216,6 +16234,21 @@ function OhhwellsBridge() {
|
|
|
15216
16234
|
return;
|
|
15217
16235
|
}
|
|
15218
16236
|
}
|
|
16237
|
+
const logoEl = getLogoElement(target);
|
|
16238
|
+
if (logoEl) {
|
|
16239
|
+
e.preventDefault();
|
|
16240
|
+
e.stopPropagation();
|
|
16241
|
+
if (!logoHasUploadedImage(logoEl)) {
|
|
16242
|
+
deselectRef.current();
|
|
16243
|
+
deactivateRef.current();
|
|
16244
|
+
const identity = readLogoIdentityFromDom();
|
|
16245
|
+
postToParentRef.current({ type: "ow:open-logo-settings", ...identity });
|
|
16246
|
+
return;
|
|
16247
|
+
}
|
|
16248
|
+
selectLogoRef.current(logoEl);
|
|
16249
|
+
openLogoSizePanelRef.current(logoEl);
|
|
16250
|
+
return;
|
|
16251
|
+
}
|
|
15219
16252
|
const editable = target.closest("[data-ohw-editable]");
|
|
15220
16253
|
if (editable) {
|
|
15221
16254
|
if (editable.dataset.ohwEditable === "link") {
|
|
@@ -15368,10 +16401,12 @@ function OhhwellsBridge() {
|
|
|
15368
16401
|
};
|
|
15369
16402
|
const handleDblClick = (e) => {
|
|
15370
16403
|
const target = e.target;
|
|
16404
|
+
if (target.closest("[data-ohw-ai-review]")) return;
|
|
15371
16405
|
if (target.closest("[data-ohw-toolbar]")) return;
|
|
15372
16406
|
if (target.closest("[data-ohw-state-toggle]")) return;
|
|
15373
16407
|
if (target.closest("[data-ohw-max-badge]")) return;
|
|
15374
16408
|
if (isInsideLinkEditor(target)) return;
|
|
16409
|
+
if (isInsideFloatingPanel(target)) return;
|
|
15375
16410
|
if (target.closest('[data-ohw-edit-chrome], [data-ohw-item-interaction], [data-ohw-drag-handle-container], [data-slot="drag-handle"]')) {
|
|
15376
16411
|
return;
|
|
15377
16412
|
}
|
|
@@ -15399,11 +16434,14 @@ function OhhwellsBridge() {
|
|
|
15399
16434
|
setHoveredNavContainerRect(null);
|
|
15400
16435
|
return;
|
|
15401
16436
|
}
|
|
15402
|
-
if (document.documentElement.hasAttribute("data-ohw-panel-dragging") || target.
|
|
16437
|
+
if (document.documentElement.hasAttribute("data-ohw-panel-dragging") || isInsideFloatingPanel(target) || isPointOverFloatingPanel(e.clientX, e.clientY)) {
|
|
15403
16438
|
hoveredItemElRef.current = null;
|
|
15404
16439
|
setHoveredItemRect(null);
|
|
15405
16440
|
hoveredNavContainerRef.current = null;
|
|
15406
16441
|
setHoveredNavContainerRect(null);
|
|
16442
|
+
siblingHintElRef.current = null;
|
|
16443
|
+
setSiblingHintRect(null);
|
|
16444
|
+
setSiblingHintRects([]);
|
|
15407
16445
|
return;
|
|
15408
16446
|
}
|
|
15409
16447
|
{
|
|
@@ -15413,7 +16451,7 @@ function OhhwellsBridge() {
|
|
|
15413
16451
|
const allowFooterLinksHover = toolbarVariantRef.current !== "select-frame" || selectedIsFooterColumn;
|
|
15414
16452
|
if (allowNavContainerHover) {
|
|
15415
16453
|
const navContainer = target.closest("[data-ohw-nav-container]");
|
|
15416
|
-
if (navContainer && !getNavigationItemAnchor(target)) {
|
|
16454
|
+
if (navContainer && !getNavigationItemAnchor(target) && !getLogoElement(target)) {
|
|
15417
16455
|
hoveredNavContainerRef.current = navContainer;
|
|
15418
16456
|
setHoveredNavContainerRect(navContainer.getBoundingClientRect());
|
|
15419
16457
|
hoveredItemElRef.current = null;
|
|
@@ -15442,6 +16480,15 @@ function OhhwellsBridge() {
|
|
|
15442
16480
|
setHoveredNavContainerRect(null);
|
|
15443
16481
|
}
|
|
15444
16482
|
}
|
|
16483
|
+
const logoEl = getLogoElement(target);
|
|
16484
|
+
if (logoEl) {
|
|
16485
|
+
hoveredNavContainerRef.current = null;
|
|
16486
|
+
setHoveredNavContainerRect(null);
|
|
16487
|
+
if (selectedElRef.current === logoEl) return;
|
|
16488
|
+
hoveredItemElRef.current = logoEl;
|
|
16489
|
+
setHoveredItemRect(getLogoInteractionRect(logoEl));
|
|
16490
|
+
return;
|
|
16491
|
+
}
|
|
15445
16492
|
const navAnchor = getNavigationItemAnchor(target);
|
|
15446
16493
|
if (navAnchor) {
|
|
15447
16494
|
hoveredNavContainerRef.current = null;
|
|
@@ -15479,6 +16526,11 @@ function OhhwellsBridge() {
|
|
|
15479
16526
|
setHoveredItemRect(hoverTarget.getBoundingClientRect());
|
|
15480
16527
|
} else if (!isInsideNavigationItem(editable)) {
|
|
15481
16528
|
hoverTarget.setAttribute("data-ohw-hovered", "");
|
|
16529
|
+
if (editable.closest("footer") || editable.closest('[data-ohw-section="footer"]')) {
|
|
16530
|
+
hoveredNavContainerRef.current = null;
|
|
16531
|
+
setHoveredNavContainerRect(null);
|
|
16532
|
+
hoveredItemElRef.current = editable;
|
|
16533
|
+
}
|
|
15482
16534
|
}
|
|
15483
16535
|
}
|
|
15484
16536
|
};
|
|
@@ -15514,6 +16566,18 @@ function OhhwellsBridge() {
|
|
|
15514
16566
|
}
|
|
15515
16567
|
return;
|
|
15516
16568
|
}
|
|
16569
|
+
const logoEl = getLogoElement(target);
|
|
16570
|
+
if (logoEl) {
|
|
16571
|
+
const related2 = e.relatedTarget instanceof Element ? e.relatedTarget : null;
|
|
16572
|
+
if (related2 && (logoEl === related2 || logoEl.contains(related2) || related2.closest?.('[data-ohw-role="logo"], [data-ohw-logo]'))) {
|
|
16573
|
+
return;
|
|
16574
|
+
}
|
|
16575
|
+
if (hoveredItemElRef.current === logoEl) {
|
|
16576
|
+
hoveredItemElRef.current = null;
|
|
16577
|
+
setHoveredItemRect(null);
|
|
16578
|
+
}
|
|
16579
|
+
return;
|
|
16580
|
+
}
|
|
15517
16581
|
const editable = target.closest("[data-ohw-editable]");
|
|
15518
16582
|
if (!editable) return;
|
|
15519
16583
|
const related = e.relatedTarget instanceof Element ? e.relatedTarget : null;
|
|
@@ -15534,6 +16598,13 @@ function OhhwellsBridge() {
|
|
|
15534
16598
|
}
|
|
15535
16599
|
} else {
|
|
15536
16600
|
hoverTarget.removeAttribute("data-ohw-hovered");
|
|
16601
|
+
if (hoveredItemElRef.current === editable) {
|
|
16602
|
+
const stillOnEditable = related instanceof Element && related.closest("[data-ohw-editable]") === editable;
|
|
16603
|
+
if (!stillOnEditable) {
|
|
16604
|
+
hoveredItemElRef.current = null;
|
|
16605
|
+
setHoveredItemRect(null);
|
|
16606
|
+
}
|
|
16607
|
+
}
|
|
15537
16608
|
}
|
|
15538
16609
|
}
|
|
15539
16610
|
};
|
|
@@ -15650,6 +16721,26 @@ function OhhwellsBridge() {
|
|
|
15650
16721
|
hoveredNavContainerRef.current = null;
|
|
15651
16722
|
setHoveredNavContainerRect(null);
|
|
15652
16723
|
}
|
|
16724
|
+
const logoCandidates = [
|
|
16725
|
+
...document.querySelectorAll('[data-ohw-role="logo"], [data-ohw-logo]'),
|
|
16726
|
+
...document.querySelectorAll("nav a:not([data-ohw-href-key]), [data-ohw-nav-root] a:not([data-ohw-href-key])"),
|
|
16727
|
+
...document.querySelectorAll("footer img")
|
|
16728
|
+
];
|
|
16729
|
+
const seenLogos = /* @__PURE__ */ new Set();
|
|
16730
|
+
for (const candidate of logoCandidates) {
|
|
16731
|
+
const logo = getLogoElement(candidate);
|
|
16732
|
+
if (!logo || seenLogos.has(logo)) continue;
|
|
16733
|
+
seenLogos.add(logo);
|
|
16734
|
+
const r2 = logo.getBoundingClientRect();
|
|
16735
|
+
if (x < r2.left || x > r2.right || y < r2.top || y > r2.bottom) continue;
|
|
16736
|
+
hoveredNavContainerRef.current = null;
|
|
16737
|
+
setHoveredNavContainerRect(null);
|
|
16738
|
+
if (selectedElRef.current !== logo) {
|
|
16739
|
+
hoveredItemElRef.current = logo;
|
|
16740
|
+
setHoveredItemRect(getLogoInteractionRect(logo));
|
|
16741
|
+
}
|
|
16742
|
+
return;
|
|
16743
|
+
}
|
|
15653
16744
|
const navContainers = Array.from(
|
|
15654
16745
|
document.querySelectorAll("[data-ohw-nav-container]")
|
|
15655
16746
|
);
|
|
@@ -15735,7 +16826,7 @@ function OhhwellsBridge() {
|
|
|
15735
16826
|
}
|
|
15736
16827
|
};
|
|
15737
16828
|
const probeImageAt = (clientX, clientY, isDragOver = false, fromParentViewport = false) => {
|
|
15738
|
-
if (linkPopoverOpenRef.current) {
|
|
16829
|
+
if (linkPopoverOpenRef.current || floatingPanelOpenRef.current && isPointOverFloatingPanel(clientX, clientY)) {
|
|
15739
16830
|
if (hoveredImageRef.current) {
|
|
15740
16831
|
hoveredImageRef.current = null;
|
|
15741
16832
|
hoveredImageHasTextOverlapRef.current = false;
|
|
@@ -15989,7 +17080,7 @@ function OhhwellsBridge() {
|
|
|
15989
17080
|
}
|
|
15990
17081
|
};
|
|
15991
17082
|
const probeHoverCardsAt = (clientX, clientY, fromParentViewport = false) => {
|
|
15992
|
-
if (linkPopoverOpenRef.current || document.documentElement.hasAttribute("data-ohw-section-picking")) {
|
|
17083
|
+
if (linkPopoverOpenRef.current || floatingPanelOpenRef.current && isPointOverFloatingPanel(clientX, clientY) || document.documentElement.hasAttribute("data-ohw-section-picking")) {
|
|
15993
17084
|
if (activeStateElRef.current) {
|
|
15994
17085
|
activeStateElRef.current.removeAttribute("data-ohw-state-hovered");
|
|
15995
17086
|
activeStateElRef.current = null;
|
|
@@ -16055,16 +17146,21 @@ function OhhwellsBridge() {
|
|
|
16055
17146
|
setSectionGap(null);
|
|
16056
17147
|
}
|
|
16057
17148
|
};
|
|
16058
|
-
const pointOwnedByFloatingPanel = (clientX, clientY) => {
|
|
16059
|
-
if (document.documentElement.hasAttribute("data-ohw-panel-dragging")) return true;
|
|
16060
|
-
const panel = document.querySelector("[data-ohw-floating-panel]");
|
|
16061
|
-
if (!panel) return false;
|
|
16062
|
-
const rect = panel.getBoundingClientRect();
|
|
16063
|
-
return clientX >= rect.left && clientX <= rect.right && clientY >= rect.top && clientY <= rect.bottom;
|
|
16064
|
-
};
|
|
16065
17149
|
const handleMouseMove = (e) => {
|
|
16066
17150
|
const { clientX, clientY } = e;
|
|
16067
|
-
if (
|
|
17151
|
+
if (document.documentElement.hasAttribute("data-ohw-panel-dragging") || floatingPanelOpenRef.current && isPointOverFloatingPanel(clientX, clientY)) {
|
|
17152
|
+
hoveredItemElRef.current = null;
|
|
17153
|
+
setHoveredItemRect(null);
|
|
17154
|
+
hoveredNavContainerRef.current = null;
|
|
17155
|
+
setHoveredNavContainerRect(null);
|
|
17156
|
+
siblingHintElRef.current = null;
|
|
17157
|
+
setSiblingHintRect(null);
|
|
17158
|
+
setSiblingHintRects([]);
|
|
17159
|
+
dismissImageHover();
|
|
17160
|
+
clearImageHover();
|
|
17161
|
+
setSectionGap(null);
|
|
17162
|
+
return;
|
|
17163
|
+
}
|
|
16068
17164
|
probeSectionGapAt(clientX, clientY);
|
|
16069
17165
|
probeImageAt(clientX, clientY);
|
|
16070
17166
|
probeHoverCardsAt(clientX, clientY);
|
|
@@ -16073,7 +17169,11 @@ function OhhwellsBridge() {
|
|
|
16073
17169
|
if (e.data?.type !== "ow:pointer-sync") return;
|
|
16074
17170
|
const { clientX, clientY } = e.data;
|
|
16075
17171
|
if (typeof clientX !== "number" || typeof clientY !== "number") return;
|
|
16076
|
-
if (
|
|
17172
|
+
if (document.documentElement.hasAttribute("data-ohw-panel-dragging") || floatingPanelOpenRef.current && isPointOverFloatingPanel(clientX, clientY)) {
|
|
17173
|
+
dismissImageHover();
|
|
17174
|
+
clearImageHover();
|
|
17175
|
+
return;
|
|
17176
|
+
}
|
|
16077
17177
|
probeSectionGapAt(clientX, clientY);
|
|
16078
17178
|
probeImageAt(clientX, clientY);
|
|
16079
17179
|
probeHoverCardsAt(clientX, clientY);
|
|
@@ -16323,6 +17423,15 @@ function OhhwellsBridge() {
|
|
|
16323
17423
|
aiSectionsRef.current = content[AI_SECTIONS_KEY];
|
|
16324
17424
|
applyAiSectionsToDom(parseAiSectionsState(content[AI_SECTIONS_KEY]));
|
|
16325
17425
|
}
|
|
17426
|
+
if (typeof content[BRAND_KIT_KEY] === "string") {
|
|
17427
|
+
brandKitRef.current = content[BRAND_KIT_KEY];
|
|
17428
|
+
applyBrandToDom(parseBrandKit(content[BRAND_KIT_KEY]));
|
|
17429
|
+
}
|
|
17430
|
+
if (typeof content[STYLE_STORE_KEY] === "string") {
|
|
17431
|
+
stylesRef.current = content[STYLE_STORE_KEY];
|
|
17432
|
+
applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
|
|
17433
|
+
}
|
|
17434
|
+
applyBrandChrome(content);
|
|
16326
17435
|
let sectionsJson = null;
|
|
16327
17436
|
for (const [key, val] of Object.entries(content)) {
|
|
16328
17437
|
if (key === "__ohw_sections") {
|
|
@@ -16330,6 +17439,11 @@ function OhhwellsBridge() {
|
|
|
16330
17439
|
continue;
|
|
16331
17440
|
}
|
|
16332
17441
|
if (key === AI_SECTIONS_KEY) continue;
|
|
17442
|
+
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
17443
|
+
if (LOGO_IMAGE_KEYS.includes(key) && !String(val ?? "").trim()) continue;
|
|
17444
|
+
if (key === BRAND_KIT_KEY) continue;
|
|
17445
|
+
if (key === STYLE_STORE_KEY) continue;
|
|
17446
|
+
if (BRAND_CHROME_KEYS.has(key)) continue;
|
|
16333
17447
|
if (applyVideoSettingNode(key, val)) continue;
|
|
16334
17448
|
if (applyCarouselNode(key, val)) continue;
|
|
16335
17449
|
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
@@ -16349,6 +17463,8 @@ function OhhwellsBridge() {
|
|
|
16349
17463
|
});
|
|
16350
17464
|
applyLinkByKey(key, val);
|
|
16351
17465
|
}
|
|
17466
|
+
applyLogoFromContent(content);
|
|
17467
|
+
applyLogoSizes(content);
|
|
16352
17468
|
if (sectionsJson) {
|
|
16353
17469
|
initSectionsFromContent({ __ohw_sections: sectionsJson }, true);
|
|
16354
17470
|
sectionsLoadedRef.current = true;
|
|
@@ -16364,6 +17480,58 @@ function OhhwellsBridge() {
|
|
|
16364
17480
|
if (hydratedHeight > 50) postToParentRef.current({ type: "ow:height", height: hydratedHeight });
|
|
16365
17481
|
postToParentRef.current({ type: "ow:hydrate-done" });
|
|
16366
17482
|
};
|
|
17483
|
+
const handleUpdateLogoIdentity = (e) => {
|
|
17484
|
+
if (e.data?.type !== "ow:update-logo-identity") return;
|
|
17485
|
+
const rawText = typeof e.data.text === "string" ? e.data.text : "";
|
|
17486
|
+
const alt = typeof e.data.alt === "string" ? e.data.alt : rawText;
|
|
17487
|
+
const href = typeof e.data.href === "string" ? e.data.href : void 0;
|
|
17488
|
+
const imageProvided = "image" in e.data;
|
|
17489
|
+
const imageUrl = imageProvided && typeof e.data.image === "string" && e.data.image.trim() ? e.data.image.trim() : imageProvided ? null : void 0;
|
|
17490
|
+
let isPlaceholder = e.data.isPlaceholder !== false;
|
|
17491
|
+
if (imageUrl) isPlaceholder = false;
|
|
17492
|
+
else if (imageProvided && imageUrl === null) {
|
|
17493
|
+
isPlaceholder = e.data.isPlaceholder === true || !rawText.trim() || resolveLogoDisplayText(rawText) === PLACEHOLDER_BUSINESS_NAME;
|
|
17494
|
+
}
|
|
17495
|
+
const display = applyLogoIdentity(rawText, isPlaceholder);
|
|
17496
|
+
const displayAlt = resolveLogoDisplayText(alt || display);
|
|
17497
|
+
if (imageUrl !== void 0) {
|
|
17498
|
+
applyLogoImage(imageUrl, displayAlt);
|
|
17499
|
+
} else {
|
|
17500
|
+
for (const key of LOGO_IMAGE_KEYS) {
|
|
17501
|
+
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
17502
|
+
const img = el instanceof HTMLImageElement ? el : el.querySelector("img");
|
|
17503
|
+
if (img) img.alt = displayAlt;
|
|
17504
|
+
});
|
|
17505
|
+
}
|
|
17506
|
+
}
|
|
17507
|
+
if (href !== void 0) {
|
|
17508
|
+
applyLogoHref(href);
|
|
17509
|
+
applyLinkByKey("nav-logo-href", href);
|
|
17510
|
+
applyLinkByKey("footer-logo-href", href);
|
|
17511
|
+
applyLinkByKey("logo-href", href);
|
|
17512
|
+
}
|
|
17513
|
+
const nodes = [
|
|
17514
|
+
...LOGO_TEXT_KEYS.map((key) => ({ key, text: display })),
|
|
17515
|
+
{ key: LOGO_PLACEHOLDER_KEY, text: isPlaceholder ? "true" : "false" },
|
|
17516
|
+
{ key: LOGO_ALT_KEY, text: displayAlt }
|
|
17517
|
+
];
|
|
17518
|
+
if (imageUrl !== void 0) {
|
|
17519
|
+
if (imageUrl) {
|
|
17520
|
+
for (const key of LOGO_IMAGE_KEYS) nodes.push({ key, text: imageUrl });
|
|
17521
|
+
} else {
|
|
17522
|
+
for (const key of LOGO_IMAGE_KEYS) nodes.push({ key, text: "" });
|
|
17523
|
+
}
|
|
17524
|
+
}
|
|
17525
|
+
if (href !== void 0) {
|
|
17526
|
+
for (const key of LOGO_HREF_KEYS) nodes.push({ key, text: href.trim() || "/" });
|
|
17527
|
+
}
|
|
17528
|
+
editContentRef.current = {
|
|
17529
|
+
...editContentRef.current,
|
|
17530
|
+
...Object.fromEntries(nodes.map(({ key, text }) => [key, text]))
|
|
17531
|
+
};
|
|
17532
|
+
applyLogoSizes(editContentRef.current);
|
|
17533
|
+
postToParentRef.current({ type: "ow:change", nodes });
|
|
17534
|
+
};
|
|
16367
17535
|
window.addEventListener("message", handleHydrate);
|
|
16368
17536
|
const postAiSectionsChanged = () => {
|
|
16369
17537
|
postToParentRef.current({
|
|
@@ -16377,7 +17545,10 @@ function OhhwellsBridge() {
|
|
|
16377
17545
|
const payload = e.data.payload;
|
|
16378
17546
|
if (!payload || typeof payload.id !== "string" || !isRenderableTree(payload.tree)) return;
|
|
16379
17547
|
const previous = aiSectionsRef.current;
|
|
16380
|
-
const nextState = applyTreeToState(parseAiSectionsState(previous),
|
|
17548
|
+
const nextState = applyTreeToState(parseAiSectionsState(previous), {
|
|
17549
|
+
...payload,
|
|
17550
|
+
path: payload.path ?? window.location.pathname
|
|
17551
|
+
});
|
|
16381
17552
|
const nextValue = serializeAiSectionsState(nextState);
|
|
16382
17553
|
aiSectionsRef.current = nextValue;
|
|
16383
17554
|
applyAiSectionsToDom(nextState);
|
|
@@ -16414,12 +17585,42 @@ function OhhwellsBridge() {
|
|
|
16414
17585
|
const value = typeof e.data.value === "string" ? e.data.value : "";
|
|
16415
17586
|
aiSectionsRef.current = value;
|
|
16416
17587
|
applyAiSectionsToDom(parseAiSectionsState(value));
|
|
17588
|
+
applyStylesToDom(parseStyleStore(stylesRef.current));
|
|
16417
17589
|
const restoredHeight = document.documentElement.scrollHeight;
|
|
16418
17590
|
if (restoredHeight > 50) postToParentRef.current({ type: "ow:height", height: restoredHeight });
|
|
16419
17591
|
postToParentRef.current({ type: "ow:change", nodes: [{ key: AI_SECTIONS_KEY, text: value }] });
|
|
16420
17592
|
postAiSectionsChanged();
|
|
16421
17593
|
};
|
|
16422
17594
|
window.addEventListener("message", handleAiSetSections);
|
|
17595
|
+
const handleAiSetBrand = (e) => {
|
|
17596
|
+
if (e.data?.type !== "ow:ai-set-brand") return;
|
|
17597
|
+
const value = typeof e.data.value === "string" ? e.data.value : "";
|
|
17598
|
+
const previous = brandKitRef.current;
|
|
17599
|
+
brandKitRef.current = value;
|
|
17600
|
+
applyBrandToDom(parseBrandKit(value));
|
|
17601
|
+
if (aiSectionsRef.current) applyAiSectionsToDom(parseAiSectionsState(aiSectionsRef.current));
|
|
17602
|
+
applyStylesToDom(parseStyleStore(stylesRef.current));
|
|
17603
|
+
postToParentRef.current({ type: "ow:change", nodes: [{ key: BRAND_KIT_KEY, text: value }] });
|
|
17604
|
+
postToParentRef.current({ type: "ow:ai-brand-applied", previous, value });
|
|
17605
|
+
};
|
|
17606
|
+
window.addEventListener("message", handleAiSetBrand);
|
|
17607
|
+
const handleAiSetStyles = (e) => {
|
|
17608
|
+
if (e.data?.type !== "ow:ai-set-styles") return;
|
|
17609
|
+
const value = typeof e.data.value === "string" ? e.data.value : "";
|
|
17610
|
+
const previous = stylesRef.current;
|
|
17611
|
+
stylesRef.current = value;
|
|
17612
|
+
applyStylesToDom(parseStyleStore(value));
|
|
17613
|
+
postToParentRef.current({ type: "ow:change", nodes: [{ key: STYLE_STORE_KEY, text: value }] });
|
|
17614
|
+
postToParentRef.current({ type: "ow:ai-styles-applied", previous, value });
|
|
17615
|
+
};
|
|
17616
|
+
window.addEventListener("message", handleAiSetStyles);
|
|
17617
|
+
const handleGetBrand = (e) => {
|
|
17618
|
+
if (e.data?.type !== "ow:get-brand") return;
|
|
17619
|
+
const template = deriveTemplateBrand();
|
|
17620
|
+
const value = brandKitRef.current || (template ? JSON.stringify(template) : "");
|
|
17621
|
+
postToParentRef.current({ type: "ow:brand-value", value });
|
|
17622
|
+
};
|
|
17623
|
+
window.addEventListener("message", handleGetBrand);
|
|
16423
17624
|
const handleDeactivate = (e) => {
|
|
16424
17625
|
if (e.data?.type !== "ow:deactivate") return;
|
|
16425
17626
|
if (Date.now() < linkPopoverGraceUntilRef.current) return;
|
|
@@ -16428,6 +17629,12 @@ function OhhwellsBridge() {
|
|
|
16428
17629
|
closeLinkPopoverRef.current();
|
|
16429
17630
|
return;
|
|
16430
17631
|
}
|
|
17632
|
+
if (floatingPanelOpenRef.current) {
|
|
17633
|
+
setFloatingPanelRef.current(null);
|
|
17634
|
+
deselectRef.current();
|
|
17635
|
+
deactivateRef.current();
|
|
17636
|
+
return;
|
|
17637
|
+
}
|
|
16431
17638
|
deselectRef.current();
|
|
16432
17639
|
deactivateRef.current();
|
|
16433
17640
|
};
|
|
@@ -16481,6 +17688,10 @@ function OhhwellsBridge() {
|
|
|
16481
17688
|
return;
|
|
16482
17689
|
}
|
|
16483
17690
|
if (selectedElRef.current) {
|
|
17691
|
+
if (toolbarVariantRef.current === "logo") {
|
|
17692
|
+
deselectRef.current();
|
|
17693
|
+
return;
|
|
17694
|
+
}
|
|
16484
17695
|
if (toolbarVariantRef.current === "select-frame") {
|
|
16485
17696
|
const parent2 = getNavigationSelectionParent(selectedElRef.current);
|
|
16486
17697
|
if (parent2 && isNavigationContainer(parent2) && isFooterLinksContainer(parent2) && !isFooterLinksContainer(selectedElRef.current)) {
|
|
@@ -16520,6 +17731,10 @@ function OhhwellsBridge() {
|
|
|
16520
17731
|
return;
|
|
16521
17732
|
}
|
|
16522
17733
|
if (e.key === "Escape" && selectedElRef.current && !activeElRef.current) {
|
|
17734
|
+
if (toolbarVariantRef.current === "logo") {
|
|
17735
|
+
deselectRef.current();
|
|
17736
|
+
return;
|
|
17737
|
+
}
|
|
16523
17738
|
if (toolbarVariantRef.current === "select-frame") {
|
|
16524
17739
|
const parent2 = getNavigationSelectionParent(selectedElRef.current);
|
|
16525
17740
|
if (parent2 && isNavigationContainer(parent2) && isFooterLinksContainer(parent2) && !isFooterLinksContainer(selectedElRef.current)) {
|
|
@@ -16597,7 +17812,8 @@ function OhhwellsBridge() {
|
|
|
16597
17812
|
const handleScroll = () => {
|
|
16598
17813
|
const focusEl = activeElRef.current ?? selectedElRef.current;
|
|
16599
17814
|
if (focusEl) {
|
|
16600
|
-
const
|
|
17815
|
+
const measureEl = activeElRef.current ? getEditMeasureEl(activeElRef.current) : toolbarVariantRef.current === "logo" ? null : focusEl;
|
|
17816
|
+
const r2 = measureEl ? measureEl.getBoundingClientRect() : toolbarVariantRef.current === "logo" ? getLogoInteractionRect(focusEl) : focusEl.getBoundingClientRect();
|
|
16601
17817
|
applyToolbarPos(r2);
|
|
16602
17818
|
setToolbarRect(r2);
|
|
16603
17819
|
setMaxBadge((prev) => prev && activeElRef.current ? { ...prev, rect: r2 } : prev);
|
|
@@ -16607,7 +17823,9 @@ function OhhwellsBridge() {
|
|
|
16607
17823
|
setToggleState((prev) => prev ? { ...prev, rect } : null);
|
|
16608
17824
|
}
|
|
16609
17825
|
if (hoveredItemElRef.current) {
|
|
16610
|
-
|
|
17826
|
+
const hoverEl = hoveredItemElRef.current;
|
|
17827
|
+
const logo = getLogoElement(hoverEl);
|
|
17828
|
+
setHoveredItemRect(logo ? getLogoInteractionRect(logo) : hoverEl.getBoundingClientRect());
|
|
16611
17829
|
}
|
|
16612
17830
|
if (hoveredNavContainerRef.current) {
|
|
16613
17831
|
setHoveredNavContainerRect(hoveredNavContainerRef.current.getBoundingClientRect());
|
|
@@ -16651,6 +17869,12 @@ function OhhwellsBridge() {
|
|
|
16651
17869
|
if (aiSectionsRef.current) {
|
|
16652
17870
|
nodes.push({ key: AI_SECTIONS_KEY, type: "sections", text: aiSectionsRef.current });
|
|
16653
17871
|
}
|
|
17872
|
+
if (stylesRef.current) {
|
|
17873
|
+
nodes.push({ key: STYLE_STORE_KEY, type: "styles", text: stylesRef.current });
|
|
17874
|
+
}
|
|
17875
|
+
if (brandKitRef.current) {
|
|
17876
|
+
nodes.push({ key: BRAND_KIT_KEY, type: "brand", text: brandKitRef.current });
|
|
17877
|
+
}
|
|
16654
17878
|
postToParentRef.current({ type: "ow:save-result", nodes });
|
|
16655
17879
|
};
|
|
16656
17880
|
const handleInsertSection = (e) => {
|
|
@@ -16661,8 +17885,12 @@ function OhhwellsBridge() {
|
|
|
16661
17885
|
if (inserted) {
|
|
16662
17886
|
const tracker = getSectionsTracker();
|
|
16663
17887
|
postToParentRef.current({ type: "ow:change", nodes: [{ key: "__ohw_sections", text: tracker.textContent ?? "[]" }] });
|
|
16664
|
-
const
|
|
16665
|
-
|
|
17888
|
+
const reportHeight = () => {
|
|
17889
|
+
const h = document.body.scrollHeight;
|
|
17890
|
+
if (h > 50) postToParentRef.current({ type: "ow:height", height: h });
|
|
17891
|
+
};
|
|
17892
|
+
reportHeight();
|
|
17893
|
+
setTimeout(reportHeight, 500);
|
|
16666
17894
|
}
|
|
16667
17895
|
};
|
|
16668
17896
|
const handleSwitchSchedule = (e) => {
|
|
@@ -16855,13 +18083,17 @@ function OhhwellsBridge() {
|
|
|
16855
18083
|
if (e.data?.type !== "ow:parent-scroll") return;
|
|
16856
18084
|
const { iframeOffsetTop, headerH, canvasH } = e.data;
|
|
16857
18085
|
parentScrollRef.current = { iframeOffsetTop, headerH, canvasH };
|
|
18086
|
+
if (floatingPanelOpenRef.current) {
|
|
18087
|
+
setParentScrollSnap({ iframeOffsetTop, headerH, canvasH });
|
|
18088
|
+
}
|
|
16858
18089
|
if (visibleViewportRef.current) {
|
|
16859
18090
|
applyVisibleViewport(visibleViewportRef.current, parentScrollRef.current);
|
|
16860
18091
|
}
|
|
16861
18092
|
const focusEl = activeElRef.current ?? selectedElRef.current;
|
|
16862
18093
|
if (focusEl) {
|
|
16863
|
-
const measureEl = activeElRef.current ? getEditMeasureEl(activeElRef.current) : focusEl;
|
|
16864
|
-
|
|
18094
|
+
const measureEl = activeElRef.current ? getEditMeasureEl(activeElRef.current) : toolbarVariantRef.current === "logo" ? null : focusEl;
|
|
18095
|
+
const r2 = measureEl ? measureEl.getBoundingClientRect() : toolbarVariantRef.current === "logo" ? getLogoInteractionRect(focusEl) : focusEl.getBoundingClientRect();
|
|
18096
|
+
applyToolbarPos(r2);
|
|
16865
18097
|
}
|
|
16866
18098
|
};
|
|
16867
18099
|
const handleClickAt = (e) => {
|
|
@@ -16886,6 +18118,25 @@ function OhhwellsBridge() {
|
|
|
16886
18118
|
postToParentRef.current({ type: "ow:image-pick", key: stateCardImage.dataset.ohwKey ?? "", elementType: stateCardImage.dataset.ohwEditable ?? "image" });
|
|
16887
18119
|
return;
|
|
16888
18120
|
}
|
|
18121
|
+
const logoAtPoint = Array.from(
|
|
18122
|
+
document.querySelectorAll('[data-ohw-role="logo"], [data-ohw-logo]')
|
|
18123
|
+
).map((el) => getLogoElement(el)).find((logo) => {
|
|
18124
|
+
if (!logo) return false;
|
|
18125
|
+
const r2 = logo.getBoundingClientRect();
|
|
18126
|
+
return clientX >= r2.left && clientX <= r2.right && clientY >= r2.top && clientY <= r2.bottom;
|
|
18127
|
+
});
|
|
18128
|
+
if (logoAtPoint) {
|
|
18129
|
+
if (!logoHasUploadedImage(logoAtPoint)) {
|
|
18130
|
+
deselectRef.current();
|
|
18131
|
+
deactivateRef.current();
|
|
18132
|
+
const identity = readLogoIdentityFromDom();
|
|
18133
|
+
postToParentRef.current({ type: "ow:open-logo-settings", ...identity });
|
|
18134
|
+
return;
|
|
18135
|
+
}
|
|
18136
|
+
selectLogoRef.current(logoAtPoint);
|
|
18137
|
+
openLogoSizePanelRef.current(logoAtPoint);
|
|
18138
|
+
return;
|
|
18139
|
+
}
|
|
16889
18140
|
const textEditable = Array.from(
|
|
16890
18141
|
document.querySelectorAll(NON_MEDIA_SELECTOR)
|
|
16891
18142
|
).find((el) => {
|
|
@@ -16957,6 +18208,14 @@ function OhhwellsBridge() {
|
|
|
16957
18208
|
window.addEventListener("message", handleParentScroll);
|
|
16958
18209
|
window.addEventListener("message", handlePointerSync);
|
|
16959
18210
|
window.addEventListener("message", handleClickAt);
|
|
18211
|
+
window.addEventListener("message", handleUpdateLogoIdentity);
|
|
18212
|
+
const handleViewMode = (e) => {
|
|
18213
|
+
if (e.data?.type !== "ow:view-mode") return;
|
|
18214
|
+
const mode = e.data.mode === "Mobile" || e.data.mode === "mobile" ? "mobile" : "desktop";
|
|
18215
|
+
setEditorViewport(mode);
|
|
18216
|
+
applyLogoSizes(editContentRef.current);
|
|
18217
|
+
};
|
|
18218
|
+
window.addEventListener("message", handleViewMode);
|
|
16960
18219
|
const handleViewportResize = () => {
|
|
16961
18220
|
if (visibleViewportRef.current) {
|
|
16962
18221
|
applyVisibleViewport(visibleViewportRef.current, parentScrollRef.current);
|
|
@@ -17012,10 +18271,15 @@ function OhhwellsBridge() {
|
|
|
17012
18271
|
window.removeEventListener("resize", handleViewportResize);
|
|
17013
18272
|
window.removeEventListener("message", handlePointerSync);
|
|
17014
18273
|
window.removeEventListener("message", handleClickAt);
|
|
18274
|
+
window.removeEventListener("message", handleUpdateLogoIdentity);
|
|
18275
|
+
window.removeEventListener("message", handleViewMode);
|
|
17015
18276
|
window.removeEventListener("message", handleHydrate);
|
|
17016
18277
|
window.removeEventListener("message", handleAiApplyTree);
|
|
17017
18278
|
window.removeEventListener("message", handleAiDeleteSection);
|
|
17018
18279
|
window.removeEventListener("message", handleAiSetSections);
|
|
18280
|
+
window.removeEventListener("message", handleAiSetBrand);
|
|
18281
|
+
window.removeEventListener("message", handleAiSetStyles);
|
|
18282
|
+
window.removeEventListener("message", handleGetBrand);
|
|
17019
18283
|
window.removeEventListener("message", handleDeactivate);
|
|
17020
18284
|
window.removeEventListener("message", handleToastAction);
|
|
17021
18285
|
window.removeEventListener("message", handleUiEscape);
|
|
@@ -17219,7 +18483,7 @@ function OhhwellsBridge() {
|
|
|
17219
18483
|
postToParent2({
|
|
17220
18484
|
type: "ow:ready",
|
|
17221
18485
|
version: "1",
|
|
17222
|
-
bridgeVersion: "0.1.
|
|
18486
|
+
bridgeVersion: "0.1.61",
|
|
17223
18487
|
path: pathname,
|
|
17224
18488
|
nodes: collectEditableNodes(editContentRef.current),
|
|
17225
18489
|
sections
|
|
@@ -17614,10 +18878,10 @@ function OhhwellsBridge() {
|
|
|
17614
18878
|
[postToParent2]
|
|
17615
18879
|
);
|
|
17616
18880
|
return bridgeRoot ? createPortal2(
|
|
17617
|
-
/* @__PURE__ */
|
|
17618
|
-
/* @__PURE__ */
|
|
17619
|
-
isEditMode && /* @__PURE__ */
|
|
17620
|
-
Object.entries(uploadingRects).map(([key, { rect, fadingOut }]) => /* @__PURE__ */
|
|
18881
|
+
/* @__PURE__ */ jsxs20(Fragment8, { children: [
|
|
18882
|
+
/* @__PURE__ */ jsx33("div", { ref: attachVisibleViewport, "data-ohw-visible-viewport": "", "aria-hidden": true }),
|
|
18883
|
+
isEditMode && /* @__PURE__ */ jsx33(AiSectionOverlay, { postToParent: postToParent2, apiRef: aiSectionApiRef }),
|
|
18884
|
+
Object.entries(uploadingRects).map(([key, { rect, fadingOut }]) => /* @__PURE__ */ jsx33(
|
|
17621
18885
|
MediaOverlay,
|
|
17622
18886
|
{
|
|
17623
18887
|
hover: { key, rect, elementType: "image", isDragOver: false, hasTextOverlap: false },
|
|
@@ -17628,7 +18892,7 @@ function OhhwellsBridge() {
|
|
|
17628
18892
|
},
|
|
17629
18893
|
`uploading-${key}`
|
|
17630
18894
|
)),
|
|
17631
|
-
mediaHover && !(mediaHover.key in uploadingRects) && /* @__PURE__ */
|
|
18895
|
+
mediaHover && !(mediaHover.key in uploadingRects) && /* @__PURE__ */ jsx33(
|
|
17632
18896
|
MediaOverlay,
|
|
17633
18897
|
{
|
|
17634
18898
|
hover: mediaHover,
|
|
@@ -17637,11 +18901,11 @@ function OhhwellsBridge() {
|
|
|
17637
18901
|
onVideoSettingsChange: handleVideoSettingsChange
|
|
17638
18902
|
}
|
|
17639
18903
|
),
|
|
17640
|
-
carouselHover && !linkPopover && !isItemDragging && /* @__PURE__ */
|
|
17641
|
-
siblingHintRect && !linkPopover && !isItemDragging && siblingHintRects.length === 0 && /* @__PURE__ */
|
|
17642
|
-
siblingHintRects.length > 0 && !linkPopover && !isItemDragging && siblingHintRects.map((rect, i) => /* @__PURE__ */
|
|
17643
|
-
isItemDragging && draggedItemRect && selectedElRef.current !== footerDragRef.current?.draggedEl && selectedElRef.current !== navDragRef.current?.draggedEl && /* @__PURE__ */
|
|
17644
|
-
isItemDragging && footerDropSlots.map((slot, i) => /* @__PURE__ */
|
|
18904
|
+
carouselHover && !linkPopover && !isItemDragging && /* @__PURE__ */ jsx33(CarouselOverlay, { hover: carouselHover, onEdit: handleEditCarousel }),
|
|
18905
|
+
siblingHintRect && !linkPopover && !isItemDragging && siblingHintRects.length === 0 && /* @__PURE__ */ jsx33(ItemInteractionLayer, { rect: siblingHintRect, state: "sibling-hint" }),
|
|
18906
|
+
siblingHintRects.length > 0 && !linkPopover && !isItemDragging && siblingHintRects.map((rect, i) => /* @__PURE__ */ jsx33(ItemInteractionLayer, { rect, state: "sibling-hint" }, `sibling-hint-${i}`)),
|
|
18907
|
+
isItemDragging && draggedItemRect && selectedElRef.current !== footerDragRef.current?.draggedEl && selectedElRef.current !== navDragRef.current?.draggedEl && /* @__PURE__ */ jsx33(ItemInteractionLayer, { rect: draggedItemRect, state: "dragging" }),
|
|
18908
|
+
isItemDragging && footerDropSlots.map((slot, i) => /* @__PURE__ */ jsx33(
|
|
17645
18909
|
"div",
|
|
17646
18910
|
{
|
|
17647
18911
|
className: "pointer-events-none fixed z-2147483646",
|
|
@@ -17651,7 +18915,7 @@ function OhhwellsBridge() {
|
|
|
17651
18915
|
width: slot.width,
|
|
17652
18916
|
height: slot.height
|
|
17653
18917
|
},
|
|
17654
|
-
children: /* @__PURE__ */
|
|
18918
|
+
children: /* @__PURE__ */ jsx33(
|
|
17655
18919
|
DropIndicator,
|
|
17656
18920
|
{
|
|
17657
18921
|
direction: slot.direction,
|
|
@@ -17662,7 +18926,7 @@ function OhhwellsBridge() {
|
|
|
17662
18926
|
},
|
|
17663
18927
|
`footer-drop-${slot.direction}-${slot.columnIndex}-${slot.insertIndex}-${i}`
|
|
17664
18928
|
)),
|
|
17665
|
-
isItemDragging && navDropSlots.map((slot, i) => /* @__PURE__ */
|
|
18929
|
+
isItemDragging && navDropSlots.map((slot, i) => /* @__PURE__ */ jsx33(
|
|
17666
18930
|
"div",
|
|
17667
18931
|
{
|
|
17668
18932
|
className: "pointer-events-none fixed z-2147483646",
|
|
@@ -17672,7 +18936,7 @@ function OhhwellsBridge() {
|
|
|
17672
18936
|
width: slot.width,
|
|
17673
18937
|
height: slot.height
|
|
17674
18938
|
},
|
|
17675
|
-
children: /* @__PURE__ */
|
|
18939
|
+
children: /* @__PURE__ */ jsx33(
|
|
17676
18940
|
DropIndicator,
|
|
17677
18941
|
{
|
|
17678
18942
|
direction: slot.direction,
|
|
@@ -17683,11 +18947,11 @@ function OhhwellsBridge() {
|
|
|
17683
18947
|
},
|
|
17684
18948
|
`nav-drop-${slot.direction}-${slot.parentId ?? "root"}-${slot.insertIndex}-${i}`
|
|
17685
18949
|
)),
|
|
17686
|
-
hoveredNavContainerRect && (toolbarVariant !== "select-frame" || isFooterFrameSelection) && !linkPopover && !isItemDragging && /* @__PURE__ */
|
|
17687
|
-
hoveredItemRect && !linkPopover && !hoveredNavContainerRect && !isItemDragging && hoveredItemElRef.current !== selectedElRef.current && /* @__PURE__ */
|
|
17688
|
-
hoveredTextRect && !isItemDragging && toolbarVariant !== "rich-text" && /* @__PURE__ */
|
|
17689
|
-
toolbarVariant === "select-frame" && toolbarRect && !linkPopover && !isItemDragging && !isFooterFrameSelection && selectedElRef.current && isNavbarLinksContainer2(selectedElRef.current) && /* @__PURE__ */
|
|
17690
|
-
toolbarVariant === "select-frame" && toolbarRect && !linkPopover && !isItemDragging && !isFooterFrameSelection && selectedElRef.current && isFooterLinksContainer(selectedElRef.current) && /* @__PURE__ */
|
|
18950
|
+
hoveredNavContainerRect && (toolbarVariant !== "select-frame" || isFooterFrameSelection) && !linkPopover && !isItemDragging && /* @__PURE__ */ jsx33(ItemInteractionLayer, { rect: hoveredNavContainerRect, state: "hover" }),
|
|
18951
|
+
hoveredItemRect && !linkPopover && !hoveredNavContainerRect && !isItemDragging && hoveredItemElRef.current !== selectedElRef.current && /* @__PURE__ */ jsx33(ItemInteractionLayer, { rect: hoveredItemRect, state: "hover" }),
|
|
18952
|
+
hoveredTextRect && !isItemDragging && toolbarVariant !== "rich-text" && /* @__PURE__ */ jsx33(ItemInteractionLayer, { rect: hoveredTextRect, state: "hover" }),
|
|
18953
|
+
toolbarVariant === "select-frame" && toolbarRect && !linkPopover && !isItemDragging && !isFooterFrameSelection && selectedElRef.current && isNavbarLinksContainer2(selectedElRef.current) && /* @__PURE__ */ jsx33(NavbarContainerChrome, { rect: toolbarRect, onAdd: handleAddTopLevelNavItem }),
|
|
18954
|
+
toolbarVariant === "select-frame" && toolbarRect && !linkPopover && !isItemDragging && !isFooterFrameSelection && selectedElRef.current && isFooterLinksContainer(selectedElRef.current) && /* @__PURE__ */ jsx33(
|
|
17691
18955
|
FooterContainerChrome,
|
|
17692
18956
|
{
|
|
17693
18957
|
rect: toolbarRect,
|
|
@@ -17695,7 +18959,7 @@ function OhhwellsBridge() {
|
|
|
17695
18959
|
addDisabled: !canAddFooterColumn()
|
|
17696
18960
|
}
|
|
17697
18961
|
),
|
|
17698
|
-
toolbarRect && !linkPopover && (toolbarVariant === "link-action" || toolbarVariant === "select-frame") && /* @__PURE__ */
|
|
18962
|
+
toolbarRect && !linkPopover && (toolbarVariant === "link-action" || toolbarVariant === "select-frame" || toolbarVariant === "logo") && /* @__PURE__ */ jsx33(
|
|
17699
18963
|
ItemInteractionLayer,
|
|
17700
18964
|
{
|
|
17701
18965
|
rect: isItemDragging && draggedItemRect && (footerDragRef.current?.wasSelected || navDragRef.current?.wasSelected) ? draggedItemRect : toolbarRect,
|
|
@@ -17707,10 +18971,10 @@ function OhhwellsBridge() {
|
|
|
17707
18971
|
dragHandleLabel: reorderHrefKey ? `Reorder ${reorderHrefKey}` : "Reorder item",
|
|
17708
18972
|
onDragHandleDragStart: handleItemDragStart,
|
|
17709
18973
|
onDragHandleDragEnd: handleItemDragEnd,
|
|
17710
|
-
onItemPointerDown: handleItemChromePointerDown,
|
|
17711
|
-
onItemClick: handleItemChromeClick,
|
|
17712
|
-
itemDragSurface: !isFooterFrameSelection,
|
|
17713
|
-
toolbar: toolbarVariant === "link-action" && !isItemDragging || toolbarVariant === "select-frame" && (isFooterFrameSelection || selectedIsSocialsRow) && !isItemDragging ? /* @__PURE__ */
|
|
18974
|
+
onItemPointerDown: toolbarVariant === "logo" ? void 0 : handleItemChromePointerDown,
|
|
18975
|
+
onItemClick: toolbarVariant === "logo" ? void 0 : handleItemChromeClick,
|
|
18976
|
+
itemDragSurface: toolbarVariant !== "logo" && !isFooterFrameSelection,
|
|
18977
|
+
toolbar: toolbarVariant === "link-action" && !isItemDragging || toolbarVariant === "select-frame" && (isFooterFrameSelection || selectedIsSocialsRow) && !isItemDragging ? /* @__PURE__ */ jsx33(
|
|
17714
18978
|
ItemActionToolbar,
|
|
17715
18979
|
{
|
|
17716
18980
|
onEditLink: openLinkPopoverForSelected,
|
|
@@ -17746,8 +19010,8 @@ function OhhwellsBridge() {
|
|
|
17746
19010
|
) : void 0
|
|
17747
19011
|
}
|
|
17748
19012
|
),
|
|
17749
|
-
toolbarRect && toolbarVariant === "rich-text" && !linkPopover && /* @__PURE__ */
|
|
17750
|
-
/* @__PURE__ */
|
|
19013
|
+
toolbarRect && toolbarVariant === "rich-text" && !linkPopover && /* @__PURE__ */ jsxs20(Fragment8, { children: [
|
|
19014
|
+
/* @__PURE__ */ jsx33(
|
|
17751
19015
|
EditGlowChrome,
|
|
17752
19016
|
{
|
|
17753
19017
|
rect: toolbarRect,
|
|
@@ -17757,7 +19021,7 @@ function OhhwellsBridge() {
|
|
|
17757
19021
|
hideHandle: isItemDragging
|
|
17758
19022
|
}
|
|
17759
19023
|
),
|
|
17760
|
-
/* @__PURE__ */
|
|
19024
|
+
/* @__PURE__ */ jsx33(
|
|
17761
19025
|
FloatingToolbar,
|
|
17762
19026
|
{
|
|
17763
19027
|
rect: toolbarRect,
|
|
@@ -17770,7 +19034,7 @@ function OhhwellsBridge() {
|
|
|
17770
19034
|
}
|
|
17771
19035
|
)
|
|
17772
19036
|
] }),
|
|
17773
|
-
maxBadge && /* @__PURE__ */
|
|
19037
|
+
maxBadge && /* @__PURE__ */ jsxs20(
|
|
17774
19038
|
"div",
|
|
17775
19039
|
{
|
|
17776
19040
|
"data-ohw-max-badge": "",
|
|
@@ -17796,7 +19060,7 @@ function OhhwellsBridge() {
|
|
|
17796
19060
|
]
|
|
17797
19061
|
}
|
|
17798
19062
|
),
|
|
17799
|
-
toggleState && !linkPopover && /* @__PURE__ */
|
|
19063
|
+
toggleState && !linkPopover && /* @__PURE__ */ jsx33(
|
|
17800
19064
|
StateToggle,
|
|
17801
19065
|
{
|
|
17802
19066
|
rect: toggleState.rect,
|
|
@@ -17805,15 +19069,15 @@ function OhhwellsBridge() {
|
|
|
17805
19069
|
onStateChange: handleStateChange
|
|
17806
19070
|
}
|
|
17807
19071
|
),
|
|
17808
|
-
sectionGap && !linkPopover && /* @__PURE__ */
|
|
19072
|
+
sectionGap && !linkPopover && /* @__PURE__ */ jsxs20(
|
|
17809
19073
|
"div",
|
|
17810
19074
|
{
|
|
17811
19075
|
"data-ohw-section-insert-line": "",
|
|
17812
19076
|
className: "fixed left-0 w-full z-2147483646 flex items-center pointer-events-none",
|
|
17813
19077
|
style: { top: sectionGap.y, transform: "translateY(-50%)" },
|
|
17814
19078
|
children: [
|
|
17815
|
-
/* @__PURE__ */
|
|
17816
|
-
/* @__PURE__ */
|
|
19079
|
+
/* @__PURE__ */ jsx33("div", { className: "flex-1 bg-primary", style: { height: 3 } }),
|
|
19080
|
+
/* @__PURE__ */ jsx33(
|
|
17817
19081
|
Badge,
|
|
17818
19082
|
{
|
|
17819
19083
|
className: "px-8 py-1 bg-primary hover:bg-primary text-primary-foreground text-xs font-medium shrink-0 rounded-full cursor-pointer pointer-events-auto",
|
|
@@ -17830,11 +19094,11 @@ function OhhwellsBridge() {
|
|
|
17830
19094
|
children: "Add Section"
|
|
17831
19095
|
}
|
|
17832
19096
|
),
|
|
17833
|
-
/* @__PURE__ */
|
|
19097
|
+
/* @__PURE__ */ jsx33("div", { className: "flex-1 bg-primary", style: { height: 3 } })
|
|
17834
19098
|
]
|
|
17835
19099
|
}
|
|
17836
19100
|
),
|
|
17837
|
-
linkPopover && dialogPortalContainer ? /* @__PURE__ */
|
|
19101
|
+
linkPopover && dialogPortalContainer ? /* @__PURE__ */ jsx33(
|
|
17838
19102
|
LinkPopover,
|
|
17839
19103
|
{
|
|
17840
19104
|
panelRef: linkPopoverPanelRef,
|
|
@@ -17851,7 +19115,7 @@ function OhhwellsBridge() {
|
|
|
17851
19115
|
},
|
|
17852
19116
|
linkPopover.key
|
|
17853
19117
|
) : null,
|
|
17854
|
-
floatingPanel && floatingPanel.kind === "socials-display" ? /* @__PURE__ */
|
|
19118
|
+
floatingPanel && floatingPanel.kind === "socials-display" ? /* @__PURE__ */ jsx33(
|
|
17855
19119
|
FloatingPanel,
|
|
17856
19120
|
{
|
|
17857
19121
|
open: true,
|
|
@@ -17861,7 +19125,7 @@ function OhhwellsBridge() {
|
|
|
17861
19125
|
onPositionChange: setFloatingPanelPos,
|
|
17862
19126
|
parentScroll: parentScrollSnap ?? parentScrollRef.current,
|
|
17863
19127
|
onClose: closeFloatingPanelOnly,
|
|
17864
|
-
children: /* @__PURE__ */
|
|
19128
|
+
children: /* @__PURE__ */ jsx33(
|
|
17865
19129
|
SocialsDisplayPanel,
|
|
17866
19130
|
{
|
|
17867
19131
|
display: socialsDisplayFor(floatingPanel.row, editContentRef.current),
|
|
@@ -17872,11 +19136,115 @@ function OhhwellsBridge() {
|
|
|
17872
19136
|
}
|
|
17873
19137
|
)
|
|
17874
19138
|
}
|
|
19139
|
+
) : null,
|
|
19140
|
+
floatingPanel && floatingPanel.kind === "logo-size" && logoSizeDraft ? /* @__PURE__ */ jsx33(
|
|
19141
|
+
FloatingPanel,
|
|
19142
|
+
{
|
|
19143
|
+
open: true,
|
|
19144
|
+
title: floatingPanel.title,
|
|
19145
|
+
context: floatingPanel.context,
|
|
19146
|
+
position: floatingPanelPos,
|
|
19147
|
+
onPositionChange: setFloatingPanelPos,
|
|
19148
|
+
parentScroll: parentScrollSnap ?? parentScrollRef.current,
|
|
19149
|
+
onClose: closeFloatingPanelAndDeselect,
|
|
19150
|
+
children: /* @__PURE__ */ jsx33(
|
|
19151
|
+
LogoSizePanel,
|
|
19152
|
+
{
|
|
19153
|
+
viewport: editorViewport,
|
|
19154
|
+
sizePx: editorViewport === "mobile" && !logoSizeDraft.mobileFollowing ? logoSizeDraft.mobilePx : logoSizeDraft.desktopPx,
|
|
19155
|
+
mobileFollowing: logoSizeDraft.mobileFollowing,
|
|
19156
|
+
onSizeChange: (px) => {
|
|
19157
|
+
const next = editorViewport === "mobile" ? { ...logoSizeDraft, mobilePx: px, mobileFollowing: false } : {
|
|
19158
|
+
...logoSizeDraft,
|
|
19159
|
+
desktopPx: px,
|
|
19160
|
+
mobilePx: logoSizeDraft.mobileFollowing ? px : logoSizeDraft.mobilePx
|
|
19161
|
+
};
|
|
19162
|
+
setLogoSizeDraft(next);
|
|
19163
|
+
persistLogoSizeDraft(floatingPanel.placement, next);
|
|
19164
|
+
},
|
|
19165
|
+
onCustomizeMobile: () => {
|
|
19166
|
+
const next = {
|
|
19167
|
+
...logoSizeDraft,
|
|
19168
|
+
mobileFollowing: false,
|
|
19169
|
+
mobilePx: logoSizeDraft.desktopPx
|
|
19170
|
+
};
|
|
19171
|
+
setLogoSizeDraft(next);
|
|
19172
|
+
persistLogoSizeDraft(floatingPanel.placement, next);
|
|
19173
|
+
},
|
|
19174
|
+
onResetMobile: () => {
|
|
19175
|
+
const next = {
|
|
19176
|
+
...logoSizeDraft,
|
|
19177
|
+
mobileFollowing: true,
|
|
19178
|
+
mobilePx: logoSizeDraft.desktopPx
|
|
19179
|
+
};
|
|
19180
|
+
setLogoSizeDraft(next);
|
|
19181
|
+
persistLogoSizeDraft(floatingPanel.placement, next);
|
|
19182
|
+
},
|
|
19183
|
+
onUpdateEverywhere: () => {
|
|
19184
|
+
const identity = readLogoIdentityFromDom();
|
|
19185
|
+
postToParent2({ type: "ow:open-logo-settings", ...identity });
|
|
19186
|
+
}
|
|
19187
|
+
}
|
|
19188
|
+
)
|
|
19189
|
+
}
|
|
17875
19190
|
) : null
|
|
17876
19191
|
] }),
|
|
17877
19192
|
bridgeRoot
|
|
17878
19193
|
) : null;
|
|
17879
19194
|
}
|
|
19195
|
+
|
|
19196
|
+
// src/ui/EmptySection.tsx
|
|
19197
|
+
import Link4 from "next/link";
|
|
19198
|
+
import { Fragment as Fragment9, jsx as jsx34, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
19199
|
+
function EmptySection({ title, homeHref = "/", eyebrowKey, titleKey, subtitleKey }) {
|
|
19200
|
+
return /* @__PURE__ */ jsxs21(Fragment9, { children: [
|
|
19201
|
+
/* @__PURE__ */ jsx34(
|
|
19202
|
+
"p",
|
|
19203
|
+
{
|
|
19204
|
+
style: {
|
|
19205
|
+
fontFamily: "var(--brand-font-body)",
|
|
19206
|
+
fontSize: "0.75rem",
|
|
19207
|
+
fontWeight: 500,
|
|
19208
|
+
letterSpacing: "0.15em",
|
|
19209
|
+
textTransform: "uppercase",
|
|
19210
|
+
color: "var(--brand-accent)",
|
|
19211
|
+
marginBottom: "1.5rem"
|
|
19212
|
+
},
|
|
19213
|
+
children: /* @__PURE__ */ jsx34(Link4, { href: homeHref, style: { color: "inherit" }, children: /* @__PURE__ */ jsx34("span", { ...eyebrowKey ? { "data-ohw-editable": "text", "data-ohw-key": eyebrowKey } : {}, children: "Home" }) })
|
|
19214
|
+
}
|
|
19215
|
+
),
|
|
19216
|
+
/* @__PURE__ */ jsx34(
|
|
19217
|
+
"h1",
|
|
19218
|
+
{
|
|
19219
|
+
style: {
|
|
19220
|
+
fontFamily: "var(--brand-font-heading)",
|
|
19221
|
+
fontSize: "clamp(2rem, 3.5vw, 2.75rem)",
|
|
19222
|
+
lineHeight: 1.1,
|
|
19223
|
+
letterSpacing: "-0.025em",
|
|
19224
|
+
color: "var(--brand-text)",
|
|
19225
|
+
marginBottom: "1rem"
|
|
19226
|
+
},
|
|
19227
|
+
...titleKey ? { "data-ohw-editable": "text", "data-ohw-key": titleKey, "data-ohw-max-length": 80 } : {},
|
|
19228
|
+
children: title
|
|
19229
|
+
}
|
|
19230
|
+
),
|
|
19231
|
+
/* @__PURE__ */ jsx34(
|
|
19232
|
+
"p",
|
|
19233
|
+
{
|
|
19234
|
+
style: {
|
|
19235
|
+
fontFamily: "var(--brand-font-body)",
|
|
19236
|
+
fontSize: "1rem",
|
|
19237
|
+
lineHeight: 1.7,
|
|
19238
|
+
fontWeight: 300,
|
|
19239
|
+
color: "var(--brand-text-muted)",
|
|
19240
|
+
maxWidth: "340px"
|
|
19241
|
+
},
|
|
19242
|
+
...subtitleKey ? { "data-ohw-editable": "text", "data-ohw-key": subtitleKey, "data-ohw-max-length": 160 } : {},
|
|
19243
|
+
children: "This page doesn't have any content yet."
|
|
19244
|
+
}
|
|
19245
|
+
)
|
|
19246
|
+
] });
|
|
19247
|
+
}
|
|
17880
19248
|
export {
|
|
17881
19249
|
AI_DEFAULT_BRAND,
|
|
17882
19250
|
AI_TREE_SCHEMA_VERSIONS,
|
|
@@ -17893,6 +19261,7 @@ export {
|
|
|
17893
19261
|
DropdownMenuItem,
|
|
17894
19262
|
DropdownMenuSeparator,
|
|
17895
19263
|
DropdownMenuTrigger,
|
|
19264
|
+
EmptySection,
|
|
17896
19265
|
ItemActionToolbar,
|
|
17897
19266
|
ItemInteractionLayer,
|
|
17898
19267
|
LinkEditorPanel,
|