@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.cjs
CHANGED
|
@@ -46,6 +46,7 @@ __export(index_exports, {
|
|
|
46
46
|
DropdownMenuItem: () => DropdownMenuItem,
|
|
47
47
|
DropdownMenuSeparator: () => DropdownMenuSeparator,
|
|
48
48
|
DropdownMenuTrigger: () => DropdownMenuTrigger,
|
|
49
|
+
EmptySection: () => EmptySection,
|
|
49
50
|
ItemActionToolbar: () => ItemActionToolbar,
|
|
50
51
|
ItemInteractionLayer: () => ItemInteractionLayer,
|
|
51
52
|
LinkEditorPanel: () => LinkEditorPanel,
|
|
@@ -169,6 +170,7 @@ function applyTreeToState(state, payload) {
|
|
|
169
170
|
const entry = {
|
|
170
171
|
id: payload.id,
|
|
171
172
|
label: payload.label ?? "Generated section",
|
|
173
|
+
...typeof payload.path === "string" && payload.path ? { path: payload.path } : {},
|
|
172
174
|
afterSection: payload.mode === "insert" && !insertBefore ? payload.targetSectionId ?? null : null,
|
|
173
175
|
...insertBefore && payload.targetSectionId ? { beforeSection: payload.targetSectionId } : {},
|
|
174
176
|
...payload.mode === "replace" && payload.targetSectionId ? { replaces: payload.targetSectionId } : {},
|
|
@@ -191,6 +193,287 @@ function deleteSectionFromState(state, sectionId) {
|
|
|
191
193
|
return { ...state, v: 1, sections: state.sections, removed: [...removed, sectionId] };
|
|
192
194
|
}
|
|
193
195
|
|
|
196
|
+
// src/lib/brand-chrome.ts
|
|
197
|
+
var BRAND_NAME_KEY = "__ohw_brand_name";
|
|
198
|
+
var BRAND_TITLE_KEY = "__ohw_site_title";
|
|
199
|
+
var BRAND_FAVICON_LETTER_KEY = "__ohw_favicon_letter";
|
|
200
|
+
var BRAND_CHROME_KEYS = /* @__PURE__ */ new Set([
|
|
201
|
+
BRAND_NAME_KEY,
|
|
202
|
+
BRAND_TITLE_KEY,
|
|
203
|
+
BRAND_FAVICON_LETTER_KEY
|
|
204
|
+
]);
|
|
205
|
+
function upsertMeta(selector, attr, token, value) {
|
|
206
|
+
let el = document.head.querySelector(selector);
|
|
207
|
+
if (!el) {
|
|
208
|
+
el = document.createElement("meta");
|
|
209
|
+
el.setAttribute(attr, token);
|
|
210
|
+
document.head.appendChild(el);
|
|
211
|
+
}
|
|
212
|
+
if (el.getAttribute("content") !== value) el.setAttribute("content", value);
|
|
213
|
+
}
|
|
214
|
+
function escapeXml(value) {
|
|
215
|
+
return value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
216
|
+
}
|
|
217
|
+
function applyLetterFavicon(letter) {
|
|
218
|
+
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>`;
|
|
219
|
+
const href = `data:image/svg+xml,${encodeURIComponent(svg)}`;
|
|
220
|
+
let link = document.head.querySelector('link[rel="icon"]');
|
|
221
|
+
if (!link) {
|
|
222
|
+
link = document.createElement("link");
|
|
223
|
+
link.rel = "icon";
|
|
224
|
+
document.head.appendChild(link);
|
|
225
|
+
}
|
|
226
|
+
link.type = "image/svg+xml";
|
|
227
|
+
if (link.href !== href) link.href = href;
|
|
228
|
+
}
|
|
229
|
+
function applyBrandChrome(content) {
|
|
230
|
+
const name = content[BRAND_NAME_KEY];
|
|
231
|
+
if (typeof name === "string" && name.length > 0) {
|
|
232
|
+
document.querySelectorAll("[data-ohw-wordmark]").forEach((el) => {
|
|
233
|
+
if (el.textContent !== name) el.textContent = name;
|
|
234
|
+
if (el.getAttribute("title") !== name) el.setAttribute("title", name);
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
const title = content[BRAND_TITLE_KEY];
|
|
238
|
+
if (typeof title === "string" && title.length > 0) {
|
|
239
|
+
if (document.title !== title) document.title = title;
|
|
240
|
+
upsertMeta('meta[property="og:title"]', "property", "og:title", title);
|
|
241
|
+
upsertMeta('meta[name="twitter:title"]', "name", "twitter:title", title);
|
|
242
|
+
}
|
|
243
|
+
const letter = content[BRAND_FAVICON_LETTER_KEY];
|
|
244
|
+
if (typeof letter === "string" && letter.length > 0) {
|
|
245
|
+
applyLetterFavicon(letter);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
// src/lib/brand-kit.ts
|
|
250
|
+
var BRAND_KIT_KEY = "__ohw_brand";
|
|
251
|
+
var BRAND_VAR_PREFIX = "--ohw-brand-";
|
|
252
|
+
var BRAND_VAR_NAMES = ["primary", "accent", "light", "dark", "surface", "border", "muted"].map(
|
|
253
|
+
(role) => `${BRAND_VAR_PREFIX}${role}`
|
|
254
|
+
);
|
|
255
|
+
var FONT_VARS = { heading: ["--font-heading", "--font-display"], body: ["--font-body"] };
|
|
256
|
+
var BRAND_FONT_LINK_ID = "ohw-brand-fonts";
|
|
257
|
+
function brandColorVars(kit) {
|
|
258
|
+
const { dark, primary, accent, light } = kit.palette;
|
|
259
|
+
const mix = (a, aPct, b) => `color-mix(in srgb, ${a} ${aPct}%, ${b})`;
|
|
260
|
+
return {
|
|
261
|
+
[`${BRAND_VAR_PREFIX}primary`]: primary,
|
|
262
|
+
[`${BRAND_VAR_PREFIX}accent`]: accent,
|
|
263
|
+
[`${BRAND_VAR_PREFIX}light`]: light,
|
|
264
|
+
[`${BRAND_VAR_PREFIX}dark`]: dark,
|
|
265
|
+
[`${BRAND_VAR_PREFIX}surface`]: mix(light, 95, dark),
|
|
266
|
+
[`${BRAND_VAR_PREFIX}border`]: mix(light, 85, dark),
|
|
267
|
+
[`${BRAND_VAR_PREFIX}muted`]: mix(dark, 62, light)
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
function parseBrandKit(raw) {
|
|
271
|
+
if (!raw) return null;
|
|
272
|
+
try {
|
|
273
|
+
const parsed = JSON.parse(raw);
|
|
274
|
+
const p = parsed?.palette;
|
|
275
|
+
const f = parsed?.fonts;
|
|
276
|
+
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") {
|
|
277
|
+
return null;
|
|
278
|
+
}
|
|
279
|
+
return {
|
|
280
|
+
palette: { dark: p.dark, primary: p.primary, accent: p.accent, light: p.light },
|
|
281
|
+
fonts: { heading: f.heading, body: f.body }
|
|
282
|
+
};
|
|
283
|
+
} catch {
|
|
284
|
+
return null;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
function familyOf(stack) {
|
|
288
|
+
const first = stack.split(",")[0]?.trim() ?? "";
|
|
289
|
+
return first.replace(/^['"]|['"]$/g, "");
|
|
290
|
+
}
|
|
291
|
+
function loadBrandFonts(families) {
|
|
292
|
+
const unique = [...new Set(families.map((f) => f.trim()).filter(Boolean))];
|
|
293
|
+
if (unique.length === 0) return;
|
|
294
|
+
const spec = unique.map((f) => `${f.replace(/ /g, "+")}:400,500,600,700`).join("|");
|
|
295
|
+
const href = `https://fonts.googleapis.com/css?family=${spec}&display=swap`;
|
|
296
|
+
let link = document.getElementById(BRAND_FONT_LINK_ID);
|
|
297
|
+
if (!link) {
|
|
298
|
+
link = document.createElement("link");
|
|
299
|
+
link.id = BRAND_FONT_LINK_ID;
|
|
300
|
+
link.rel = "stylesheet";
|
|
301
|
+
document.head.appendChild(link);
|
|
302
|
+
}
|
|
303
|
+
if (link.href !== href) link.href = href;
|
|
304
|
+
}
|
|
305
|
+
function applyBrandToDom(kit) {
|
|
306
|
+
const root = document.documentElement;
|
|
307
|
+
if (!kit) {
|
|
308
|
+
for (const name of BRAND_VAR_NAMES) root.style.removeProperty(name);
|
|
309
|
+
for (const name of [...FONT_VARS.heading, ...FONT_VARS.body]) root.style.removeProperty(name);
|
|
310
|
+
document.getElementById(BRAND_FONT_LINK_ID)?.remove();
|
|
311
|
+
return;
|
|
312
|
+
}
|
|
313
|
+
for (const [name, value] of Object.entries(brandColorVars(kit))) root.style.setProperty(name, value);
|
|
314
|
+
for (const name of FONT_VARS.heading) root.style.setProperty(name, kit.fonts.heading);
|
|
315
|
+
for (const name of FONT_VARS.body) root.style.setProperty(name, kit.fonts.body);
|
|
316
|
+
loadBrandFonts([familyOf(kit.fonts.heading), familyOf(kit.fonts.body)]);
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
// src/lib/section-styles.ts
|
|
320
|
+
var STYLE_STORE_KEY = "__ohw_styles";
|
|
321
|
+
var STYLE_SHEET_ID = "ohw-section-styles";
|
|
322
|
+
function parseStyleStore(raw) {
|
|
323
|
+
if (!raw) return null;
|
|
324
|
+
try {
|
|
325
|
+
const parsed = JSON.parse(raw);
|
|
326
|
+
if (parsed?.v !== 1) return null;
|
|
327
|
+
return {
|
|
328
|
+
v: 1,
|
|
329
|
+
sections: typeof parsed.sections === "object" && parsed.sections ? parsed.sections : {},
|
|
330
|
+
nodes: typeof parsed.nodes === "object" && parsed.nodes ? parsed.nodes : {}
|
|
331
|
+
};
|
|
332
|
+
} catch {
|
|
333
|
+
return null;
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
var BG_VALUES = {
|
|
337
|
+
surface: "color-mix(in srgb, var(--ohw-brand-light, var(--color-light, #ECECEB)) 94%, var(--ohw-brand-dark, var(--color-dark, #0C0A09)))",
|
|
338
|
+
accent: "var(--ohw-brand-primary, var(--color-primary, #0078E5))",
|
|
339
|
+
"accent-soft": "color-mix(in srgb, var(--ohw-brand-primary, var(--color-primary, #0078E5)) 12%, var(--ohw-brand-light, var(--color-light, #FFFFFF)))"
|
|
340
|
+
};
|
|
341
|
+
var HEADLINE_SIZES = { md: 24, lg: 32, xl: 40, display: 56 };
|
|
342
|
+
function styleSheetCss() {
|
|
343
|
+
const rules = [];
|
|
344
|
+
for (const [tone, value] of Object.entries(BG_VALUES)) {
|
|
345
|
+
rules.push(`[data-ohw-style-bg="${tone}"] { background: ${value} !important; }`);
|
|
346
|
+
}
|
|
347
|
+
rules.push(
|
|
348
|
+
`[data-ohw-style-bg="accent"] { color: var(--ohw-brand-light, var(--color-light, #FFFFFF)) !important; }`
|
|
349
|
+
);
|
|
350
|
+
rules.push(
|
|
351
|
+
`[data-ohw-style-distribution="space-between"] { display: flex !important; flex-direction: column; justify-content: space-between; }`,
|
|
352
|
+
`[data-ohw-style-distribution="center"] { display: flex !important; flex-direction: column; justify-content: center; }`
|
|
353
|
+
);
|
|
354
|
+
for (const [scale, size] of Object.entries(HEADLINE_SIZES)) {
|
|
355
|
+
rules.push(
|
|
356
|
+
`[data-ohw-style-headline="${scale}"] :is(h1, h2, h3) { font-size: ${size}px !important; line-height: 1.15 !important; }`
|
|
357
|
+
);
|
|
358
|
+
}
|
|
359
|
+
rules.push(
|
|
360
|
+
`[data-ohw-style-aspect="fill-height"] img { height: 100% !important; aspect-ratio: auto !important; object-fit: cover; }`
|
|
361
|
+
);
|
|
362
|
+
for (const aspect of ["1:1", "4:5", "3:4", "3:2", "16:9", "2:1", "3:1"]) {
|
|
363
|
+
rules.push(
|
|
364
|
+
`[data-ohw-style-aspect="${aspect.replace(":", "-")}"] img { aspect-ratio: ${aspect.replace(":", " / ")} !important; height: auto !important; object-fit: cover; }`
|
|
365
|
+
);
|
|
366
|
+
}
|
|
367
|
+
const pad = { tight: 40, balanced: 64, airy: 96 };
|
|
368
|
+
for (const [spacing, px] of Object.entries(pad)) {
|
|
369
|
+
rules.push(
|
|
370
|
+
`[data-ohw-style-spacing="${spacing}"] { padding-top: ${px}px !important; padding-bottom: ${px}px !important; }`
|
|
371
|
+
);
|
|
372
|
+
}
|
|
373
|
+
return rules.join("\n");
|
|
374
|
+
}
|
|
375
|
+
var SECTION_ATTRS = {
|
|
376
|
+
sectionBackground: "data-ohw-style-bg",
|
|
377
|
+
textDistribution: "data-ohw-style-distribution",
|
|
378
|
+
headlineScale: "data-ohw-style-headline",
|
|
379
|
+
imageAspect: "data-ohw-style-aspect",
|
|
380
|
+
spacing: "data-ohw-style-spacing"
|
|
381
|
+
};
|
|
382
|
+
var NODE_WROTE_ATTR = "data-ohw-style-node";
|
|
383
|
+
var NODE_PROPS = ["color", "font-size", "background"];
|
|
384
|
+
function saveInline(el, prop) {
|
|
385
|
+
const attr = `data-ohw-style-prev-${prop}`;
|
|
386
|
+
if (!el.hasAttribute(attr)) el.setAttribute(attr, el.style.getPropertyValue(prop));
|
|
387
|
+
}
|
|
388
|
+
function restoreInline(el, prop) {
|
|
389
|
+
const attr = `data-ohw-style-prev-${prop}`;
|
|
390
|
+
if (!el.hasAttribute(attr)) return;
|
|
391
|
+
const prev = el.getAttribute(attr) ?? "";
|
|
392
|
+
if (prev) el.style.setProperty(prop, prev);
|
|
393
|
+
else el.style.removeProperty(prop);
|
|
394
|
+
el.removeAttribute(attr);
|
|
395
|
+
}
|
|
396
|
+
function ensureStyleSheet() {
|
|
397
|
+
let el = document.getElementById(STYLE_SHEET_ID);
|
|
398
|
+
if (!el) {
|
|
399
|
+
el = document.createElement("style");
|
|
400
|
+
el.id = STYLE_SHEET_ID;
|
|
401
|
+
document.head.appendChild(el);
|
|
402
|
+
}
|
|
403
|
+
const css = styleSheetCss();
|
|
404
|
+
if (el.textContent !== css) el.textContent = css;
|
|
405
|
+
}
|
|
406
|
+
function clearSectionAttrs(root) {
|
|
407
|
+
for (const attr of Object.values(SECTION_ATTRS)) {
|
|
408
|
+
for (const el of Array.from(root.querySelectorAll(`[${attr}]`))) el.removeAttribute(attr);
|
|
409
|
+
}
|
|
410
|
+
for (const el of Array.from(root.querySelectorAll("[data-ohw-style-bgcolor]"))) {
|
|
411
|
+
restoreInline(el, "background");
|
|
412
|
+
el.removeAttribute("data-ohw-style-bgcolor");
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
function clearNodeProps(root) {
|
|
416
|
+
for (const el of Array.from(root.querySelectorAll(`[${NODE_WROTE_ATTR}]`))) {
|
|
417
|
+
const h = el;
|
|
418
|
+
for (const prop of NODE_PROPS) restoreInline(h, prop);
|
|
419
|
+
h.removeAttribute(NODE_WROTE_ATTR);
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
function buttonSurfaceOf(el) {
|
|
423
|
+
return el.closest("a, button") ?? el;
|
|
424
|
+
}
|
|
425
|
+
function applyStylesToDom(store) {
|
|
426
|
+
ensureStyleSheet();
|
|
427
|
+
clearSectionAttrs(document);
|
|
428
|
+
clearNodeProps(document);
|
|
429
|
+
if (!store) return;
|
|
430
|
+
for (const [sectionId, override] of Object.entries(store.sections)) {
|
|
431
|
+
const sections = document.querySelectorAll(
|
|
432
|
+
`[data-ohw-section="${CSS.escape(sectionId)}"]`
|
|
433
|
+
);
|
|
434
|
+
for (const section of Array.from(sections)) {
|
|
435
|
+
for (const [prop, attr] of Object.entries(SECTION_ATTRS)) {
|
|
436
|
+
const value = override[prop];
|
|
437
|
+
if (value === void 0) continue;
|
|
438
|
+
if (prop === "sectionBackground" && override.sectionBackgroundColor !== void 0) continue;
|
|
439
|
+
section.setAttribute(attr, String(value).replace(":", "-"));
|
|
440
|
+
}
|
|
441
|
+
if (override.sectionBackgroundColor !== void 0) {
|
|
442
|
+
saveInline(section, "background");
|
|
443
|
+
section.style.setProperty("background", override.sectionBackgroundColor, "important");
|
|
444
|
+
section.setAttribute("data-ohw-style-bgcolor", "");
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
for (const [key, override] of Object.entries(store.nodes)) {
|
|
449
|
+
const nodes = document.querySelectorAll(`[data-ohw-key="${CSS.escape(key)}"]`);
|
|
450
|
+
for (const el of Array.from(nodes)) {
|
|
451
|
+
if (override.color !== void 0) {
|
|
452
|
+
saveInline(el, "color");
|
|
453
|
+
el.style.setProperty("color", override.color, "important");
|
|
454
|
+
el.setAttribute(NODE_WROTE_ATTR, "");
|
|
455
|
+
}
|
|
456
|
+
if (override.fontSize !== void 0) {
|
|
457
|
+
saveInline(el, "font-size");
|
|
458
|
+
el.style.setProperty("font-size", `${override.fontSize}px`, "important");
|
|
459
|
+
el.setAttribute(NODE_WROTE_ATTR, "");
|
|
460
|
+
}
|
|
461
|
+
if (override.buttonBackground !== void 0 || override.buttonText !== void 0) {
|
|
462
|
+
const surface = buttonSurfaceOf(el);
|
|
463
|
+
if (override.buttonBackground !== void 0) {
|
|
464
|
+
saveInline(surface, "background");
|
|
465
|
+
surface.style.setProperty("background", override.buttonBackground, "important");
|
|
466
|
+
}
|
|
467
|
+
if (override.buttonText !== void 0) {
|
|
468
|
+
saveInline(surface, "color");
|
|
469
|
+
surface.style.setProperty("color", override.buttonText, "important");
|
|
470
|
+
}
|
|
471
|
+
surface.setAttribute(NODE_WROTE_ATTR, "");
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
|
|
194
477
|
// src/ui/ai-tree/aiSectionsManager.tsx
|
|
195
478
|
var import_react_dom = require("react-dom");
|
|
196
479
|
var import_client = require("react-dom/client");
|
|
@@ -205,7 +488,8 @@ function lucideByName(name) {
|
|
|
205
488
|
}
|
|
206
489
|
var typeStyle = (spec, font) => ({
|
|
207
490
|
fontFamily: font,
|
|
208
|
-
|
|
491
|
+
// Headings shrink with the viewport (reaching full size around ~900px wide); body copy stays put.
|
|
492
|
+
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,
|
|
209
493
|
lineHeight: spec.line,
|
|
210
494
|
fontWeight: spec.weight
|
|
211
495
|
});
|
|
@@ -232,6 +516,8 @@ var AI_RESPONSIVE_CSS = [
|
|
|
232
516
|
" [data-ai-responsive] [data-ai-grid] { grid-template-columns: 1fr !important; }",
|
|
233
517
|
" [data-ai-responsive] [data-ai-columns] > * { grid-column: 1 / -1 !important; }",
|
|
234
518
|
" [data-ai-responsive] [data-ai-section-inner] { padding-left: 20px !important; padding-right: 20px !important; }",
|
|
519
|
+
" [data-ai-responsive] { overflow-x: hidden; }",
|
|
520
|
+
" [data-ai-responsive] img { max-width: 100%; }",
|
|
235
521
|
"}"
|
|
236
522
|
].join("\n");
|
|
237
523
|
var TRANSPARENT_PX = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7";
|
|
@@ -1239,6 +1525,20 @@ function AiTreeRenderer({ tree, brand, resolveMedia, editKeyPrefix }) {
|
|
|
1239
1525
|
const overlayAlpha = { low: 0.25, medium: 0.45, high: 0.65 }[settings.overlayIntensity ?? "medium"];
|
|
1240
1526
|
const backgroundUrl = isOverlay && settings.backgroundMedia ? ctx.resolveMedia(settings.backgroundMedia) : null;
|
|
1241
1527
|
const bgAttrs = ctx.keyFor && isOverlay && settings.backgroundMedia ? { "data-ohw-key": ctx.keyFor("settings.backgroundMedia"), "data-ohw-editable": "bg-image" } : {};
|
|
1528
|
+
const toneBackground = (() => {
|
|
1529
|
+
const { dark, primary, light } = resolvedBrand.palette;
|
|
1530
|
+
switch (settings.sectionBackground) {
|
|
1531
|
+
case "surface":
|
|
1532
|
+
return `color-mix(in srgb, ${light} 94%, ${dark})`;
|
|
1533
|
+
case "accent":
|
|
1534
|
+
return primary;
|
|
1535
|
+
case "accent-soft":
|
|
1536
|
+
return `color-mix(in srgb, ${primary} 12%, ${light})`;
|
|
1537
|
+
default:
|
|
1538
|
+
return void 0;
|
|
1539
|
+
}
|
|
1540
|
+
})();
|
|
1541
|
+
const distributed = !isOverlay && settings.textDistribution;
|
|
1242
1542
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
1243
1543
|
"section",
|
|
1244
1544
|
{
|
|
@@ -1248,10 +1548,11 @@ function AiTreeRenderer({ tree, brand, resolveMedia, editKeyPrefix }) {
|
|
|
1248
1548
|
style: {
|
|
1249
1549
|
position: "relative",
|
|
1250
1550
|
padding: `${pad}px 0`,
|
|
1251
|
-
background: isOverlay && !backgroundUrl ? "#DBEAFE" : void 0,
|
|
1551
|
+
background: toneBackground ?? (isOverlay && !backgroundUrl ? "#DBEAFE" : void 0),
|
|
1252
1552
|
backgroundImage: backgroundUrl ? `url(${backgroundUrl})` : void 0,
|
|
1253
1553
|
backgroundSize: "cover",
|
|
1254
|
-
backgroundPosition: "center"
|
|
1554
|
+
backgroundPosition: "center",
|
|
1555
|
+
color: settings.sectionBackground === "accent" ? resolvedBrand.palette.light : void 0
|
|
1255
1556
|
},
|
|
1256
1557
|
children: [
|
|
1257
1558
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("style", { children: AI_RESPONSIVE_CSS }),
|
|
@@ -1275,10 +1576,24 @@ function AiTreeRenderer({ tree, brand, resolveMedia, editKeyPrefix }) {
|
|
|
1275
1576
|
display: "grid",
|
|
1276
1577
|
gridTemplateColumns: "repeat(12, 1fr)",
|
|
1277
1578
|
gap: AI_TREE_TOKENS.spacing6,
|
|
1278
|
-
alignItems: settings.verticalPosition === "top" ? "start" : "center",
|
|
1579
|
+
alignItems: distributed === "space-between" ? "stretch" : (distributed ?? settings.verticalPosition) === "top" ? "start" : "center",
|
|
1279
1580
|
marginTop: r2 > 0 ? AI_TREE_TOKENS.spacing8 : 0
|
|
1280
1581
|
},
|
|
1281
|
-
children: (row.blocks ?? []).map((block, b) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1582
|
+
children: (row.blocks ?? []).map((block, b) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1583
|
+
"div",
|
|
1584
|
+
{
|
|
1585
|
+
"data-ai-cell": "",
|
|
1586
|
+
style: {
|
|
1587
|
+
gridColumn: `span ${Math.min(12, Math.max(1, block.span))}`,
|
|
1588
|
+
minWidth: 0,
|
|
1589
|
+
// space-between: each column becomes a flex column whose content spreads over
|
|
1590
|
+
// the full row height instead of clumping at the top.
|
|
1591
|
+
...distributed === "space-between" ? { display: "flex", flexDirection: "column", justifyContent: "space-between" } : {}
|
|
1592
|
+
},
|
|
1593
|
+
children: renderNode(block, ctx, `r${r2}.b${b}`)
|
|
1594
|
+
},
|
|
1595
|
+
b
|
|
1596
|
+
))
|
|
1282
1597
|
},
|
|
1283
1598
|
r2
|
|
1284
1599
|
))
|
|
@@ -1294,17 +1609,34 @@ var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
|
1294
1609
|
var CONTAINER_ATTR = "data-ohw-ai-generated";
|
|
1295
1610
|
var REPLACED_ATTR = "data-ohw-ai-replaced-by";
|
|
1296
1611
|
var REMOVED_ATTR = "data-ohw-ai-removed";
|
|
1612
|
+
function readRootVar(name) {
|
|
1613
|
+
if (typeof document === "undefined") return "";
|
|
1614
|
+
return getComputedStyle(document.documentElement).getPropertyValue(name).trim();
|
|
1615
|
+
}
|
|
1616
|
+
function deriveBrandOverride() {
|
|
1617
|
+
const dark = readRootVar("--ohw-brand-dark");
|
|
1618
|
+
const primary = readRootVar("--ohw-brand-primary");
|
|
1619
|
+
const light = readRootVar("--ohw-brand-light");
|
|
1620
|
+
if (!dark || !primary || !light) return null;
|
|
1621
|
+
const accent = readRootVar("--ohw-brand-accent");
|
|
1622
|
+
const heading = readRootVar("--font-heading") || readRootVar("--font-display");
|
|
1623
|
+
const body = readRootVar("--font-body");
|
|
1624
|
+
return {
|
|
1625
|
+
palette: { dark, primary, accent: accent || dark, light },
|
|
1626
|
+
fonts: {
|
|
1627
|
+
heading: heading || AI_DEFAULT_BRAND.fonts.heading,
|
|
1628
|
+
body: body || AI_DEFAULT_BRAND.fonts.body
|
|
1629
|
+
}
|
|
1630
|
+
};
|
|
1631
|
+
}
|
|
1297
1632
|
function deriveTemplateBrand() {
|
|
1298
|
-
|
|
1299
|
-
const
|
|
1300
|
-
const
|
|
1301
|
-
const dark = read("--color-dark");
|
|
1302
|
-
const primary = read("--color-primary");
|
|
1303
|
-
const light = read("--color-light");
|
|
1633
|
+
const dark = readRootVar("--color-dark");
|
|
1634
|
+
const primary = readRootVar("--color-primary");
|
|
1635
|
+
const light = readRootVar("--color-light");
|
|
1304
1636
|
if (!dark || !primary || !light) return null;
|
|
1305
|
-
const accent =
|
|
1306
|
-
const heading =
|
|
1307
|
-
const body =
|
|
1637
|
+
const accent = readRootVar("--color-accent");
|
|
1638
|
+
const heading = readRootVar("--font-heading") || readRootVar("--font-display");
|
|
1639
|
+
const body = readRootVar("--font-body");
|
|
1308
1640
|
return {
|
|
1309
1641
|
palette: { dark, primary, accent: accent || dark, light },
|
|
1310
1642
|
fonts: {
|
|
@@ -1396,8 +1728,12 @@ function syncReplacedOriginals(state) {
|
|
|
1396
1728
|
}
|
|
1397
1729
|
function applyAiSectionsToDom(state, options) {
|
|
1398
1730
|
if (typeof document === "undefined") return;
|
|
1731
|
+
const brandOverride = deriveBrandOverride();
|
|
1399
1732
|
const templateBrand = deriveTemplateBrand();
|
|
1400
|
-
const
|
|
1733
|
+
const brandKey = brandOverride ? JSON.stringify(brandOverride) : "";
|
|
1734
|
+
const pagePath = window.location.pathname;
|
|
1735
|
+
const pageSections = state.sections.filter((entry) => !entry.path || entry.path === pagePath);
|
|
1736
|
+
const activeIds = new Set(pageSections.map((entry) => entry.id));
|
|
1401
1737
|
for (const [id, section] of mounted) {
|
|
1402
1738
|
if (!activeIds.has(id)) {
|
|
1403
1739
|
section.root.unmount();
|
|
@@ -1405,8 +1741,8 @@ function applyAiSectionsToDom(state, options) {
|
|
|
1405
1741
|
mounted.delete(id);
|
|
1406
1742
|
}
|
|
1407
1743
|
}
|
|
1408
|
-
for (const entry of
|
|
1409
|
-
const serialized = JSON.stringify(entry);
|
|
1744
|
+
for (const entry of pageSections) {
|
|
1745
|
+
const serialized = JSON.stringify(entry) + brandKey;
|
|
1410
1746
|
const existing = mounted.get(entry.id);
|
|
1411
1747
|
if (existing && existing.serialized === serialized && existing.container.isConnected) {
|
|
1412
1748
|
continue;
|
|
@@ -1420,6 +1756,7 @@ function applyAiSectionsToDom(state, options) {
|
|
|
1420
1756
|
mounted.delete(entry.id);
|
|
1421
1757
|
}
|
|
1422
1758
|
container.setAttribute("data-ohw-section", entry.id);
|
|
1759
|
+
container.setAttribute("data-ohw-instance", entry.id);
|
|
1423
1760
|
container.setAttribute("data-ohw-section-label", entry.label);
|
|
1424
1761
|
placeContainer(container, entry);
|
|
1425
1762
|
const root = mounted.get(entry.id)?.root ?? (0, import_client.createRoot)(container);
|
|
@@ -1430,7 +1767,7 @@ function applyAiSectionsToDom(state, options) {
|
|
|
1430
1767
|
AiTreeRenderer,
|
|
1431
1768
|
{
|
|
1432
1769
|
tree: entry.tree,
|
|
1433
|
-
brand: entry.brand ?? options?.brand ?? templateBrand ?? void 0,
|
|
1770
|
+
brand: brandOverride ?? entry.brand ?? options?.brand ?? templateBrand ?? void 0,
|
|
1434
1771
|
resolveMedia,
|
|
1435
1772
|
editKeyPrefix: `ai.${entry.id}`
|
|
1436
1773
|
}
|
|
@@ -2047,7 +2384,7 @@ function SchedulingWidget({ notifyOnConnect = false, initialScheduleId, insertAf
|
|
|
2047
2384
|
const autoId = (0, import_react5.useId)();
|
|
2048
2385
|
const insertAfter = insertAfterProp ?? autoId;
|
|
2049
2386
|
const [schedule, setSchedule] = (0, import_react5.useState)(null);
|
|
2050
|
-
const [loading, setLoading] = (0, import_react5.useState)(
|
|
2387
|
+
const [loading, setLoading] = (0, import_react5.useState)(initialScheduleId !== null);
|
|
2051
2388
|
const [inEditor, setInEditor] = (0, import_react5.useState)(false);
|
|
2052
2389
|
const [isHovered, setIsHovered] = (0, import_react5.useState)(false);
|
|
2053
2390
|
const [modalState, setModalState] = (0, import_react5.useState)(null);
|
|
@@ -2221,8 +2558,10 @@ function SchedulingWidget({ notifyOnConnect = false, initialScheduleId, insertAf
|
|
|
2221
2558
|
"*"
|
|
2222
2559
|
);
|
|
2223
2560
|
};
|
|
2224
|
-
if (!inEditor && !loading && !schedule) return null;
|
|
2225
2561
|
const sectionId = `scheduling-${insertAfter}`;
|
|
2562
|
+
if (!inEditor && !loading && !schedule) {
|
|
2563
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("section", { "data-ohw-section": sectionId, "data-ohw-scheduling-anchor": insertAfter, style: { display: "none" } });
|
|
2564
|
+
}
|
|
2226
2565
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
2227
2566
|
"section",
|
|
2228
2567
|
{
|
|
@@ -6741,8 +7080,12 @@ function parseSectionsFromHtml(html) {
|
|
|
6741
7080
|
|
|
6742
7081
|
// src/ui/ai-section/AiSectionOverlay.tsx
|
|
6743
7082
|
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
6744
|
-
function
|
|
6745
|
-
const
|
|
7083
|
+
function findSectionElement(instanceId) {
|
|
7084
|
+
const escaped = CSS.escape(instanceId);
|
|
7085
|
+
return document.querySelector(`[data-ohw-instance="${escaped}"]`) ?? document.querySelector(`[data-ohw-section="${escaped}"]:not([data-ohw-instance])`);
|
|
7086
|
+
}
|
|
7087
|
+
function readRect(instanceId) {
|
|
7088
|
+
const el = findSectionElement(instanceId);
|
|
6746
7089
|
if (!el) return null;
|
|
6747
7090
|
const r2 = el.getBoundingClientRect();
|
|
6748
7091
|
if (r2.width <= 0 || r2.height <= 0) return null;
|
|
@@ -6765,7 +7108,7 @@ function useLiveSectionRect(sectionId) {
|
|
|
6765
7108
|
const opts = { capture: true, passive: true };
|
|
6766
7109
|
window.addEventListener("scroll", update, opts);
|
|
6767
7110
|
window.addEventListener("resize", update);
|
|
6768
|
-
const el =
|
|
7111
|
+
const el = findSectionElement(sectionId);
|
|
6769
7112
|
const ro = el ? new ResizeObserver(update) : null;
|
|
6770
7113
|
if (el && ro) ro.observe(el);
|
|
6771
7114
|
const interval = setInterval(update, 500);
|
|
@@ -6778,6 +7121,14 @@ function useLiveSectionRect(sectionId) {
|
|
|
6778
7121
|
}, [sectionId]);
|
|
6779
7122
|
return rect;
|
|
6780
7123
|
}
|
|
7124
|
+
function computeSectionBoundaryFlags(instanceId) {
|
|
7125
|
+
const topLevel = Array.from(document.querySelectorAll("[data-ohw-section]")).filter(
|
|
7126
|
+
(el) => !el.parentElement?.closest("[data-ohw-section]")
|
|
7127
|
+
);
|
|
7128
|
+
const index = topLevel.findIndex((el) => (el.dataset.ohwInstance ?? el.dataset.ohwSection) === instanceId);
|
|
7129
|
+
if (index === -1) return { isFirst: true, isLast: true };
|
|
7130
|
+
return { isFirst: index === 0, isLast: index === topLevel.length - 1 };
|
|
7131
|
+
}
|
|
6781
7132
|
var PRIMARY2 = "#0885FE";
|
|
6782
7133
|
function edgeAwareRadius(rect) {
|
|
6783
7134
|
const container = window.innerWidth <= 480 ? 16 : 24;
|
|
@@ -6851,6 +7202,7 @@ function AiSectionOverlay({
|
|
|
6851
7202
|
}) {
|
|
6852
7203
|
const [selectedId, setSelectedId] = (0, import_react8.useState)(null);
|
|
6853
7204
|
const [reviewId, setReviewId] = (0, import_react8.useState)(null);
|
|
7205
|
+
const [reviewButtonsHidden, setReviewButtonsHidden] = (0, import_react8.useState)(false);
|
|
6854
7206
|
const reviewIdRef = (0, import_react8.useRef)(null);
|
|
6855
7207
|
reviewIdRef.current = reviewId;
|
|
6856
7208
|
const selectedIdRef = (0, import_react8.useRef)(null);
|
|
@@ -6859,7 +7211,7 @@ function AiSectionOverlay({
|
|
|
6859
7211
|
(el) => {
|
|
6860
7212
|
postToParent2({
|
|
6861
7213
|
type: "ow:section-selected",
|
|
6862
|
-
sectionId: el
|
|
7214
|
+
sectionId: el ? el.dataset.ohwInstance ?? el.dataset.ohwSection ?? null : null,
|
|
6863
7215
|
sectionLabel: el ? el.dataset.ohwSectionLabel ?? titleCaseSectionId(el.dataset.ohwSection ?? "") : null
|
|
6864
7216
|
});
|
|
6865
7217
|
},
|
|
@@ -6868,7 +7220,7 @@ function AiSectionOverlay({
|
|
|
6868
7220
|
const selectFromElement = (0, import_react8.useCallback)(
|
|
6869
7221
|
(el, options) => {
|
|
6870
7222
|
const sectionEl = el?.closest("[data-ohw-section]") ?? null;
|
|
6871
|
-
const id = sectionEl
|
|
7223
|
+
const id = sectionEl ? sectionEl.dataset.ohwInstance ?? sectionEl.dataset.ohwSection ?? null : null;
|
|
6872
7224
|
if (id === selectedIdRef.current) return;
|
|
6873
7225
|
setSelectedId(id);
|
|
6874
7226
|
if (options?.report !== false) report(sectionEl);
|
|
@@ -6909,9 +7261,10 @@ function AiSectionOverlay({
|
|
|
6909
7261
|
}
|
|
6910
7262
|
const found = readRect(sectionId) != null;
|
|
6911
7263
|
setReviewId(found ? sectionId : null);
|
|
7264
|
+
setReviewButtonsHidden(e.data.hideButtons === true);
|
|
6912
7265
|
postToParent2({ type: "ow:ai-review-started", sectionId, found });
|
|
6913
7266
|
if (found) {
|
|
6914
|
-
document.querySelector(`[data-ohw-
|
|
7267
|
+
document.querySelector(`[data-ohw-instance="${CSS.escape(sectionId)}"]`)?.scrollIntoView({ behavior: "smooth", block: "nearest" });
|
|
6915
7268
|
}
|
|
6916
7269
|
}
|
|
6917
7270
|
};
|
|
@@ -6930,7 +7283,7 @@ function AiSectionOverlay({
|
|
|
6930
7283
|
return;
|
|
6931
7284
|
}
|
|
6932
7285
|
const sec = t.closest("[data-ohw-section]");
|
|
6933
|
-
setHoveredId(sec
|
|
7286
|
+
setHoveredId(sec ? sec.dataset.ohwInstance ?? sec.dataset.ohwSection ?? null : null);
|
|
6934
7287
|
};
|
|
6935
7288
|
const onLeave = () => setHoveredId(null);
|
|
6936
7289
|
document.addEventListener("mousemove", onMove, { passive: true });
|
|
@@ -6962,9 +7315,29 @@ function AiSectionOverlay({
|
|
|
6962
7315
|
},
|
|
6963
7316
|
[postToParent2]
|
|
6964
7317
|
);
|
|
6965
|
-
const
|
|
7318
|
+
const activeSelectionId = reviewId ? null : selectedId;
|
|
7319
|
+
const selectionRect = useLiveSectionRect(activeSelectionId);
|
|
6966
7320
|
const reviewRect = useLiveSectionRect(reviewId);
|
|
6967
7321
|
const hoverRect = useLiveSectionRect(reviewId || hoveredId === selectedId ? null : hoveredId);
|
|
7322
|
+
(0, import_react8.useEffect)(() => {
|
|
7323
|
+
if (!activeSelectionId || !selectionRect) {
|
|
7324
|
+
postToParent2({ type: "ow:section-rect", instanceId: null, rect: null });
|
|
7325
|
+
return;
|
|
7326
|
+
}
|
|
7327
|
+
const { isFirst, isLast } = computeSectionBoundaryFlags(activeSelectionId);
|
|
7328
|
+
postToParent2({
|
|
7329
|
+
type: "ow:section-rect",
|
|
7330
|
+
instanceId: activeSelectionId,
|
|
7331
|
+
rect: {
|
|
7332
|
+
top: selectionRect.top + window.scrollY,
|
|
7333
|
+
left: selectionRect.left + window.scrollX,
|
|
7334
|
+
width: selectionRect.width,
|
|
7335
|
+
height: selectionRect.height
|
|
7336
|
+
},
|
|
7337
|
+
isFirst,
|
|
7338
|
+
isLast
|
|
7339
|
+
});
|
|
7340
|
+
}, [activeSelectionId, selectionRect, postToParent2]);
|
|
6968
7341
|
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_jsx_runtime16.Fragment, { children: [
|
|
6969
7342
|
hoverRect && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
6970
7343
|
"div",
|
|
@@ -7015,13 +7388,16 @@ function AiSectionOverlay({
|
|
|
7015
7388
|
border: `2px solid ${PRIMARY2}`,
|
|
7016
7389
|
borderRadius: edgeAwareRadius(reviewRect),
|
|
7017
7390
|
zIndex: 2147483200,
|
|
7018
|
-
// The veil itself: swallows clicks so the section stays locked until decided.
|
|
7391
|
+
// The veil itself: swallows clicks so the section stays locked until decided. This
|
|
7392
|
+
// stopPropagation only guards the bubble phase; the bridge's capture-phase click
|
|
7393
|
+
// handlers additionally bail on `[data-ohw-ai-review]`, without which a click on
|
|
7394
|
+
// Accept/Discard resolves to the media beneath and opens the file picker.
|
|
7019
7395
|
background: "rgba(8, 133, 254, 0.04)",
|
|
7020
7396
|
pointerEvents: "auto",
|
|
7021
7397
|
cursor: "default"
|
|
7022
7398
|
},
|
|
7023
7399
|
onClick: (e) => e.stopPropagation(),
|
|
7024
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
|
|
7400
|
+
children: !reviewButtonsHidden && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
|
|
7025
7401
|
"div",
|
|
7026
7402
|
{
|
|
7027
7403
|
style: {
|
|
@@ -10921,6 +11297,329 @@ function deleteFooterColumn(column) {
|
|
|
10921
11297
|
};
|
|
10922
11298
|
}
|
|
10923
11299
|
|
|
11300
|
+
// src/lib/logo-identity.ts
|
|
11301
|
+
var LOGO_TEXT_KEYS = ["nav-logo-text", "footer-logo-text", "logo-text"];
|
|
11302
|
+
var LOGO_IMAGE_KEYS = ["nav-logo-image", "footer-logo", "footer-logo-image"];
|
|
11303
|
+
var LOGO_HREF_KEYS = ["nav-logo-href", "footer-logo-href", "logo-href"];
|
|
11304
|
+
var LOGO_PLACEHOLDER_KEY = "logo-is-placeholder";
|
|
11305
|
+
var LOGO_ALT_KEY = "logo-alt";
|
|
11306
|
+
var LOGO_IMAGE_URL_KEY = "nav-logo-image";
|
|
11307
|
+
var PLACEHOLDER_BUSINESS_NAME = "Business name";
|
|
11308
|
+
function resolveLogoDisplayText(text) {
|
|
11309
|
+
const trimmed = (text ?? "").trim();
|
|
11310
|
+
return trimmed || PLACEHOLDER_BUSINESS_NAME;
|
|
11311
|
+
}
|
|
11312
|
+
function isFooterLogoRoot(root) {
|
|
11313
|
+
return Boolean(root.closest("footer") || root.closest('[data-ohw-section="footer"]'));
|
|
11314
|
+
}
|
|
11315
|
+
function imageKeyForRoot(root) {
|
|
11316
|
+
return isFooterLogoRoot(root) ? "footer-logo" : "nav-logo-image";
|
|
11317
|
+
}
|
|
11318
|
+
function textKeyForRoot(root) {
|
|
11319
|
+
return isFooterLogoRoot(root) ? "footer-logo-text" : "nav-logo-text";
|
|
11320
|
+
}
|
|
11321
|
+
function ensureLogoHrefKey(root) {
|
|
11322
|
+
if (!(root instanceof HTMLAnchorElement)) return;
|
|
11323
|
+
if (root.hasAttribute("data-ohw-href-key")) return;
|
|
11324
|
+
root.setAttribute("data-ohw-href-key", isFooterLogoRoot(root) ? "footer-logo-href" : "nav-logo-href");
|
|
11325
|
+
}
|
|
11326
|
+
function applyLogoIdentity(text, isPlaceholder) {
|
|
11327
|
+
const display = resolveLogoDisplayText(text);
|
|
11328
|
+
const placeholder = isPlaceholder || !text.trim() || display === PLACEHOLDER_BUSINESS_NAME;
|
|
11329
|
+
for (const key of LOGO_TEXT_KEYS) {
|
|
11330
|
+
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
11331
|
+
if (el.textContent !== display) el.textContent = display;
|
|
11332
|
+
});
|
|
11333
|
+
}
|
|
11334
|
+
for (const key of LOGO_IMAGE_KEYS) {
|
|
11335
|
+
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
11336
|
+
const img = el instanceof HTMLImageElement ? el : el.querySelector("img");
|
|
11337
|
+
if (img) img.alt = display;
|
|
11338
|
+
});
|
|
11339
|
+
}
|
|
11340
|
+
document.querySelectorAll('[data-ohw-role="logo"], [data-ohw-logo]').forEach((el) => {
|
|
11341
|
+
if (placeholder) el.setAttribute("data-ohw-placeholder", "");
|
|
11342
|
+
else el.removeAttribute("data-ohw-placeholder");
|
|
11343
|
+
});
|
|
11344
|
+
return display;
|
|
11345
|
+
}
|
|
11346
|
+
function applyLogoImage(url, alt) {
|
|
11347
|
+
const displayAlt = resolveLogoDisplayText(alt);
|
|
11348
|
+
document.querySelectorAll('[data-ohw-role="logo"], [data-ohw-logo]').forEach((root) => {
|
|
11349
|
+
ensureLogoHrefKey(root);
|
|
11350
|
+
const imageKey = imageKeyForRoot(root);
|
|
11351
|
+
const textKey = textKeyForRoot(root);
|
|
11352
|
+
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");
|
|
11353
|
+
let textEl = root.querySelector(`[data-ohw-key="${textKey}"]`) ?? root.querySelector('[data-ohw-key="logo-text"]');
|
|
11354
|
+
if (url) {
|
|
11355
|
+
if (!img) {
|
|
11356
|
+
img = document.createElement("img");
|
|
11357
|
+
img.setAttribute("data-ohw-editable", "image");
|
|
11358
|
+
img.setAttribute("data-ohw-key", imageKey);
|
|
11359
|
+
img.alt = displayAlt;
|
|
11360
|
+
img.style.height = "";
|
|
11361
|
+
img.style.maxHeight = "none";
|
|
11362
|
+
img.style.width = "auto";
|
|
11363
|
+
img.style.display = "block";
|
|
11364
|
+
img.style.objectFit = "contain";
|
|
11365
|
+
root.insertBefore(img, root.firstChild);
|
|
11366
|
+
} else {
|
|
11367
|
+
img.setAttribute("data-ohw-editable", "image");
|
|
11368
|
+
img.setAttribute("data-ohw-key", imageKey);
|
|
11369
|
+
}
|
|
11370
|
+
img.removeAttribute("srcset");
|
|
11371
|
+
img.removeAttribute("sizes");
|
|
11372
|
+
img.src = url;
|
|
11373
|
+
img.alt = displayAlt;
|
|
11374
|
+
img.style.display = "block";
|
|
11375
|
+
if (textEl) textEl.style.display = "none";
|
|
11376
|
+
root.removeAttribute("data-ohw-placeholder");
|
|
11377
|
+
return;
|
|
11378
|
+
}
|
|
11379
|
+
if (img) {
|
|
11380
|
+
img.removeAttribute("src");
|
|
11381
|
+
img.removeAttribute("srcset");
|
|
11382
|
+
img.removeAttribute("sizes");
|
|
11383
|
+
img.alt = displayAlt;
|
|
11384
|
+
img.style.display = "none";
|
|
11385
|
+
}
|
|
11386
|
+
if (!textEl) {
|
|
11387
|
+
textEl = document.createElement("span");
|
|
11388
|
+
textEl.setAttribute("data-ohw-editable", "plain");
|
|
11389
|
+
textEl.setAttribute("data-ohw-key", textKey);
|
|
11390
|
+
root.appendChild(textEl);
|
|
11391
|
+
}
|
|
11392
|
+
textEl.style.display = "";
|
|
11393
|
+
if (textEl.textContent !== displayAlt) textEl.textContent = displayAlt;
|
|
11394
|
+
if (!displayAlt.trim() || displayAlt === PLACEHOLDER_BUSINESS_NAME) {
|
|
11395
|
+
root.setAttribute("data-ohw-placeholder", "");
|
|
11396
|
+
} else {
|
|
11397
|
+
root.removeAttribute("data-ohw-placeholder");
|
|
11398
|
+
}
|
|
11399
|
+
});
|
|
11400
|
+
}
|
|
11401
|
+
function applyLogoHref(href) {
|
|
11402
|
+
const target = href.trim() || "/";
|
|
11403
|
+
document.querySelectorAll('[data-ohw-role="logo"], [data-ohw-logo]').forEach((root) => {
|
|
11404
|
+
ensureLogoHrefKey(root);
|
|
11405
|
+
if (root instanceof HTMLAnchorElement) {
|
|
11406
|
+
root.setAttribute("href", target);
|
|
11407
|
+
}
|
|
11408
|
+
});
|
|
11409
|
+
for (const key of LOGO_HREF_KEYS) setStoredLinkHref(key, target);
|
|
11410
|
+
}
|
|
11411
|
+
function readLogoIdentityFromDom() {
|
|
11412
|
+
let imageUrl = null;
|
|
11413
|
+
for (const key of LOGO_IMAGE_KEYS) {
|
|
11414
|
+
const el = document.querySelector(`[data-ohw-key="${key}"]`);
|
|
11415
|
+
const img = el instanceof HTMLImageElement ? el : el?.querySelector("img");
|
|
11416
|
+
const attrSrc = img?.getAttribute("src")?.trim() ?? "";
|
|
11417
|
+
if (attrSrc && !attrSrc.startsWith("data:") && img && img.style.display !== "none") {
|
|
11418
|
+
imageUrl = img.currentSrc || img.src;
|
|
11419
|
+
break;
|
|
11420
|
+
}
|
|
11421
|
+
}
|
|
11422
|
+
let text = PLACEHOLDER_BUSINESS_NAME;
|
|
11423
|
+
let isPlaceholder = true;
|
|
11424
|
+
for (const key of LOGO_TEXT_KEYS) {
|
|
11425
|
+
const el = document.querySelector(`[data-ohw-key="${key}"]`);
|
|
11426
|
+
if (el?.textContent?.trim()) {
|
|
11427
|
+
text = el.textContent.trim();
|
|
11428
|
+
const logoRoot2 = el.closest('[data-ohw-role="logo"], [data-ohw-logo]');
|
|
11429
|
+
isPlaceholder = logoRoot2?.hasAttribute("data-ohw-placeholder") === true || text === PLACEHOLDER_BUSINESS_NAME;
|
|
11430
|
+
break;
|
|
11431
|
+
}
|
|
11432
|
+
}
|
|
11433
|
+
if (imageUrl) {
|
|
11434
|
+
const logoImg = document.querySelector(
|
|
11435
|
+
'[data-ohw-key="nav-logo-image"], [data-ohw-key="footer-logo"]'
|
|
11436
|
+
);
|
|
11437
|
+
const alt = logoImg?.alt?.trim() || text;
|
|
11438
|
+
isPlaceholder = false;
|
|
11439
|
+
const hrefEl = document.querySelector(
|
|
11440
|
+
'a[data-ohw-role="logo"], a[data-ohw-logo], [data-ohw-role="logo"]'
|
|
11441
|
+
);
|
|
11442
|
+
const href2 = (hrefEl instanceof HTMLAnchorElement ? hrefEl.getAttribute("href") : null) || hrefEl?.closest("a")?.getAttribute("href") || "/";
|
|
11443
|
+
return { text, isPlaceholder, imageUrl, href: href2, alt };
|
|
11444
|
+
}
|
|
11445
|
+
const logoRoot = document.querySelector('[data-ohw-role="logo"], [data-ohw-logo]');
|
|
11446
|
+
const href = (logoRoot instanceof HTMLAnchorElement ? logoRoot.getAttribute("href") : null) || logoRoot?.closest("a")?.getAttribute("href") || "/";
|
|
11447
|
+
return { text, isPlaceholder, imageUrl: null, href, alt: text };
|
|
11448
|
+
}
|
|
11449
|
+
function applyLogoFromContent(content) {
|
|
11450
|
+
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);
|
|
11451
|
+
if (!hasLogoIdentity) return false;
|
|
11452
|
+
const logoText = content[LOGO_TEXT_KEYS[0]] ?? content[LOGO_TEXT_KEYS[1]] ?? readLogoIdentityFromDom().text;
|
|
11453
|
+
const logoAlt = content[LOGO_ALT_KEY] ?? logoText;
|
|
11454
|
+
const rawLogoImage = content[LOGO_IMAGE_URL_KEY] ?? content["footer-logo"] ?? content["footer-logo-image"] ?? null;
|
|
11455
|
+
const logoImageUrl = typeof rawLogoImage === "string" && rawLogoImage.trim() ? rawLogoImage.trim() : null;
|
|
11456
|
+
const imageExplicitlyCleared = LOGO_IMAGE_KEYS.some((key) => key in content) && !logoImageUrl;
|
|
11457
|
+
const logoIsPlaceholder = LOGO_PLACEHOLDER_KEY in content ? content[LOGO_PLACEHOLDER_KEY] !== "false" : !logoImageUrl && (!logoText.trim() || logoText === PLACEHOLDER_BUSINESS_NAME);
|
|
11458
|
+
if (logoImageUrl) {
|
|
11459
|
+
applyLogoImage(logoImageUrl, logoAlt);
|
|
11460
|
+
} else {
|
|
11461
|
+
if (imageExplicitlyCleared) applyLogoImage(null, logoAlt);
|
|
11462
|
+
applyLogoIdentity(logoText, logoIsPlaceholder);
|
|
11463
|
+
}
|
|
11464
|
+
const logoHref = content["nav-logo-href"] ?? content["footer-logo-href"] ?? content["logo-href"];
|
|
11465
|
+
if (typeof logoHref === "string" && logoHref.trim()) {
|
|
11466
|
+
applyLogoHref(logoHref);
|
|
11467
|
+
}
|
|
11468
|
+
return true;
|
|
11469
|
+
}
|
|
11470
|
+
|
|
11471
|
+
// src/lib/logo-size.ts
|
|
11472
|
+
var LOGO_SIZE_DEFAULTS = {
|
|
11473
|
+
navbar: 28,
|
|
11474
|
+
footer: 32
|
|
11475
|
+
};
|
|
11476
|
+
var LOGO_SIZE_MIN = 16;
|
|
11477
|
+
var LOGO_SIZE_MAX = 80;
|
|
11478
|
+
var LOGO_SIZE_DESKTOP_KEYS = {
|
|
11479
|
+
navbar: "nav-logo-size",
|
|
11480
|
+
footer: "footer-logo-size"
|
|
11481
|
+
};
|
|
11482
|
+
var LOGO_SIZE_MOBILE_KEYS = {
|
|
11483
|
+
navbar: "nav-logo-size-mobile",
|
|
11484
|
+
footer: "footer-logo-size-mobile"
|
|
11485
|
+
};
|
|
11486
|
+
var LOGO_SIZE_KEYS = [
|
|
11487
|
+
LOGO_SIZE_DESKTOP_KEYS.navbar,
|
|
11488
|
+
LOGO_SIZE_DESKTOP_KEYS.footer,
|
|
11489
|
+
LOGO_SIZE_MOBILE_KEYS.navbar,
|
|
11490
|
+
LOGO_SIZE_MOBILE_KEYS.footer
|
|
11491
|
+
];
|
|
11492
|
+
function isFooterLogoRoot2(root) {
|
|
11493
|
+
return Boolean(root.closest("footer") || root.closest('[data-ohw-section="footer"]'));
|
|
11494
|
+
}
|
|
11495
|
+
function getLogoPlacement(root) {
|
|
11496
|
+
return isFooterLogoRoot2(root) ? "footer" : "navbar";
|
|
11497
|
+
}
|
|
11498
|
+
function parseLogoSizePx(raw, fallback) {
|
|
11499
|
+
if (raw == null || raw === "") return fallback;
|
|
11500
|
+
const n = Number.parseFloat(raw);
|
|
11501
|
+
if (!Number.isFinite(n)) return fallback;
|
|
11502
|
+
return Math.min(LOGO_SIZE_MAX, Math.max(LOGO_SIZE_MIN, Math.round(n)));
|
|
11503
|
+
}
|
|
11504
|
+
function isMobileLogoSizeFollowing(content, placement) {
|
|
11505
|
+
const raw = content[LOGO_SIZE_MOBILE_KEYS[placement]];
|
|
11506
|
+
return raw == null || raw.trim() === "";
|
|
11507
|
+
}
|
|
11508
|
+
function resolveDesktopLogoSize(content, placement) {
|
|
11509
|
+
return parseLogoSizePx(content[LOGO_SIZE_DESKTOP_KEYS[placement]], LOGO_SIZE_DEFAULTS[placement]);
|
|
11510
|
+
}
|
|
11511
|
+
function resolveMobileLogoSize(content, placement) {
|
|
11512
|
+
if (isMobileLogoSizeFollowing(content, placement)) {
|
|
11513
|
+
return resolveDesktopLogoSize(content, placement);
|
|
11514
|
+
}
|
|
11515
|
+
return parseLogoSizePx(
|
|
11516
|
+
content[LOGO_SIZE_MOBILE_KEYS[placement]],
|
|
11517
|
+
resolveDesktopLogoSize(content, placement)
|
|
11518
|
+
);
|
|
11519
|
+
}
|
|
11520
|
+
function setRootSizeVars(root, desktopPx, mobilePx, following) {
|
|
11521
|
+
root.style.setProperty("--ohw-logo-size", `${desktopPx}px`);
|
|
11522
|
+
if (following) {
|
|
11523
|
+
root.style.removeProperty("--ohw-logo-size-mobile");
|
|
11524
|
+
} else {
|
|
11525
|
+
root.style.setProperty("--ohw-logo-size-mobile", `${mobilePx}px`);
|
|
11526
|
+
}
|
|
11527
|
+
root.querySelectorAll("img").forEach((img) => {
|
|
11528
|
+
img.style.height = "";
|
|
11529
|
+
img.style.maxHeight = "none";
|
|
11530
|
+
img.style.width = "auto";
|
|
11531
|
+
img.style.objectFit = "contain";
|
|
11532
|
+
});
|
|
11533
|
+
}
|
|
11534
|
+
function applyLogoSizes(content) {
|
|
11535
|
+
document.querySelectorAll('[data-ohw-role="logo"], [data-ohw-logo]').forEach((root) => {
|
|
11536
|
+
const placement = getLogoPlacement(root);
|
|
11537
|
+
const desktop = resolveDesktopLogoSize(content, placement);
|
|
11538
|
+
const following = isMobileLogoSizeFollowing(content, placement);
|
|
11539
|
+
const mobile = following ? desktop : resolveMobileLogoSize(content, placement);
|
|
11540
|
+
setRootSizeVars(root, desktop, mobile, following);
|
|
11541
|
+
});
|
|
11542
|
+
}
|
|
11543
|
+
function applyLogoSizeToPlacement(placement, desktopPx, mobilePx, following) {
|
|
11544
|
+
document.querySelectorAll('[data-ohw-role="logo"], [data-ohw-logo]').forEach((root) => {
|
|
11545
|
+
if (getLogoPlacement(root) !== placement) return;
|
|
11546
|
+
setRootSizeVars(root, desktopPx, mobilePx, following);
|
|
11547
|
+
});
|
|
11548
|
+
}
|
|
11549
|
+
function logoHasUploadedImage(logoEl) {
|
|
11550
|
+
if (logoEl.hasAttribute("data-ohw-placeholder")) return false;
|
|
11551
|
+
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");
|
|
11552
|
+
if (!img) return false;
|
|
11553
|
+
const src = img.getAttribute("src")?.trim() ?? "";
|
|
11554
|
+
if (!src || src.startsWith("data:")) return false;
|
|
11555
|
+
if (img.style.display === "none") return false;
|
|
11556
|
+
return true;
|
|
11557
|
+
}
|
|
11558
|
+
function getLogoInteractionRect(logoEl) {
|
|
11559
|
+
if (logoHasUploadedImage(logoEl)) {
|
|
11560
|
+
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");
|
|
11561
|
+
if (img) {
|
|
11562
|
+
const r2 = img.getBoundingClientRect();
|
|
11563
|
+
if (r2.width > 0 && r2.height > 0) return r2;
|
|
11564
|
+
}
|
|
11565
|
+
}
|
|
11566
|
+
const text = logoEl.querySelector(
|
|
11567
|
+
'[data-ohw-key="nav-logo-text"], [data-ohw-key="footer-logo-text"]'
|
|
11568
|
+
);
|
|
11569
|
+
if (text) {
|
|
11570
|
+
const style = window.getComputedStyle(text);
|
|
11571
|
+
if (style.display !== "none" && style.visibility !== "hidden") {
|
|
11572
|
+
const r2 = text.getBoundingClientRect();
|
|
11573
|
+
if (r2.width > 0 && r2.height > 0) return r2;
|
|
11574
|
+
}
|
|
11575
|
+
}
|
|
11576
|
+
return logoEl.getBoundingClientRect();
|
|
11577
|
+
}
|
|
11578
|
+
function readLogoSizeState(content, placement) {
|
|
11579
|
+
const desktopPx = resolveDesktopLogoSize(content, placement);
|
|
11580
|
+
const mobileFollowing = isMobileLogoSizeFollowing(content, placement);
|
|
11581
|
+
const mobilePx = mobileFollowing ? desktopPx : resolveMobileLogoSize(content, placement);
|
|
11582
|
+
return { desktopPx, mobilePx, mobileFollowing };
|
|
11583
|
+
}
|
|
11584
|
+
|
|
11585
|
+
// src/lib/site-wide-scope.ts
|
|
11586
|
+
function getLogoElement(el) {
|
|
11587
|
+
const marked = el.closest('[data-ohw-role="logo"], [data-ohw-logo]');
|
|
11588
|
+
if (marked) return marked;
|
|
11589
|
+
if (el.closest('[data-ohw-editable="icon"]')) return null;
|
|
11590
|
+
const root = el.closest("nav, [data-ohw-nav-root], footer");
|
|
11591
|
+
if (!root) return null;
|
|
11592
|
+
const anchor = el.closest("a");
|
|
11593
|
+
if (anchor && root.contains(anchor) && !anchor.hasAttribute("data-ohw-href-key") && !anchor.closest("[data-ohw-nav-container]") && Boolean(anchor.querySelector("img") || anchor.matches("img"))) {
|
|
11594
|
+
return anchor;
|
|
11595
|
+
}
|
|
11596
|
+
const img = el.matches("img") ? el : null;
|
|
11597
|
+
if (img && !img.closest("[data-ohw-href-key]") && !img.closest("[data-ohw-nav-container]") && (img.closest("footer") || img.closest("nav, [data-ohw-nav-root]"))) {
|
|
11598
|
+
return img;
|
|
11599
|
+
}
|
|
11600
|
+
return null;
|
|
11601
|
+
}
|
|
11602
|
+
function isInFooter(el) {
|
|
11603
|
+
if (!el) return false;
|
|
11604
|
+
return Boolean(el.closest("footer") || el.closest('[data-ohw-section="footer"]'));
|
|
11605
|
+
}
|
|
11606
|
+
function isSiteWideElement(el) {
|
|
11607
|
+
if (!el) return false;
|
|
11608
|
+
if (getLogoElement(el)) return true;
|
|
11609
|
+
if (isInFooter(el)) return true;
|
|
11610
|
+
if (el.hasAttribute("data-ohw-nav-container") || el.hasAttribute("data-ohw-nav-root")) {
|
|
11611
|
+
return true;
|
|
11612
|
+
}
|
|
11613
|
+
if (el.hasAttribute("data-ohw-href-key") && el.closest("nav, [data-ohw-nav-root], [data-ohw-nav-drawer], aside")) {
|
|
11614
|
+
return true;
|
|
11615
|
+
}
|
|
11616
|
+
if (el.closest('[data-ohw-role="navbar-button"]')) return true;
|
|
11617
|
+
return false;
|
|
11618
|
+
}
|
|
11619
|
+
function isSiteWideScopeActive(args) {
|
|
11620
|
+
return isSiteWideElement(args.selected) || isSiteWideElement(args.hoveredItem) || isSiteWideElement(args.hoveredNavContainer) || isSiteWideElement(args.active);
|
|
11621
|
+
}
|
|
11622
|
+
|
|
10924
11623
|
// src/lib/add-footer-column.ts
|
|
10925
11624
|
function buildFooterColumnEditContentPatch(result) {
|
|
10926
11625
|
return {
|
|
@@ -11136,16 +11835,127 @@ function FloatingPanel({
|
|
|
11136
11835
|
);
|
|
11137
11836
|
}
|
|
11138
11837
|
|
|
11139
|
-
// src/ui/
|
|
11838
|
+
// src/ui/logo-size-panel.tsx
|
|
11839
|
+
var import_lucide_react14 = require("lucide-react");
|
|
11140
11840
|
var import_jsx_runtime27 = require("react/jsx-runtime");
|
|
11841
|
+
function SizeSlider({
|
|
11842
|
+
value,
|
|
11843
|
+
onChange
|
|
11844
|
+
}) {
|
|
11845
|
+
const pct = (value - LOGO_SIZE_MIN) / (LOGO_SIZE_MAX - LOGO_SIZE_MIN) * 100;
|
|
11846
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex w-full flex-col gap-3", children: [
|
|
11847
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex w-full items-center gap-2 text-sm font-medium leading-5", children: [
|
|
11848
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "min-w-0 flex-1 text-foreground", children: "Size" }),
|
|
11849
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("span", { className: "shrink-0 whitespace-nowrap text-muted-foreground", children: [
|
|
11850
|
+
value,
|
|
11851
|
+
" px"
|
|
11852
|
+
] })
|
|
11853
|
+
] }),
|
|
11854
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "relative h-2 w-full rounded-full bg-primary-50", children: [
|
|
11855
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
11856
|
+
"div",
|
|
11857
|
+
{
|
|
11858
|
+
className: "absolute inset-y-0 left-0 rounded-full bg-primary",
|
|
11859
|
+
style: { width: `${pct}%` }
|
|
11860
|
+
}
|
|
11861
|
+
),
|
|
11862
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
11863
|
+
"input",
|
|
11864
|
+
{
|
|
11865
|
+
type: "range",
|
|
11866
|
+
min: LOGO_SIZE_MIN,
|
|
11867
|
+
max: LOGO_SIZE_MAX,
|
|
11868
|
+
step: 1,
|
|
11869
|
+
value,
|
|
11870
|
+
"aria-label": "Logo size",
|
|
11871
|
+
className: cn(
|
|
11872
|
+
"absolute inset-0 h-full w-full cursor-pointer appearance-none bg-transparent",
|
|
11873
|
+
"[&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:size-5",
|
|
11874
|
+
"[&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:border-2",
|
|
11875
|
+
"[&::-webkit-slider-thumb]:border-primary [&::-webkit-slider-thumb]:bg-background",
|
|
11876
|
+
"[&::-moz-range-thumb]:size-5 [&::-moz-range-thumb]:rounded-full",
|
|
11877
|
+
"[&::-moz-range-thumb]:border-2 [&::-moz-range-thumb]:border-primary",
|
|
11878
|
+
"[&::-moz-range-thumb]:bg-background"
|
|
11879
|
+
),
|
|
11880
|
+
onChange: (e) => onChange(Number(e.target.value))
|
|
11881
|
+
}
|
|
11882
|
+
)
|
|
11883
|
+
] })
|
|
11884
|
+
] });
|
|
11885
|
+
}
|
|
11886
|
+
function LogoSizePanel({
|
|
11887
|
+
viewport,
|
|
11888
|
+
sizePx,
|
|
11889
|
+
mobileFollowing = true,
|
|
11890
|
+
onSizeChange,
|
|
11891
|
+
onCustomizeMobile,
|
|
11892
|
+
onResetMobile,
|
|
11893
|
+
onUpdateEverywhere,
|
|
11894
|
+
className
|
|
11895
|
+
}) {
|
|
11896
|
+
const showFollowing = viewport === "mobile" && mobileFollowing;
|
|
11897
|
+
const showMobileSlider = viewport === "mobile" && !mobileFollowing;
|
|
11898
|
+
const showDesktopSlider = viewport === "desktop";
|
|
11899
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: cn("flex w-full flex-col gap-4", className), children: [
|
|
11900
|
+
showFollowing ? /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex w-full flex-col gap-2", children: [
|
|
11901
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex items-start gap-1", children: [
|
|
11902
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_lucide_react14.Link, { size: 16, className: "mt-0.5 shrink-0 text-foreground", "aria-hidden": true }),
|
|
11903
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("p", { className: "text-sm font-semibold leading-5 text-foreground", children: "Following desktop size" })
|
|
11904
|
+
] }),
|
|
11905
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("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." }),
|
|
11906
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
11907
|
+
Button,
|
|
11908
|
+
{
|
|
11909
|
+
type: "button",
|
|
11910
|
+
variant: "outline",
|
|
11911
|
+
size: "sm",
|
|
11912
|
+
className: "h-9 w-full min-w-0 cursor-pointer",
|
|
11913
|
+
onClick: onCustomizeMobile,
|
|
11914
|
+
children: "Customize for mobile"
|
|
11915
|
+
}
|
|
11916
|
+
)
|
|
11917
|
+
] }) : null,
|
|
11918
|
+
showDesktopSlider || showMobileSlider ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(SizeSlider, { value: sizePx, onChange: onSizeChange }) : null,
|
|
11919
|
+
showMobileSlider ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
11920
|
+
Button,
|
|
11921
|
+
{
|
|
11922
|
+
type: "button",
|
|
11923
|
+
variant: "outline",
|
|
11924
|
+
size: "sm",
|
|
11925
|
+
className: "h-9 w-full min-w-0 cursor-pointer",
|
|
11926
|
+
onClick: onResetMobile,
|
|
11927
|
+
children: "Reset to desktop size"
|
|
11928
|
+
}
|
|
11929
|
+
) : null,
|
|
11930
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "h-px w-full bg-border", role: "separator" }),
|
|
11931
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
|
|
11932
|
+
Button,
|
|
11933
|
+
{
|
|
11934
|
+
type: "button",
|
|
11935
|
+
variant: "outline",
|
|
11936
|
+
size: "sm",
|
|
11937
|
+
className: "h-9 w-full min-w-0 cursor-pointer gap-1",
|
|
11938
|
+
onClick: onUpdateEverywhere,
|
|
11939
|
+
children: [
|
|
11940
|
+
"Update logo everywhere",
|
|
11941
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_lucide_react14.ArrowUpRight, { size: 16, "aria-hidden": true })
|
|
11942
|
+
]
|
|
11943
|
+
}
|
|
11944
|
+
),
|
|
11945
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("p", { className: "text-sm leading-5 text-muted-foreground", children: "Matches the right version to your background." })
|
|
11946
|
+
] });
|
|
11947
|
+
}
|
|
11948
|
+
|
|
11949
|
+
// src/ui/socials-display-panel.tsx
|
|
11950
|
+
var import_jsx_runtime28 = require("react/jsx-runtime");
|
|
11141
11951
|
function DisplaySwitch({
|
|
11142
11952
|
label,
|
|
11143
11953
|
checked,
|
|
11144
11954
|
disabled,
|
|
11145
11955
|
onChange
|
|
11146
11956
|
}) {
|
|
11147
|
-
return /* @__PURE__ */ (0,
|
|
11148
|
-
/* @__PURE__ */ (0,
|
|
11957
|
+
return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "flex w-full items-center gap-2", children: [
|
|
11958
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
11149
11959
|
"span",
|
|
11150
11960
|
{
|
|
11151
11961
|
className: cn(
|
|
@@ -11155,7 +11965,7 @@ function DisplaySwitch({
|
|
|
11155
11965
|
children: label
|
|
11156
11966
|
}
|
|
11157
11967
|
),
|
|
11158
|
-
/* @__PURE__ */ (0,
|
|
11968
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
11159
11969
|
"button",
|
|
11160
11970
|
{
|
|
11161
11971
|
type: "button",
|
|
@@ -11169,7 +11979,7 @@ function DisplaySwitch({
|
|
|
11169
11979
|
checked ? "bg-primary" : "bg-primary-50",
|
|
11170
11980
|
disabled ? "cursor-default opacity-50" : "cursor-pointer"
|
|
11171
11981
|
),
|
|
11172
|
-
children: /* @__PURE__ */ (0,
|
|
11982
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
11173
11983
|
"span",
|
|
11174
11984
|
{
|
|
11175
11985
|
className: cn(
|
|
@@ -11183,8 +11993,8 @@ function DisplaySwitch({
|
|
|
11183
11993
|
] });
|
|
11184
11994
|
}
|
|
11185
11995
|
function SocialsDisplayPanel({ display, onChange, className }) {
|
|
11186
|
-
return /* @__PURE__ */ (0,
|
|
11187
|
-
/* @__PURE__ */ (0,
|
|
11996
|
+
return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: cn("flex w-full flex-col gap-3", className), children: [
|
|
11997
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
11188
11998
|
DisplaySwitch,
|
|
11189
11999
|
{
|
|
11190
12000
|
label: "Text",
|
|
@@ -11193,7 +12003,7 @@ function SocialsDisplayPanel({ display, onChange, className }) {
|
|
|
11193
12003
|
onChange: (text) => onChange({ ...display, text })
|
|
11194
12004
|
}
|
|
11195
12005
|
),
|
|
11196
|
-
/* @__PURE__ */ (0,
|
|
12006
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
11197
12007
|
DisplaySwitch,
|
|
11198
12008
|
{
|
|
11199
12009
|
label: "Icon",
|
|
@@ -11753,8 +12563,8 @@ function useNavItemDrag({
|
|
|
11753
12563
|
}
|
|
11754
12564
|
|
|
11755
12565
|
// src/ui/footer-container-chrome.tsx
|
|
11756
|
-
var
|
|
11757
|
-
var
|
|
12566
|
+
var import_lucide_react15 = require("lucide-react");
|
|
12567
|
+
var import_jsx_runtime29 = require("react/jsx-runtime");
|
|
11758
12568
|
function FooterContainerChrome({
|
|
11759
12569
|
rect,
|
|
11760
12570
|
onAdd,
|
|
@@ -11762,7 +12572,7 @@ function FooterContainerChrome({
|
|
|
11762
12572
|
}) {
|
|
11763
12573
|
const chromeGap = 6;
|
|
11764
12574
|
const buttonMargin = 7;
|
|
11765
|
-
return /* @__PURE__ */ (0,
|
|
12575
|
+
return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(TooltipProvider, { delayDuration: 0, children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
11766
12576
|
"div",
|
|
11767
12577
|
{
|
|
11768
12578
|
"data-ohw-footer-container-chrome": "",
|
|
@@ -11774,8 +12584,8 @@ function FooterContainerChrome({
|
|
|
11774
12584
|
width: rect.width + chromeGap * 2,
|
|
11775
12585
|
height: rect.height + chromeGap * 2
|
|
11776
12586
|
},
|
|
11777
|
-
children: /* @__PURE__ */ (0,
|
|
11778
|
-
/* @__PURE__ */ (0,
|
|
12587
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(Tooltip, { children: [
|
|
12588
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
11779
12589
|
"button",
|
|
11780
12590
|
{
|
|
11781
12591
|
type: "button",
|
|
@@ -11794,10 +12604,10 @@ function FooterContainerChrome({
|
|
|
11794
12604
|
if (addDisabled) return;
|
|
11795
12605
|
onAdd();
|
|
11796
12606
|
},
|
|
11797
|
-
children: /* @__PURE__ */ (0,
|
|
12607
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_lucide_react15.Plus, { className: "size-4 shrink-0 text-foreground", "aria-hidden": true })
|
|
11798
12608
|
}
|
|
11799
12609
|
) }),
|
|
11800
|
-
/* @__PURE__ */ (0,
|
|
12610
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(TooltipContent, { side: "bottom", sideOffset: 9, children: addDisabled ? "Maximum columns reached" : "Add item" })
|
|
11801
12611
|
] })
|
|
11802
12612
|
}
|
|
11803
12613
|
) });
|
|
@@ -11980,6 +12790,18 @@ function collectEditableNodes(extraContent, root = document) {
|
|
|
11980
12790
|
}
|
|
11981
12791
|
if (extraContent && !isScoped) {
|
|
11982
12792
|
applyNavFooterDeleteOverrides(byKey, extraContent);
|
|
12793
|
+
for (const key of LOGO_IMAGE_KEYS) {
|
|
12794
|
+
if (!(key in extraContent)) continue;
|
|
12795
|
+
byKey.set(key, { key, type: "image", text: extraContent[key] ?? "" });
|
|
12796
|
+
}
|
|
12797
|
+
for (const key of [LOGO_PLACEHOLDER_KEY, LOGO_ALT_KEY]) {
|
|
12798
|
+
if (!(key in extraContent)) continue;
|
|
12799
|
+
byKey.set(key, { key, type: "meta", text: extraContent[key] ?? "" });
|
|
12800
|
+
}
|
|
12801
|
+
for (const key of LOGO_SIZE_KEYS) {
|
|
12802
|
+
if (!(key in extraContent)) continue;
|
|
12803
|
+
byKey.set(key, { key, type: "meta", text: extraContent[key] ?? "" });
|
|
12804
|
+
}
|
|
11983
12805
|
}
|
|
11984
12806
|
return Array.from(byKey.values());
|
|
11985
12807
|
}
|
|
@@ -12245,14 +13067,14 @@ function deleteSelectedNavFooterItem(deps) {
|
|
|
12245
13067
|
}
|
|
12246
13068
|
|
|
12247
13069
|
// src/ui/navbar-container-chrome.tsx
|
|
12248
|
-
var
|
|
12249
|
-
var
|
|
13070
|
+
var import_lucide_react16 = require("lucide-react");
|
|
13071
|
+
var import_jsx_runtime30 = require("react/jsx-runtime");
|
|
12250
13072
|
function NavbarContainerChrome({
|
|
12251
13073
|
rect,
|
|
12252
13074
|
onAdd
|
|
12253
13075
|
}) {
|
|
12254
13076
|
const chromeGap = 6;
|
|
12255
|
-
return /* @__PURE__ */ (0,
|
|
13077
|
+
return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
12256
13078
|
"div",
|
|
12257
13079
|
{
|
|
12258
13080
|
"data-ohw-navbar-container-chrome": "",
|
|
@@ -12264,7 +13086,7 @@ function NavbarContainerChrome({
|
|
|
12264
13086
|
width: rect.width + chromeGap * 2,
|
|
12265
13087
|
height: rect.height + chromeGap * 2
|
|
12266
13088
|
},
|
|
12267
|
-
children: /* @__PURE__ */ (0,
|
|
13089
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
12268
13090
|
"button",
|
|
12269
13091
|
{
|
|
12270
13092
|
type: "button",
|
|
@@ -12281,7 +13103,7 @@ function NavbarContainerChrome({
|
|
|
12281
13103
|
e.stopPropagation();
|
|
12282
13104
|
onAdd();
|
|
12283
13105
|
},
|
|
12284
|
-
children: /* @__PURE__ */ (0,
|
|
13106
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_lucide_react16.Plus, { className: "size-4 shrink-0 text-foreground", "aria-hidden": true })
|
|
12285
13107
|
}
|
|
12286
13108
|
)
|
|
12287
13109
|
}
|
|
@@ -12290,7 +13112,7 @@ function NavbarContainerChrome({
|
|
|
12290
13112
|
|
|
12291
13113
|
// src/ui/drop-indicator.tsx
|
|
12292
13114
|
var React10 = __toESM(require("react"), 1);
|
|
12293
|
-
var
|
|
13115
|
+
var import_jsx_runtime31 = require("react/jsx-runtime");
|
|
12294
13116
|
var dropIndicatorVariants = cva(
|
|
12295
13117
|
"ov-gap-line pointer-events-none shrink-0 transition-opacity duration-150",
|
|
12296
13118
|
{
|
|
@@ -12314,7 +13136,7 @@ var dropIndicatorVariants = cva(
|
|
|
12314
13136
|
);
|
|
12315
13137
|
var DropIndicator = React10.forwardRef(
|
|
12316
13138
|
({ className, direction, state, ...props }, ref) => {
|
|
12317
|
-
return /* @__PURE__ */ (0,
|
|
13139
|
+
return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
|
|
12318
13140
|
"div",
|
|
12319
13141
|
{
|
|
12320
13142
|
ref,
|
|
@@ -12331,7 +13153,7 @@ var DropIndicator = React10.forwardRef(
|
|
|
12331
13153
|
DropIndicator.displayName = "DropIndicator";
|
|
12332
13154
|
|
|
12333
13155
|
// src/ui/badge.tsx
|
|
12334
|
-
var
|
|
13156
|
+
var import_jsx_runtime32 = require("react/jsx-runtime");
|
|
12335
13157
|
var badgeVariants = cva(
|
|
12336
13158
|
"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",
|
|
12337
13159
|
{
|
|
@@ -12349,12 +13171,12 @@ var badgeVariants = cva(
|
|
|
12349
13171
|
}
|
|
12350
13172
|
);
|
|
12351
13173
|
function Badge({ className, variant, ...props }) {
|
|
12352
|
-
return /* @__PURE__ */ (0,
|
|
13174
|
+
return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: cn(badgeVariants({ variant }), className), ...props });
|
|
12353
13175
|
}
|
|
12354
13176
|
|
|
12355
13177
|
// src/OhhwellsBridge.tsx
|
|
12356
|
-
var
|
|
12357
|
-
var
|
|
13178
|
+
var import_lucide_react17 = require("lucide-react");
|
|
13179
|
+
var import_jsx_runtime33 = require("react/jsx-runtime");
|
|
12358
13180
|
var PRIMARY3 = "#0885FE";
|
|
12359
13181
|
var IMAGE_FADE_MS = 300;
|
|
12360
13182
|
function runOpacityFade(el, onDone) {
|
|
@@ -12448,21 +13270,10 @@ function parseSchedulingInsertAfter(insertAfter) {
|
|
|
12448
13270
|
insertBefore: insertAfter.slice(idx + INSERT_BEFORE_MARKER.length)
|
|
12449
13271
|
};
|
|
12450
13272
|
}
|
|
12451
|
-
function
|
|
12452
|
-
|
|
12453
|
-
const
|
|
12454
|
-
|
|
12455
|
-
return { effectiveInsertAfter, insertBefore };
|
|
12456
|
-
}
|
|
12457
|
-
function getSchedulingMountPoint(insertAfter) {
|
|
12458
|
-
const { anchor } = parseSchedulingInsertAfter(insertAfter);
|
|
12459
|
-
let anchorEl = document.querySelector(`[data-ohw-section="${anchor}"]`);
|
|
12460
|
-
if (!anchorEl && anchor === "scheduling") {
|
|
12461
|
-
const widgets = Array.from(document.querySelectorAll('[data-ohw-section^="scheduling-"]'));
|
|
12462
|
-
anchorEl = widgets.at(-1) ?? null;
|
|
12463
|
-
}
|
|
12464
|
-
if (!anchorEl) return null;
|
|
12465
|
-
return anchorEl.closest('[data-ohw-section-container="scheduling"]') ?? anchorEl;
|
|
13273
|
+
function resolveEntryAnchor(entry) {
|
|
13274
|
+
if (entry.anchorId !== void 0) return { anchorId: entry.anchorId, beforeId: entry.beforeId ?? null };
|
|
13275
|
+
const parsed = parseSchedulingInsertAfter(entry.insertAfter);
|
|
13276
|
+
return { anchorId: parsed.anchor, beforeId: parsed.insertBefore };
|
|
12466
13277
|
}
|
|
12467
13278
|
function schedulingMountDepth(insertAfter) {
|
|
12468
13279
|
if (!insertAfter.includes(INSERT_BEFORE_MARKER)) return 0;
|
|
@@ -12479,8 +13290,7 @@ function getPageSchedulingEntries(raw) {
|
|
|
12479
13290
|
}
|
|
12480
13291
|
}
|
|
12481
13292
|
function isSchedulingWidgetMissing(entry) {
|
|
12482
|
-
|
|
12483
|
-
return !document.querySelector(`[data-ohw-section="${schedulingSectionId(effectiveInsertAfter)}"]`);
|
|
13293
|
+
return !document.querySelector(`[data-ohw-section="${schedulingSectionId(entry.insertAfter)}"]`);
|
|
12484
13294
|
}
|
|
12485
13295
|
function hasMissingSchedulingWidgets(entries) {
|
|
12486
13296
|
return entries.some(isSchedulingWidgetMissing);
|
|
@@ -12510,16 +13320,17 @@ function initSectionsFromContent(content, removeExisting = false) {
|
|
|
12510
13320
|
} catch {
|
|
12511
13321
|
}
|
|
12512
13322
|
}
|
|
12513
|
-
function mountSchedulingWidget(
|
|
12514
|
-
const
|
|
12515
|
-
const sectionId = schedulingSectionId(
|
|
13323
|
+
function mountSchedulingWidget(anchorId, notifyOnConnect = false, scheduleId, beforeId, existingWidgetId) {
|
|
13324
|
+
const widgetId = existingWidgetId ?? (beforeId ? `${anchorId}${INSERT_BEFORE_MARKER}${beforeId}` : anchorId);
|
|
13325
|
+
const sectionId = schedulingSectionId(widgetId);
|
|
12516
13326
|
if (document.querySelector(`[data-ohw-section="${sectionId}"]`)) return false;
|
|
12517
|
-
const
|
|
12518
|
-
if (!
|
|
13327
|
+
const anchorEl = document.querySelector(`[data-ohw-section="${anchorId}"]`);
|
|
13328
|
+
if (!anchorEl) return false;
|
|
13329
|
+
const mountPoint = anchorEl.closest('[data-ohw-section-container="scheduling"]') ?? anchorEl;
|
|
12519
13330
|
const container = document.createElement("div");
|
|
12520
13331
|
container.dataset.ohwSectionContainer = "scheduling";
|
|
12521
|
-
if (
|
|
12522
|
-
const beforeAnchor = document.querySelector(`[data-ohw-section="${
|
|
13332
|
+
if (beforeId) {
|
|
13333
|
+
const beforeAnchor = document.querySelector(`[data-ohw-section="${beforeId}"]`);
|
|
12523
13334
|
const beforePoint = beforeAnchor?.closest('[data-ohw-section-container="scheduling"]') ?? beforeAnchor;
|
|
12524
13335
|
if (!beforePoint) return false;
|
|
12525
13336
|
beforePoint.insertAdjacentElement("beforebegin", container);
|
|
@@ -12530,19 +13341,25 @@ function mountSchedulingWidget(insertAfter, notifyOnConnect = false, scheduleId,
|
|
|
12530
13341
|
}
|
|
12531
13342
|
tail.insertAdjacentElement("afterend", container);
|
|
12532
13343
|
}
|
|
12533
|
-
|
|
12534
|
-
|
|
12535
|
-
|
|
12536
|
-
|
|
12537
|
-
|
|
12538
|
-
|
|
12539
|
-
|
|
12540
|
-
|
|
12541
|
-
|
|
12542
|
-
|
|
12543
|
-
|
|
12544
|
-
|
|
12545
|
-
|
|
13344
|
+
try {
|
|
13345
|
+
const root = (0, import_client2.createRoot)(container);
|
|
13346
|
+
(0, import_react_dom3.flushSync)(() => {
|
|
13347
|
+
root.render(
|
|
13348
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
13349
|
+
SchedulingWidget,
|
|
13350
|
+
{
|
|
13351
|
+
notifyOnConnect,
|
|
13352
|
+
initialScheduleId: scheduleId,
|
|
13353
|
+
insertAfter: widgetId
|
|
13354
|
+
}
|
|
13355
|
+
)
|
|
13356
|
+
);
|
|
13357
|
+
});
|
|
13358
|
+
} catch (err) {
|
|
13359
|
+
console.error("[ow:scheduling] render threw", err);
|
|
13360
|
+
container.remove();
|
|
13361
|
+
return false;
|
|
13362
|
+
}
|
|
12546
13363
|
const tracker = getSectionsTracker();
|
|
12547
13364
|
let sections = [];
|
|
12548
13365
|
try {
|
|
@@ -12550,10 +13367,12 @@ function mountSchedulingWidget(insertAfter, notifyOnConnect = false, scheduleId,
|
|
|
12550
13367
|
} catch {
|
|
12551
13368
|
}
|
|
12552
13369
|
const inEditor = typeof window !== "undefined" && window.self !== window.top;
|
|
12553
|
-
if (inEditor && !sections.find((s) => s.type === "scheduling" && s.insertAfter ===
|
|
13370
|
+
if (inEditor && !sections.find((s) => s.type === "scheduling" && s.insertAfter === widgetId)) {
|
|
12554
13371
|
sections.push({
|
|
12555
13372
|
type: "scheduling",
|
|
12556
|
-
insertAfter:
|
|
13373
|
+
insertAfter: widgetId,
|
|
13374
|
+
anchorId,
|
|
13375
|
+
beforeId: beforeId ?? null,
|
|
12557
13376
|
pagePath: window.location.pathname,
|
|
12558
13377
|
...scheduleId ? { scheduleId } : {}
|
|
12559
13378
|
});
|
|
@@ -12567,7 +13386,8 @@ function mountSchedulingEntries(entries, notifyOnConnect = false) {
|
|
|
12567
13386
|
for (let i = pending.length - 1; i >= 0; i--) {
|
|
12568
13387
|
const entry = pending[i];
|
|
12569
13388
|
const shouldNotify = typeof notifyOnConnect === "function" ? notifyOnConnect(entry) : notifyOnConnect;
|
|
12570
|
-
|
|
13389
|
+
const { anchorId, beforeId } = resolveEntryAnchor(entry);
|
|
13390
|
+
if (mountSchedulingWidget(anchorId, shouldNotify, entry.scheduleId ?? null, beforeId, entry.insertAfter)) {
|
|
12571
13391
|
pending.splice(i, 1);
|
|
12572
13392
|
}
|
|
12573
13393
|
}
|
|
@@ -12711,6 +13531,13 @@ function isInsideLinkEditor(target) {
|
|
|
12711
13531
|
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"]')
|
|
12712
13532
|
);
|
|
12713
13533
|
}
|
|
13534
|
+
function isInsideFloatingPanel(target) {
|
|
13535
|
+
return Boolean(target.closest("[data-ohw-floating-panel]"));
|
|
13536
|
+
}
|
|
13537
|
+
function isPointOverFloatingPanel(clientX, clientY) {
|
|
13538
|
+
const el = document.elementFromPoint(clientX, clientY);
|
|
13539
|
+
return Boolean(el instanceof Element && el.closest("[data-ohw-floating-panel]"));
|
|
13540
|
+
}
|
|
12714
13541
|
function getHrefKeyFromElement(el) {
|
|
12715
13542
|
if (!el) return null;
|
|
12716
13543
|
const anchor = el.closest("[data-ohw-href-key]");
|
|
@@ -12948,7 +13775,7 @@ function getNavigationSelectionParent(el) {
|
|
|
12948
13775
|
if (!isFooterLinksContainer(el) && (el.hasAttribute("data-ohw-footer-col") || el.hasAttribute("data-ohw-footer-column") || isInferredFooterGroup2(el))) {
|
|
12949
13776
|
return getFooterLinksContainer();
|
|
12950
13777
|
}
|
|
12951
|
-
if (el.hasAttribute("data-ohw-nav-container") || el.hasAttribute("data-ohw-nav-drawer") || isFooterLinksContainer(el)) {
|
|
13778
|
+
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)) {
|
|
12952
13779
|
return getNavigationRoot(el);
|
|
12953
13780
|
}
|
|
12954
13781
|
return null;
|
|
@@ -13194,7 +14021,7 @@ function EditGlowChrome({
|
|
|
13194
14021
|
hideHandle = false
|
|
13195
14022
|
}) {
|
|
13196
14023
|
const GAP = SELECTION_CHROME_GAP2;
|
|
13197
|
-
return /* @__PURE__ */ (0,
|
|
14024
|
+
return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(
|
|
13198
14025
|
"div",
|
|
13199
14026
|
{
|
|
13200
14027
|
ref: elRef,
|
|
@@ -13209,7 +14036,7 @@ function EditGlowChrome({
|
|
|
13209
14036
|
zIndex: 2147483646
|
|
13210
14037
|
},
|
|
13211
14038
|
children: [
|
|
13212
|
-
/* @__PURE__ */ (0,
|
|
14039
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
13213
14040
|
"div",
|
|
13214
14041
|
{
|
|
13215
14042
|
style: {
|
|
@@ -13222,7 +14049,7 @@ function EditGlowChrome({
|
|
|
13222
14049
|
}
|
|
13223
14050
|
}
|
|
13224
14051
|
),
|
|
13225
|
-
reorderHrefKey && !hideHandle && /* @__PURE__ */ (0,
|
|
14052
|
+
reorderHrefKey && !hideHandle && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
13226
14053
|
"div",
|
|
13227
14054
|
{
|
|
13228
14055
|
"data-ohw-drag-handle-container": "",
|
|
@@ -13234,7 +14061,7 @@ function EditGlowChrome({
|
|
|
13234
14061
|
transform: "translate(calc(-100% - 7px), -50%)",
|
|
13235
14062
|
pointerEvents: dragDisabled ? "none" : "auto"
|
|
13236
14063
|
},
|
|
13237
|
-
children: /* @__PURE__ */ (0,
|
|
14064
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
13238
14065
|
DragHandle,
|
|
13239
14066
|
{
|
|
13240
14067
|
"aria-label": `Reorder ${reorderHrefKey}`,
|
|
@@ -13444,7 +14271,7 @@ function FloatingToolbar({
|
|
|
13444
14271
|
return () => ro.disconnect();
|
|
13445
14272
|
}, [showEditLink, activeCommands]);
|
|
13446
14273
|
const { top, left, transform } = calcToolbarPos(rect, parentScroll, measuredW);
|
|
13447
|
-
return /* @__PURE__ */ (0,
|
|
14274
|
+
return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
13448
14275
|
"div",
|
|
13449
14276
|
{
|
|
13450
14277
|
ref: setRefs,
|
|
@@ -13456,12 +14283,12 @@ function FloatingToolbar({
|
|
|
13456
14283
|
zIndex: 2147483647,
|
|
13457
14284
|
pointerEvents: "auto"
|
|
13458
14285
|
},
|
|
13459
|
-
children: /* @__PURE__ */ (0,
|
|
13460
|
-
TOOLBAR_GROUPS.map((btns, gi) => /* @__PURE__ */ (0,
|
|
13461
|
-
gi > 0 && /* @__PURE__ */ (0,
|
|
14286
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(CustomToolbar, { children: [
|
|
14287
|
+
TOOLBAR_GROUPS.map((btns, gi) => /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(import_react16.default.Fragment, { children: [
|
|
14288
|
+
gi > 0 && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(CustomToolbarDivider, {}),
|
|
13462
14289
|
btns.map((btn) => {
|
|
13463
14290
|
const isActive = activeCommands.has(btn.cmd);
|
|
13464
|
-
return /* @__PURE__ */ (0,
|
|
14291
|
+
return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
13465
14292
|
CustomToolbarButton,
|
|
13466
14293
|
{
|
|
13467
14294
|
title: btn.title,
|
|
@@ -13470,7 +14297,7 @@ function FloatingToolbar({
|
|
|
13470
14297
|
e.preventDefault();
|
|
13471
14298
|
onCommand(btn.cmd);
|
|
13472
14299
|
},
|
|
13473
|
-
children: /* @__PURE__ */ (0,
|
|
14300
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
13474
14301
|
"svg",
|
|
13475
14302
|
{
|
|
13476
14303
|
width: "16",
|
|
@@ -13491,7 +14318,7 @@ function FloatingToolbar({
|
|
|
13491
14318
|
);
|
|
13492
14319
|
})
|
|
13493
14320
|
] }, gi)),
|
|
13494
|
-
showEditLink ? /* @__PURE__ */ (0,
|
|
14321
|
+
showEditLink ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
13495
14322
|
CustomToolbarButton,
|
|
13496
14323
|
{
|
|
13497
14324
|
type: "button",
|
|
@@ -13505,7 +14332,7 @@ function FloatingToolbar({
|
|
|
13505
14332
|
e.preventDefault();
|
|
13506
14333
|
e.stopPropagation();
|
|
13507
14334
|
},
|
|
13508
|
-
children: /* @__PURE__ */ (0,
|
|
14335
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_lucide_react17.Link, { className: "size-4 shrink-0", "aria-hidden": true })
|
|
13509
14336
|
}
|
|
13510
14337
|
) : null
|
|
13511
14338
|
] })
|
|
@@ -13522,7 +14349,7 @@ function StateToggle({
|
|
|
13522
14349
|
states,
|
|
13523
14350
|
onStateChange
|
|
13524
14351
|
}) {
|
|
13525
|
-
return /* @__PURE__ */ (0,
|
|
14352
|
+
return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
13526
14353
|
ToggleGroup,
|
|
13527
14354
|
{
|
|
13528
14355
|
"data-ohw-state-toggle": "",
|
|
@@ -13536,11 +14363,12 @@ function StateToggle({
|
|
|
13536
14363
|
left: rect.right - 8,
|
|
13537
14364
|
transform: "translateX(-100%)"
|
|
13538
14365
|
},
|
|
13539
|
-
children: states.map((state) => /* @__PURE__ */ (0,
|
|
14366
|
+
children: states.map((state) => /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(ToggleGroupItem, { value: state, size: "sm", children: state }, state))
|
|
13540
14367
|
}
|
|
13541
14368
|
);
|
|
13542
14369
|
}
|
|
13543
14370
|
var contentCache = /* @__PURE__ */ new Map();
|
|
14371
|
+
var fetchedContentPaths = /* @__PURE__ */ new Set();
|
|
13544
14372
|
function resolveSubdomain(subdomainFromQuery) {
|
|
13545
14373
|
if (subdomainFromQuery) return subdomainFromQuery;
|
|
13546
14374
|
if (typeof window !== "undefined") {
|
|
@@ -13635,8 +14463,14 @@ function OhhwellsBridge() {
|
|
|
13635
14463
|
});
|
|
13636
14464
|
const selectFrameRef = (0, import_react16.useRef)(() => {
|
|
13637
14465
|
});
|
|
14466
|
+
const selectLogoRef = (0, import_react16.useRef)(() => {
|
|
14467
|
+
});
|
|
14468
|
+
const openLogoSizePanelRef = (0, import_react16.useRef)(() => {
|
|
14469
|
+
});
|
|
13638
14470
|
const deselectRef = (0, import_react16.useRef)(() => {
|
|
13639
14471
|
});
|
|
14472
|
+
const closeFloatingPanelOnlyRef = (0, import_react16.useRef)(() => {
|
|
14473
|
+
});
|
|
13640
14474
|
const reselectNavigationItemRef = (0, import_react16.useRef)(() => {
|
|
13641
14475
|
});
|
|
13642
14476
|
const commitNavigationTextEditRef = (0, import_react16.useRef)(() => {
|
|
@@ -13697,11 +14531,6 @@ function OhhwellsBridge() {
|
|
|
13697
14531
|
const [isItemDragging, setIsItemDragging] = (0, import_react16.useState)(false);
|
|
13698
14532
|
const [isFooterFrameSelection, setIsFooterFrameSelection] = (0, import_react16.useState)(false);
|
|
13699
14533
|
isFooterFrameSelectionRef.current = isFooterFrameSelection;
|
|
13700
|
-
const [floatingPanel, setFloatingPanel] = (0, import_react16.useState)(null);
|
|
13701
|
-
const floatingPanelOpenRef = (0, import_react16.useRef)(false);
|
|
13702
|
-
floatingPanelOpenRef.current = floatingPanel !== null;
|
|
13703
|
-
const [floatingPanelPos, setFloatingPanelPos] = (0, import_react16.useState)(null);
|
|
13704
|
-
const [parentScrollSnap, setParentScrollSnap] = (0, import_react16.useState)(null);
|
|
13705
14534
|
const [navDropdownPreviewOpen, setNavDropdownPreviewOpen] = (0, import_react16.useState)(null);
|
|
13706
14535
|
const [footerHeadingVisible, setFooterHeadingVisible] = (0, import_react16.useState)(null);
|
|
13707
14536
|
const footerDragRef = (0, import_react16.useRef)(null);
|
|
@@ -13716,7 +14545,16 @@ function OhhwellsBridge() {
|
|
|
13716
14545
|
const addNavAfterAnchorRef = (0, import_react16.useRef)(null);
|
|
13717
14546
|
const editContentRef = (0, import_react16.useRef)({});
|
|
13718
14547
|
const aiSectionsRef = (0, import_react16.useRef)("");
|
|
14548
|
+
const brandKitRef = (0, import_react16.useRef)("");
|
|
14549
|
+
const stylesRef = (0, import_react16.useRef)("");
|
|
13719
14550
|
const pendingDeleteUndoRef = (0, import_react16.useRef)(null);
|
|
14551
|
+
const [floatingPanel, setFloatingPanel] = (0, import_react16.useState)(null);
|
|
14552
|
+
const floatingPanelOpenRef = (0, import_react16.useRef)(false);
|
|
14553
|
+
const setFloatingPanelRef = (0, import_react16.useRef)(setFloatingPanel);
|
|
14554
|
+
const [floatingPanelPos, setFloatingPanelPos] = (0, import_react16.useState)(null);
|
|
14555
|
+
const [logoSizeDraft, setLogoSizeDraft] = (0, import_react16.useState)(null);
|
|
14556
|
+
const [editorViewport, setEditorViewport] = (0, import_react16.useState)("desktop");
|
|
14557
|
+
const [parentScrollSnap, setParentScrollSnap] = (0, import_react16.useState)(null);
|
|
13720
14558
|
const [sitePages, setSitePages] = (0, import_react16.useState)([]);
|
|
13721
14559
|
const [sectionsByPath, setSectionsByPath] = (0, import_react16.useState)({});
|
|
13722
14560
|
const sectionsPrefetchGenRef = (0, import_react16.useRef)(0);
|
|
@@ -13725,7 +14563,18 @@ function OhhwellsBridge() {
|
|
|
13725
14563
|
const linkPopoverOpenRef = (0, import_react16.useRef)(false);
|
|
13726
14564
|
const linkPopoverGraceUntilRef = (0, import_react16.useRef)(0);
|
|
13727
14565
|
setLinkPopoverRef.current = setLinkPopover;
|
|
14566
|
+
setFloatingPanelRef.current = setFloatingPanel;
|
|
13728
14567
|
linkPopoverSessionRef.current = linkPopover;
|
|
14568
|
+
floatingPanelOpenRef.current = Boolean(floatingPanel);
|
|
14569
|
+
(0, import_react16.useEffect)(() => {
|
|
14570
|
+
const syncViewport = () => {
|
|
14571
|
+
const next = window.innerWidth <= 480 ? "mobile" : "desktop";
|
|
14572
|
+
setEditorViewport((prev) => prev === next ? prev : next);
|
|
14573
|
+
};
|
|
14574
|
+
syncViewport();
|
|
14575
|
+
window.addEventListener("resize", syncViewport);
|
|
14576
|
+
return () => window.removeEventListener("resize", syncViewport);
|
|
14577
|
+
}, []);
|
|
13729
14578
|
const {
|
|
13730
14579
|
navDragRef,
|
|
13731
14580
|
navDropSlots,
|
|
@@ -13948,6 +14797,10 @@ function OhhwellsBridge() {
|
|
|
13948
14797
|
setIsItemDragging(false);
|
|
13949
14798
|
hoveredNavContainerRef.current = null;
|
|
13950
14799
|
setHoveredNavContainerRect(null);
|
|
14800
|
+
hoveredItemElRef.current = null;
|
|
14801
|
+
setHoveredItemRect(null);
|
|
14802
|
+
setFloatingPanel(null);
|
|
14803
|
+
setLogoSizeDraft(null);
|
|
13951
14804
|
if (!activeElRef.current) {
|
|
13952
14805
|
setNavGroupForceOpen(null, false);
|
|
13953
14806
|
setToolbarRect(null);
|
|
@@ -14653,6 +15506,8 @@ function OhhwellsBridge() {
|
|
|
14653
15506
|
setToolbarRect(anchor.getBoundingClientRect());
|
|
14654
15507
|
setToolbarShowEditLink(false);
|
|
14655
15508
|
setActiveCommands(/* @__PURE__ */ new Set());
|
|
15509
|
+
setFloatingPanel(null);
|
|
15510
|
+
setLogoSizeDraft(null);
|
|
14656
15511
|
}, [deactivate, markSelected]);
|
|
14657
15512
|
const selectFrame = (0, import_react16.useCallback)((el) => {
|
|
14658
15513
|
if (!isNavigationContainer(el)) return;
|
|
@@ -14702,7 +15557,51 @@ function OhhwellsBridge() {
|
|
|
14702
15557
|
setToolbarRect(el.getBoundingClientRect());
|
|
14703
15558
|
setToolbarShowEditLink(false);
|
|
14704
15559
|
setActiveCommands(/* @__PURE__ */ new Set());
|
|
15560
|
+
setFloatingPanel(null);
|
|
15561
|
+
setLogoSizeDraft(null);
|
|
14705
15562
|
}, [deactivate, markSelected, postToParent2]);
|
|
15563
|
+
const selectLogo = (0, import_react16.useCallback)(
|
|
15564
|
+
(logoEl) => {
|
|
15565
|
+
if (activeElRef.current) deactivate();
|
|
15566
|
+
selectedElRef.current = logoEl;
|
|
15567
|
+
selectedHrefKeyRef.current = null;
|
|
15568
|
+
selectedFooterColAttrRef.current = null;
|
|
15569
|
+
markSelected(logoEl);
|
|
15570
|
+
setSelectedIsCta(false);
|
|
15571
|
+
setSelectedIsSocial(false);
|
|
15572
|
+
setSelectedIsSocialsRow(false);
|
|
15573
|
+
clearHrefKeyHover(logoEl);
|
|
15574
|
+
hoveredNavContainerRef.current = null;
|
|
15575
|
+
setHoveredNavContainerRect(null);
|
|
15576
|
+
setHoveredItemRect(null);
|
|
15577
|
+
hoveredItemElRef.current = null;
|
|
15578
|
+
siblingHintElRef.current = null;
|
|
15579
|
+
setSiblingHintRect(null);
|
|
15580
|
+
setSiblingHintRects([]);
|
|
15581
|
+
setIsItemDragging(false);
|
|
15582
|
+
setReorderHrefKey(null);
|
|
15583
|
+
setReorderDragDisabled(false);
|
|
15584
|
+
setIsFooterFrameSelection(false);
|
|
15585
|
+
setToolbarVariant("logo");
|
|
15586
|
+
setToolbarRect(getLogoInteractionRect(logoEl));
|
|
15587
|
+
setToolbarShowEditLink(false);
|
|
15588
|
+
setActiveCommands(/* @__PURE__ */ new Set());
|
|
15589
|
+
},
|
|
15590
|
+
[deactivate, markSelected]
|
|
15591
|
+
);
|
|
15592
|
+
const openLogoSizePanel = (0, import_react16.useCallback)((logoEl) => {
|
|
15593
|
+
const placement = getLogoPlacement(logoEl);
|
|
15594
|
+
const draft = readLogoSizeState(editContentRef.current, placement);
|
|
15595
|
+
setLogoSizeDraft(draft);
|
|
15596
|
+
setParentScrollSnap(parentScrollRef.current);
|
|
15597
|
+
setFloatingPanel({
|
|
15598
|
+
key: `logo-size:${placement}`,
|
|
15599
|
+
title: "Logo",
|
|
15600
|
+
context: placement === "navbar" ? "Navbar" : "Footer",
|
|
15601
|
+
kind: "logo-size",
|
|
15602
|
+
placement
|
|
15603
|
+
});
|
|
15604
|
+
}, []);
|
|
14706
15605
|
const openSocialsDisplayPanel = (0, import_react16.useCallback)((row) => {
|
|
14707
15606
|
setParentScrollSnap(parentScrollRef.current);
|
|
14708
15607
|
setFloatingPanel({
|
|
@@ -14738,13 +15637,53 @@ function OhhwellsBridge() {
|
|
|
14738
15637
|
);
|
|
14739
15638
|
const closeFloatingPanelOnly = (0, import_react16.useCallback)(() => {
|
|
14740
15639
|
setFloatingPanel(null);
|
|
15640
|
+
setLogoSizeDraft(null);
|
|
14741
15641
|
}, []);
|
|
14742
|
-
const closeFloatingPanelOnlyRef = (0, import_react16.useRef)(closeFloatingPanelOnly);
|
|
14743
|
-
closeFloatingPanelOnlyRef.current = closeFloatingPanelOnly;
|
|
14744
15642
|
const closeFloatingPanelAndDeselect = (0, import_react16.useCallback)(() => {
|
|
14745
15643
|
setFloatingPanel(null);
|
|
15644
|
+
setLogoSizeDraft(null);
|
|
14746
15645
|
deselectRef.current();
|
|
14747
15646
|
}, []);
|
|
15647
|
+
const persistLogoSizeDraft = (0, import_react16.useCallback)(
|
|
15648
|
+
(placement, draft) => {
|
|
15649
|
+
const desktopKey = LOGO_SIZE_DESKTOP_KEYS[placement];
|
|
15650
|
+
const mobileKey = LOGO_SIZE_MOBILE_KEYS[placement];
|
|
15651
|
+
const nodes = [
|
|
15652
|
+
{ key: desktopKey, text: String(draft.desktopPx) }
|
|
15653
|
+
];
|
|
15654
|
+
if (draft.mobileFollowing) {
|
|
15655
|
+
nodes.push({ key: mobileKey, text: "" });
|
|
15656
|
+
} else {
|
|
15657
|
+
nodes.push({ key: mobileKey, text: String(draft.mobilePx) });
|
|
15658
|
+
}
|
|
15659
|
+
editContentRef.current = {
|
|
15660
|
+
...editContentRef.current,
|
|
15661
|
+
[desktopKey]: String(draft.desktopPx),
|
|
15662
|
+
[mobileKey]: draft.mobileFollowing ? "" : String(draft.mobilePx)
|
|
15663
|
+
};
|
|
15664
|
+
applyLogoSizeToPlacement(
|
|
15665
|
+
placement,
|
|
15666
|
+
draft.desktopPx,
|
|
15667
|
+
draft.mobileFollowing ? draft.desktopPx : draft.mobilePx,
|
|
15668
|
+
draft.mobileFollowing
|
|
15669
|
+
);
|
|
15670
|
+
postToParent2({ type: "ow:change", nodes });
|
|
15671
|
+
requestAnimationFrame(() => {
|
|
15672
|
+
const selected = selectedElRef.current;
|
|
15673
|
+
if (!selected || toolbarVariantRef.current !== "logo") return;
|
|
15674
|
+
const rect = getLogoInteractionRect(selected);
|
|
15675
|
+
setToolbarRect(rect);
|
|
15676
|
+
if (glowElRef.current) {
|
|
15677
|
+
const GAP = SELECTION_CHROME_GAP2;
|
|
15678
|
+
glowElRef.current.style.top = `${rect.top - GAP}px`;
|
|
15679
|
+
glowElRef.current.style.left = `${rect.left - GAP}px`;
|
|
15680
|
+
glowElRef.current.style.width = `${rect.width + GAP * 2}px`;
|
|
15681
|
+
glowElRef.current.style.height = `${rect.height + GAP * 2}px`;
|
|
15682
|
+
}
|
|
15683
|
+
});
|
|
15684
|
+
},
|
|
15685
|
+
[postToParent2]
|
|
15686
|
+
);
|
|
14748
15687
|
const activate = (0, import_react16.useCallback)((el, options) => {
|
|
14749
15688
|
if (activeElRef.current === el) return;
|
|
14750
15689
|
if (isIconEditable(el)) return;
|
|
@@ -14825,7 +15764,37 @@ function OhhwellsBridge() {
|
|
|
14825
15764
|
deactivateRef.current = deactivate;
|
|
14826
15765
|
selectRef.current = select;
|
|
14827
15766
|
selectFrameRef.current = selectFrame;
|
|
15767
|
+
selectLogoRef.current = selectLogo;
|
|
15768
|
+
openLogoSizePanelRef.current = openLogoSizePanel;
|
|
14828
15769
|
deselectRef.current = deselect;
|
|
15770
|
+
closeFloatingPanelOnlyRef.current = closeFloatingPanelOnly;
|
|
15771
|
+
const lastSiteWideScopeRef = (0, import_react16.useRef)(null);
|
|
15772
|
+
(0, import_react16.useEffect)(() => {
|
|
15773
|
+
if (!isEditMode) {
|
|
15774
|
+
if (lastSiteWideScopeRef.current !== false) {
|
|
15775
|
+
lastSiteWideScopeRef.current = false;
|
|
15776
|
+
postToParent2({ type: "ow:site-wide-scope", active: false });
|
|
15777
|
+
}
|
|
15778
|
+
return;
|
|
15779
|
+
}
|
|
15780
|
+
const active = isSiteWideScopeActive({
|
|
15781
|
+
selected: selectedElRef.current,
|
|
15782
|
+
hoveredItem: hoveredItemElRef.current,
|
|
15783
|
+
hoveredNavContainer: hoveredNavContainerRef.current,
|
|
15784
|
+
active: activeElRef.current
|
|
15785
|
+
});
|
|
15786
|
+
if (lastSiteWideScopeRef.current === active) return;
|
|
15787
|
+
lastSiteWideScopeRef.current = active;
|
|
15788
|
+
postToParent2({ type: "ow:site-wide-scope", active });
|
|
15789
|
+
}, [
|
|
15790
|
+
isEditMode,
|
|
15791
|
+
hoveredItemRect,
|
|
15792
|
+
hoveredNavContainerRect,
|
|
15793
|
+
toolbarVariant,
|
|
15794
|
+
toolbarRect,
|
|
15795
|
+
isFooterFrameSelection,
|
|
15796
|
+
postToParent2
|
|
15797
|
+
]);
|
|
14829
15798
|
(0, import_react16.useLayoutEffect)(() => {
|
|
14830
15799
|
if (!subdomain || isEditMode) {
|
|
14831
15800
|
setFetchState("done");
|
|
@@ -14837,9 +15806,23 @@ function OhhwellsBridge() {
|
|
|
14837
15806
|
aiSectionsRef.current = content[AI_SECTIONS_KEY];
|
|
14838
15807
|
applyAiSectionsToDom(parseAiSectionsState(content[AI_SECTIONS_KEY]));
|
|
14839
15808
|
}
|
|
15809
|
+
if (typeof content[BRAND_KIT_KEY] === "string") {
|
|
15810
|
+
brandKitRef.current = content[BRAND_KIT_KEY];
|
|
15811
|
+
applyBrandToDom(parseBrandKit(content[BRAND_KIT_KEY]));
|
|
15812
|
+
}
|
|
15813
|
+
if (typeof content[STYLE_STORE_KEY] === "string") {
|
|
15814
|
+
stylesRef.current = content[STYLE_STORE_KEY];
|
|
15815
|
+
applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
|
|
15816
|
+
}
|
|
15817
|
+
applyBrandChrome(content);
|
|
14840
15818
|
for (const [key, val] of Object.entries(content)) {
|
|
14841
15819
|
if (key === "__ohw_sections") continue;
|
|
14842
15820
|
if (key === AI_SECTIONS_KEY) continue;
|
|
15821
|
+
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
15822
|
+
if (LOGO_IMAGE_KEYS.includes(key)) continue;
|
|
15823
|
+
if (key === BRAND_KIT_KEY) continue;
|
|
15824
|
+
if (key === STYLE_STORE_KEY) continue;
|
|
15825
|
+
if (BRAND_CHROME_KEYS.has(key)) continue;
|
|
14843
15826
|
if (applyVideoSettingNode(key, val)) continue;
|
|
14844
15827
|
if (applyCarouselNode(key, val)) continue;
|
|
14845
15828
|
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
@@ -14874,6 +15857,8 @@ function OhhwellsBridge() {
|
|
|
14874
15857
|
});
|
|
14875
15858
|
applyLinkByKey(key, val);
|
|
14876
15859
|
}
|
|
15860
|
+
applyLogoFromContent(content);
|
|
15861
|
+
applyLogoSizes(content);
|
|
14877
15862
|
reconcileNavbarItemsFromContent(content);
|
|
14878
15863
|
reconcileFooterOrderFromContent(content);
|
|
14879
15864
|
reconcileSocialsFromContent(content);
|
|
@@ -14894,7 +15879,9 @@ function OhhwellsBridge() {
|
|
|
14894
15879
|
let cancelled = false;
|
|
14895
15880
|
setFetchState("loading");
|
|
14896
15881
|
const apiUrl = process.env.NEXT_PUBLIC_FLOWOPS_API_URL ?? "https://flowops-backend-staging-2yfdh7pwpq-as.a.run.app";
|
|
14897
|
-
|
|
15882
|
+
const initialPath = pathname;
|
|
15883
|
+
fetchedContentPaths.add(`${subdomain}::${initialPath}`);
|
|
15884
|
+
fetch(`${apiUrl}/api/public/sites/${subdomain}/content?path=${encodeURIComponent(initialPath)}`, { cache: "no-store" }).then((r2) => r2.ok ? r2.json() : null).then((data) => {
|
|
14898
15885
|
if (cancelled) return;
|
|
14899
15886
|
const content = data?.content ?? {};
|
|
14900
15887
|
contentCache.set(subdomain, content);
|
|
@@ -14918,8 +15905,21 @@ function OhhwellsBridge() {
|
|
|
14918
15905
|
initSectionInstancesFromContent(content, window.location.pathname);
|
|
14919
15906
|
observer?.disconnect();
|
|
14920
15907
|
try {
|
|
15908
|
+
applyBrandChrome(content);
|
|
15909
|
+
if (typeof content[BRAND_KIT_KEY] === "string") {
|
|
15910
|
+
applyBrandToDom(parseBrandKit(content[BRAND_KIT_KEY]));
|
|
15911
|
+
}
|
|
15912
|
+
if (typeof content[STYLE_STORE_KEY] === "string") {
|
|
15913
|
+
applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
|
|
15914
|
+
}
|
|
14921
15915
|
for (const [key, val] of Object.entries(content)) {
|
|
14922
15916
|
if (key === "__ohw_sections") continue;
|
|
15917
|
+
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
15918
|
+
if (LOGO_IMAGE_KEYS.includes(key)) continue;
|
|
15919
|
+
if (key === BRAND_KIT_KEY) continue;
|
|
15920
|
+
if (key === STYLE_STORE_KEY) continue;
|
|
15921
|
+
if (key === STYLE_STORE_KEY) continue;
|
|
15922
|
+
if (BRAND_CHROME_KEYS.has(key)) continue;
|
|
14923
15923
|
if (applyVideoSettingNode(key, val)) continue;
|
|
14924
15924
|
if (applyCarouselNode(key, val)) continue;
|
|
14925
15925
|
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
@@ -14940,6 +15940,7 @@ function OhhwellsBridge() {
|
|
|
14940
15940
|
});
|
|
14941
15941
|
applyLinkByKey(key, val);
|
|
14942
15942
|
}
|
|
15943
|
+
applyLogoFromContent(content);
|
|
14943
15944
|
reconcileNavbarItemsFromContent(content);
|
|
14944
15945
|
reconcileFooterOrderFromContent(content);
|
|
14945
15946
|
reconcileSocialsFromContent(content);
|
|
@@ -14954,6 +15955,17 @@ function OhhwellsBridge() {
|
|
|
14954
15955
|
debounceTimer = setTimeout(applyFromCache, 150);
|
|
14955
15956
|
};
|
|
14956
15957
|
applyFromCache();
|
|
15958
|
+
const pathCacheKey = `${subdomain}::${pathname}`;
|
|
15959
|
+
if (!fetchedContentPaths.has(pathCacheKey)) {
|
|
15960
|
+
fetchedContentPaths.add(pathCacheKey);
|
|
15961
|
+
const apiUrl = process.env.NEXT_PUBLIC_FLOWOPS_API_URL ?? "https://flowops-backend-staging-2yfdh7pwpq-as.a.run.app";
|
|
15962
|
+
fetch(`${apiUrl}/api/public/sites/${subdomain}/content?path=${encodeURIComponent(pathname)}`, { cache: "no-store" }).then((r2) => r2.ok ? r2.json() : null).then((data) => {
|
|
15963
|
+
if (!data?.content) return;
|
|
15964
|
+
contentCache.set(subdomain, data.content);
|
|
15965
|
+
applyFromCache();
|
|
15966
|
+
}).catch(() => {
|
|
15967
|
+
});
|
|
15968
|
+
}
|
|
14957
15969
|
observer = new MutationObserver(scheduleApply);
|
|
14958
15970
|
observer.observe(document.body, { childList: true, subtree: true });
|
|
14959
15971
|
return () => {
|
|
@@ -15047,26 +16059,31 @@ function OhhwellsBridge() {
|
|
|
15047
16059
|
}, [isEditMode, pathname, subdomain, fetchState, resyncSelectedNavigationItem]);
|
|
15048
16060
|
(0, import_react16.useEffect)(() => {
|
|
15049
16061
|
if (!isEditMode) return;
|
|
16062
|
+
let lastPosted = 0;
|
|
15050
16063
|
const measure = () => {
|
|
15051
16064
|
const h = document.body.scrollHeight;
|
|
15052
|
-
if (h > 50
|
|
16065
|
+
if (h > 50 && Math.abs(h - lastPosted) > 1) {
|
|
16066
|
+
lastPosted = h;
|
|
16067
|
+
postToParent2({ type: "ow:height", height: h });
|
|
16068
|
+
}
|
|
16069
|
+
};
|
|
16070
|
+
let raf = null;
|
|
16071
|
+
const schedule = () => {
|
|
16072
|
+
if (raf != null) return;
|
|
16073
|
+
raf = requestAnimationFrame(() => {
|
|
16074
|
+
raf = null;
|
|
16075
|
+
measure();
|
|
16076
|
+
});
|
|
15053
16077
|
};
|
|
15054
16078
|
const t1 = setTimeout(measure, 50);
|
|
15055
16079
|
const t2 = setTimeout(measure, 500);
|
|
15056
|
-
|
|
15057
|
-
|
|
15058
|
-
const handleResize = () => {
|
|
15059
|
-
if (window.innerWidth === lastWidth) return;
|
|
15060
|
-
lastWidth = window.innerWidth;
|
|
15061
|
-
if (resizeTimer) clearTimeout(resizeTimer);
|
|
15062
|
-
resizeTimer = setTimeout(measure, 150);
|
|
15063
|
-
};
|
|
15064
|
-
window.addEventListener("resize", handleResize);
|
|
16080
|
+
const ro = new ResizeObserver(schedule);
|
|
16081
|
+
ro.observe(document.body);
|
|
15065
16082
|
return () => {
|
|
15066
16083
|
clearTimeout(t1);
|
|
15067
16084
|
clearTimeout(t2);
|
|
15068
|
-
if (
|
|
15069
|
-
|
|
16085
|
+
if (raf != null) cancelAnimationFrame(raf);
|
|
16086
|
+
ro.disconnect();
|
|
15070
16087
|
};
|
|
15071
16088
|
}, [pathname, isEditMode, postToParent2]);
|
|
15072
16089
|
(0, import_react16.useEffect)(() => {
|
|
@@ -15216,10 +16233,12 @@ function OhhwellsBridge() {
|
|
|
15216
16233
|
return;
|
|
15217
16234
|
}
|
|
15218
16235
|
const target = e.target;
|
|
16236
|
+
if (target.closest("[data-ohw-ai-review]")) return;
|
|
15219
16237
|
if (target.closest("[data-ohw-toolbar]")) return;
|
|
15220
16238
|
if (target.closest("[data-ohw-state-toggle]")) return;
|
|
15221
16239
|
if (target.closest("[data-ohw-max-badge]")) return;
|
|
15222
16240
|
if (isInsideLinkEditor(target)) return;
|
|
16241
|
+
if (isInsideFloatingPanel(target)) return;
|
|
15223
16242
|
if (target.closest('[data-ohw-edit-chrome], [data-ohw-item-interaction], [data-ohw-drag-handle-container], [data-slot="drag-handle"]')) {
|
|
15224
16243
|
const beneath = document.elementsFromPoint(e.clientX, e.clientY).find(
|
|
15225
16244
|
(el) => el instanceof HTMLElement && !el.closest("[data-ohw-bridge-root]") && el.closest("[data-ohw-section]") != null
|
|
@@ -15283,6 +16302,21 @@ function OhhwellsBridge() {
|
|
|
15283
16302
|
return;
|
|
15284
16303
|
}
|
|
15285
16304
|
}
|
|
16305
|
+
const logoEl = getLogoElement(target);
|
|
16306
|
+
if (logoEl) {
|
|
16307
|
+
e.preventDefault();
|
|
16308
|
+
e.stopPropagation();
|
|
16309
|
+
if (!logoHasUploadedImage(logoEl)) {
|
|
16310
|
+
deselectRef.current();
|
|
16311
|
+
deactivateRef.current();
|
|
16312
|
+
const identity = readLogoIdentityFromDom();
|
|
16313
|
+
postToParentRef.current({ type: "ow:open-logo-settings", ...identity });
|
|
16314
|
+
return;
|
|
16315
|
+
}
|
|
16316
|
+
selectLogoRef.current(logoEl);
|
|
16317
|
+
openLogoSizePanelRef.current(logoEl);
|
|
16318
|
+
return;
|
|
16319
|
+
}
|
|
15286
16320
|
const editable = target.closest("[data-ohw-editable]");
|
|
15287
16321
|
if (editable) {
|
|
15288
16322
|
if (editable.dataset.ohwEditable === "link") {
|
|
@@ -15435,10 +16469,12 @@ function OhhwellsBridge() {
|
|
|
15435
16469
|
};
|
|
15436
16470
|
const handleDblClick = (e) => {
|
|
15437
16471
|
const target = e.target;
|
|
16472
|
+
if (target.closest("[data-ohw-ai-review]")) return;
|
|
15438
16473
|
if (target.closest("[data-ohw-toolbar]")) return;
|
|
15439
16474
|
if (target.closest("[data-ohw-state-toggle]")) return;
|
|
15440
16475
|
if (target.closest("[data-ohw-max-badge]")) return;
|
|
15441
16476
|
if (isInsideLinkEditor(target)) return;
|
|
16477
|
+
if (isInsideFloatingPanel(target)) return;
|
|
15442
16478
|
if (target.closest('[data-ohw-edit-chrome], [data-ohw-item-interaction], [data-ohw-drag-handle-container], [data-slot="drag-handle"]')) {
|
|
15443
16479
|
return;
|
|
15444
16480
|
}
|
|
@@ -15466,11 +16502,14 @@ function OhhwellsBridge() {
|
|
|
15466
16502
|
setHoveredNavContainerRect(null);
|
|
15467
16503
|
return;
|
|
15468
16504
|
}
|
|
15469
|
-
if (document.documentElement.hasAttribute("data-ohw-panel-dragging") || target.
|
|
16505
|
+
if (document.documentElement.hasAttribute("data-ohw-panel-dragging") || isInsideFloatingPanel(target) || isPointOverFloatingPanel(e.clientX, e.clientY)) {
|
|
15470
16506
|
hoveredItemElRef.current = null;
|
|
15471
16507
|
setHoveredItemRect(null);
|
|
15472
16508
|
hoveredNavContainerRef.current = null;
|
|
15473
16509
|
setHoveredNavContainerRect(null);
|
|
16510
|
+
siblingHintElRef.current = null;
|
|
16511
|
+
setSiblingHintRect(null);
|
|
16512
|
+
setSiblingHintRects([]);
|
|
15474
16513
|
return;
|
|
15475
16514
|
}
|
|
15476
16515
|
{
|
|
@@ -15480,7 +16519,7 @@ function OhhwellsBridge() {
|
|
|
15480
16519
|
const allowFooterLinksHover = toolbarVariantRef.current !== "select-frame" || selectedIsFooterColumn;
|
|
15481
16520
|
if (allowNavContainerHover) {
|
|
15482
16521
|
const navContainer = target.closest("[data-ohw-nav-container]");
|
|
15483
|
-
if (navContainer && !getNavigationItemAnchor(target)) {
|
|
16522
|
+
if (navContainer && !getNavigationItemAnchor(target) && !getLogoElement(target)) {
|
|
15484
16523
|
hoveredNavContainerRef.current = navContainer;
|
|
15485
16524
|
setHoveredNavContainerRect(navContainer.getBoundingClientRect());
|
|
15486
16525
|
hoveredItemElRef.current = null;
|
|
@@ -15509,6 +16548,15 @@ function OhhwellsBridge() {
|
|
|
15509
16548
|
setHoveredNavContainerRect(null);
|
|
15510
16549
|
}
|
|
15511
16550
|
}
|
|
16551
|
+
const logoEl = getLogoElement(target);
|
|
16552
|
+
if (logoEl) {
|
|
16553
|
+
hoveredNavContainerRef.current = null;
|
|
16554
|
+
setHoveredNavContainerRect(null);
|
|
16555
|
+
if (selectedElRef.current === logoEl) return;
|
|
16556
|
+
hoveredItemElRef.current = logoEl;
|
|
16557
|
+
setHoveredItemRect(getLogoInteractionRect(logoEl));
|
|
16558
|
+
return;
|
|
16559
|
+
}
|
|
15512
16560
|
const navAnchor = getNavigationItemAnchor(target);
|
|
15513
16561
|
if (navAnchor) {
|
|
15514
16562
|
hoveredNavContainerRef.current = null;
|
|
@@ -15546,6 +16594,11 @@ function OhhwellsBridge() {
|
|
|
15546
16594
|
setHoveredItemRect(hoverTarget.getBoundingClientRect());
|
|
15547
16595
|
} else if (!isInsideNavigationItem(editable)) {
|
|
15548
16596
|
hoverTarget.setAttribute("data-ohw-hovered", "");
|
|
16597
|
+
if (editable.closest("footer") || editable.closest('[data-ohw-section="footer"]')) {
|
|
16598
|
+
hoveredNavContainerRef.current = null;
|
|
16599
|
+
setHoveredNavContainerRect(null);
|
|
16600
|
+
hoveredItemElRef.current = editable;
|
|
16601
|
+
}
|
|
15549
16602
|
}
|
|
15550
16603
|
}
|
|
15551
16604
|
};
|
|
@@ -15581,6 +16634,18 @@ function OhhwellsBridge() {
|
|
|
15581
16634
|
}
|
|
15582
16635
|
return;
|
|
15583
16636
|
}
|
|
16637
|
+
const logoEl = getLogoElement(target);
|
|
16638
|
+
if (logoEl) {
|
|
16639
|
+
const related2 = e.relatedTarget instanceof Element ? e.relatedTarget : null;
|
|
16640
|
+
if (related2 && (logoEl === related2 || logoEl.contains(related2) || related2.closest?.('[data-ohw-role="logo"], [data-ohw-logo]'))) {
|
|
16641
|
+
return;
|
|
16642
|
+
}
|
|
16643
|
+
if (hoveredItemElRef.current === logoEl) {
|
|
16644
|
+
hoveredItemElRef.current = null;
|
|
16645
|
+
setHoveredItemRect(null);
|
|
16646
|
+
}
|
|
16647
|
+
return;
|
|
16648
|
+
}
|
|
15584
16649
|
const editable = target.closest("[data-ohw-editable]");
|
|
15585
16650
|
if (!editable) return;
|
|
15586
16651
|
const related = e.relatedTarget instanceof Element ? e.relatedTarget : null;
|
|
@@ -15601,6 +16666,13 @@ function OhhwellsBridge() {
|
|
|
15601
16666
|
}
|
|
15602
16667
|
} else {
|
|
15603
16668
|
hoverTarget.removeAttribute("data-ohw-hovered");
|
|
16669
|
+
if (hoveredItemElRef.current === editable) {
|
|
16670
|
+
const stillOnEditable = related instanceof Element && related.closest("[data-ohw-editable]") === editable;
|
|
16671
|
+
if (!stillOnEditable) {
|
|
16672
|
+
hoveredItemElRef.current = null;
|
|
16673
|
+
setHoveredItemRect(null);
|
|
16674
|
+
}
|
|
16675
|
+
}
|
|
15604
16676
|
}
|
|
15605
16677
|
}
|
|
15606
16678
|
};
|
|
@@ -15717,6 +16789,26 @@ function OhhwellsBridge() {
|
|
|
15717
16789
|
hoveredNavContainerRef.current = null;
|
|
15718
16790
|
setHoveredNavContainerRect(null);
|
|
15719
16791
|
}
|
|
16792
|
+
const logoCandidates = [
|
|
16793
|
+
...document.querySelectorAll('[data-ohw-role="logo"], [data-ohw-logo]'),
|
|
16794
|
+
...document.querySelectorAll("nav a:not([data-ohw-href-key]), [data-ohw-nav-root] a:not([data-ohw-href-key])"),
|
|
16795
|
+
...document.querySelectorAll("footer img")
|
|
16796
|
+
];
|
|
16797
|
+
const seenLogos = /* @__PURE__ */ new Set();
|
|
16798
|
+
for (const candidate of logoCandidates) {
|
|
16799
|
+
const logo = getLogoElement(candidate);
|
|
16800
|
+
if (!logo || seenLogos.has(logo)) continue;
|
|
16801
|
+
seenLogos.add(logo);
|
|
16802
|
+
const r2 = logo.getBoundingClientRect();
|
|
16803
|
+
if (x < r2.left || x > r2.right || y < r2.top || y > r2.bottom) continue;
|
|
16804
|
+
hoveredNavContainerRef.current = null;
|
|
16805
|
+
setHoveredNavContainerRect(null);
|
|
16806
|
+
if (selectedElRef.current !== logo) {
|
|
16807
|
+
hoveredItemElRef.current = logo;
|
|
16808
|
+
setHoveredItemRect(getLogoInteractionRect(logo));
|
|
16809
|
+
}
|
|
16810
|
+
return;
|
|
16811
|
+
}
|
|
15720
16812
|
const navContainers = Array.from(
|
|
15721
16813
|
document.querySelectorAll("[data-ohw-nav-container]")
|
|
15722
16814
|
);
|
|
@@ -15802,7 +16894,7 @@ function OhhwellsBridge() {
|
|
|
15802
16894
|
}
|
|
15803
16895
|
};
|
|
15804
16896
|
const probeImageAt = (clientX, clientY, isDragOver = false, fromParentViewport = false) => {
|
|
15805
|
-
if (linkPopoverOpenRef.current) {
|
|
16897
|
+
if (linkPopoverOpenRef.current || floatingPanelOpenRef.current && isPointOverFloatingPanel(clientX, clientY)) {
|
|
15806
16898
|
if (hoveredImageRef.current) {
|
|
15807
16899
|
hoveredImageRef.current = null;
|
|
15808
16900
|
hoveredImageHasTextOverlapRef.current = false;
|
|
@@ -16056,7 +17148,7 @@ function OhhwellsBridge() {
|
|
|
16056
17148
|
}
|
|
16057
17149
|
};
|
|
16058
17150
|
const probeHoverCardsAt = (clientX, clientY, fromParentViewport = false) => {
|
|
16059
|
-
if (linkPopoverOpenRef.current || document.documentElement.hasAttribute("data-ohw-section-picking")) {
|
|
17151
|
+
if (linkPopoverOpenRef.current || floatingPanelOpenRef.current && isPointOverFloatingPanel(clientX, clientY) || document.documentElement.hasAttribute("data-ohw-section-picking")) {
|
|
16060
17152
|
if (activeStateElRef.current) {
|
|
16061
17153
|
activeStateElRef.current.removeAttribute("data-ohw-state-hovered");
|
|
16062
17154
|
activeStateElRef.current = null;
|
|
@@ -16122,16 +17214,21 @@ function OhhwellsBridge() {
|
|
|
16122
17214
|
setSectionGap(null);
|
|
16123
17215
|
}
|
|
16124
17216
|
};
|
|
16125
|
-
const pointOwnedByFloatingPanel = (clientX, clientY) => {
|
|
16126
|
-
if (document.documentElement.hasAttribute("data-ohw-panel-dragging")) return true;
|
|
16127
|
-
const panel = document.querySelector("[data-ohw-floating-panel]");
|
|
16128
|
-
if (!panel) return false;
|
|
16129
|
-
const rect = panel.getBoundingClientRect();
|
|
16130
|
-
return clientX >= rect.left && clientX <= rect.right && clientY >= rect.top && clientY <= rect.bottom;
|
|
16131
|
-
};
|
|
16132
17217
|
const handleMouseMove = (e) => {
|
|
16133
17218
|
const { clientX, clientY } = e;
|
|
16134
|
-
if (
|
|
17219
|
+
if (document.documentElement.hasAttribute("data-ohw-panel-dragging") || floatingPanelOpenRef.current && isPointOverFloatingPanel(clientX, clientY)) {
|
|
17220
|
+
hoveredItemElRef.current = null;
|
|
17221
|
+
setHoveredItemRect(null);
|
|
17222
|
+
hoveredNavContainerRef.current = null;
|
|
17223
|
+
setHoveredNavContainerRect(null);
|
|
17224
|
+
siblingHintElRef.current = null;
|
|
17225
|
+
setSiblingHintRect(null);
|
|
17226
|
+
setSiblingHintRects([]);
|
|
17227
|
+
dismissImageHover();
|
|
17228
|
+
clearImageHover();
|
|
17229
|
+
setSectionGap(null);
|
|
17230
|
+
return;
|
|
17231
|
+
}
|
|
16135
17232
|
probeSectionGapAt(clientX, clientY);
|
|
16136
17233
|
probeImageAt(clientX, clientY);
|
|
16137
17234
|
probeHoverCardsAt(clientX, clientY);
|
|
@@ -16140,7 +17237,11 @@ function OhhwellsBridge() {
|
|
|
16140
17237
|
if (e.data?.type !== "ow:pointer-sync") return;
|
|
16141
17238
|
const { clientX, clientY } = e.data;
|
|
16142
17239
|
if (typeof clientX !== "number" || typeof clientY !== "number") return;
|
|
16143
|
-
if (
|
|
17240
|
+
if (document.documentElement.hasAttribute("data-ohw-panel-dragging") || floatingPanelOpenRef.current && isPointOverFloatingPanel(clientX, clientY)) {
|
|
17241
|
+
dismissImageHover();
|
|
17242
|
+
clearImageHover();
|
|
17243
|
+
return;
|
|
17244
|
+
}
|
|
16144
17245
|
probeSectionGapAt(clientX, clientY);
|
|
16145
17246
|
probeImageAt(clientX, clientY);
|
|
16146
17247
|
probeHoverCardsAt(clientX, clientY);
|
|
@@ -16390,6 +17491,15 @@ function OhhwellsBridge() {
|
|
|
16390
17491
|
aiSectionsRef.current = content[AI_SECTIONS_KEY];
|
|
16391
17492
|
applyAiSectionsToDom(parseAiSectionsState(content[AI_SECTIONS_KEY]));
|
|
16392
17493
|
}
|
|
17494
|
+
if (typeof content[BRAND_KIT_KEY] === "string") {
|
|
17495
|
+
brandKitRef.current = content[BRAND_KIT_KEY];
|
|
17496
|
+
applyBrandToDom(parseBrandKit(content[BRAND_KIT_KEY]));
|
|
17497
|
+
}
|
|
17498
|
+
if (typeof content[STYLE_STORE_KEY] === "string") {
|
|
17499
|
+
stylesRef.current = content[STYLE_STORE_KEY];
|
|
17500
|
+
applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
|
|
17501
|
+
}
|
|
17502
|
+
applyBrandChrome(content);
|
|
16393
17503
|
let sectionsJson = null;
|
|
16394
17504
|
for (const [key, val] of Object.entries(content)) {
|
|
16395
17505
|
if (key === "__ohw_sections") {
|
|
@@ -16397,6 +17507,11 @@ function OhhwellsBridge() {
|
|
|
16397
17507
|
continue;
|
|
16398
17508
|
}
|
|
16399
17509
|
if (key === AI_SECTIONS_KEY) continue;
|
|
17510
|
+
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
17511
|
+
if (LOGO_IMAGE_KEYS.includes(key) && !String(val ?? "").trim()) continue;
|
|
17512
|
+
if (key === BRAND_KIT_KEY) continue;
|
|
17513
|
+
if (key === STYLE_STORE_KEY) continue;
|
|
17514
|
+
if (BRAND_CHROME_KEYS.has(key)) continue;
|
|
16400
17515
|
if (applyVideoSettingNode(key, val)) continue;
|
|
16401
17516
|
if (applyCarouselNode(key, val)) continue;
|
|
16402
17517
|
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
@@ -16416,6 +17531,8 @@ function OhhwellsBridge() {
|
|
|
16416
17531
|
});
|
|
16417
17532
|
applyLinkByKey(key, val);
|
|
16418
17533
|
}
|
|
17534
|
+
applyLogoFromContent(content);
|
|
17535
|
+
applyLogoSizes(content);
|
|
16419
17536
|
if (sectionsJson) {
|
|
16420
17537
|
initSectionsFromContent({ __ohw_sections: sectionsJson }, true);
|
|
16421
17538
|
sectionsLoadedRef.current = true;
|
|
@@ -16431,6 +17548,58 @@ function OhhwellsBridge() {
|
|
|
16431
17548
|
if (hydratedHeight > 50) postToParentRef.current({ type: "ow:height", height: hydratedHeight });
|
|
16432
17549
|
postToParentRef.current({ type: "ow:hydrate-done" });
|
|
16433
17550
|
};
|
|
17551
|
+
const handleUpdateLogoIdentity = (e) => {
|
|
17552
|
+
if (e.data?.type !== "ow:update-logo-identity") return;
|
|
17553
|
+
const rawText = typeof e.data.text === "string" ? e.data.text : "";
|
|
17554
|
+
const alt = typeof e.data.alt === "string" ? e.data.alt : rawText;
|
|
17555
|
+
const href = typeof e.data.href === "string" ? e.data.href : void 0;
|
|
17556
|
+
const imageProvided = "image" in e.data;
|
|
17557
|
+
const imageUrl = imageProvided && typeof e.data.image === "string" && e.data.image.trim() ? e.data.image.trim() : imageProvided ? null : void 0;
|
|
17558
|
+
let isPlaceholder = e.data.isPlaceholder !== false;
|
|
17559
|
+
if (imageUrl) isPlaceholder = false;
|
|
17560
|
+
else if (imageProvided && imageUrl === null) {
|
|
17561
|
+
isPlaceholder = e.data.isPlaceholder === true || !rawText.trim() || resolveLogoDisplayText(rawText) === PLACEHOLDER_BUSINESS_NAME;
|
|
17562
|
+
}
|
|
17563
|
+
const display = applyLogoIdentity(rawText, isPlaceholder);
|
|
17564
|
+
const displayAlt = resolveLogoDisplayText(alt || display);
|
|
17565
|
+
if (imageUrl !== void 0) {
|
|
17566
|
+
applyLogoImage(imageUrl, displayAlt);
|
|
17567
|
+
} else {
|
|
17568
|
+
for (const key of LOGO_IMAGE_KEYS) {
|
|
17569
|
+
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
17570
|
+
const img = el instanceof HTMLImageElement ? el : el.querySelector("img");
|
|
17571
|
+
if (img) img.alt = displayAlt;
|
|
17572
|
+
});
|
|
17573
|
+
}
|
|
17574
|
+
}
|
|
17575
|
+
if (href !== void 0) {
|
|
17576
|
+
applyLogoHref(href);
|
|
17577
|
+
applyLinkByKey("nav-logo-href", href);
|
|
17578
|
+
applyLinkByKey("footer-logo-href", href);
|
|
17579
|
+
applyLinkByKey("logo-href", href);
|
|
17580
|
+
}
|
|
17581
|
+
const nodes = [
|
|
17582
|
+
...LOGO_TEXT_KEYS.map((key) => ({ key, text: display })),
|
|
17583
|
+
{ key: LOGO_PLACEHOLDER_KEY, text: isPlaceholder ? "true" : "false" },
|
|
17584
|
+
{ key: LOGO_ALT_KEY, text: displayAlt }
|
|
17585
|
+
];
|
|
17586
|
+
if (imageUrl !== void 0) {
|
|
17587
|
+
if (imageUrl) {
|
|
17588
|
+
for (const key of LOGO_IMAGE_KEYS) nodes.push({ key, text: imageUrl });
|
|
17589
|
+
} else {
|
|
17590
|
+
for (const key of LOGO_IMAGE_KEYS) nodes.push({ key, text: "" });
|
|
17591
|
+
}
|
|
17592
|
+
}
|
|
17593
|
+
if (href !== void 0) {
|
|
17594
|
+
for (const key of LOGO_HREF_KEYS) nodes.push({ key, text: href.trim() || "/" });
|
|
17595
|
+
}
|
|
17596
|
+
editContentRef.current = {
|
|
17597
|
+
...editContentRef.current,
|
|
17598
|
+
...Object.fromEntries(nodes.map(({ key, text }) => [key, text]))
|
|
17599
|
+
};
|
|
17600
|
+
applyLogoSizes(editContentRef.current);
|
|
17601
|
+
postToParentRef.current({ type: "ow:change", nodes });
|
|
17602
|
+
};
|
|
16434
17603
|
window.addEventListener("message", handleHydrate);
|
|
16435
17604
|
const postAiSectionsChanged = () => {
|
|
16436
17605
|
postToParentRef.current({
|
|
@@ -16444,7 +17613,10 @@ function OhhwellsBridge() {
|
|
|
16444
17613
|
const payload = e.data.payload;
|
|
16445
17614
|
if (!payload || typeof payload.id !== "string" || !isRenderableTree(payload.tree)) return;
|
|
16446
17615
|
const previous = aiSectionsRef.current;
|
|
16447
|
-
const nextState = applyTreeToState(parseAiSectionsState(previous),
|
|
17616
|
+
const nextState = applyTreeToState(parseAiSectionsState(previous), {
|
|
17617
|
+
...payload,
|
|
17618
|
+
path: payload.path ?? window.location.pathname
|
|
17619
|
+
});
|
|
16448
17620
|
const nextValue = serializeAiSectionsState(nextState);
|
|
16449
17621
|
aiSectionsRef.current = nextValue;
|
|
16450
17622
|
applyAiSectionsToDom(nextState);
|
|
@@ -16481,12 +17653,42 @@ function OhhwellsBridge() {
|
|
|
16481
17653
|
const value = typeof e.data.value === "string" ? e.data.value : "";
|
|
16482
17654
|
aiSectionsRef.current = value;
|
|
16483
17655
|
applyAiSectionsToDom(parseAiSectionsState(value));
|
|
17656
|
+
applyStylesToDom(parseStyleStore(stylesRef.current));
|
|
16484
17657
|
const restoredHeight = document.documentElement.scrollHeight;
|
|
16485
17658
|
if (restoredHeight > 50) postToParentRef.current({ type: "ow:height", height: restoredHeight });
|
|
16486
17659
|
postToParentRef.current({ type: "ow:change", nodes: [{ key: AI_SECTIONS_KEY, text: value }] });
|
|
16487
17660
|
postAiSectionsChanged();
|
|
16488
17661
|
};
|
|
16489
17662
|
window.addEventListener("message", handleAiSetSections);
|
|
17663
|
+
const handleAiSetBrand = (e) => {
|
|
17664
|
+
if (e.data?.type !== "ow:ai-set-brand") return;
|
|
17665
|
+
const value = typeof e.data.value === "string" ? e.data.value : "";
|
|
17666
|
+
const previous = brandKitRef.current;
|
|
17667
|
+
brandKitRef.current = value;
|
|
17668
|
+
applyBrandToDom(parseBrandKit(value));
|
|
17669
|
+
if (aiSectionsRef.current) applyAiSectionsToDom(parseAiSectionsState(aiSectionsRef.current));
|
|
17670
|
+
applyStylesToDom(parseStyleStore(stylesRef.current));
|
|
17671
|
+
postToParentRef.current({ type: "ow:change", nodes: [{ key: BRAND_KIT_KEY, text: value }] });
|
|
17672
|
+
postToParentRef.current({ type: "ow:ai-brand-applied", previous, value });
|
|
17673
|
+
};
|
|
17674
|
+
window.addEventListener("message", handleAiSetBrand);
|
|
17675
|
+
const handleAiSetStyles = (e) => {
|
|
17676
|
+
if (e.data?.type !== "ow:ai-set-styles") return;
|
|
17677
|
+
const value = typeof e.data.value === "string" ? e.data.value : "";
|
|
17678
|
+
const previous = stylesRef.current;
|
|
17679
|
+
stylesRef.current = value;
|
|
17680
|
+
applyStylesToDom(parseStyleStore(value));
|
|
17681
|
+
postToParentRef.current({ type: "ow:change", nodes: [{ key: STYLE_STORE_KEY, text: value }] });
|
|
17682
|
+
postToParentRef.current({ type: "ow:ai-styles-applied", previous, value });
|
|
17683
|
+
};
|
|
17684
|
+
window.addEventListener("message", handleAiSetStyles);
|
|
17685
|
+
const handleGetBrand = (e) => {
|
|
17686
|
+
if (e.data?.type !== "ow:get-brand") return;
|
|
17687
|
+
const template = deriveTemplateBrand();
|
|
17688
|
+
const value = brandKitRef.current || (template ? JSON.stringify(template) : "");
|
|
17689
|
+
postToParentRef.current({ type: "ow:brand-value", value });
|
|
17690
|
+
};
|
|
17691
|
+
window.addEventListener("message", handleGetBrand);
|
|
16490
17692
|
const handleDeactivate = (e) => {
|
|
16491
17693
|
if (e.data?.type !== "ow:deactivate") return;
|
|
16492
17694
|
if (Date.now() < linkPopoverGraceUntilRef.current) return;
|
|
@@ -16495,6 +17697,12 @@ function OhhwellsBridge() {
|
|
|
16495
17697
|
closeLinkPopoverRef.current();
|
|
16496
17698
|
return;
|
|
16497
17699
|
}
|
|
17700
|
+
if (floatingPanelOpenRef.current) {
|
|
17701
|
+
setFloatingPanelRef.current(null);
|
|
17702
|
+
deselectRef.current();
|
|
17703
|
+
deactivateRef.current();
|
|
17704
|
+
return;
|
|
17705
|
+
}
|
|
16498
17706
|
deselectRef.current();
|
|
16499
17707
|
deactivateRef.current();
|
|
16500
17708
|
};
|
|
@@ -16548,6 +17756,10 @@ function OhhwellsBridge() {
|
|
|
16548
17756
|
return;
|
|
16549
17757
|
}
|
|
16550
17758
|
if (selectedElRef.current) {
|
|
17759
|
+
if (toolbarVariantRef.current === "logo") {
|
|
17760
|
+
deselectRef.current();
|
|
17761
|
+
return;
|
|
17762
|
+
}
|
|
16551
17763
|
if (toolbarVariantRef.current === "select-frame") {
|
|
16552
17764
|
const parent2 = getNavigationSelectionParent(selectedElRef.current);
|
|
16553
17765
|
if (parent2 && isNavigationContainer(parent2) && isFooterLinksContainer(parent2) && !isFooterLinksContainer(selectedElRef.current)) {
|
|
@@ -16587,6 +17799,10 @@ function OhhwellsBridge() {
|
|
|
16587
17799
|
return;
|
|
16588
17800
|
}
|
|
16589
17801
|
if (e.key === "Escape" && selectedElRef.current && !activeElRef.current) {
|
|
17802
|
+
if (toolbarVariantRef.current === "logo") {
|
|
17803
|
+
deselectRef.current();
|
|
17804
|
+
return;
|
|
17805
|
+
}
|
|
16590
17806
|
if (toolbarVariantRef.current === "select-frame") {
|
|
16591
17807
|
const parent2 = getNavigationSelectionParent(selectedElRef.current);
|
|
16592
17808
|
if (parent2 && isNavigationContainer(parent2) && isFooterLinksContainer(parent2) && !isFooterLinksContainer(selectedElRef.current)) {
|
|
@@ -16664,7 +17880,8 @@ function OhhwellsBridge() {
|
|
|
16664
17880
|
const handleScroll = () => {
|
|
16665
17881
|
const focusEl = activeElRef.current ?? selectedElRef.current;
|
|
16666
17882
|
if (focusEl) {
|
|
16667
|
-
const
|
|
17883
|
+
const measureEl = activeElRef.current ? getEditMeasureEl(activeElRef.current) : toolbarVariantRef.current === "logo" ? null : focusEl;
|
|
17884
|
+
const r2 = measureEl ? measureEl.getBoundingClientRect() : toolbarVariantRef.current === "logo" ? getLogoInteractionRect(focusEl) : focusEl.getBoundingClientRect();
|
|
16668
17885
|
applyToolbarPos(r2);
|
|
16669
17886
|
setToolbarRect(r2);
|
|
16670
17887
|
setMaxBadge((prev) => prev && activeElRef.current ? { ...prev, rect: r2 } : prev);
|
|
@@ -16674,7 +17891,9 @@ function OhhwellsBridge() {
|
|
|
16674
17891
|
setToggleState((prev) => prev ? { ...prev, rect } : null);
|
|
16675
17892
|
}
|
|
16676
17893
|
if (hoveredItemElRef.current) {
|
|
16677
|
-
|
|
17894
|
+
const hoverEl = hoveredItemElRef.current;
|
|
17895
|
+
const logo = getLogoElement(hoverEl);
|
|
17896
|
+
setHoveredItemRect(logo ? getLogoInteractionRect(logo) : hoverEl.getBoundingClientRect());
|
|
16678
17897
|
}
|
|
16679
17898
|
if (hoveredNavContainerRef.current) {
|
|
16680
17899
|
setHoveredNavContainerRect(hoveredNavContainerRef.current.getBoundingClientRect());
|
|
@@ -16718,6 +17937,12 @@ function OhhwellsBridge() {
|
|
|
16718
17937
|
if (aiSectionsRef.current) {
|
|
16719
17938
|
nodes.push({ key: AI_SECTIONS_KEY, type: "sections", text: aiSectionsRef.current });
|
|
16720
17939
|
}
|
|
17940
|
+
if (stylesRef.current) {
|
|
17941
|
+
nodes.push({ key: STYLE_STORE_KEY, type: "styles", text: stylesRef.current });
|
|
17942
|
+
}
|
|
17943
|
+
if (brandKitRef.current) {
|
|
17944
|
+
nodes.push({ key: BRAND_KIT_KEY, type: "brand", text: brandKitRef.current });
|
|
17945
|
+
}
|
|
16721
17946
|
postToParentRef.current({ type: "ow:save-result", nodes });
|
|
16722
17947
|
};
|
|
16723
17948
|
const handleInsertSection = (e) => {
|
|
@@ -16728,8 +17953,12 @@ function OhhwellsBridge() {
|
|
|
16728
17953
|
if (inserted) {
|
|
16729
17954
|
const tracker = getSectionsTracker();
|
|
16730
17955
|
postToParentRef.current({ type: "ow:change", nodes: [{ key: "__ohw_sections", text: tracker.textContent ?? "[]" }] });
|
|
16731
|
-
const
|
|
16732
|
-
|
|
17956
|
+
const reportHeight = () => {
|
|
17957
|
+
const h = document.body.scrollHeight;
|
|
17958
|
+
if (h > 50) postToParentRef.current({ type: "ow:height", height: h });
|
|
17959
|
+
};
|
|
17960
|
+
reportHeight();
|
|
17961
|
+
setTimeout(reportHeight, 500);
|
|
16733
17962
|
}
|
|
16734
17963
|
};
|
|
16735
17964
|
const handleSwitchSchedule = (e) => {
|
|
@@ -16922,13 +18151,17 @@ function OhhwellsBridge() {
|
|
|
16922
18151
|
if (e.data?.type !== "ow:parent-scroll") return;
|
|
16923
18152
|
const { iframeOffsetTop, headerH, canvasH } = e.data;
|
|
16924
18153
|
parentScrollRef.current = { iframeOffsetTop, headerH, canvasH };
|
|
18154
|
+
if (floatingPanelOpenRef.current) {
|
|
18155
|
+
setParentScrollSnap({ iframeOffsetTop, headerH, canvasH });
|
|
18156
|
+
}
|
|
16925
18157
|
if (visibleViewportRef.current) {
|
|
16926
18158
|
applyVisibleViewport(visibleViewportRef.current, parentScrollRef.current);
|
|
16927
18159
|
}
|
|
16928
18160
|
const focusEl = activeElRef.current ?? selectedElRef.current;
|
|
16929
18161
|
if (focusEl) {
|
|
16930
|
-
const measureEl = activeElRef.current ? getEditMeasureEl(activeElRef.current) : focusEl;
|
|
16931
|
-
|
|
18162
|
+
const measureEl = activeElRef.current ? getEditMeasureEl(activeElRef.current) : toolbarVariantRef.current === "logo" ? null : focusEl;
|
|
18163
|
+
const r2 = measureEl ? measureEl.getBoundingClientRect() : toolbarVariantRef.current === "logo" ? getLogoInteractionRect(focusEl) : focusEl.getBoundingClientRect();
|
|
18164
|
+
applyToolbarPos(r2);
|
|
16932
18165
|
}
|
|
16933
18166
|
};
|
|
16934
18167
|
const handleClickAt = (e) => {
|
|
@@ -16953,6 +18186,25 @@ function OhhwellsBridge() {
|
|
|
16953
18186
|
postToParentRef.current({ type: "ow:image-pick", key: stateCardImage.dataset.ohwKey ?? "", elementType: stateCardImage.dataset.ohwEditable ?? "image" });
|
|
16954
18187
|
return;
|
|
16955
18188
|
}
|
|
18189
|
+
const logoAtPoint = Array.from(
|
|
18190
|
+
document.querySelectorAll('[data-ohw-role="logo"], [data-ohw-logo]')
|
|
18191
|
+
).map((el) => getLogoElement(el)).find((logo) => {
|
|
18192
|
+
if (!logo) return false;
|
|
18193
|
+
const r2 = logo.getBoundingClientRect();
|
|
18194
|
+
return clientX >= r2.left && clientX <= r2.right && clientY >= r2.top && clientY <= r2.bottom;
|
|
18195
|
+
});
|
|
18196
|
+
if (logoAtPoint) {
|
|
18197
|
+
if (!logoHasUploadedImage(logoAtPoint)) {
|
|
18198
|
+
deselectRef.current();
|
|
18199
|
+
deactivateRef.current();
|
|
18200
|
+
const identity = readLogoIdentityFromDom();
|
|
18201
|
+
postToParentRef.current({ type: "ow:open-logo-settings", ...identity });
|
|
18202
|
+
return;
|
|
18203
|
+
}
|
|
18204
|
+
selectLogoRef.current(logoAtPoint);
|
|
18205
|
+
openLogoSizePanelRef.current(logoAtPoint);
|
|
18206
|
+
return;
|
|
18207
|
+
}
|
|
16956
18208
|
const textEditable = Array.from(
|
|
16957
18209
|
document.querySelectorAll(NON_MEDIA_SELECTOR)
|
|
16958
18210
|
).find((el) => {
|
|
@@ -17024,6 +18276,14 @@ function OhhwellsBridge() {
|
|
|
17024
18276
|
window.addEventListener("message", handleParentScroll);
|
|
17025
18277
|
window.addEventListener("message", handlePointerSync);
|
|
17026
18278
|
window.addEventListener("message", handleClickAt);
|
|
18279
|
+
window.addEventListener("message", handleUpdateLogoIdentity);
|
|
18280
|
+
const handleViewMode = (e) => {
|
|
18281
|
+
if (e.data?.type !== "ow:view-mode") return;
|
|
18282
|
+
const mode = e.data.mode === "Mobile" || e.data.mode === "mobile" ? "mobile" : "desktop";
|
|
18283
|
+
setEditorViewport(mode);
|
|
18284
|
+
applyLogoSizes(editContentRef.current);
|
|
18285
|
+
};
|
|
18286
|
+
window.addEventListener("message", handleViewMode);
|
|
17027
18287
|
const handleViewportResize = () => {
|
|
17028
18288
|
if (visibleViewportRef.current) {
|
|
17029
18289
|
applyVisibleViewport(visibleViewportRef.current, parentScrollRef.current);
|
|
@@ -17079,10 +18339,15 @@ function OhhwellsBridge() {
|
|
|
17079
18339
|
window.removeEventListener("resize", handleViewportResize);
|
|
17080
18340
|
window.removeEventListener("message", handlePointerSync);
|
|
17081
18341
|
window.removeEventListener("message", handleClickAt);
|
|
18342
|
+
window.removeEventListener("message", handleUpdateLogoIdentity);
|
|
18343
|
+
window.removeEventListener("message", handleViewMode);
|
|
17082
18344
|
window.removeEventListener("message", handleHydrate);
|
|
17083
18345
|
window.removeEventListener("message", handleAiApplyTree);
|
|
17084
18346
|
window.removeEventListener("message", handleAiDeleteSection);
|
|
17085
18347
|
window.removeEventListener("message", handleAiSetSections);
|
|
18348
|
+
window.removeEventListener("message", handleAiSetBrand);
|
|
18349
|
+
window.removeEventListener("message", handleAiSetStyles);
|
|
18350
|
+
window.removeEventListener("message", handleGetBrand);
|
|
17086
18351
|
window.removeEventListener("message", handleDeactivate);
|
|
17087
18352
|
window.removeEventListener("message", handleToastAction);
|
|
17088
18353
|
window.removeEventListener("message", handleUiEscape);
|
|
@@ -17286,7 +18551,7 @@ function OhhwellsBridge() {
|
|
|
17286
18551
|
postToParent2({
|
|
17287
18552
|
type: "ow:ready",
|
|
17288
18553
|
version: "1",
|
|
17289
|
-
bridgeVersion: "0.1.
|
|
18554
|
+
bridgeVersion: "0.1.61",
|
|
17290
18555
|
path: pathname,
|
|
17291
18556
|
nodes: collectEditableNodes(editContentRef.current),
|
|
17292
18557
|
sections
|
|
@@ -17681,10 +18946,10 @@ function OhhwellsBridge() {
|
|
|
17681
18946
|
[postToParent2]
|
|
17682
18947
|
);
|
|
17683
18948
|
return bridgeRoot ? (0, import_react_dom4.createPortal)(
|
|
17684
|
-
/* @__PURE__ */ (0,
|
|
17685
|
-
/* @__PURE__ */ (0,
|
|
17686
|
-
isEditMode && /* @__PURE__ */ (0,
|
|
17687
|
-
Object.entries(uploadingRects).map(([key, { rect, fadingOut }]) => /* @__PURE__ */ (0,
|
|
18949
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(import_jsx_runtime33.Fragment, { children: [
|
|
18950
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { ref: attachVisibleViewport, "data-ohw-visible-viewport": "", "aria-hidden": true }),
|
|
18951
|
+
isEditMode && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(AiSectionOverlay, { postToParent: postToParent2, apiRef: aiSectionApiRef }),
|
|
18952
|
+
Object.entries(uploadingRects).map(([key, { rect, fadingOut }]) => /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
17688
18953
|
MediaOverlay,
|
|
17689
18954
|
{
|
|
17690
18955
|
hover: { key, rect, elementType: "image", isDragOver: false, hasTextOverlap: false },
|
|
@@ -17695,7 +18960,7 @@ function OhhwellsBridge() {
|
|
|
17695
18960
|
},
|
|
17696
18961
|
`uploading-${key}`
|
|
17697
18962
|
)),
|
|
17698
|
-
mediaHover && !(mediaHover.key in uploadingRects) && /* @__PURE__ */ (0,
|
|
18963
|
+
mediaHover && !(mediaHover.key in uploadingRects) && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
17699
18964
|
MediaOverlay,
|
|
17700
18965
|
{
|
|
17701
18966
|
hover: mediaHover,
|
|
@@ -17704,11 +18969,11 @@ function OhhwellsBridge() {
|
|
|
17704
18969
|
onVideoSettingsChange: handleVideoSettingsChange
|
|
17705
18970
|
}
|
|
17706
18971
|
),
|
|
17707
|
-
carouselHover && !linkPopover && !isItemDragging && /* @__PURE__ */ (0,
|
|
17708
|
-
siblingHintRect && !linkPopover && !isItemDragging && siblingHintRects.length === 0 && /* @__PURE__ */ (0,
|
|
17709
|
-
siblingHintRects.length > 0 && !linkPopover && !isItemDragging && siblingHintRects.map((rect, i) => /* @__PURE__ */ (0,
|
|
17710
|
-
isItemDragging && draggedItemRect && selectedElRef.current !== footerDragRef.current?.draggedEl && selectedElRef.current !== navDragRef.current?.draggedEl && /* @__PURE__ */ (0,
|
|
17711
|
-
isItemDragging && footerDropSlots.map((slot, i) => /* @__PURE__ */ (0,
|
|
18972
|
+
carouselHover && !linkPopover && !isItemDragging && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(CarouselOverlay, { hover: carouselHover, onEdit: handleEditCarousel }),
|
|
18973
|
+
siblingHintRect && !linkPopover && !isItemDragging && siblingHintRects.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(ItemInteractionLayer, { rect: siblingHintRect, state: "sibling-hint" }),
|
|
18974
|
+
siblingHintRects.length > 0 && !linkPopover && !isItemDragging && siblingHintRects.map((rect, i) => /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(ItemInteractionLayer, { rect, state: "sibling-hint" }, `sibling-hint-${i}`)),
|
|
18975
|
+
isItemDragging && draggedItemRect && selectedElRef.current !== footerDragRef.current?.draggedEl && selectedElRef.current !== navDragRef.current?.draggedEl && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(ItemInteractionLayer, { rect: draggedItemRect, state: "dragging" }),
|
|
18976
|
+
isItemDragging && footerDropSlots.map((slot, i) => /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
17712
18977
|
"div",
|
|
17713
18978
|
{
|
|
17714
18979
|
className: "pointer-events-none fixed z-2147483646",
|
|
@@ -17718,7 +18983,7 @@ function OhhwellsBridge() {
|
|
|
17718
18983
|
width: slot.width,
|
|
17719
18984
|
height: slot.height
|
|
17720
18985
|
},
|
|
17721
|
-
children: /* @__PURE__ */ (0,
|
|
18986
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
17722
18987
|
DropIndicator,
|
|
17723
18988
|
{
|
|
17724
18989
|
direction: slot.direction,
|
|
@@ -17729,7 +18994,7 @@ function OhhwellsBridge() {
|
|
|
17729
18994
|
},
|
|
17730
18995
|
`footer-drop-${slot.direction}-${slot.columnIndex}-${slot.insertIndex}-${i}`
|
|
17731
18996
|
)),
|
|
17732
|
-
isItemDragging && navDropSlots.map((slot, i) => /* @__PURE__ */ (0,
|
|
18997
|
+
isItemDragging && navDropSlots.map((slot, i) => /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
17733
18998
|
"div",
|
|
17734
18999
|
{
|
|
17735
19000
|
className: "pointer-events-none fixed z-2147483646",
|
|
@@ -17739,7 +19004,7 @@ function OhhwellsBridge() {
|
|
|
17739
19004
|
width: slot.width,
|
|
17740
19005
|
height: slot.height
|
|
17741
19006
|
},
|
|
17742
|
-
children: /* @__PURE__ */ (0,
|
|
19007
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
17743
19008
|
DropIndicator,
|
|
17744
19009
|
{
|
|
17745
19010
|
direction: slot.direction,
|
|
@@ -17750,11 +19015,11 @@ function OhhwellsBridge() {
|
|
|
17750
19015
|
},
|
|
17751
19016
|
`nav-drop-${slot.direction}-${slot.parentId ?? "root"}-${slot.insertIndex}-${i}`
|
|
17752
19017
|
)),
|
|
17753
|
-
hoveredNavContainerRect && (toolbarVariant !== "select-frame" || isFooterFrameSelection) && !linkPopover && !isItemDragging && /* @__PURE__ */ (0,
|
|
17754
|
-
hoveredItemRect && !linkPopover && !hoveredNavContainerRect && !isItemDragging && hoveredItemElRef.current !== selectedElRef.current && /* @__PURE__ */ (0,
|
|
17755
|
-
hoveredTextRect && !isItemDragging && toolbarVariant !== "rich-text" && /* @__PURE__ */ (0,
|
|
17756
|
-
toolbarVariant === "select-frame" && toolbarRect && !linkPopover && !isItemDragging && !isFooterFrameSelection && selectedElRef.current && isNavbarLinksContainer2(selectedElRef.current) && /* @__PURE__ */ (0,
|
|
17757
|
-
toolbarVariant === "select-frame" && toolbarRect && !linkPopover && !isItemDragging && !isFooterFrameSelection && selectedElRef.current && isFooterLinksContainer(selectedElRef.current) && /* @__PURE__ */ (0,
|
|
19018
|
+
hoveredNavContainerRect && (toolbarVariant !== "select-frame" || isFooterFrameSelection) && !linkPopover && !isItemDragging && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(ItemInteractionLayer, { rect: hoveredNavContainerRect, state: "hover" }),
|
|
19019
|
+
hoveredItemRect && !linkPopover && !hoveredNavContainerRect && !isItemDragging && hoveredItemElRef.current !== selectedElRef.current && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(ItemInteractionLayer, { rect: hoveredItemRect, state: "hover" }),
|
|
19020
|
+
hoveredTextRect && !isItemDragging && toolbarVariant !== "rich-text" && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(ItemInteractionLayer, { rect: hoveredTextRect, state: "hover" }),
|
|
19021
|
+
toolbarVariant === "select-frame" && toolbarRect && !linkPopover && !isItemDragging && !isFooterFrameSelection && selectedElRef.current && isNavbarLinksContainer2(selectedElRef.current) && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(NavbarContainerChrome, { rect: toolbarRect, onAdd: handleAddTopLevelNavItem }),
|
|
19022
|
+
toolbarVariant === "select-frame" && toolbarRect && !linkPopover && !isItemDragging && !isFooterFrameSelection && selectedElRef.current && isFooterLinksContainer(selectedElRef.current) && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
17758
19023
|
FooterContainerChrome,
|
|
17759
19024
|
{
|
|
17760
19025
|
rect: toolbarRect,
|
|
@@ -17762,7 +19027,7 @@ function OhhwellsBridge() {
|
|
|
17762
19027
|
addDisabled: !canAddFooterColumn()
|
|
17763
19028
|
}
|
|
17764
19029
|
),
|
|
17765
|
-
toolbarRect && !linkPopover && (toolbarVariant === "link-action" || toolbarVariant === "select-frame") && /* @__PURE__ */ (0,
|
|
19030
|
+
toolbarRect && !linkPopover && (toolbarVariant === "link-action" || toolbarVariant === "select-frame" || toolbarVariant === "logo") && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
17766
19031
|
ItemInteractionLayer,
|
|
17767
19032
|
{
|
|
17768
19033
|
rect: isItemDragging && draggedItemRect && (footerDragRef.current?.wasSelected || navDragRef.current?.wasSelected) ? draggedItemRect : toolbarRect,
|
|
@@ -17774,10 +19039,10 @@ function OhhwellsBridge() {
|
|
|
17774
19039
|
dragHandleLabel: reorderHrefKey ? `Reorder ${reorderHrefKey}` : "Reorder item",
|
|
17775
19040
|
onDragHandleDragStart: handleItemDragStart,
|
|
17776
19041
|
onDragHandleDragEnd: handleItemDragEnd,
|
|
17777
|
-
onItemPointerDown: handleItemChromePointerDown,
|
|
17778
|
-
onItemClick: handleItemChromeClick,
|
|
17779
|
-
itemDragSurface: !isFooterFrameSelection,
|
|
17780
|
-
toolbar: toolbarVariant === "link-action" && !isItemDragging || toolbarVariant === "select-frame" && (isFooterFrameSelection || selectedIsSocialsRow) && !isItemDragging ? /* @__PURE__ */ (0,
|
|
19042
|
+
onItemPointerDown: toolbarVariant === "logo" ? void 0 : handleItemChromePointerDown,
|
|
19043
|
+
onItemClick: toolbarVariant === "logo" ? void 0 : handleItemChromeClick,
|
|
19044
|
+
itemDragSurface: toolbarVariant !== "logo" && !isFooterFrameSelection,
|
|
19045
|
+
toolbar: toolbarVariant === "link-action" && !isItemDragging || toolbarVariant === "select-frame" && (isFooterFrameSelection || selectedIsSocialsRow) && !isItemDragging ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
17781
19046
|
ItemActionToolbar,
|
|
17782
19047
|
{
|
|
17783
19048
|
onEditLink: openLinkPopoverForSelected,
|
|
@@ -17813,8 +19078,8 @@ function OhhwellsBridge() {
|
|
|
17813
19078
|
) : void 0
|
|
17814
19079
|
}
|
|
17815
19080
|
),
|
|
17816
|
-
toolbarRect && toolbarVariant === "rich-text" && !linkPopover && /* @__PURE__ */ (0,
|
|
17817
|
-
/* @__PURE__ */ (0,
|
|
19081
|
+
toolbarRect && toolbarVariant === "rich-text" && !linkPopover && /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(import_jsx_runtime33.Fragment, { children: [
|
|
19082
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
17818
19083
|
EditGlowChrome,
|
|
17819
19084
|
{
|
|
17820
19085
|
rect: toolbarRect,
|
|
@@ -17824,7 +19089,7 @@ function OhhwellsBridge() {
|
|
|
17824
19089
|
hideHandle: isItemDragging
|
|
17825
19090
|
}
|
|
17826
19091
|
),
|
|
17827
|
-
/* @__PURE__ */ (0,
|
|
19092
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
17828
19093
|
FloatingToolbar,
|
|
17829
19094
|
{
|
|
17830
19095
|
rect: toolbarRect,
|
|
@@ -17837,7 +19102,7 @@ function OhhwellsBridge() {
|
|
|
17837
19102
|
}
|
|
17838
19103
|
)
|
|
17839
19104
|
] }),
|
|
17840
|
-
maxBadge && /* @__PURE__ */ (0,
|
|
19105
|
+
maxBadge && /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(
|
|
17841
19106
|
"div",
|
|
17842
19107
|
{
|
|
17843
19108
|
"data-ohw-max-badge": "",
|
|
@@ -17863,7 +19128,7 @@ function OhhwellsBridge() {
|
|
|
17863
19128
|
]
|
|
17864
19129
|
}
|
|
17865
19130
|
),
|
|
17866
|
-
toggleState && !linkPopover && /* @__PURE__ */ (0,
|
|
19131
|
+
toggleState && !linkPopover && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
17867
19132
|
StateToggle,
|
|
17868
19133
|
{
|
|
17869
19134
|
rect: toggleState.rect,
|
|
@@ -17872,15 +19137,15 @@ function OhhwellsBridge() {
|
|
|
17872
19137
|
onStateChange: handleStateChange
|
|
17873
19138
|
}
|
|
17874
19139
|
),
|
|
17875
|
-
sectionGap && !linkPopover && /* @__PURE__ */ (0,
|
|
19140
|
+
sectionGap && !linkPopover && /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(
|
|
17876
19141
|
"div",
|
|
17877
19142
|
{
|
|
17878
19143
|
"data-ohw-section-insert-line": "",
|
|
17879
19144
|
className: "fixed left-0 w-full z-2147483646 flex items-center pointer-events-none",
|
|
17880
19145
|
style: { top: sectionGap.y, transform: "translateY(-50%)" },
|
|
17881
19146
|
children: [
|
|
17882
|
-
/* @__PURE__ */ (0,
|
|
17883
|
-
/* @__PURE__ */ (0,
|
|
19147
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } }),
|
|
19148
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
17884
19149
|
Badge,
|
|
17885
19150
|
{
|
|
17886
19151
|
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",
|
|
@@ -17897,11 +19162,11 @@ function OhhwellsBridge() {
|
|
|
17897
19162
|
children: "Add Section"
|
|
17898
19163
|
}
|
|
17899
19164
|
),
|
|
17900
|
-
/* @__PURE__ */ (0,
|
|
19165
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } })
|
|
17901
19166
|
]
|
|
17902
19167
|
}
|
|
17903
19168
|
),
|
|
17904
|
-
linkPopover && dialogPortalContainer ? /* @__PURE__ */ (0,
|
|
19169
|
+
linkPopover && dialogPortalContainer ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
17905
19170
|
LinkPopover,
|
|
17906
19171
|
{
|
|
17907
19172
|
panelRef: linkPopoverPanelRef,
|
|
@@ -17918,7 +19183,7 @@ function OhhwellsBridge() {
|
|
|
17918
19183
|
},
|
|
17919
19184
|
linkPopover.key
|
|
17920
19185
|
) : null,
|
|
17921
|
-
floatingPanel && floatingPanel.kind === "socials-display" ? /* @__PURE__ */ (0,
|
|
19186
|
+
floatingPanel && floatingPanel.kind === "socials-display" ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
17922
19187
|
FloatingPanel,
|
|
17923
19188
|
{
|
|
17924
19189
|
open: true,
|
|
@@ -17928,7 +19193,7 @@ function OhhwellsBridge() {
|
|
|
17928
19193
|
onPositionChange: setFloatingPanelPos,
|
|
17929
19194
|
parentScroll: parentScrollSnap ?? parentScrollRef.current,
|
|
17930
19195
|
onClose: closeFloatingPanelOnly,
|
|
17931
|
-
children: /* @__PURE__ */ (0,
|
|
19196
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
17932
19197
|
SocialsDisplayPanel,
|
|
17933
19198
|
{
|
|
17934
19199
|
display: socialsDisplayFor(floatingPanel.row, editContentRef.current),
|
|
@@ -17939,11 +19204,115 @@ function OhhwellsBridge() {
|
|
|
17939
19204
|
}
|
|
17940
19205
|
)
|
|
17941
19206
|
}
|
|
19207
|
+
) : null,
|
|
19208
|
+
floatingPanel && floatingPanel.kind === "logo-size" && logoSizeDraft ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
19209
|
+
FloatingPanel,
|
|
19210
|
+
{
|
|
19211
|
+
open: true,
|
|
19212
|
+
title: floatingPanel.title,
|
|
19213
|
+
context: floatingPanel.context,
|
|
19214
|
+
position: floatingPanelPos,
|
|
19215
|
+
onPositionChange: setFloatingPanelPos,
|
|
19216
|
+
parentScroll: parentScrollSnap ?? parentScrollRef.current,
|
|
19217
|
+
onClose: closeFloatingPanelAndDeselect,
|
|
19218
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
19219
|
+
LogoSizePanel,
|
|
19220
|
+
{
|
|
19221
|
+
viewport: editorViewport,
|
|
19222
|
+
sizePx: editorViewport === "mobile" && !logoSizeDraft.mobileFollowing ? logoSizeDraft.mobilePx : logoSizeDraft.desktopPx,
|
|
19223
|
+
mobileFollowing: logoSizeDraft.mobileFollowing,
|
|
19224
|
+
onSizeChange: (px) => {
|
|
19225
|
+
const next = editorViewport === "mobile" ? { ...logoSizeDraft, mobilePx: px, mobileFollowing: false } : {
|
|
19226
|
+
...logoSizeDraft,
|
|
19227
|
+
desktopPx: px,
|
|
19228
|
+
mobilePx: logoSizeDraft.mobileFollowing ? px : logoSizeDraft.mobilePx
|
|
19229
|
+
};
|
|
19230
|
+
setLogoSizeDraft(next);
|
|
19231
|
+
persistLogoSizeDraft(floatingPanel.placement, next);
|
|
19232
|
+
},
|
|
19233
|
+
onCustomizeMobile: () => {
|
|
19234
|
+
const next = {
|
|
19235
|
+
...logoSizeDraft,
|
|
19236
|
+
mobileFollowing: false,
|
|
19237
|
+
mobilePx: logoSizeDraft.desktopPx
|
|
19238
|
+
};
|
|
19239
|
+
setLogoSizeDraft(next);
|
|
19240
|
+
persistLogoSizeDraft(floatingPanel.placement, next);
|
|
19241
|
+
},
|
|
19242
|
+
onResetMobile: () => {
|
|
19243
|
+
const next = {
|
|
19244
|
+
...logoSizeDraft,
|
|
19245
|
+
mobileFollowing: true,
|
|
19246
|
+
mobilePx: logoSizeDraft.desktopPx
|
|
19247
|
+
};
|
|
19248
|
+
setLogoSizeDraft(next);
|
|
19249
|
+
persistLogoSizeDraft(floatingPanel.placement, next);
|
|
19250
|
+
},
|
|
19251
|
+
onUpdateEverywhere: () => {
|
|
19252
|
+
const identity = readLogoIdentityFromDom();
|
|
19253
|
+
postToParent2({ type: "ow:open-logo-settings", ...identity });
|
|
19254
|
+
}
|
|
19255
|
+
}
|
|
19256
|
+
)
|
|
19257
|
+
}
|
|
17942
19258
|
) : null
|
|
17943
19259
|
] }),
|
|
17944
19260
|
bridgeRoot
|
|
17945
19261
|
) : null;
|
|
17946
19262
|
}
|
|
19263
|
+
|
|
19264
|
+
// src/ui/EmptySection.tsx
|
|
19265
|
+
var import_link = __toESM(require("next/link"), 1);
|
|
19266
|
+
var import_jsx_runtime34 = require("react/jsx-runtime");
|
|
19267
|
+
function EmptySection({ title, homeHref = "/", eyebrowKey, titleKey, subtitleKey }) {
|
|
19268
|
+
return /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(import_jsx_runtime34.Fragment, { children: [
|
|
19269
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
19270
|
+
"p",
|
|
19271
|
+
{
|
|
19272
|
+
style: {
|
|
19273
|
+
fontFamily: "var(--brand-font-body)",
|
|
19274
|
+
fontSize: "0.75rem",
|
|
19275
|
+
fontWeight: 500,
|
|
19276
|
+
letterSpacing: "0.15em",
|
|
19277
|
+
textTransform: "uppercase",
|
|
19278
|
+
color: "var(--brand-accent)",
|
|
19279
|
+
marginBottom: "1.5rem"
|
|
19280
|
+
},
|
|
19281
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_link.default, { href: homeHref, style: { color: "inherit" }, children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { ...eyebrowKey ? { "data-ohw-editable": "text", "data-ohw-key": eyebrowKey } : {}, children: "Home" }) })
|
|
19282
|
+
}
|
|
19283
|
+
),
|
|
19284
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
19285
|
+
"h1",
|
|
19286
|
+
{
|
|
19287
|
+
style: {
|
|
19288
|
+
fontFamily: "var(--brand-font-heading)",
|
|
19289
|
+
fontSize: "clamp(2rem, 3.5vw, 2.75rem)",
|
|
19290
|
+
lineHeight: 1.1,
|
|
19291
|
+
letterSpacing: "-0.025em",
|
|
19292
|
+
color: "var(--brand-text)",
|
|
19293
|
+
marginBottom: "1rem"
|
|
19294
|
+
},
|
|
19295
|
+
...titleKey ? { "data-ohw-editable": "text", "data-ohw-key": titleKey, "data-ohw-max-length": 80 } : {},
|
|
19296
|
+
children: title
|
|
19297
|
+
}
|
|
19298
|
+
),
|
|
19299
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
19300
|
+
"p",
|
|
19301
|
+
{
|
|
19302
|
+
style: {
|
|
19303
|
+
fontFamily: "var(--brand-font-body)",
|
|
19304
|
+
fontSize: "1rem",
|
|
19305
|
+
lineHeight: 1.7,
|
|
19306
|
+
fontWeight: 300,
|
|
19307
|
+
color: "var(--brand-text-muted)",
|
|
19308
|
+
maxWidth: "340px"
|
|
19309
|
+
},
|
|
19310
|
+
...subtitleKey ? { "data-ohw-editable": "text", "data-ohw-key": subtitleKey, "data-ohw-max-length": 160 } : {},
|
|
19311
|
+
children: "This page doesn't have any content yet."
|
|
19312
|
+
}
|
|
19313
|
+
)
|
|
19314
|
+
] });
|
|
19315
|
+
}
|
|
17947
19316
|
// Annotate the CommonJS export names for ESM import in node:
|
|
17948
19317
|
0 && (module.exports = {
|
|
17949
19318
|
AI_DEFAULT_BRAND,
|
|
@@ -17961,6 +19330,7 @@ function OhhwellsBridge() {
|
|
|
17961
19330
|
DropdownMenuItem,
|
|
17962
19331
|
DropdownMenuSeparator,
|
|
17963
19332
|
DropdownMenuTrigger,
|
|
19333
|
+
EmptySection,
|
|
17964
19334
|
ItemActionToolbar,
|
|
17965
19335
|
ItemInteractionLayer,
|
|
17966
19336
|
LinkEditorPanel,
|