@ohhwells/bridge 0.1.60 → 0.1.61-next.172
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 +1542 -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 +1539 -185
- package/dist/index.js.map +1 -1
- package/dist/pages.cjs +141 -0
- package/dist/pages.cjs.map +1 -0
- package/dist/pages.d.cts +45 -0
- package/dist/pages.d.ts +45 -0
- package/dist/pages.js +107 -0
- package/dist/pages.js.map +1 -0
- package/dist/styles.css +61 -0
- package/package.json +6 -1
package/dist/index.js
CHANGED
|
@@ -96,6 +96,7 @@ function applyTreeToState(state, payload) {
|
|
|
96
96
|
const entry = {
|
|
97
97
|
id: payload.id,
|
|
98
98
|
label: payload.label ?? "Generated section",
|
|
99
|
+
...typeof payload.path === "string" && payload.path ? { path: payload.path } : {},
|
|
99
100
|
afterSection: payload.mode === "insert" && !insertBefore ? payload.targetSectionId ?? null : null,
|
|
100
101
|
...insertBefore && payload.targetSectionId ? { beforeSection: payload.targetSectionId } : {},
|
|
101
102
|
...payload.mode === "replace" && payload.targetSectionId ? { replaces: payload.targetSectionId } : {},
|
|
@@ -118,6 +119,272 @@ function deleteSectionFromState(state, sectionId) {
|
|
|
118
119
|
return { ...state, v: 1, sections: state.sections, removed: [...removed, sectionId] };
|
|
119
120
|
}
|
|
120
121
|
|
|
122
|
+
// src/lib/brand-chrome.ts
|
|
123
|
+
var BRAND_NAME_KEY = "__ohw_brand_name";
|
|
124
|
+
var BRAND_TITLE_KEY = "__ohw_site_title";
|
|
125
|
+
var BRAND_FAVICON_LETTER_KEY = "__ohw_favicon_letter";
|
|
126
|
+
var BRAND_CHROME_KEYS = /* @__PURE__ */ new Set([
|
|
127
|
+
BRAND_NAME_KEY,
|
|
128
|
+
BRAND_TITLE_KEY,
|
|
129
|
+
BRAND_FAVICON_LETTER_KEY
|
|
130
|
+
]);
|
|
131
|
+
function upsertMeta(selector, attr, token, value) {
|
|
132
|
+
let el = document.head.querySelector(selector);
|
|
133
|
+
if (!el) {
|
|
134
|
+
el = document.createElement("meta");
|
|
135
|
+
el.setAttribute(attr, token);
|
|
136
|
+
document.head.appendChild(el);
|
|
137
|
+
}
|
|
138
|
+
if (el.getAttribute("content") !== value) el.setAttribute("content", value);
|
|
139
|
+
}
|
|
140
|
+
function escapeXml(value) {
|
|
141
|
+
return value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
142
|
+
}
|
|
143
|
+
function applyLetterFavicon(letter) {
|
|
144
|
+
const svg = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><rect width="64" height="64" rx="12" fill="#111827"/><text x="32" y="46" font-family="system-ui,-apple-system,Segoe UI,sans-serif" font-size="40" font-weight="700" text-anchor="middle" fill="#ffffff">${escapeXml(letter)}</text></svg>`;
|
|
145
|
+
const href = `data:image/svg+xml,${encodeURIComponent(svg)}`;
|
|
146
|
+
let link = document.head.querySelector('link[rel="icon"]');
|
|
147
|
+
if (!link) {
|
|
148
|
+
link = document.createElement("link");
|
|
149
|
+
link.rel = "icon";
|
|
150
|
+
document.head.appendChild(link);
|
|
151
|
+
}
|
|
152
|
+
link.type = "image/svg+xml";
|
|
153
|
+
if (link.href !== href) link.href = href;
|
|
154
|
+
}
|
|
155
|
+
function applyBrandChrome(content) {
|
|
156
|
+
const name = content[BRAND_NAME_KEY];
|
|
157
|
+
if (typeof name === "string" && name.length > 0) {
|
|
158
|
+
document.querySelectorAll("[data-ohw-wordmark]").forEach((el) => {
|
|
159
|
+
if (el.textContent !== name) el.textContent = name;
|
|
160
|
+
if (el.getAttribute("title") !== name) el.setAttribute("title", name);
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
const title = content[BRAND_TITLE_KEY];
|
|
164
|
+
if (typeof title === "string" && title.length > 0) {
|
|
165
|
+
if (document.title !== title) document.title = title;
|
|
166
|
+
upsertMeta('meta[property="og:title"]', "property", "og:title", title);
|
|
167
|
+
upsertMeta('meta[name="twitter:title"]', "name", "twitter:title", title);
|
|
168
|
+
}
|
|
169
|
+
const letter = content[BRAND_FAVICON_LETTER_KEY];
|
|
170
|
+
if (typeof letter === "string" && letter.length > 0) {
|
|
171
|
+
applyLetterFavicon(letter);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// src/lib/brand-kit.ts
|
|
176
|
+
var BRAND_KIT_KEY = "__ohw_brand";
|
|
177
|
+
var BRAND_VAR_PREFIX = "--ohw-brand-";
|
|
178
|
+
var BRAND_VAR_NAMES = ["primary", "accent", "light", "dark", "surface", "border", "muted"].map(
|
|
179
|
+
(role) => `${BRAND_VAR_PREFIX}${role}`
|
|
180
|
+
);
|
|
181
|
+
var FONT_VARS = { heading: ["--font-heading", "--font-display"], body: ["--font-body"] };
|
|
182
|
+
var BRAND_FONT_LINK_ID = "ohw-brand-fonts";
|
|
183
|
+
function brandColorVars(kit) {
|
|
184
|
+
const { dark, primary, accent, light } = kit.palette;
|
|
185
|
+
const mix = (a, aPct, b) => `color-mix(in srgb, ${a} ${aPct}%, ${b})`;
|
|
186
|
+
return {
|
|
187
|
+
[`${BRAND_VAR_PREFIX}primary`]: primary,
|
|
188
|
+
[`${BRAND_VAR_PREFIX}accent`]: accent,
|
|
189
|
+
[`${BRAND_VAR_PREFIX}light`]: light,
|
|
190
|
+
[`${BRAND_VAR_PREFIX}dark`]: dark,
|
|
191
|
+
[`${BRAND_VAR_PREFIX}surface`]: mix(light, 95, dark),
|
|
192
|
+
[`${BRAND_VAR_PREFIX}border`]: mix(light, 85, dark),
|
|
193
|
+
[`${BRAND_VAR_PREFIX}muted`]: mix(dark, 62, light)
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
function parseBrandKit(raw) {
|
|
197
|
+
if (!raw) return null;
|
|
198
|
+
try {
|
|
199
|
+
const parsed = JSON.parse(raw);
|
|
200
|
+
const p = parsed?.palette;
|
|
201
|
+
const f = parsed?.fonts;
|
|
202
|
+
if (!p || !f || typeof p.dark !== "string" || typeof p.primary !== "string" || typeof p.accent !== "string" || typeof p.light !== "string" || typeof f.heading !== "string" || typeof f.body !== "string") {
|
|
203
|
+
return null;
|
|
204
|
+
}
|
|
205
|
+
return {
|
|
206
|
+
palette: { dark: p.dark, primary: p.primary, accent: p.accent, light: p.light },
|
|
207
|
+
fonts: { heading: f.heading, body: f.body }
|
|
208
|
+
};
|
|
209
|
+
} catch {
|
|
210
|
+
return null;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
function familyOf(stack) {
|
|
214
|
+
const first = stack.split(",")[0]?.trim() ?? "";
|
|
215
|
+
return first.replace(/^['"]|['"]$/g, "");
|
|
216
|
+
}
|
|
217
|
+
function loadBrandFonts(families) {
|
|
218
|
+
const unique = [...new Set(families.map((f) => f.trim()).filter(Boolean))];
|
|
219
|
+
if (unique.length === 0) return;
|
|
220
|
+
const spec = unique.map((f) => `${f.replace(/ /g, "+")}:400,500,600,700`).join("|");
|
|
221
|
+
const href = `https://fonts.googleapis.com/css?family=${spec}&display=swap`;
|
|
222
|
+
let link = document.getElementById(BRAND_FONT_LINK_ID);
|
|
223
|
+
if (!link) {
|
|
224
|
+
link = document.createElement("link");
|
|
225
|
+
link.id = BRAND_FONT_LINK_ID;
|
|
226
|
+
link.rel = "stylesheet";
|
|
227
|
+
document.head.appendChild(link);
|
|
228
|
+
}
|
|
229
|
+
if (link.href !== href) link.href = href;
|
|
230
|
+
}
|
|
231
|
+
function applyBrandToDom(kit) {
|
|
232
|
+
const root = document.documentElement;
|
|
233
|
+
if (!kit) {
|
|
234
|
+
for (const name of BRAND_VAR_NAMES) root.style.removeProperty(name);
|
|
235
|
+
for (const name of [...FONT_VARS.heading, ...FONT_VARS.body]) root.style.removeProperty(name);
|
|
236
|
+
document.getElementById(BRAND_FONT_LINK_ID)?.remove();
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
for (const [name, value] of Object.entries(brandColorVars(kit))) root.style.setProperty(name, value);
|
|
240
|
+
for (const name of FONT_VARS.heading) root.style.setProperty(name, kit.fonts.heading);
|
|
241
|
+
for (const name of FONT_VARS.body) root.style.setProperty(name, kit.fonts.body);
|
|
242
|
+
loadBrandFonts([familyOf(kit.fonts.heading), familyOf(kit.fonts.body)]);
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
// src/lib/section-styles.ts
|
|
246
|
+
var STYLE_STORE_KEY = "__ohw_styles";
|
|
247
|
+
var STYLE_SHEET_ID = "ohw-section-styles";
|
|
248
|
+
function parseStyleStore(raw) {
|
|
249
|
+
if (!raw) return null;
|
|
250
|
+
try {
|
|
251
|
+
const parsed = JSON.parse(raw);
|
|
252
|
+
if (parsed?.v !== 1) return null;
|
|
253
|
+
return {
|
|
254
|
+
v: 1,
|
|
255
|
+
sections: typeof parsed.sections === "object" && parsed.sections ? parsed.sections : {},
|
|
256
|
+
nodes: typeof parsed.nodes === "object" && parsed.nodes ? parsed.nodes : {}
|
|
257
|
+
};
|
|
258
|
+
} catch {
|
|
259
|
+
return null;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
var BG_VALUES = {
|
|
263
|
+
surface: "color-mix(in srgb, var(--ohw-brand-light, var(--color-light, #ECECEB)) 94%, var(--ohw-brand-dark, var(--color-dark, #0C0A09)))",
|
|
264
|
+
accent: "var(--ohw-brand-primary, var(--color-primary, #0078E5))",
|
|
265
|
+
"accent-soft": "color-mix(in srgb, var(--ohw-brand-primary, var(--color-primary, #0078E5)) 12%, var(--ohw-brand-light, var(--color-light, #FFFFFF)))"
|
|
266
|
+
};
|
|
267
|
+
var HEADLINE_SIZES = { md: 24, lg: 32, xl: 40, display: 56 };
|
|
268
|
+
function styleSheetCss() {
|
|
269
|
+
const rules = [];
|
|
270
|
+
for (const [tone, value] of Object.entries(BG_VALUES)) {
|
|
271
|
+
rules.push(`[data-ohw-style-bg="${tone}"] { background: ${value} !important; }`);
|
|
272
|
+
}
|
|
273
|
+
rules.push(
|
|
274
|
+
`[data-ohw-style-bg="accent"] { color: var(--ohw-brand-light, var(--color-light, #FFFFFF)) !important; }`
|
|
275
|
+
);
|
|
276
|
+
rules.push(
|
|
277
|
+
`[data-ohw-style-distribution="space-between"] { display: flex !important; flex-direction: column; justify-content: space-between; }`,
|
|
278
|
+
`[data-ohw-style-distribution="center"] { display: flex !important; flex-direction: column; justify-content: center; }`
|
|
279
|
+
);
|
|
280
|
+
for (const [scale, size] of Object.entries(HEADLINE_SIZES)) {
|
|
281
|
+
rules.push(
|
|
282
|
+
`[data-ohw-style-headline="${scale}"] :is(h1, h2, h3) { font-size: ${size}px !important; line-height: 1.15 !important; }`
|
|
283
|
+
);
|
|
284
|
+
}
|
|
285
|
+
rules.push(
|
|
286
|
+
`[data-ohw-style-aspect="fill-height"] img { height: 100% !important; aspect-ratio: auto !important; object-fit: cover; }`
|
|
287
|
+
);
|
|
288
|
+
for (const aspect of ["1:1", "4:5", "3:4", "3:2", "16:9", "2:1", "3:1"]) {
|
|
289
|
+
rules.push(
|
|
290
|
+
`[data-ohw-style-aspect="${aspect.replace(":", "-")}"] img { aspect-ratio: ${aspect.replace(":", " / ")} !important; height: auto !important; object-fit: cover; }`
|
|
291
|
+
);
|
|
292
|
+
}
|
|
293
|
+
const pad = { tight: 40, balanced: 64, airy: 96 };
|
|
294
|
+
for (const [spacing, px] of Object.entries(pad)) {
|
|
295
|
+
rules.push(
|
|
296
|
+
`[data-ohw-style-spacing="${spacing}"] { padding-top: ${px}px !important; padding-bottom: ${px}px !important; }`
|
|
297
|
+
);
|
|
298
|
+
}
|
|
299
|
+
return rules.join("\n");
|
|
300
|
+
}
|
|
301
|
+
var SECTION_ATTRS = {
|
|
302
|
+
sectionBackground: "data-ohw-style-bg",
|
|
303
|
+
textDistribution: "data-ohw-style-distribution",
|
|
304
|
+
headlineScale: "data-ohw-style-headline",
|
|
305
|
+
imageAspect: "data-ohw-style-aspect",
|
|
306
|
+
spacing: "data-ohw-style-spacing"
|
|
307
|
+
};
|
|
308
|
+
var NODE_WROTE_ATTR = "data-ohw-style-node";
|
|
309
|
+
function ensureStyleSheet() {
|
|
310
|
+
let el = document.getElementById(STYLE_SHEET_ID);
|
|
311
|
+
if (!el) {
|
|
312
|
+
el = document.createElement("style");
|
|
313
|
+
el.id = STYLE_SHEET_ID;
|
|
314
|
+
document.head.appendChild(el);
|
|
315
|
+
}
|
|
316
|
+
const css = styleSheetCss();
|
|
317
|
+
if (el.textContent !== css) el.textContent = css;
|
|
318
|
+
}
|
|
319
|
+
function clearSectionAttrs(root) {
|
|
320
|
+
for (const attr of Object.values(SECTION_ATTRS)) {
|
|
321
|
+
for (const el of Array.from(root.querySelectorAll(`[${attr}]`))) el.removeAttribute(attr);
|
|
322
|
+
}
|
|
323
|
+
for (const el of Array.from(root.querySelectorAll("[data-ohw-style-bgcolor]"))) {
|
|
324
|
+
;
|
|
325
|
+
el.style.removeProperty("background");
|
|
326
|
+
el.removeAttribute("data-ohw-style-bgcolor");
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
function clearNodeProps(root) {
|
|
330
|
+
for (const el of Array.from(root.querySelectorAll(`[${NODE_WROTE_ATTR}]`))) {
|
|
331
|
+
const h = el;
|
|
332
|
+
h.style.removeProperty("color");
|
|
333
|
+
h.style.removeProperty("font-size");
|
|
334
|
+
h.style.removeProperty("background");
|
|
335
|
+
h.removeAttribute(NODE_WROTE_ATTR);
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
function buttonSurfaceOf(el) {
|
|
339
|
+
return el.closest("a, button") ?? el;
|
|
340
|
+
}
|
|
341
|
+
function applyStylesToDom(store) {
|
|
342
|
+
ensureStyleSheet();
|
|
343
|
+
clearSectionAttrs(document);
|
|
344
|
+
clearNodeProps(document);
|
|
345
|
+
if (!store) return;
|
|
346
|
+
for (const [sectionId, override] of Object.entries(store.sections)) {
|
|
347
|
+
const sections = document.querySelectorAll(
|
|
348
|
+
`[data-ohw-section="${CSS.escape(sectionId)}"]`
|
|
349
|
+
);
|
|
350
|
+
for (const section of Array.from(sections)) {
|
|
351
|
+
for (const [prop, attr] of Object.entries(SECTION_ATTRS)) {
|
|
352
|
+
const value = override[prop];
|
|
353
|
+
if (value === void 0) continue;
|
|
354
|
+
if (prop === "sectionBackground" && override.sectionBackgroundColor !== void 0) continue;
|
|
355
|
+
section.setAttribute(attr, String(value).replace(":", "-"));
|
|
356
|
+
}
|
|
357
|
+
if (override.sectionBackgroundColor !== void 0) {
|
|
358
|
+
section.style.setProperty("background", override.sectionBackgroundColor, "important");
|
|
359
|
+
section.setAttribute("data-ohw-style-bgcolor", "");
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
for (const [key, override] of Object.entries(store.nodes)) {
|
|
364
|
+
const nodes = document.querySelectorAll(`[data-ohw-key="${CSS.escape(key)}"]`);
|
|
365
|
+
for (const el of Array.from(nodes)) {
|
|
366
|
+
if (override.color !== void 0) {
|
|
367
|
+
el.style.setProperty("color", override.color, "important");
|
|
368
|
+
el.setAttribute(NODE_WROTE_ATTR, "");
|
|
369
|
+
}
|
|
370
|
+
if (override.fontSize !== void 0) {
|
|
371
|
+
el.style.setProperty("font-size", `${override.fontSize}px`, "important");
|
|
372
|
+
el.setAttribute(NODE_WROTE_ATTR, "");
|
|
373
|
+
}
|
|
374
|
+
if (override.buttonBackground !== void 0 || override.buttonText !== void 0) {
|
|
375
|
+
const surface = buttonSurfaceOf(el);
|
|
376
|
+
if (override.buttonBackground !== void 0) {
|
|
377
|
+
surface.style.setProperty("background", override.buttonBackground, "important");
|
|
378
|
+
}
|
|
379
|
+
if (override.buttonText !== void 0) {
|
|
380
|
+
surface.style.setProperty("color", override.buttonText, "important");
|
|
381
|
+
}
|
|
382
|
+
surface.setAttribute(NODE_WROTE_ATTR, "");
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
|
|
121
388
|
// src/ui/ai-tree/aiSectionsManager.tsx
|
|
122
389
|
import { flushSync } from "react-dom";
|
|
123
390
|
import { createRoot } from "react-dom/client";
|
|
@@ -132,7 +399,8 @@ function lucideByName(name) {
|
|
|
132
399
|
}
|
|
133
400
|
var typeStyle = (spec, font) => ({
|
|
134
401
|
fontFamily: font,
|
|
135
|
-
|
|
402
|
+
// Headings shrink with the viewport (reaching full size around ~900px wide); body copy stays put.
|
|
403
|
+
fontSize: spec.size >= 24 ? `clamp(${Math.max(18, Math.round(spec.size * 0.6))}px, ${(spec.size / 9).toFixed(2)}vw, ${spec.size}px)` : spec.size,
|
|
136
404
|
lineHeight: spec.line,
|
|
137
405
|
fontWeight: spec.weight
|
|
138
406
|
});
|
|
@@ -159,6 +427,8 @@ var AI_RESPONSIVE_CSS = [
|
|
|
159
427
|
" [data-ai-responsive] [data-ai-grid] { grid-template-columns: 1fr !important; }",
|
|
160
428
|
" [data-ai-responsive] [data-ai-columns] > * { grid-column: 1 / -1 !important; }",
|
|
161
429
|
" [data-ai-responsive] [data-ai-section-inner] { padding-left: 20px !important; padding-right: 20px !important; }",
|
|
430
|
+
" [data-ai-responsive] { overflow-x: hidden; }",
|
|
431
|
+
" [data-ai-responsive] img { max-width: 100%; }",
|
|
162
432
|
"}"
|
|
163
433
|
].join("\n");
|
|
164
434
|
var TRANSPARENT_PX = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7";
|
|
@@ -1166,6 +1436,20 @@ function AiTreeRenderer({ tree, brand, resolveMedia, editKeyPrefix }) {
|
|
|
1166
1436
|
const overlayAlpha = { low: 0.25, medium: 0.45, high: 0.65 }[settings.overlayIntensity ?? "medium"];
|
|
1167
1437
|
const backgroundUrl = isOverlay && settings.backgroundMedia ? ctx.resolveMedia(settings.backgroundMedia) : null;
|
|
1168
1438
|
const bgAttrs = ctx.keyFor && isOverlay && settings.backgroundMedia ? { "data-ohw-key": ctx.keyFor("settings.backgroundMedia"), "data-ohw-editable": "bg-image" } : {};
|
|
1439
|
+
const toneBackground = (() => {
|
|
1440
|
+
const { dark, primary, light } = resolvedBrand.palette;
|
|
1441
|
+
switch (settings.sectionBackground) {
|
|
1442
|
+
case "surface":
|
|
1443
|
+
return `color-mix(in srgb, ${light} 94%, ${dark})`;
|
|
1444
|
+
case "accent":
|
|
1445
|
+
return primary;
|
|
1446
|
+
case "accent-soft":
|
|
1447
|
+
return `color-mix(in srgb, ${primary} 12%, ${light})`;
|
|
1448
|
+
default:
|
|
1449
|
+
return void 0;
|
|
1450
|
+
}
|
|
1451
|
+
})();
|
|
1452
|
+
const distributed = !isOverlay && settings.textDistribution;
|
|
1169
1453
|
return /* @__PURE__ */ jsxs(
|
|
1170
1454
|
"section",
|
|
1171
1455
|
{
|
|
@@ -1175,10 +1459,11 @@ function AiTreeRenderer({ tree, brand, resolveMedia, editKeyPrefix }) {
|
|
|
1175
1459
|
style: {
|
|
1176
1460
|
position: "relative",
|
|
1177
1461
|
padding: `${pad}px 0`,
|
|
1178
|
-
background: isOverlay && !backgroundUrl ? "#DBEAFE" : void 0,
|
|
1462
|
+
background: toneBackground ?? (isOverlay && !backgroundUrl ? "#DBEAFE" : void 0),
|
|
1179
1463
|
backgroundImage: backgroundUrl ? `url(${backgroundUrl})` : void 0,
|
|
1180
1464
|
backgroundSize: "cover",
|
|
1181
|
-
backgroundPosition: "center"
|
|
1465
|
+
backgroundPosition: "center",
|
|
1466
|
+
color: settings.sectionBackground === "accent" ? resolvedBrand.palette.light : void 0
|
|
1182
1467
|
},
|
|
1183
1468
|
children: [
|
|
1184
1469
|
/* @__PURE__ */ jsx("style", { children: AI_RESPONSIVE_CSS }),
|
|
@@ -1202,10 +1487,24 @@ function AiTreeRenderer({ tree, brand, resolveMedia, editKeyPrefix }) {
|
|
|
1202
1487
|
display: "grid",
|
|
1203
1488
|
gridTemplateColumns: "repeat(12, 1fr)",
|
|
1204
1489
|
gap: AI_TREE_TOKENS.spacing6,
|
|
1205
|
-
alignItems: settings.verticalPosition === "top" ? "start" : "center",
|
|
1490
|
+
alignItems: distributed === "space-between" ? "stretch" : (distributed ?? settings.verticalPosition) === "top" ? "start" : "center",
|
|
1206
1491
|
marginTop: r2 > 0 ? AI_TREE_TOKENS.spacing8 : 0
|
|
1207
1492
|
},
|
|
1208
|
-
children: (row.blocks ?? []).map((block, b) => /* @__PURE__ */ jsx(
|
|
1493
|
+
children: (row.blocks ?? []).map((block, b) => /* @__PURE__ */ jsx(
|
|
1494
|
+
"div",
|
|
1495
|
+
{
|
|
1496
|
+
"data-ai-cell": "",
|
|
1497
|
+
style: {
|
|
1498
|
+
gridColumn: `span ${Math.min(12, Math.max(1, block.span))}`,
|
|
1499
|
+
minWidth: 0,
|
|
1500
|
+
// space-between: each column becomes a flex column whose content spreads over
|
|
1501
|
+
// the full row height instead of clumping at the top.
|
|
1502
|
+
...distributed === "space-between" ? { display: "flex", flexDirection: "column", justifyContent: "space-between" } : {}
|
|
1503
|
+
},
|
|
1504
|
+
children: renderNode(block, ctx, `r${r2}.b${b}`)
|
|
1505
|
+
},
|
|
1506
|
+
b
|
|
1507
|
+
))
|
|
1209
1508
|
},
|
|
1210
1509
|
r2
|
|
1211
1510
|
))
|
|
@@ -1221,17 +1520,34 @@ import { jsx as jsx2 } from "react/jsx-runtime";
|
|
|
1221
1520
|
var CONTAINER_ATTR = "data-ohw-ai-generated";
|
|
1222
1521
|
var REPLACED_ATTR = "data-ohw-ai-replaced-by";
|
|
1223
1522
|
var REMOVED_ATTR = "data-ohw-ai-removed";
|
|
1523
|
+
function readRootVar(name) {
|
|
1524
|
+
if (typeof document === "undefined") return "";
|
|
1525
|
+
return getComputedStyle(document.documentElement).getPropertyValue(name).trim();
|
|
1526
|
+
}
|
|
1527
|
+
function deriveBrandOverride() {
|
|
1528
|
+
const dark = readRootVar("--ohw-brand-dark");
|
|
1529
|
+
const primary = readRootVar("--ohw-brand-primary");
|
|
1530
|
+
const light = readRootVar("--ohw-brand-light");
|
|
1531
|
+
if (!dark || !primary || !light) return null;
|
|
1532
|
+
const accent = readRootVar("--ohw-brand-accent");
|
|
1533
|
+
const heading = readRootVar("--font-heading") || readRootVar("--font-display");
|
|
1534
|
+
const body = readRootVar("--font-body");
|
|
1535
|
+
return {
|
|
1536
|
+
palette: { dark, primary, accent: accent || dark, light },
|
|
1537
|
+
fonts: {
|
|
1538
|
+
heading: heading || AI_DEFAULT_BRAND.fonts.heading,
|
|
1539
|
+
body: body || AI_DEFAULT_BRAND.fonts.body
|
|
1540
|
+
}
|
|
1541
|
+
};
|
|
1542
|
+
}
|
|
1224
1543
|
function deriveTemplateBrand() {
|
|
1225
|
-
|
|
1226
|
-
const
|
|
1227
|
-
const
|
|
1228
|
-
const dark = read("--color-dark");
|
|
1229
|
-
const primary = read("--color-primary");
|
|
1230
|
-
const light = read("--color-light");
|
|
1544
|
+
const dark = readRootVar("--color-dark");
|
|
1545
|
+
const primary = readRootVar("--color-primary");
|
|
1546
|
+
const light = readRootVar("--color-light");
|
|
1231
1547
|
if (!dark || !primary || !light) return null;
|
|
1232
|
-
const accent =
|
|
1233
|
-
const heading =
|
|
1234
|
-
const body =
|
|
1548
|
+
const accent = readRootVar("--color-accent");
|
|
1549
|
+
const heading = readRootVar("--font-heading") || readRootVar("--font-display");
|
|
1550
|
+
const body = readRootVar("--font-body");
|
|
1235
1551
|
return {
|
|
1236
1552
|
palette: { dark, primary, accent: accent || dark, light },
|
|
1237
1553
|
fonts: {
|
|
@@ -1323,8 +1639,12 @@ function syncReplacedOriginals(state) {
|
|
|
1323
1639
|
}
|
|
1324
1640
|
function applyAiSectionsToDom(state, options) {
|
|
1325
1641
|
if (typeof document === "undefined") return;
|
|
1642
|
+
const brandOverride = deriveBrandOverride();
|
|
1326
1643
|
const templateBrand = deriveTemplateBrand();
|
|
1327
|
-
const
|
|
1644
|
+
const brandKey = brandOverride ? JSON.stringify(brandOverride) : "";
|
|
1645
|
+
const pagePath = window.location.pathname;
|
|
1646
|
+
const pageSections = state.sections.filter((entry) => !entry.path || entry.path === pagePath);
|
|
1647
|
+
const activeIds = new Set(pageSections.map((entry) => entry.id));
|
|
1328
1648
|
for (const [id, section] of mounted) {
|
|
1329
1649
|
if (!activeIds.has(id)) {
|
|
1330
1650
|
section.root.unmount();
|
|
@@ -1332,8 +1652,8 @@ function applyAiSectionsToDom(state, options) {
|
|
|
1332
1652
|
mounted.delete(id);
|
|
1333
1653
|
}
|
|
1334
1654
|
}
|
|
1335
|
-
for (const entry of
|
|
1336
|
-
const serialized = JSON.stringify(entry);
|
|
1655
|
+
for (const entry of pageSections) {
|
|
1656
|
+
const serialized = JSON.stringify(entry) + brandKey;
|
|
1337
1657
|
const existing = mounted.get(entry.id);
|
|
1338
1658
|
if (existing && existing.serialized === serialized && existing.container.isConnected) {
|
|
1339
1659
|
continue;
|
|
@@ -1347,6 +1667,7 @@ function applyAiSectionsToDom(state, options) {
|
|
|
1347
1667
|
mounted.delete(entry.id);
|
|
1348
1668
|
}
|
|
1349
1669
|
container.setAttribute("data-ohw-section", entry.id);
|
|
1670
|
+
container.setAttribute("data-ohw-instance", entry.id);
|
|
1350
1671
|
container.setAttribute("data-ohw-section-label", entry.label);
|
|
1351
1672
|
placeContainer(container, entry);
|
|
1352
1673
|
const root = mounted.get(entry.id)?.root ?? createRoot(container);
|
|
@@ -1357,7 +1678,7 @@ function applyAiSectionsToDom(state, options) {
|
|
|
1357
1678
|
AiTreeRenderer,
|
|
1358
1679
|
{
|
|
1359
1680
|
tree: entry.tree,
|
|
1360
|
-
brand: entry.brand ?? options?.brand ?? templateBrand ?? void 0,
|
|
1681
|
+
brand: brandOverride ?? entry.brand ?? options?.brand ?? templateBrand ?? void 0,
|
|
1361
1682
|
resolveMedia,
|
|
1362
1683
|
editKeyPrefix: `ai.${entry.id}`
|
|
1363
1684
|
}
|
|
@@ -1974,7 +2295,7 @@ function SchedulingWidget({ notifyOnConnect = false, initialScheduleId, insertAf
|
|
|
1974
2295
|
const autoId = useId();
|
|
1975
2296
|
const insertAfter = insertAfterProp ?? autoId;
|
|
1976
2297
|
const [schedule, setSchedule] = useState2(null);
|
|
1977
|
-
const [loading, setLoading] = useState2(
|
|
2298
|
+
const [loading, setLoading] = useState2(initialScheduleId !== null);
|
|
1978
2299
|
const [inEditor, setInEditor] = useState2(false);
|
|
1979
2300
|
const [isHovered, setIsHovered] = useState2(false);
|
|
1980
2301
|
const [modalState, setModalState] = useState2(null);
|
|
@@ -2148,8 +2469,10 @@ function SchedulingWidget({ notifyOnConnect = false, initialScheduleId, insertAf
|
|
|
2148
2469
|
"*"
|
|
2149
2470
|
);
|
|
2150
2471
|
};
|
|
2151
|
-
if (!inEditor && !loading && !schedule) return null;
|
|
2152
2472
|
const sectionId = `scheduling-${insertAfter}`;
|
|
2473
|
+
if (!inEditor && !loading && !schedule) {
|
|
2474
|
+
return /* @__PURE__ */ jsx4("section", { "data-ohw-section": sectionId, "data-ohw-scheduling-anchor": insertAfter, style: { display: "none" } });
|
|
2475
|
+
}
|
|
2153
2476
|
return /* @__PURE__ */ jsxs3(
|
|
2154
2477
|
"section",
|
|
2155
2478
|
{
|
|
@@ -6668,8 +6991,12 @@ function parseSectionsFromHtml(html) {
|
|
|
6668
6991
|
|
|
6669
6992
|
// src/ui/ai-section/AiSectionOverlay.tsx
|
|
6670
6993
|
import { Fragment as Fragment5, jsx as jsx16, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
6671
|
-
function
|
|
6672
|
-
const
|
|
6994
|
+
function findSectionElement(instanceId) {
|
|
6995
|
+
const escaped = CSS.escape(instanceId);
|
|
6996
|
+
return document.querySelector(`[data-ohw-instance="${escaped}"]`) ?? document.querySelector(`[data-ohw-section="${escaped}"]:not([data-ohw-instance])`);
|
|
6997
|
+
}
|
|
6998
|
+
function readRect(instanceId) {
|
|
6999
|
+
const el = findSectionElement(instanceId);
|
|
6673
7000
|
if (!el) return null;
|
|
6674
7001
|
const r2 = el.getBoundingClientRect();
|
|
6675
7002
|
if (r2.width <= 0 || r2.height <= 0) return null;
|
|
@@ -6692,7 +7019,7 @@ function useLiveSectionRect(sectionId) {
|
|
|
6692
7019
|
const opts = { capture: true, passive: true };
|
|
6693
7020
|
window.addEventListener("scroll", update, opts);
|
|
6694
7021
|
window.addEventListener("resize", update);
|
|
6695
|
-
const el =
|
|
7022
|
+
const el = findSectionElement(sectionId);
|
|
6696
7023
|
const ro = el ? new ResizeObserver(update) : null;
|
|
6697
7024
|
if (el && ro) ro.observe(el);
|
|
6698
7025
|
const interval = setInterval(update, 500);
|
|
@@ -6705,6 +7032,14 @@ function useLiveSectionRect(sectionId) {
|
|
|
6705
7032
|
}, [sectionId]);
|
|
6706
7033
|
return rect;
|
|
6707
7034
|
}
|
|
7035
|
+
function computeSectionBoundaryFlags(instanceId) {
|
|
7036
|
+
const topLevel = Array.from(document.querySelectorAll("[data-ohw-section]")).filter(
|
|
7037
|
+
(el) => !el.parentElement?.closest("[data-ohw-section]")
|
|
7038
|
+
);
|
|
7039
|
+
const index = topLevel.findIndex((el) => (el.dataset.ohwInstance ?? el.dataset.ohwSection) === instanceId);
|
|
7040
|
+
if (index === -1) return { isFirst: true, isLast: true };
|
|
7041
|
+
return { isFirst: index === 0, isLast: index === topLevel.length - 1 };
|
|
7042
|
+
}
|
|
6708
7043
|
var PRIMARY2 = "#0885FE";
|
|
6709
7044
|
function edgeAwareRadius(rect) {
|
|
6710
7045
|
const container = window.innerWidth <= 480 ? 16 : 24;
|
|
@@ -6778,6 +7113,7 @@ function AiSectionOverlay({
|
|
|
6778
7113
|
}) {
|
|
6779
7114
|
const [selectedId, setSelectedId] = useState4(null);
|
|
6780
7115
|
const [reviewId, setReviewId] = useState4(null);
|
|
7116
|
+
const [reviewButtonsHidden, setReviewButtonsHidden] = useState4(false);
|
|
6781
7117
|
const reviewIdRef = useRef4(null);
|
|
6782
7118
|
reviewIdRef.current = reviewId;
|
|
6783
7119
|
const selectedIdRef = useRef4(null);
|
|
@@ -6786,7 +7122,7 @@ function AiSectionOverlay({
|
|
|
6786
7122
|
(el) => {
|
|
6787
7123
|
postToParent2({
|
|
6788
7124
|
type: "ow:section-selected",
|
|
6789
|
-
sectionId: el
|
|
7125
|
+
sectionId: el ? el.dataset.ohwInstance ?? el.dataset.ohwSection ?? null : null,
|
|
6790
7126
|
sectionLabel: el ? el.dataset.ohwSectionLabel ?? titleCaseSectionId(el.dataset.ohwSection ?? "") : null
|
|
6791
7127
|
});
|
|
6792
7128
|
},
|
|
@@ -6795,7 +7131,7 @@ function AiSectionOverlay({
|
|
|
6795
7131
|
const selectFromElement = useCallback2(
|
|
6796
7132
|
(el, options) => {
|
|
6797
7133
|
const sectionEl = el?.closest("[data-ohw-section]") ?? null;
|
|
6798
|
-
const id = sectionEl
|
|
7134
|
+
const id = sectionEl ? sectionEl.dataset.ohwInstance ?? sectionEl.dataset.ohwSection ?? null : null;
|
|
6799
7135
|
if (id === selectedIdRef.current) return;
|
|
6800
7136
|
setSelectedId(id);
|
|
6801
7137
|
if (options?.report !== false) report(sectionEl);
|
|
@@ -6836,9 +7172,10 @@ function AiSectionOverlay({
|
|
|
6836
7172
|
}
|
|
6837
7173
|
const found = readRect(sectionId) != null;
|
|
6838
7174
|
setReviewId(found ? sectionId : null);
|
|
7175
|
+
setReviewButtonsHidden(e.data.hideButtons === true);
|
|
6839
7176
|
postToParent2({ type: "ow:ai-review-started", sectionId, found });
|
|
6840
7177
|
if (found) {
|
|
6841
|
-
document.querySelector(`[data-ohw-
|
|
7178
|
+
document.querySelector(`[data-ohw-instance="${CSS.escape(sectionId)}"]`)?.scrollIntoView({ behavior: "smooth", block: "nearest" });
|
|
6842
7179
|
}
|
|
6843
7180
|
}
|
|
6844
7181
|
};
|
|
@@ -6857,7 +7194,7 @@ function AiSectionOverlay({
|
|
|
6857
7194
|
return;
|
|
6858
7195
|
}
|
|
6859
7196
|
const sec = t.closest("[data-ohw-section]");
|
|
6860
|
-
setHoveredId(sec
|
|
7197
|
+
setHoveredId(sec ? sec.dataset.ohwInstance ?? sec.dataset.ohwSection ?? null : null);
|
|
6861
7198
|
};
|
|
6862
7199
|
const onLeave = () => setHoveredId(null);
|
|
6863
7200
|
document.addEventListener("mousemove", onMove, { passive: true });
|
|
@@ -6889,9 +7226,29 @@ function AiSectionOverlay({
|
|
|
6889
7226
|
},
|
|
6890
7227
|
[postToParent2]
|
|
6891
7228
|
);
|
|
6892
|
-
const
|
|
7229
|
+
const activeSelectionId = reviewId ? null : selectedId;
|
|
7230
|
+
const selectionRect = useLiveSectionRect(activeSelectionId);
|
|
6893
7231
|
const reviewRect = useLiveSectionRect(reviewId);
|
|
6894
7232
|
const hoverRect = useLiveSectionRect(reviewId || hoveredId === selectedId ? null : hoveredId);
|
|
7233
|
+
useEffect4(() => {
|
|
7234
|
+
if (!activeSelectionId || !selectionRect) {
|
|
7235
|
+
postToParent2({ type: "ow:section-rect", instanceId: null, rect: null });
|
|
7236
|
+
return;
|
|
7237
|
+
}
|
|
7238
|
+
const { isFirst, isLast } = computeSectionBoundaryFlags(activeSelectionId);
|
|
7239
|
+
postToParent2({
|
|
7240
|
+
type: "ow:section-rect",
|
|
7241
|
+
instanceId: activeSelectionId,
|
|
7242
|
+
rect: {
|
|
7243
|
+
top: selectionRect.top + window.scrollY,
|
|
7244
|
+
left: selectionRect.left + window.scrollX,
|
|
7245
|
+
width: selectionRect.width,
|
|
7246
|
+
height: selectionRect.height
|
|
7247
|
+
},
|
|
7248
|
+
isFirst,
|
|
7249
|
+
isLast
|
|
7250
|
+
});
|
|
7251
|
+
}, [activeSelectionId, selectionRect, postToParent2]);
|
|
6895
7252
|
return /* @__PURE__ */ jsxs8(Fragment5, { children: [
|
|
6896
7253
|
hoverRect && /* @__PURE__ */ jsx16(
|
|
6897
7254
|
"div",
|
|
@@ -6942,13 +7299,16 @@ function AiSectionOverlay({
|
|
|
6942
7299
|
border: `2px solid ${PRIMARY2}`,
|
|
6943
7300
|
borderRadius: edgeAwareRadius(reviewRect),
|
|
6944
7301
|
zIndex: 2147483200,
|
|
6945
|
-
// The veil itself: swallows clicks so the section stays locked until decided.
|
|
7302
|
+
// The veil itself: swallows clicks so the section stays locked until decided. This
|
|
7303
|
+
// stopPropagation only guards the bubble phase; the bridge's capture-phase click
|
|
7304
|
+
// handlers additionally bail on `[data-ohw-ai-review]`, without which a click on
|
|
7305
|
+
// Accept/Discard resolves to the media beneath and opens the file picker.
|
|
6946
7306
|
background: "rgba(8, 133, 254, 0.04)",
|
|
6947
7307
|
pointerEvents: "auto",
|
|
6948
7308
|
cursor: "default"
|
|
6949
7309
|
},
|
|
6950
7310
|
onClick: (e) => e.stopPropagation(),
|
|
6951
|
-
children: /* @__PURE__ */ jsxs8(
|
|
7311
|
+
children: !reviewButtonsHidden && /* @__PURE__ */ jsxs8(
|
|
6952
7312
|
"div",
|
|
6953
7313
|
{
|
|
6954
7314
|
style: {
|
|
@@ -10848,6 +11208,329 @@ function deleteFooterColumn(column) {
|
|
|
10848
11208
|
};
|
|
10849
11209
|
}
|
|
10850
11210
|
|
|
11211
|
+
// src/lib/logo-identity.ts
|
|
11212
|
+
var LOGO_TEXT_KEYS = ["nav-logo-text", "footer-logo-text", "logo-text"];
|
|
11213
|
+
var LOGO_IMAGE_KEYS = ["nav-logo-image", "footer-logo", "footer-logo-image"];
|
|
11214
|
+
var LOGO_HREF_KEYS = ["nav-logo-href", "footer-logo-href", "logo-href"];
|
|
11215
|
+
var LOGO_PLACEHOLDER_KEY = "logo-is-placeholder";
|
|
11216
|
+
var LOGO_ALT_KEY = "logo-alt";
|
|
11217
|
+
var LOGO_IMAGE_URL_KEY = "nav-logo-image";
|
|
11218
|
+
var PLACEHOLDER_BUSINESS_NAME = "Business name";
|
|
11219
|
+
function resolveLogoDisplayText(text) {
|
|
11220
|
+
const trimmed = (text ?? "").trim();
|
|
11221
|
+
return trimmed || PLACEHOLDER_BUSINESS_NAME;
|
|
11222
|
+
}
|
|
11223
|
+
function isFooterLogoRoot(root) {
|
|
11224
|
+
return Boolean(root.closest("footer") || root.closest('[data-ohw-section="footer"]'));
|
|
11225
|
+
}
|
|
11226
|
+
function imageKeyForRoot(root) {
|
|
11227
|
+
return isFooterLogoRoot(root) ? "footer-logo" : "nav-logo-image";
|
|
11228
|
+
}
|
|
11229
|
+
function textKeyForRoot(root) {
|
|
11230
|
+
return isFooterLogoRoot(root) ? "footer-logo-text" : "nav-logo-text";
|
|
11231
|
+
}
|
|
11232
|
+
function ensureLogoHrefKey(root) {
|
|
11233
|
+
if (!(root instanceof HTMLAnchorElement)) return;
|
|
11234
|
+
if (root.hasAttribute("data-ohw-href-key")) return;
|
|
11235
|
+
root.setAttribute("data-ohw-href-key", isFooterLogoRoot(root) ? "footer-logo-href" : "nav-logo-href");
|
|
11236
|
+
}
|
|
11237
|
+
function applyLogoIdentity(text, isPlaceholder) {
|
|
11238
|
+
const display = resolveLogoDisplayText(text);
|
|
11239
|
+
const placeholder = isPlaceholder || !text.trim() || display === PLACEHOLDER_BUSINESS_NAME;
|
|
11240
|
+
for (const key of LOGO_TEXT_KEYS) {
|
|
11241
|
+
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
11242
|
+
if (el.textContent !== display) el.textContent = display;
|
|
11243
|
+
});
|
|
11244
|
+
}
|
|
11245
|
+
for (const key of LOGO_IMAGE_KEYS) {
|
|
11246
|
+
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
11247
|
+
const img = el instanceof HTMLImageElement ? el : el.querySelector("img");
|
|
11248
|
+
if (img) img.alt = display;
|
|
11249
|
+
});
|
|
11250
|
+
}
|
|
11251
|
+
document.querySelectorAll('[data-ohw-role="logo"], [data-ohw-logo]').forEach((el) => {
|
|
11252
|
+
if (placeholder) el.setAttribute("data-ohw-placeholder", "");
|
|
11253
|
+
else el.removeAttribute("data-ohw-placeholder");
|
|
11254
|
+
});
|
|
11255
|
+
return display;
|
|
11256
|
+
}
|
|
11257
|
+
function applyLogoImage(url, alt) {
|
|
11258
|
+
const displayAlt = resolveLogoDisplayText(alt);
|
|
11259
|
+
document.querySelectorAll('[data-ohw-role="logo"], [data-ohw-logo]').forEach((root) => {
|
|
11260
|
+
ensureLogoHrefKey(root);
|
|
11261
|
+
const imageKey = imageKeyForRoot(root);
|
|
11262
|
+
const textKey = textKeyForRoot(root);
|
|
11263
|
+
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");
|
|
11264
|
+
let textEl = root.querySelector(`[data-ohw-key="${textKey}"]`) ?? root.querySelector('[data-ohw-key="logo-text"]');
|
|
11265
|
+
if (url) {
|
|
11266
|
+
if (!img) {
|
|
11267
|
+
img = document.createElement("img");
|
|
11268
|
+
img.setAttribute("data-ohw-editable", "image");
|
|
11269
|
+
img.setAttribute("data-ohw-key", imageKey);
|
|
11270
|
+
img.alt = displayAlt;
|
|
11271
|
+
img.style.height = "";
|
|
11272
|
+
img.style.maxHeight = "none";
|
|
11273
|
+
img.style.width = "auto";
|
|
11274
|
+
img.style.display = "block";
|
|
11275
|
+
img.style.objectFit = "contain";
|
|
11276
|
+
root.insertBefore(img, root.firstChild);
|
|
11277
|
+
} else {
|
|
11278
|
+
img.setAttribute("data-ohw-editable", "image");
|
|
11279
|
+
img.setAttribute("data-ohw-key", imageKey);
|
|
11280
|
+
}
|
|
11281
|
+
img.removeAttribute("srcset");
|
|
11282
|
+
img.removeAttribute("sizes");
|
|
11283
|
+
img.src = url;
|
|
11284
|
+
img.alt = displayAlt;
|
|
11285
|
+
img.style.display = "block";
|
|
11286
|
+
if (textEl) textEl.style.display = "none";
|
|
11287
|
+
root.removeAttribute("data-ohw-placeholder");
|
|
11288
|
+
return;
|
|
11289
|
+
}
|
|
11290
|
+
if (img) {
|
|
11291
|
+
img.removeAttribute("src");
|
|
11292
|
+
img.removeAttribute("srcset");
|
|
11293
|
+
img.removeAttribute("sizes");
|
|
11294
|
+
img.alt = displayAlt;
|
|
11295
|
+
img.style.display = "none";
|
|
11296
|
+
}
|
|
11297
|
+
if (!textEl) {
|
|
11298
|
+
textEl = document.createElement("span");
|
|
11299
|
+
textEl.setAttribute("data-ohw-editable", "plain");
|
|
11300
|
+
textEl.setAttribute("data-ohw-key", textKey);
|
|
11301
|
+
root.appendChild(textEl);
|
|
11302
|
+
}
|
|
11303
|
+
textEl.style.display = "";
|
|
11304
|
+
if (textEl.textContent !== displayAlt) textEl.textContent = displayAlt;
|
|
11305
|
+
if (!displayAlt.trim() || displayAlt === PLACEHOLDER_BUSINESS_NAME) {
|
|
11306
|
+
root.setAttribute("data-ohw-placeholder", "");
|
|
11307
|
+
} else {
|
|
11308
|
+
root.removeAttribute("data-ohw-placeholder");
|
|
11309
|
+
}
|
|
11310
|
+
});
|
|
11311
|
+
}
|
|
11312
|
+
function applyLogoHref(href) {
|
|
11313
|
+
const target = href.trim() || "/";
|
|
11314
|
+
document.querySelectorAll('[data-ohw-role="logo"], [data-ohw-logo]').forEach((root) => {
|
|
11315
|
+
ensureLogoHrefKey(root);
|
|
11316
|
+
if (root instanceof HTMLAnchorElement) {
|
|
11317
|
+
root.setAttribute("href", target);
|
|
11318
|
+
}
|
|
11319
|
+
});
|
|
11320
|
+
for (const key of LOGO_HREF_KEYS) setStoredLinkHref(key, target);
|
|
11321
|
+
}
|
|
11322
|
+
function readLogoIdentityFromDom() {
|
|
11323
|
+
let imageUrl = null;
|
|
11324
|
+
for (const key of LOGO_IMAGE_KEYS) {
|
|
11325
|
+
const el = document.querySelector(`[data-ohw-key="${key}"]`);
|
|
11326
|
+
const img = el instanceof HTMLImageElement ? el : el?.querySelector("img");
|
|
11327
|
+
const attrSrc = img?.getAttribute("src")?.trim() ?? "";
|
|
11328
|
+
if (attrSrc && !attrSrc.startsWith("data:") && img && img.style.display !== "none") {
|
|
11329
|
+
imageUrl = img.currentSrc || img.src;
|
|
11330
|
+
break;
|
|
11331
|
+
}
|
|
11332
|
+
}
|
|
11333
|
+
let text = PLACEHOLDER_BUSINESS_NAME;
|
|
11334
|
+
let isPlaceholder = true;
|
|
11335
|
+
for (const key of LOGO_TEXT_KEYS) {
|
|
11336
|
+
const el = document.querySelector(`[data-ohw-key="${key}"]`);
|
|
11337
|
+
if (el?.textContent?.trim()) {
|
|
11338
|
+
text = el.textContent.trim();
|
|
11339
|
+
const logoRoot2 = el.closest('[data-ohw-role="logo"], [data-ohw-logo]');
|
|
11340
|
+
isPlaceholder = logoRoot2?.hasAttribute("data-ohw-placeholder") === true || text === PLACEHOLDER_BUSINESS_NAME;
|
|
11341
|
+
break;
|
|
11342
|
+
}
|
|
11343
|
+
}
|
|
11344
|
+
if (imageUrl) {
|
|
11345
|
+
const logoImg = document.querySelector(
|
|
11346
|
+
'[data-ohw-key="nav-logo-image"], [data-ohw-key="footer-logo"]'
|
|
11347
|
+
);
|
|
11348
|
+
const alt = logoImg?.alt?.trim() || text;
|
|
11349
|
+
isPlaceholder = false;
|
|
11350
|
+
const hrefEl = document.querySelector(
|
|
11351
|
+
'a[data-ohw-role="logo"], a[data-ohw-logo], [data-ohw-role="logo"]'
|
|
11352
|
+
);
|
|
11353
|
+
const href2 = (hrefEl instanceof HTMLAnchorElement ? hrefEl.getAttribute("href") : null) || hrefEl?.closest("a")?.getAttribute("href") || "/";
|
|
11354
|
+
return { text, isPlaceholder, imageUrl, href: href2, alt };
|
|
11355
|
+
}
|
|
11356
|
+
const logoRoot = document.querySelector('[data-ohw-role="logo"], [data-ohw-logo]');
|
|
11357
|
+
const href = (logoRoot instanceof HTMLAnchorElement ? logoRoot.getAttribute("href") : null) || logoRoot?.closest("a")?.getAttribute("href") || "/";
|
|
11358
|
+
return { text, isPlaceholder, imageUrl: null, href, alt: text };
|
|
11359
|
+
}
|
|
11360
|
+
function applyLogoFromContent(content) {
|
|
11361
|
+
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);
|
|
11362
|
+
if (!hasLogoIdentity) return false;
|
|
11363
|
+
const logoText = content[LOGO_TEXT_KEYS[0]] ?? content[LOGO_TEXT_KEYS[1]] ?? readLogoIdentityFromDom().text;
|
|
11364
|
+
const logoAlt = content[LOGO_ALT_KEY] ?? logoText;
|
|
11365
|
+
const rawLogoImage = content[LOGO_IMAGE_URL_KEY] ?? content["footer-logo"] ?? content["footer-logo-image"] ?? null;
|
|
11366
|
+
const logoImageUrl = typeof rawLogoImage === "string" && rawLogoImage.trim() ? rawLogoImage.trim() : null;
|
|
11367
|
+
const imageExplicitlyCleared = LOGO_IMAGE_KEYS.some((key) => key in content) && !logoImageUrl;
|
|
11368
|
+
const logoIsPlaceholder = LOGO_PLACEHOLDER_KEY in content ? content[LOGO_PLACEHOLDER_KEY] !== "false" : !logoImageUrl && (!logoText.trim() || logoText === PLACEHOLDER_BUSINESS_NAME);
|
|
11369
|
+
if (logoImageUrl) {
|
|
11370
|
+
applyLogoImage(logoImageUrl, logoAlt);
|
|
11371
|
+
} else {
|
|
11372
|
+
if (imageExplicitlyCleared) applyLogoImage(null, logoAlt);
|
|
11373
|
+
applyLogoIdentity(logoText, logoIsPlaceholder);
|
|
11374
|
+
}
|
|
11375
|
+
const logoHref = content["nav-logo-href"] ?? content["footer-logo-href"] ?? content["logo-href"];
|
|
11376
|
+
if (typeof logoHref === "string" && logoHref.trim()) {
|
|
11377
|
+
applyLogoHref(logoHref);
|
|
11378
|
+
}
|
|
11379
|
+
return true;
|
|
11380
|
+
}
|
|
11381
|
+
|
|
11382
|
+
// src/lib/logo-size.ts
|
|
11383
|
+
var LOGO_SIZE_DEFAULTS = {
|
|
11384
|
+
navbar: 28,
|
|
11385
|
+
footer: 32
|
|
11386
|
+
};
|
|
11387
|
+
var LOGO_SIZE_MIN = 16;
|
|
11388
|
+
var LOGO_SIZE_MAX = 80;
|
|
11389
|
+
var LOGO_SIZE_DESKTOP_KEYS = {
|
|
11390
|
+
navbar: "nav-logo-size",
|
|
11391
|
+
footer: "footer-logo-size"
|
|
11392
|
+
};
|
|
11393
|
+
var LOGO_SIZE_MOBILE_KEYS = {
|
|
11394
|
+
navbar: "nav-logo-size-mobile",
|
|
11395
|
+
footer: "footer-logo-size-mobile"
|
|
11396
|
+
};
|
|
11397
|
+
var LOGO_SIZE_KEYS = [
|
|
11398
|
+
LOGO_SIZE_DESKTOP_KEYS.navbar,
|
|
11399
|
+
LOGO_SIZE_DESKTOP_KEYS.footer,
|
|
11400
|
+
LOGO_SIZE_MOBILE_KEYS.navbar,
|
|
11401
|
+
LOGO_SIZE_MOBILE_KEYS.footer
|
|
11402
|
+
];
|
|
11403
|
+
function isFooterLogoRoot2(root) {
|
|
11404
|
+
return Boolean(root.closest("footer") || root.closest('[data-ohw-section="footer"]'));
|
|
11405
|
+
}
|
|
11406
|
+
function getLogoPlacement(root) {
|
|
11407
|
+
return isFooterLogoRoot2(root) ? "footer" : "navbar";
|
|
11408
|
+
}
|
|
11409
|
+
function parseLogoSizePx(raw, fallback) {
|
|
11410
|
+
if (raw == null || raw === "") return fallback;
|
|
11411
|
+
const n = Number.parseFloat(raw);
|
|
11412
|
+
if (!Number.isFinite(n)) return fallback;
|
|
11413
|
+
return Math.min(LOGO_SIZE_MAX, Math.max(LOGO_SIZE_MIN, Math.round(n)));
|
|
11414
|
+
}
|
|
11415
|
+
function isMobileLogoSizeFollowing(content, placement) {
|
|
11416
|
+
const raw = content[LOGO_SIZE_MOBILE_KEYS[placement]];
|
|
11417
|
+
return raw == null || raw.trim() === "";
|
|
11418
|
+
}
|
|
11419
|
+
function resolveDesktopLogoSize(content, placement) {
|
|
11420
|
+
return parseLogoSizePx(content[LOGO_SIZE_DESKTOP_KEYS[placement]], LOGO_SIZE_DEFAULTS[placement]);
|
|
11421
|
+
}
|
|
11422
|
+
function resolveMobileLogoSize(content, placement) {
|
|
11423
|
+
if (isMobileLogoSizeFollowing(content, placement)) {
|
|
11424
|
+
return resolveDesktopLogoSize(content, placement);
|
|
11425
|
+
}
|
|
11426
|
+
return parseLogoSizePx(
|
|
11427
|
+
content[LOGO_SIZE_MOBILE_KEYS[placement]],
|
|
11428
|
+
resolveDesktopLogoSize(content, placement)
|
|
11429
|
+
);
|
|
11430
|
+
}
|
|
11431
|
+
function setRootSizeVars(root, desktopPx, mobilePx, following) {
|
|
11432
|
+
root.style.setProperty("--ohw-logo-size", `${desktopPx}px`);
|
|
11433
|
+
if (following) {
|
|
11434
|
+
root.style.removeProperty("--ohw-logo-size-mobile");
|
|
11435
|
+
} else {
|
|
11436
|
+
root.style.setProperty("--ohw-logo-size-mobile", `${mobilePx}px`);
|
|
11437
|
+
}
|
|
11438
|
+
root.querySelectorAll("img").forEach((img) => {
|
|
11439
|
+
img.style.height = "";
|
|
11440
|
+
img.style.maxHeight = "none";
|
|
11441
|
+
img.style.width = "auto";
|
|
11442
|
+
img.style.objectFit = "contain";
|
|
11443
|
+
});
|
|
11444
|
+
}
|
|
11445
|
+
function applyLogoSizes(content) {
|
|
11446
|
+
document.querySelectorAll('[data-ohw-role="logo"], [data-ohw-logo]').forEach((root) => {
|
|
11447
|
+
const placement = getLogoPlacement(root);
|
|
11448
|
+
const desktop = resolveDesktopLogoSize(content, placement);
|
|
11449
|
+
const following = isMobileLogoSizeFollowing(content, placement);
|
|
11450
|
+
const mobile = following ? desktop : resolveMobileLogoSize(content, placement);
|
|
11451
|
+
setRootSizeVars(root, desktop, mobile, following);
|
|
11452
|
+
});
|
|
11453
|
+
}
|
|
11454
|
+
function applyLogoSizeToPlacement(placement, desktopPx, mobilePx, following) {
|
|
11455
|
+
document.querySelectorAll('[data-ohw-role="logo"], [data-ohw-logo]').forEach((root) => {
|
|
11456
|
+
if (getLogoPlacement(root) !== placement) return;
|
|
11457
|
+
setRootSizeVars(root, desktopPx, mobilePx, following);
|
|
11458
|
+
});
|
|
11459
|
+
}
|
|
11460
|
+
function logoHasUploadedImage(logoEl) {
|
|
11461
|
+
if (logoEl.hasAttribute("data-ohw-placeholder")) return false;
|
|
11462
|
+
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");
|
|
11463
|
+
if (!img) return false;
|
|
11464
|
+
const src = img.getAttribute("src")?.trim() ?? "";
|
|
11465
|
+
if (!src || src.startsWith("data:")) return false;
|
|
11466
|
+
if (img.style.display === "none") return false;
|
|
11467
|
+
return true;
|
|
11468
|
+
}
|
|
11469
|
+
function getLogoInteractionRect(logoEl) {
|
|
11470
|
+
if (logoHasUploadedImage(logoEl)) {
|
|
11471
|
+
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");
|
|
11472
|
+
if (img) {
|
|
11473
|
+
const r2 = img.getBoundingClientRect();
|
|
11474
|
+
if (r2.width > 0 && r2.height > 0) return r2;
|
|
11475
|
+
}
|
|
11476
|
+
}
|
|
11477
|
+
const text = logoEl.querySelector(
|
|
11478
|
+
'[data-ohw-key="nav-logo-text"], [data-ohw-key="footer-logo-text"]'
|
|
11479
|
+
);
|
|
11480
|
+
if (text) {
|
|
11481
|
+
const style = window.getComputedStyle(text);
|
|
11482
|
+
if (style.display !== "none" && style.visibility !== "hidden") {
|
|
11483
|
+
const r2 = text.getBoundingClientRect();
|
|
11484
|
+
if (r2.width > 0 && r2.height > 0) return r2;
|
|
11485
|
+
}
|
|
11486
|
+
}
|
|
11487
|
+
return logoEl.getBoundingClientRect();
|
|
11488
|
+
}
|
|
11489
|
+
function readLogoSizeState(content, placement) {
|
|
11490
|
+
const desktopPx = resolveDesktopLogoSize(content, placement);
|
|
11491
|
+
const mobileFollowing = isMobileLogoSizeFollowing(content, placement);
|
|
11492
|
+
const mobilePx = mobileFollowing ? desktopPx : resolveMobileLogoSize(content, placement);
|
|
11493
|
+
return { desktopPx, mobilePx, mobileFollowing };
|
|
11494
|
+
}
|
|
11495
|
+
|
|
11496
|
+
// src/lib/site-wide-scope.ts
|
|
11497
|
+
function getLogoElement(el) {
|
|
11498
|
+
const marked = el.closest('[data-ohw-role="logo"], [data-ohw-logo]');
|
|
11499
|
+
if (marked) return marked;
|
|
11500
|
+
if (el.closest('[data-ohw-editable="icon"]')) return null;
|
|
11501
|
+
const root = el.closest("nav, [data-ohw-nav-root], footer");
|
|
11502
|
+
if (!root) return null;
|
|
11503
|
+
const anchor = el.closest("a");
|
|
11504
|
+
if (anchor && root.contains(anchor) && !anchor.hasAttribute("data-ohw-href-key") && !anchor.closest("[data-ohw-nav-container]") && Boolean(anchor.querySelector("img") || anchor.matches("img"))) {
|
|
11505
|
+
return anchor;
|
|
11506
|
+
}
|
|
11507
|
+
const img = el.matches("img") ? el : null;
|
|
11508
|
+
if (img && !img.closest("[data-ohw-href-key]") && !img.closest("[data-ohw-nav-container]") && (img.closest("footer") || img.closest("nav, [data-ohw-nav-root]"))) {
|
|
11509
|
+
return img;
|
|
11510
|
+
}
|
|
11511
|
+
return null;
|
|
11512
|
+
}
|
|
11513
|
+
function isInFooter(el) {
|
|
11514
|
+
if (!el) return false;
|
|
11515
|
+
return Boolean(el.closest("footer") || el.closest('[data-ohw-section="footer"]'));
|
|
11516
|
+
}
|
|
11517
|
+
function isSiteWideElement(el) {
|
|
11518
|
+
if (!el) return false;
|
|
11519
|
+
if (getLogoElement(el)) return true;
|
|
11520
|
+
if (isInFooter(el)) return true;
|
|
11521
|
+
if (el.hasAttribute("data-ohw-nav-container") || el.hasAttribute("data-ohw-nav-root")) {
|
|
11522
|
+
return true;
|
|
11523
|
+
}
|
|
11524
|
+
if (el.hasAttribute("data-ohw-href-key") && el.closest("nav, [data-ohw-nav-root], [data-ohw-nav-drawer], aside")) {
|
|
11525
|
+
return true;
|
|
11526
|
+
}
|
|
11527
|
+
if (el.closest('[data-ohw-role="navbar-button"]')) return true;
|
|
11528
|
+
return false;
|
|
11529
|
+
}
|
|
11530
|
+
function isSiteWideScopeActive(args) {
|
|
11531
|
+
return isSiteWideElement(args.selected) || isSiteWideElement(args.hoveredItem) || isSiteWideElement(args.hoveredNavContainer) || isSiteWideElement(args.active);
|
|
11532
|
+
}
|
|
11533
|
+
|
|
10851
11534
|
// src/lib/add-footer-column.ts
|
|
10852
11535
|
function buildFooterColumnEditContentPatch(result) {
|
|
10853
11536
|
return {
|
|
@@ -11069,16 +11752,127 @@ function FloatingPanel({
|
|
|
11069
11752
|
);
|
|
11070
11753
|
}
|
|
11071
11754
|
|
|
11072
|
-
// src/ui/
|
|
11755
|
+
// src/ui/logo-size-panel.tsx
|
|
11756
|
+
import { ArrowUpRight, Link as Link2 } from "lucide-react";
|
|
11073
11757
|
import { jsx as jsx27, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
11758
|
+
function SizeSlider({
|
|
11759
|
+
value,
|
|
11760
|
+
onChange
|
|
11761
|
+
}) {
|
|
11762
|
+
const pct = (value - LOGO_SIZE_MIN) / (LOGO_SIZE_MAX - LOGO_SIZE_MIN) * 100;
|
|
11763
|
+
return /* @__PURE__ */ jsxs17("div", { className: "flex w-full flex-col gap-3", children: [
|
|
11764
|
+
/* @__PURE__ */ jsxs17("div", { className: "flex w-full items-center gap-2 text-sm font-medium leading-5", children: [
|
|
11765
|
+
/* @__PURE__ */ jsx27("span", { className: "min-w-0 flex-1 text-foreground", children: "Size" }),
|
|
11766
|
+
/* @__PURE__ */ jsxs17("span", { className: "shrink-0 whitespace-nowrap text-muted-foreground", children: [
|
|
11767
|
+
value,
|
|
11768
|
+
" px"
|
|
11769
|
+
] })
|
|
11770
|
+
] }),
|
|
11771
|
+
/* @__PURE__ */ jsxs17("div", { className: "relative h-2 w-full rounded-full bg-primary-50", children: [
|
|
11772
|
+
/* @__PURE__ */ jsx27(
|
|
11773
|
+
"div",
|
|
11774
|
+
{
|
|
11775
|
+
className: "absolute inset-y-0 left-0 rounded-full bg-primary",
|
|
11776
|
+
style: { width: `${pct}%` }
|
|
11777
|
+
}
|
|
11778
|
+
),
|
|
11779
|
+
/* @__PURE__ */ jsx27(
|
|
11780
|
+
"input",
|
|
11781
|
+
{
|
|
11782
|
+
type: "range",
|
|
11783
|
+
min: LOGO_SIZE_MIN,
|
|
11784
|
+
max: LOGO_SIZE_MAX,
|
|
11785
|
+
step: 1,
|
|
11786
|
+
value,
|
|
11787
|
+
"aria-label": "Logo size",
|
|
11788
|
+
className: cn(
|
|
11789
|
+
"absolute inset-0 h-full w-full cursor-pointer appearance-none bg-transparent",
|
|
11790
|
+
"[&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:size-5",
|
|
11791
|
+
"[&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:border-2",
|
|
11792
|
+
"[&::-webkit-slider-thumb]:border-primary [&::-webkit-slider-thumb]:bg-background",
|
|
11793
|
+
"[&::-moz-range-thumb]:size-5 [&::-moz-range-thumb]:rounded-full",
|
|
11794
|
+
"[&::-moz-range-thumb]:border-2 [&::-moz-range-thumb]:border-primary",
|
|
11795
|
+
"[&::-moz-range-thumb]:bg-background"
|
|
11796
|
+
),
|
|
11797
|
+
onChange: (e) => onChange(Number(e.target.value))
|
|
11798
|
+
}
|
|
11799
|
+
)
|
|
11800
|
+
] })
|
|
11801
|
+
] });
|
|
11802
|
+
}
|
|
11803
|
+
function LogoSizePanel({
|
|
11804
|
+
viewport,
|
|
11805
|
+
sizePx,
|
|
11806
|
+
mobileFollowing = true,
|
|
11807
|
+
onSizeChange,
|
|
11808
|
+
onCustomizeMobile,
|
|
11809
|
+
onResetMobile,
|
|
11810
|
+
onUpdateEverywhere,
|
|
11811
|
+
className
|
|
11812
|
+
}) {
|
|
11813
|
+
const showFollowing = viewport === "mobile" && mobileFollowing;
|
|
11814
|
+
const showMobileSlider = viewport === "mobile" && !mobileFollowing;
|
|
11815
|
+
const showDesktopSlider = viewport === "desktop";
|
|
11816
|
+
return /* @__PURE__ */ jsxs17("div", { className: cn("flex w-full flex-col gap-4", className), children: [
|
|
11817
|
+
showFollowing ? /* @__PURE__ */ jsxs17("div", { className: "flex w-full flex-col gap-2", children: [
|
|
11818
|
+
/* @__PURE__ */ jsxs17("div", { className: "flex items-start gap-1", children: [
|
|
11819
|
+
/* @__PURE__ */ jsx27(Link2, { size: 16, className: "mt-0.5 shrink-0 text-foreground", "aria-hidden": true }),
|
|
11820
|
+
/* @__PURE__ */ jsx27("p", { className: "text-sm font-semibold leading-5 text-foreground", children: "Following desktop size" })
|
|
11821
|
+
] }),
|
|
11822
|
+
/* @__PURE__ */ jsx27("p", { className: "text-sm leading-5 text-muted-foreground", children: "Mobile uses the desktop size until you customize it. Change the desktop size and it follows automatically." }),
|
|
11823
|
+
/* @__PURE__ */ jsx27(
|
|
11824
|
+
Button,
|
|
11825
|
+
{
|
|
11826
|
+
type: "button",
|
|
11827
|
+
variant: "outline",
|
|
11828
|
+
size: "sm",
|
|
11829
|
+
className: "h-9 w-full min-w-0 cursor-pointer",
|
|
11830
|
+
onClick: onCustomizeMobile,
|
|
11831
|
+
children: "Customize for mobile"
|
|
11832
|
+
}
|
|
11833
|
+
)
|
|
11834
|
+
] }) : null,
|
|
11835
|
+
showDesktopSlider || showMobileSlider ? /* @__PURE__ */ jsx27(SizeSlider, { value: sizePx, onChange: onSizeChange }) : null,
|
|
11836
|
+
showMobileSlider ? /* @__PURE__ */ jsx27(
|
|
11837
|
+
Button,
|
|
11838
|
+
{
|
|
11839
|
+
type: "button",
|
|
11840
|
+
variant: "outline",
|
|
11841
|
+
size: "sm",
|
|
11842
|
+
className: "h-9 w-full min-w-0 cursor-pointer",
|
|
11843
|
+
onClick: onResetMobile,
|
|
11844
|
+
children: "Reset to desktop size"
|
|
11845
|
+
}
|
|
11846
|
+
) : null,
|
|
11847
|
+
/* @__PURE__ */ jsx27("div", { className: "h-px w-full bg-border", role: "separator" }),
|
|
11848
|
+
/* @__PURE__ */ jsxs17(
|
|
11849
|
+
Button,
|
|
11850
|
+
{
|
|
11851
|
+
type: "button",
|
|
11852
|
+
variant: "outline",
|
|
11853
|
+
size: "sm",
|
|
11854
|
+
className: "h-9 w-full min-w-0 cursor-pointer gap-1",
|
|
11855
|
+
onClick: onUpdateEverywhere,
|
|
11856
|
+
children: [
|
|
11857
|
+
"Update logo everywhere",
|
|
11858
|
+
/* @__PURE__ */ jsx27(ArrowUpRight, { size: 16, "aria-hidden": true })
|
|
11859
|
+
]
|
|
11860
|
+
}
|
|
11861
|
+
),
|
|
11862
|
+
/* @__PURE__ */ jsx27("p", { className: "text-sm leading-5 text-muted-foreground", children: "Matches the right version to your background." })
|
|
11863
|
+
] });
|
|
11864
|
+
}
|
|
11865
|
+
|
|
11866
|
+
// src/ui/socials-display-panel.tsx
|
|
11867
|
+
import { jsx as jsx28, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
11074
11868
|
function DisplaySwitch({
|
|
11075
11869
|
label,
|
|
11076
11870
|
checked,
|
|
11077
11871
|
disabled,
|
|
11078
11872
|
onChange
|
|
11079
11873
|
}) {
|
|
11080
|
-
return /* @__PURE__ */
|
|
11081
|
-
/* @__PURE__ */
|
|
11874
|
+
return /* @__PURE__ */ jsxs18("div", { className: "flex w-full items-center gap-2", children: [
|
|
11875
|
+
/* @__PURE__ */ jsx28(
|
|
11082
11876
|
"span",
|
|
11083
11877
|
{
|
|
11084
11878
|
className: cn(
|
|
@@ -11088,7 +11882,7 @@ function DisplaySwitch({
|
|
|
11088
11882
|
children: label
|
|
11089
11883
|
}
|
|
11090
11884
|
),
|
|
11091
|
-
/* @__PURE__ */
|
|
11885
|
+
/* @__PURE__ */ jsx28(
|
|
11092
11886
|
"button",
|
|
11093
11887
|
{
|
|
11094
11888
|
type: "button",
|
|
@@ -11102,7 +11896,7 @@ function DisplaySwitch({
|
|
|
11102
11896
|
checked ? "bg-primary" : "bg-primary-50",
|
|
11103
11897
|
disabled ? "cursor-default opacity-50" : "cursor-pointer"
|
|
11104
11898
|
),
|
|
11105
|
-
children: /* @__PURE__ */
|
|
11899
|
+
children: /* @__PURE__ */ jsx28(
|
|
11106
11900
|
"span",
|
|
11107
11901
|
{
|
|
11108
11902
|
className: cn(
|
|
@@ -11116,8 +11910,8 @@ function DisplaySwitch({
|
|
|
11116
11910
|
] });
|
|
11117
11911
|
}
|
|
11118
11912
|
function SocialsDisplayPanel({ display, onChange, className }) {
|
|
11119
|
-
return /* @__PURE__ */
|
|
11120
|
-
/* @__PURE__ */
|
|
11913
|
+
return /* @__PURE__ */ jsxs18("div", { className: cn("flex w-full flex-col gap-3", className), children: [
|
|
11914
|
+
/* @__PURE__ */ jsx28(
|
|
11121
11915
|
DisplaySwitch,
|
|
11122
11916
|
{
|
|
11123
11917
|
label: "Text",
|
|
@@ -11126,7 +11920,7 @@ function SocialsDisplayPanel({ display, onChange, className }) {
|
|
|
11126
11920
|
onChange: (text) => onChange({ ...display, text })
|
|
11127
11921
|
}
|
|
11128
11922
|
),
|
|
11129
|
-
/* @__PURE__ */
|
|
11923
|
+
/* @__PURE__ */ jsx28(
|
|
11130
11924
|
DisplaySwitch,
|
|
11131
11925
|
{
|
|
11132
11926
|
label: "Icon",
|
|
@@ -11687,7 +12481,7 @@ function useNavItemDrag({
|
|
|
11687
12481
|
|
|
11688
12482
|
// src/ui/footer-container-chrome.tsx
|
|
11689
12483
|
import { Plus as Plus2 } from "lucide-react";
|
|
11690
|
-
import { jsx as
|
|
12484
|
+
import { jsx as jsx29, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
11691
12485
|
function FooterContainerChrome({
|
|
11692
12486
|
rect,
|
|
11693
12487
|
onAdd,
|
|
@@ -11695,7 +12489,7 @@ function FooterContainerChrome({
|
|
|
11695
12489
|
}) {
|
|
11696
12490
|
const chromeGap = 6;
|
|
11697
12491
|
const buttonMargin = 7;
|
|
11698
|
-
return /* @__PURE__ */
|
|
12492
|
+
return /* @__PURE__ */ jsx29(TooltipProvider, { delayDuration: 0, children: /* @__PURE__ */ jsx29(
|
|
11699
12493
|
"div",
|
|
11700
12494
|
{
|
|
11701
12495
|
"data-ohw-footer-container-chrome": "",
|
|
@@ -11707,8 +12501,8 @@ function FooterContainerChrome({
|
|
|
11707
12501
|
width: rect.width + chromeGap * 2,
|
|
11708
12502
|
height: rect.height + chromeGap * 2
|
|
11709
12503
|
},
|
|
11710
|
-
children: /* @__PURE__ */
|
|
11711
|
-
/* @__PURE__ */
|
|
12504
|
+
children: /* @__PURE__ */ jsxs19(Tooltip, { children: [
|
|
12505
|
+
/* @__PURE__ */ jsx29(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx29(
|
|
11712
12506
|
"button",
|
|
11713
12507
|
{
|
|
11714
12508
|
type: "button",
|
|
@@ -11727,10 +12521,10 @@ function FooterContainerChrome({
|
|
|
11727
12521
|
if (addDisabled) return;
|
|
11728
12522
|
onAdd();
|
|
11729
12523
|
},
|
|
11730
|
-
children: /* @__PURE__ */
|
|
12524
|
+
children: /* @__PURE__ */ jsx29(Plus2, { className: "size-4 shrink-0 text-foreground", "aria-hidden": true })
|
|
11731
12525
|
}
|
|
11732
12526
|
) }),
|
|
11733
|
-
/* @__PURE__ */
|
|
12527
|
+
/* @__PURE__ */ jsx29(TooltipContent, { side: "bottom", sideOffset: 9, children: addDisabled ? "Maximum columns reached" : "Add item" })
|
|
11734
12528
|
] })
|
|
11735
12529
|
}
|
|
11736
12530
|
) });
|
|
@@ -11913,6 +12707,18 @@ function collectEditableNodes(extraContent, root = document) {
|
|
|
11913
12707
|
}
|
|
11914
12708
|
if (extraContent && !isScoped) {
|
|
11915
12709
|
applyNavFooterDeleteOverrides(byKey, extraContent);
|
|
12710
|
+
for (const key of LOGO_IMAGE_KEYS) {
|
|
12711
|
+
if (!(key in extraContent)) continue;
|
|
12712
|
+
byKey.set(key, { key, type: "image", text: extraContent[key] ?? "" });
|
|
12713
|
+
}
|
|
12714
|
+
for (const key of [LOGO_PLACEHOLDER_KEY, LOGO_ALT_KEY]) {
|
|
12715
|
+
if (!(key in extraContent)) continue;
|
|
12716
|
+
byKey.set(key, { key, type: "meta", text: extraContent[key] ?? "" });
|
|
12717
|
+
}
|
|
12718
|
+
for (const key of LOGO_SIZE_KEYS) {
|
|
12719
|
+
if (!(key in extraContent)) continue;
|
|
12720
|
+
byKey.set(key, { key, type: "meta", text: extraContent[key] ?? "" });
|
|
12721
|
+
}
|
|
11916
12722
|
}
|
|
11917
12723
|
return Array.from(byKey.values());
|
|
11918
12724
|
}
|
|
@@ -12179,13 +12985,13 @@ function deleteSelectedNavFooterItem(deps) {
|
|
|
12179
12985
|
|
|
12180
12986
|
// src/ui/navbar-container-chrome.tsx
|
|
12181
12987
|
import { Plus as Plus3 } from "lucide-react";
|
|
12182
|
-
import { jsx as
|
|
12988
|
+
import { jsx as jsx30 } from "react/jsx-runtime";
|
|
12183
12989
|
function NavbarContainerChrome({
|
|
12184
12990
|
rect,
|
|
12185
12991
|
onAdd
|
|
12186
12992
|
}) {
|
|
12187
12993
|
const chromeGap = 6;
|
|
12188
|
-
return /* @__PURE__ */
|
|
12994
|
+
return /* @__PURE__ */ jsx30(
|
|
12189
12995
|
"div",
|
|
12190
12996
|
{
|
|
12191
12997
|
"data-ohw-navbar-container-chrome": "",
|
|
@@ -12197,7 +13003,7 @@ function NavbarContainerChrome({
|
|
|
12197
13003
|
width: rect.width + chromeGap * 2,
|
|
12198
13004
|
height: rect.height + chromeGap * 2
|
|
12199
13005
|
},
|
|
12200
|
-
children: /* @__PURE__ */
|
|
13006
|
+
children: /* @__PURE__ */ jsx30(
|
|
12201
13007
|
"button",
|
|
12202
13008
|
{
|
|
12203
13009
|
type: "button",
|
|
@@ -12214,7 +13020,7 @@ function NavbarContainerChrome({
|
|
|
12214
13020
|
e.stopPropagation();
|
|
12215
13021
|
onAdd();
|
|
12216
13022
|
},
|
|
12217
|
-
children: /* @__PURE__ */
|
|
13023
|
+
children: /* @__PURE__ */ jsx30(Plus3, { className: "size-4 shrink-0 text-foreground", "aria-hidden": true })
|
|
12218
13024
|
}
|
|
12219
13025
|
)
|
|
12220
13026
|
}
|
|
@@ -12223,7 +13029,7 @@ function NavbarContainerChrome({
|
|
|
12223
13029
|
|
|
12224
13030
|
// src/ui/drop-indicator.tsx
|
|
12225
13031
|
import * as React10 from "react";
|
|
12226
|
-
import { jsx as
|
|
13032
|
+
import { jsx as jsx31 } from "react/jsx-runtime";
|
|
12227
13033
|
var dropIndicatorVariants = cva(
|
|
12228
13034
|
"ov-gap-line pointer-events-none shrink-0 transition-opacity duration-150",
|
|
12229
13035
|
{
|
|
@@ -12247,7 +13053,7 @@ var dropIndicatorVariants = cva(
|
|
|
12247
13053
|
);
|
|
12248
13054
|
var DropIndicator = React10.forwardRef(
|
|
12249
13055
|
({ className, direction, state, ...props }, ref) => {
|
|
12250
|
-
return /* @__PURE__ */
|
|
13056
|
+
return /* @__PURE__ */ jsx31(
|
|
12251
13057
|
"div",
|
|
12252
13058
|
{
|
|
12253
13059
|
ref,
|
|
@@ -12264,7 +13070,7 @@ var DropIndicator = React10.forwardRef(
|
|
|
12264
13070
|
DropIndicator.displayName = "DropIndicator";
|
|
12265
13071
|
|
|
12266
13072
|
// src/ui/badge.tsx
|
|
12267
|
-
import { jsx as
|
|
13073
|
+
import { jsx as jsx32 } from "react/jsx-runtime";
|
|
12268
13074
|
var badgeVariants = cva(
|
|
12269
13075
|
"inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
|
|
12270
13076
|
{
|
|
@@ -12282,12 +13088,12 @@ var badgeVariants = cva(
|
|
|
12282
13088
|
}
|
|
12283
13089
|
);
|
|
12284
13090
|
function Badge({ className, variant, ...props }) {
|
|
12285
|
-
return /* @__PURE__ */
|
|
13091
|
+
return /* @__PURE__ */ jsx32("div", { className: cn(badgeVariants({ variant }), className), ...props });
|
|
12286
13092
|
}
|
|
12287
13093
|
|
|
12288
13094
|
// src/OhhwellsBridge.tsx
|
|
12289
|
-
import { Link as
|
|
12290
|
-
import { Fragment as Fragment8, jsx as
|
|
13095
|
+
import { Link as Link3 } from "lucide-react";
|
|
13096
|
+
import { Fragment as Fragment8, jsx as jsx33, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
12291
13097
|
var PRIMARY3 = "#0885FE";
|
|
12292
13098
|
var IMAGE_FADE_MS = 300;
|
|
12293
13099
|
function runOpacityFade(el, onDone) {
|
|
@@ -12381,21 +13187,10 @@ function parseSchedulingInsertAfter(insertAfter) {
|
|
|
12381
13187
|
insertBefore: insertAfter.slice(idx + INSERT_BEFORE_MARKER.length)
|
|
12382
13188
|
};
|
|
12383
13189
|
}
|
|
12384
|
-
function
|
|
12385
|
-
|
|
12386
|
-
const
|
|
12387
|
-
|
|
12388
|
-
return { effectiveInsertAfter, insertBefore };
|
|
12389
|
-
}
|
|
12390
|
-
function getSchedulingMountPoint(insertAfter) {
|
|
12391
|
-
const { anchor } = parseSchedulingInsertAfter(insertAfter);
|
|
12392
|
-
let anchorEl = document.querySelector(`[data-ohw-section="${anchor}"]`);
|
|
12393
|
-
if (!anchorEl && anchor === "scheduling") {
|
|
12394
|
-
const widgets = Array.from(document.querySelectorAll('[data-ohw-section^="scheduling-"]'));
|
|
12395
|
-
anchorEl = widgets.at(-1) ?? null;
|
|
12396
|
-
}
|
|
12397
|
-
if (!anchorEl) return null;
|
|
12398
|
-
return anchorEl.closest('[data-ohw-section-container="scheduling"]') ?? anchorEl;
|
|
13190
|
+
function resolveEntryAnchor(entry) {
|
|
13191
|
+
if (entry.anchorId !== void 0) return { anchorId: entry.anchorId, beforeId: entry.beforeId ?? null };
|
|
13192
|
+
const parsed = parseSchedulingInsertAfter(entry.insertAfter);
|
|
13193
|
+
return { anchorId: parsed.anchor, beforeId: parsed.insertBefore };
|
|
12399
13194
|
}
|
|
12400
13195
|
function schedulingMountDepth(insertAfter) {
|
|
12401
13196
|
if (!insertAfter.includes(INSERT_BEFORE_MARKER)) return 0;
|
|
@@ -12412,8 +13207,7 @@ function getPageSchedulingEntries(raw) {
|
|
|
12412
13207
|
}
|
|
12413
13208
|
}
|
|
12414
13209
|
function isSchedulingWidgetMissing(entry) {
|
|
12415
|
-
|
|
12416
|
-
return !document.querySelector(`[data-ohw-section="${schedulingSectionId(effectiveInsertAfter)}"]`);
|
|
13210
|
+
return !document.querySelector(`[data-ohw-section="${schedulingSectionId(entry.insertAfter)}"]`);
|
|
12417
13211
|
}
|
|
12418
13212
|
function hasMissingSchedulingWidgets(entries) {
|
|
12419
13213
|
return entries.some(isSchedulingWidgetMissing);
|
|
@@ -12443,16 +13237,17 @@ function initSectionsFromContent(content, removeExisting = false) {
|
|
|
12443
13237
|
} catch {
|
|
12444
13238
|
}
|
|
12445
13239
|
}
|
|
12446
|
-
function mountSchedulingWidget(
|
|
12447
|
-
const
|
|
12448
|
-
const sectionId = schedulingSectionId(
|
|
13240
|
+
function mountSchedulingWidget(anchorId, notifyOnConnect = false, scheduleId, beforeId, existingWidgetId) {
|
|
13241
|
+
const widgetId = existingWidgetId ?? (beforeId ? `${anchorId}${INSERT_BEFORE_MARKER}${beforeId}` : anchorId);
|
|
13242
|
+
const sectionId = schedulingSectionId(widgetId);
|
|
12449
13243
|
if (document.querySelector(`[data-ohw-section="${sectionId}"]`)) return false;
|
|
12450
|
-
const
|
|
12451
|
-
if (!
|
|
13244
|
+
const anchorEl = document.querySelector(`[data-ohw-section="${anchorId}"]`);
|
|
13245
|
+
if (!anchorEl) return false;
|
|
13246
|
+
const mountPoint = anchorEl.closest('[data-ohw-section-container="scheduling"]') ?? anchorEl;
|
|
12452
13247
|
const container = document.createElement("div");
|
|
12453
13248
|
container.dataset.ohwSectionContainer = "scheduling";
|
|
12454
|
-
if (
|
|
12455
|
-
const beforeAnchor = document.querySelector(`[data-ohw-section="${
|
|
13249
|
+
if (beforeId) {
|
|
13250
|
+
const beforeAnchor = document.querySelector(`[data-ohw-section="${beforeId}"]`);
|
|
12456
13251
|
const beforePoint = beforeAnchor?.closest('[data-ohw-section-container="scheduling"]') ?? beforeAnchor;
|
|
12457
13252
|
if (!beforePoint) return false;
|
|
12458
13253
|
beforePoint.insertAdjacentElement("beforebegin", container);
|
|
@@ -12463,19 +13258,25 @@ function mountSchedulingWidget(insertAfter, notifyOnConnect = false, scheduleId,
|
|
|
12463
13258
|
}
|
|
12464
13259
|
tail.insertAdjacentElement("afterend", container);
|
|
12465
13260
|
}
|
|
12466
|
-
|
|
12467
|
-
|
|
12468
|
-
|
|
12469
|
-
|
|
12470
|
-
|
|
12471
|
-
|
|
12472
|
-
|
|
12473
|
-
|
|
12474
|
-
|
|
12475
|
-
|
|
12476
|
-
|
|
12477
|
-
|
|
12478
|
-
|
|
13261
|
+
try {
|
|
13262
|
+
const root = createRoot2(container);
|
|
13263
|
+
flushSync2(() => {
|
|
13264
|
+
root.render(
|
|
13265
|
+
/* @__PURE__ */ jsx33(
|
|
13266
|
+
SchedulingWidget,
|
|
13267
|
+
{
|
|
13268
|
+
notifyOnConnect,
|
|
13269
|
+
initialScheduleId: scheduleId,
|
|
13270
|
+
insertAfter: widgetId
|
|
13271
|
+
}
|
|
13272
|
+
)
|
|
13273
|
+
);
|
|
13274
|
+
});
|
|
13275
|
+
} catch (err) {
|
|
13276
|
+
console.error("[ow:scheduling] render threw", err);
|
|
13277
|
+
container.remove();
|
|
13278
|
+
return false;
|
|
13279
|
+
}
|
|
12479
13280
|
const tracker = getSectionsTracker();
|
|
12480
13281
|
let sections = [];
|
|
12481
13282
|
try {
|
|
@@ -12483,10 +13284,12 @@ function mountSchedulingWidget(insertAfter, notifyOnConnect = false, scheduleId,
|
|
|
12483
13284
|
} catch {
|
|
12484
13285
|
}
|
|
12485
13286
|
const inEditor = typeof window !== "undefined" && window.self !== window.top;
|
|
12486
|
-
if (inEditor && !sections.find((s) => s.type === "scheduling" && s.insertAfter ===
|
|
13287
|
+
if (inEditor && !sections.find((s) => s.type === "scheduling" && s.insertAfter === widgetId)) {
|
|
12487
13288
|
sections.push({
|
|
12488
13289
|
type: "scheduling",
|
|
12489
|
-
insertAfter:
|
|
13290
|
+
insertAfter: widgetId,
|
|
13291
|
+
anchorId,
|
|
13292
|
+
beforeId: beforeId ?? null,
|
|
12490
13293
|
pagePath: window.location.pathname,
|
|
12491
13294
|
...scheduleId ? { scheduleId } : {}
|
|
12492
13295
|
});
|
|
@@ -12500,7 +13303,8 @@ function mountSchedulingEntries(entries, notifyOnConnect = false) {
|
|
|
12500
13303
|
for (let i = pending.length - 1; i >= 0; i--) {
|
|
12501
13304
|
const entry = pending[i];
|
|
12502
13305
|
const shouldNotify = typeof notifyOnConnect === "function" ? notifyOnConnect(entry) : notifyOnConnect;
|
|
12503
|
-
|
|
13306
|
+
const { anchorId, beforeId } = resolveEntryAnchor(entry);
|
|
13307
|
+
if (mountSchedulingWidget(anchorId, shouldNotify, entry.scheduleId ?? null, beforeId, entry.insertAfter)) {
|
|
12504
13308
|
pending.splice(i, 1);
|
|
12505
13309
|
}
|
|
12506
13310
|
}
|
|
@@ -12644,6 +13448,13 @@ function isInsideLinkEditor(target) {
|
|
|
12644
13448
|
target.closest("[data-ohw-link-popover-root]") || target.closest("[data-ohw-link-modal-root]") || target.closest("[data-ohw-link-page-dropdown]") || target.closest("[data-ohw-section-picker]") || target.closest("[data-ohw-navbar-container-chrome]") || target.closest("[data-ohw-navbar-add-button]") || target.closest("[data-ohw-footer-container-chrome]") || target.closest("[data-ohw-footer-add-button]") || target.closest("[data-ohw-more-menu]") || target.closest('[data-slot="dropdown-menu-content"]') || target.closest('[data-slot="popover-content"]') || target.closest('[data-slot="dialog-content"]') || target.closest('[data-slot="dialog-overlay"]')
|
|
12645
13449
|
);
|
|
12646
13450
|
}
|
|
13451
|
+
function isInsideFloatingPanel(target) {
|
|
13452
|
+
return Boolean(target.closest("[data-ohw-floating-panel]"));
|
|
13453
|
+
}
|
|
13454
|
+
function isPointOverFloatingPanel(clientX, clientY) {
|
|
13455
|
+
const el = document.elementFromPoint(clientX, clientY);
|
|
13456
|
+
return Boolean(el instanceof Element && el.closest("[data-ohw-floating-panel]"));
|
|
13457
|
+
}
|
|
12647
13458
|
function getHrefKeyFromElement(el) {
|
|
12648
13459
|
if (!el) return null;
|
|
12649
13460
|
const anchor = el.closest("[data-ohw-href-key]");
|
|
@@ -12881,7 +13692,7 @@ function getNavigationSelectionParent(el) {
|
|
|
12881
13692
|
if (!isFooterLinksContainer(el) && (el.hasAttribute("data-ohw-footer-col") || el.hasAttribute("data-ohw-footer-column") || isInferredFooterGroup2(el))) {
|
|
12882
13693
|
return getFooterLinksContainer();
|
|
12883
13694
|
}
|
|
12884
|
-
if (el.hasAttribute("data-ohw-nav-container") || el.hasAttribute("data-ohw-nav-drawer") || isFooterLinksContainer(el)) {
|
|
13695
|
+
if (el.hasAttribute("data-ohw-nav-container") || el.hasAttribute("data-ohw-nav-drawer") || el.hasAttribute("data-ohw-footer-col") || el.hasAttribute("data-ohw-footer-column") || isFooterLinksContainer(el) || isInferredFooterGroup2(el)) {
|
|
12885
13696
|
return getNavigationRoot(el);
|
|
12886
13697
|
}
|
|
12887
13698
|
return null;
|
|
@@ -13127,7 +13938,7 @@ function EditGlowChrome({
|
|
|
13127
13938
|
hideHandle = false
|
|
13128
13939
|
}) {
|
|
13129
13940
|
const GAP = SELECTION_CHROME_GAP2;
|
|
13130
|
-
return /* @__PURE__ */
|
|
13941
|
+
return /* @__PURE__ */ jsxs20(
|
|
13131
13942
|
"div",
|
|
13132
13943
|
{
|
|
13133
13944
|
ref: elRef,
|
|
@@ -13142,7 +13953,7 @@ function EditGlowChrome({
|
|
|
13142
13953
|
zIndex: 2147483646
|
|
13143
13954
|
},
|
|
13144
13955
|
children: [
|
|
13145
|
-
/* @__PURE__ */
|
|
13956
|
+
/* @__PURE__ */ jsx33(
|
|
13146
13957
|
"div",
|
|
13147
13958
|
{
|
|
13148
13959
|
style: {
|
|
@@ -13155,7 +13966,7 @@ function EditGlowChrome({
|
|
|
13155
13966
|
}
|
|
13156
13967
|
}
|
|
13157
13968
|
),
|
|
13158
|
-
reorderHrefKey && !hideHandle && /* @__PURE__ */
|
|
13969
|
+
reorderHrefKey && !hideHandle && /* @__PURE__ */ jsx33(
|
|
13159
13970
|
"div",
|
|
13160
13971
|
{
|
|
13161
13972
|
"data-ohw-drag-handle-container": "",
|
|
@@ -13167,7 +13978,7 @@ function EditGlowChrome({
|
|
|
13167
13978
|
transform: "translate(calc(-100% - 7px), -50%)",
|
|
13168
13979
|
pointerEvents: dragDisabled ? "none" : "auto"
|
|
13169
13980
|
},
|
|
13170
|
-
children: /* @__PURE__ */
|
|
13981
|
+
children: /* @__PURE__ */ jsx33(
|
|
13171
13982
|
DragHandle,
|
|
13172
13983
|
{
|
|
13173
13984
|
"aria-label": `Reorder ${reorderHrefKey}`,
|
|
@@ -13377,7 +14188,7 @@ function FloatingToolbar({
|
|
|
13377
14188
|
return () => ro.disconnect();
|
|
13378
14189
|
}, [showEditLink, activeCommands]);
|
|
13379
14190
|
const { top, left, transform } = calcToolbarPos(rect, parentScroll, measuredW);
|
|
13380
|
-
return /* @__PURE__ */
|
|
14191
|
+
return /* @__PURE__ */ jsx33(
|
|
13381
14192
|
"div",
|
|
13382
14193
|
{
|
|
13383
14194
|
ref: setRefs,
|
|
@@ -13389,12 +14200,12 @@ function FloatingToolbar({
|
|
|
13389
14200
|
zIndex: 2147483647,
|
|
13390
14201
|
pointerEvents: "auto"
|
|
13391
14202
|
},
|
|
13392
|
-
children: /* @__PURE__ */
|
|
13393
|
-
TOOLBAR_GROUPS.map((btns, gi) => /* @__PURE__ */
|
|
13394
|
-
gi > 0 && /* @__PURE__ */
|
|
14203
|
+
children: /* @__PURE__ */ jsxs20(CustomToolbar, { children: [
|
|
14204
|
+
TOOLBAR_GROUPS.map((btns, gi) => /* @__PURE__ */ jsxs20(React11.Fragment, { children: [
|
|
14205
|
+
gi > 0 && /* @__PURE__ */ jsx33(CustomToolbarDivider, {}),
|
|
13395
14206
|
btns.map((btn) => {
|
|
13396
14207
|
const isActive = activeCommands.has(btn.cmd);
|
|
13397
|
-
return /* @__PURE__ */
|
|
14208
|
+
return /* @__PURE__ */ jsx33(
|
|
13398
14209
|
CustomToolbarButton,
|
|
13399
14210
|
{
|
|
13400
14211
|
title: btn.title,
|
|
@@ -13403,7 +14214,7 @@ function FloatingToolbar({
|
|
|
13403
14214
|
e.preventDefault();
|
|
13404
14215
|
onCommand(btn.cmd);
|
|
13405
14216
|
},
|
|
13406
|
-
children: /* @__PURE__ */
|
|
14217
|
+
children: /* @__PURE__ */ jsx33(
|
|
13407
14218
|
"svg",
|
|
13408
14219
|
{
|
|
13409
14220
|
width: "16",
|
|
@@ -13424,7 +14235,7 @@ function FloatingToolbar({
|
|
|
13424
14235
|
);
|
|
13425
14236
|
})
|
|
13426
14237
|
] }, gi)),
|
|
13427
|
-
showEditLink ? /* @__PURE__ */
|
|
14238
|
+
showEditLink ? /* @__PURE__ */ jsx33(
|
|
13428
14239
|
CustomToolbarButton,
|
|
13429
14240
|
{
|
|
13430
14241
|
type: "button",
|
|
@@ -13438,7 +14249,7 @@ function FloatingToolbar({
|
|
|
13438
14249
|
e.preventDefault();
|
|
13439
14250
|
e.stopPropagation();
|
|
13440
14251
|
},
|
|
13441
|
-
children: /* @__PURE__ */
|
|
14252
|
+
children: /* @__PURE__ */ jsx33(Link3, { className: "size-4 shrink-0", "aria-hidden": true })
|
|
13442
14253
|
}
|
|
13443
14254
|
) : null
|
|
13444
14255
|
] })
|
|
@@ -13455,7 +14266,7 @@ function StateToggle({
|
|
|
13455
14266
|
states,
|
|
13456
14267
|
onStateChange
|
|
13457
14268
|
}) {
|
|
13458
|
-
return /* @__PURE__ */
|
|
14269
|
+
return /* @__PURE__ */ jsx33(
|
|
13459
14270
|
ToggleGroup,
|
|
13460
14271
|
{
|
|
13461
14272
|
"data-ohw-state-toggle": "",
|
|
@@ -13469,11 +14280,12 @@ function StateToggle({
|
|
|
13469
14280
|
left: rect.right - 8,
|
|
13470
14281
|
transform: "translateX(-100%)"
|
|
13471
14282
|
},
|
|
13472
|
-
children: states.map((state) => /* @__PURE__ */
|
|
14283
|
+
children: states.map((state) => /* @__PURE__ */ jsx33(ToggleGroupItem, { value: state, size: "sm", children: state }, state))
|
|
13473
14284
|
}
|
|
13474
14285
|
);
|
|
13475
14286
|
}
|
|
13476
14287
|
var contentCache = /* @__PURE__ */ new Map();
|
|
14288
|
+
var fetchedContentPaths = /* @__PURE__ */ new Set();
|
|
13477
14289
|
function resolveSubdomain(subdomainFromQuery) {
|
|
13478
14290
|
if (subdomainFromQuery) return subdomainFromQuery;
|
|
13479
14291
|
if (typeof window !== "undefined") {
|
|
@@ -13568,8 +14380,14 @@ function OhhwellsBridge() {
|
|
|
13568
14380
|
});
|
|
13569
14381
|
const selectFrameRef = useRef9(() => {
|
|
13570
14382
|
});
|
|
14383
|
+
const selectLogoRef = useRef9(() => {
|
|
14384
|
+
});
|
|
14385
|
+
const openLogoSizePanelRef = useRef9(() => {
|
|
14386
|
+
});
|
|
13571
14387
|
const deselectRef = useRef9(() => {
|
|
13572
14388
|
});
|
|
14389
|
+
const closeFloatingPanelOnlyRef = useRef9(() => {
|
|
14390
|
+
});
|
|
13573
14391
|
const reselectNavigationItemRef = useRef9(() => {
|
|
13574
14392
|
});
|
|
13575
14393
|
const commitNavigationTextEditRef = useRef9(() => {
|
|
@@ -13630,11 +14448,6 @@ function OhhwellsBridge() {
|
|
|
13630
14448
|
const [isItemDragging, setIsItemDragging] = useState11(false);
|
|
13631
14449
|
const [isFooterFrameSelection, setIsFooterFrameSelection] = useState11(false);
|
|
13632
14450
|
isFooterFrameSelectionRef.current = isFooterFrameSelection;
|
|
13633
|
-
const [floatingPanel, setFloatingPanel] = useState11(null);
|
|
13634
|
-
const floatingPanelOpenRef = useRef9(false);
|
|
13635
|
-
floatingPanelOpenRef.current = floatingPanel !== null;
|
|
13636
|
-
const [floatingPanelPos, setFloatingPanelPos] = useState11(null);
|
|
13637
|
-
const [parentScrollSnap, setParentScrollSnap] = useState11(null);
|
|
13638
14451
|
const [navDropdownPreviewOpen, setNavDropdownPreviewOpen] = useState11(null);
|
|
13639
14452
|
const [footerHeadingVisible, setFooterHeadingVisible] = useState11(null);
|
|
13640
14453
|
const footerDragRef = useRef9(null);
|
|
@@ -13649,7 +14462,16 @@ function OhhwellsBridge() {
|
|
|
13649
14462
|
const addNavAfterAnchorRef = useRef9(null);
|
|
13650
14463
|
const editContentRef = useRef9({});
|
|
13651
14464
|
const aiSectionsRef = useRef9("");
|
|
14465
|
+
const brandKitRef = useRef9("");
|
|
14466
|
+
const stylesRef = useRef9("");
|
|
13652
14467
|
const pendingDeleteUndoRef = useRef9(null);
|
|
14468
|
+
const [floatingPanel, setFloatingPanel] = useState11(null);
|
|
14469
|
+
const floatingPanelOpenRef = useRef9(false);
|
|
14470
|
+
const setFloatingPanelRef = useRef9(setFloatingPanel);
|
|
14471
|
+
const [floatingPanelPos, setFloatingPanelPos] = useState11(null);
|
|
14472
|
+
const [logoSizeDraft, setLogoSizeDraft] = useState11(null);
|
|
14473
|
+
const [editorViewport, setEditorViewport] = useState11("desktop");
|
|
14474
|
+
const [parentScrollSnap, setParentScrollSnap] = useState11(null);
|
|
13653
14475
|
const [sitePages, setSitePages] = useState11([]);
|
|
13654
14476
|
const [sectionsByPath, setSectionsByPath] = useState11({});
|
|
13655
14477
|
const sectionsPrefetchGenRef = useRef9(0);
|
|
@@ -13658,7 +14480,18 @@ function OhhwellsBridge() {
|
|
|
13658
14480
|
const linkPopoverOpenRef = useRef9(false);
|
|
13659
14481
|
const linkPopoverGraceUntilRef = useRef9(0);
|
|
13660
14482
|
setLinkPopoverRef.current = setLinkPopover;
|
|
14483
|
+
setFloatingPanelRef.current = setFloatingPanel;
|
|
13661
14484
|
linkPopoverSessionRef.current = linkPopover;
|
|
14485
|
+
floatingPanelOpenRef.current = Boolean(floatingPanel);
|
|
14486
|
+
useEffect12(() => {
|
|
14487
|
+
const syncViewport = () => {
|
|
14488
|
+
const next = window.innerWidth <= 480 ? "mobile" : "desktop";
|
|
14489
|
+
setEditorViewport((prev) => prev === next ? prev : next);
|
|
14490
|
+
};
|
|
14491
|
+
syncViewport();
|
|
14492
|
+
window.addEventListener("resize", syncViewport);
|
|
14493
|
+
return () => window.removeEventListener("resize", syncViewport);
|
|
14494
|
+
}, []);
|
|
13662
14495
|
const {
|
|
13663
14496
|
navDragRef,
|
|
13664
14497
|
navDropSlots,
|
|
@@ -13881,6 +14714,10 @@ function OhhwellsBridge() {
|
|
|
13881
14714
|
setIsItemDragging(false);
|
|
13882
14715
|
hoveredNavContainerRef.current = null;
|
|
13883
14716
|
setHoveredNavContainerRect(null);
|
|
14717
|
+
hoveredItemElRef.current = null;
|
|
14718
|
+
setHoveredItemRect(null);
|
|
14719
|
+
setFloatingPanel(null);
|
|
14720
|
+
setLogoSizeDraft(null);
|
|
13884
14721
|
if (!activeElRef.current) {
|
|
13885
14722
|
setNavGroupForceOpen(null, false);
|
|
13886
14723
|
setToolbarRect(null);
|
|
@@ -14586,6 +15423,8 @@ function OhhwellsBridge() {
|
|
|
14586
15423
|
setToolbarRect(anchor.getBoundingClientRect());
|
|
14587
15424
|
setToolbarShowEditLink(false);
|
|
14588
15425
|
setActiveCommands(/* @__PURE__ */ new Set());
|
|
15426
|
+
setFloatingPanel(null);
|
|
15427
|
+
setLogoSizeDraft(null);
|
|
14589
15428
|
}, [deactivate, markSelected]);
|
|
14590
15429
|
const selectFrame = useCallback7((el) => {
|
|
14591
15430
|
if (!isNavigationContainer(el)) return;
|
|
@@ -14635,7 +15474,51 @@ function OhhwellsBridge() {
|
|
|
14635
15474
|
setToolbarRect(el.getBoundingClientRect());
|
|
14636
15475
|
setToolbarShowEditLink(false);
|
|
14637
15476
|
setActiveCommands(/* @__PURE__ */ new Set());
|
|
15477
|
+
setFloatingPanel(null);
|
|
15478
|
+
setLogoSizeDraft(null);
|
|
14638
15479
|
}, [deactivate, markSelected, postToParent2]);
|
|
15480
|
+
const selectLogo = useCallback7(
|
|
15481
|
+
(logoEl) => {
|
|
15482
|
+
if (activeElRef.current) deactivate();
|
|
15483
|
+
selectedElRef.current = logoEl;
|
|
15484
|
+
selectedHrefKeyRef.current = null;
|
|
15485
|
+
selectedFooterColAttrRef.current = null;
|
|
15486
|
+
markSelected(logoEl);
|
|
15487
|
+
setSelectedIsCta(false);
|
|
15488
|
+
setSelectedIsSocial(false);
|
|
15489
|
+
setSelectedIsSocialsRow(false);
|
|
15490
|
+
clearHrefKeyHover(logoEl);
|
|
15491
|
+
hoveredNavContainerRef.current = null;
|
|
15492
|
+
setHoveredNavContainerRect(null);
|
|
15493
|
+
setHoveredItemRect(null);
|
|
15494
|
+
hoveredItemElRef.current = null;
|
|
15495
|
+
siblingHintElRef.current = null;
|
|
15496
|
+
setSiblingHintRect(null);
|
|
15497
|
+
setSiblingHintRects([]);
|
|
15498
|
+
setIsItemDragging(false);
|
|
15499
|
+
setReorderHrefKey(null);
|
|
15500
|
+
setReorderDragDisabled(false);
|
|
15501
|
+
setIsFooterFrameSelection(false);
|
|
15502
|
+
setToolbarVariant("logo");
|
|
15503
|
+
setToolbarRect(getLogoInteractionRect(logoEl));
|
|
15504
|
+
setToolbarShowEditLink(false);
|
|
15505
|
+
setActiveCommands(/* @__PURE__ */ new Set());
|
|
15506
|
+
},
|
|
15507
|
+
[deactivate, markSelected]
|
|
15508
|
+
);
|
|
15509
|
+
const openLogoSizePanel = useCallback7((logoEl) => {
|
|
15510
|
+
const placement = getLogoPlacement(logoEl);
|
|
15511
|
+
const draft = readLogoSizeState(editContentRef.current, placement);
|
|
15512
|
+
setLogoSizeDraft(draft);
|
|
15513
|
+
setParentScrollSnap(parentScrollRef.current);
|
|
15514
|
+
setFloatingPanel({
|
|
15515
|
+
key: `logo-size:${placement}`,
|
|
15516
|
+
title: "Logo",
|
|
15517
|
+
context: placement === "navbar" ? "Navbar" : "Footer",
|
|
15518
|
+
kind: "logo-size",
|
|
15519
|
+
placement
|
|
15520
|
+
});
|
|
15521
|
+
}, []);
|
|
14639
15522
|
const openSocialsDisplayPanel = useCallback7((row) => {
|
|
14640
15523
|
setParentScrollSnap(parentScrollRef.current);
|
|
14641
15524
|
setFloatingPanel({
|
|
@@ -14671,13 +15554,53 @@ function OhhwellsBridge() {
|
|
|
14671
15554
|
);
|
|
14672
15555
|
const closeFloatingPanelOnly = useCallback7(() => {
|
|
14673
15556
|
setFloatingPanel(null);
|
|
15557
|
+
setLogoSizeDraft(null);
|
|
14674
15558
|
}, []);
|
|
14675
|
-
const closeFloatingPanelOnlyRef = useRef9(closeFloatingPanelOnly);
|
|
14676
|
-
closeFloatingPanelOnlyRef.current = closeFloatingPanelOnly;
|
|
14677
15559
|
const closeFloatingPanelAndDeselect = useCallback7(() => {
|
|
14678
15560
|
setFloatingPanel(null);
|
|
15561
|
+
setLogoSizeDraft(null);
|
|
14679
15562
|
deselectRef.current();
|
|
14680
15563
|
}, []);
|
|
15564
|
+
const persistLogoSizeDraft = useCallback7(
|
|
15565
|
+
(placement, draft) => {
|
|
15566
|
+
const desktopKey = LOGO_SIZE_DESKTOP_KEYS[placement];
|
|
15567
|
+
const mobileKey = LOGO_SIZE_MOBILE_KEYS[placement];
|
|
15568
|
+
const nodes = [
|
|
15569
|
+
{ key: desktopKey, text: String(draft.desktopPx) }
|
|
15570
|
+
];
|
|
15571
|
+
if (draft.mobileFollowing) {
|
|
15572
|
+
nodes.push({ key: mobileKey, text: "" });
|
|
15573
|
+
} else {
|
|
15574
|
+
nodes.push({ key: mobileKey, text: String(draft.mobilePx) });
|
|
15575
|
+
}
|
|
15576
|
+
editContentRef.current = {
|
|
15577
|
+
...editContentRef.current,
|
|
15578
|
+
[desktopKey]: String(draft.desktopPx),
|
|
15579
|
+
[mobileKey]: draft.mobileFollowing ? "" : String(draft.mobilePx)
|
|
15580
|
+
};
|
|
15581
|
+
applyLogoSizeToPlacement(
|
|
15582
|
+
placement,
|
|
15583
|
+
draft.desktopPx,
|
|
15584
|
+
draft.mobileFollowing ? draft.desktopPx : draft.mobilePx,
|
|
15585
|
+
draft.mobileFollowing
|
|
15586
|
+
);
|
|
15587
|
+
postToParent2({ type: "ow:change", nodes });
|
|
15588
|
+
requestAnimationFrame(() => {
|
|
15589
|
+
const selected = selectedElRef.current;
|
|
15590
|
+
if (!selected || toolbarVariantRef.current !== "logo") return;
|
|
15591
|
+
const rect = getLogoInteractionRect(selected);
|
|
15592
|
+
setToolbarRect(rect);
|
|
15593
|
+
if (glowElRef.current) {
|
|
15594
|
+
const GAP = SELECTION_CHROME_GAP2;
|
|
15595
|
+
glowElRef.current.style.top = `${rect.top - GAP}px`;
|
|
15596
|
+
glowElRef.current.style.left = `${rect.left - GAP}px`;
|
|
15597
|
+
glowElRef.current.style.width = `${rect.width + GAP * 2}px`;
|
|
15598
|
+
glowElRef.current.style.height = `${rect.height + GAP * 2}px`;
|
|
15599
|
+
}
|
|
15600
|
+
});
|
|
15601
|
+
},
|
|
15602
|
+
[postToParent2]
|
|
15603
|
+
);
|
|
14681
15604
|
const activate = useCallback7((el, options) => {
|
|
14682
15605
|
if (activeElRef.current === el) return;
|
|
14683
15606
|
if (isIconEditable(el)) return;
|
|
@@ -14758,7 +15681,37 @@ function OhhwellsBridge() {
|
|
|
14758
15681
|
deactivateRef.current = deactivate;
|
|
14759
15682
|
selectRef.current = select;
|
|
14760
15683
|
selectFrameRef.current = selectFrame;
|
|
15684
|
+
selectLogoRef.current = selectLogo;
|
|
15685
|
+
openLogoSizePanelRef.current = openLogoSizePanel;
|
|
14761
15686
|
deselectRef.current = deselect;
|
|
15687
|
+
closeFloatingPanelOnlyRef.current = closeFloatingPanelOnly;
|
|
15688
|
+
const lastSiteWideScopeRef = useRef9(null);
|
|
15689
|
+
useEffect12(() => {
|
|
15690
|
+
if (!isEditMode) {
|
|
15691
|
+
if (lastSiteWideScopeRef.current !== false) {
|
|
15692
|
+
lastSiteWideScopeRef.current = false;
|
|
15693
|
+
postToParent2({ type: "ow:site-wide-scope", active: false });
|
|
15694
|
+
}
|
|
15695
|
+
return;
|
|
15696
|
+
}
|
|
15697
|
+
const active = isSiteWideScopeActive({
|
|
15698
|
+
selected: selectedElRef.current,
|
|
15699
|
+
hoveredItem: hoveredItemElRef.current,
|
|
15700
|
+
hoveredNavContainer: hoveredNavContainerRef.current,
|
|
15701
|
+
active: activeElRef.current
|
|
15702
|
+
});
|
|
15703
|
+
if (lastSiteWideScopeRef.current === active) return;
|
|
15704
|
+
lastSiteWideScopeRef.current = active;
|
|
15705
|
+
postToParent2({ type: "ow:site-wide-scope", active });
|
|
15706
|
+
}, [
|
|
15707
|
+
isEditMode,
|
|
15708
|
+
hoveredItemRect,
|
|
15709
|
+
hoveredNavContainerRect,
|
|
15710
|
+
toolbarVariant,
|
|
15711
|
+
toolbarRect,
|
|
15712
|
+
isFooterFrameSelection,
|
|
15713
|
+
postToParent2
|
|
15714
|
+
]);
|
|
14762
15715
|
useLayoutEffect4(() => {
|
|
14763
15716
|
if (!subdomain || isEditMode) {
|
|
14764
15717
|
setFetchState("done");
|
|
@@ -14770,9 +15723,23 @@ function OhhwellsBridge() {
|
|
|
14770
15723
|
aiSectionsRef.current = content[AI_SECTIONS_KEY];
|
|
14771
15724
|
applyAiSectionsToDom(parseAiSectionsState(content[AI_SECTIONS_KEY]));
|
|
14772
15725
|
}
|
|
15726
|
+
if (typeof content[BRAND_KIT_KEY] === "string") {
|
|
15727
|
+
brandKitRef.current = content[BRAND_KIT_KEY];
|
|
15728
|
+
applyBrandToDom(parseBrandKit(content[BRAND_KIT_KEY]));
|
|
15729
|
+
}
|
|
15730
|
+
if (typeof content[STYLE_STORE_KEY] === "string") {
|
|
15731
|
+
stylesRef.current = content[STYLE_STORE_KEY];
|
|
15732
|
+
applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
|
|
15733
|
+
}
|
|
15734
|
+
applyBrandChrome(content);
|
|
14773
15735
|
for (const [key, val] of Object.entries(content)) {
|
|
14774
15736
|
if (key === "__ohw_sections") continue;
|
|
14775
15737
|
if (key === AI_SECTIONS_KEY) continue;
|
|
15738
|
+
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
15739
|
+
if (LOGO_IMAGE_KEYS.includes(key)) continue;
|
|
15740
|
+
if (key === BRAND_KIT_KEY) continue;
|
|
15741
|
+
if (key === STYLE_STORE_KEY) continue;
|
|
15742
|
+
if (BRAND_CHROME_KEYS.has(key)) continue;
|
|
14776
15743
|
if (applyVideoSettingNode(key, val)) continue;
|
|
14777
15744
|
if (applyCarouselNode(key, val)) continue;
|
|
14778
15745
|
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
@@ -14807,6 +15774,8 @@ function OhhwellsBridge() {
|
|
|
14807
15774
|
});
|
|
14808
15775
|
applyLinkByKey(key, val);
|
|
14809
15776
|
}
|
|
15777
|
+
applyLogoFromContent(content);
|
|
15778
|
+
applyLogoSizes(content);
|
|
14810
15779
|
reconcileNavbarItemsFromContent(content);
|
|
14811
15780
|
reconcileFooterOrderFromContent(content);
|
|
14812
15781
|
reconcileSocialsFromContent(content);
|
|
@@ -14827,7 +15796,9 @@ function OhhwellsBridge() {
|
|
|
14827
15796
|
let cancelled = false;
|
|
14828
15797
|
setFetchState("loading");
|
|
14829
15798
|
const apiUrl = process.env.NEXT_PUBLIC_FLOWOPS_API_URL ?? "https://flowops-backend-staging-2yfdh7pwpq-as.a.run.app";
|
|
14830
|
-
|
|
15799
|
+
const initialPath = pathname;
|
|
15800
|
+
fetchedContentPaths.add(`${subdomain}::${initialPath}`);
|
|
15801
|
+
fetch(`${apiUrl}/api/public/sites/${subdomain}/content?path=${encodeURIComponent(initialPath)}`, { cache: "no-store" }).then((r2) => r2.ok ? r2.json() : null).then((data) => {
|
|
14831
15802
|
if (cancelled) return;
|
|
14832
15803
|
const content = data?.content ?? {};
|
|
14833
15804
|
contentCache.set(subdomain, content);
|
|
@@ -14851,8 +15822,21 @@ function OhhwellsBridge() {
|
|
|
14851
15822
|
initSectionInstancesFromContent(content, window.location.pathname);
|
|
14852
15823
|
observer?.disconnect();
|
|
14853
15824
|
try {
|
|
15825
|
+
applyBrandChrome(content);
|
|
15826
|
+
if (typeof content[BRAND_KIT_KEY] === "string") {
|
|
15827
|
+
applyBrandToDom(parseBrandKit(content[BRAND_KIT_KEY]));
|
|
15828
|
+
}
|
|
15829
|
+
if (typeof content[STYLE_STORE_KEY] === "string") {
|
|
15830
|
+
applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
|
|
15831
|
+
}
|
|
14854
15832
|
for (const [key, val] of Object.entries(content)) {
|
|
14855
15833
|
if (key === "__ohw_sections") continue;
|
|
15834
|
+
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
15835
|
+
if (LOGO_IMAGE_KEYS.includes(key)) continue;
|
|
15836
|
+
if (key === BRAND_KIT_KEY) continue;
|
|
15837
|
+
if (key === STYLE_STORE_KEY) continue;
|
|
15838
|
+
if (key === STYLE_STORE_KEY) continue;
|
|
15839
|
+
if (BRAND_CHROME_KEYS.has(key)) continue;
|
|
14856
15840
|
if (applyVideoSettingNode(key, val)) continue;
|
|
14857
15841
|
if (applyCarouselNode(key, val)) continue;
|
|
14858
15842
|
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
@@ -14873,6 +15857,7 @@ function OhhwellsBridge() {
|
|
|
14873
15857
|
});
|
|
14874
15858
|
applyLinkByKey(key, val);
|
|
14875
15859
|
}
|
|
15860
|
+
applyLogoFromContent(content);
|
|
14876
15861
|
reconcileNavbarItemsFromContent(content);
|
|
14877
15862
|
reconcileFooterOrderFromContent(content);
|
|
14878
15863
|
reconcileSocialsFromContent(content);
|
|
@@ -14887,6 +15872,17 @@ function OhhwellsBridge() {
|
|
|
14887
15872
|
debounceTimer = setTimeout(applyFromCache, 150);
|
|
14888
15873
|
};
|
|
14889
15874
|
applyFromCache();
|
|
15875
|
+
const pathCacheKey = `${subdomain}::${pathname}`;
|
|
15876
|
+
if (!fetchedContentPaths.has(pathCacheKey)) {
|
|
15877
|
+
fetchedContentPaths.add(pathCacheKey);
|
|
15878
|
+
const apiUrl = process.env.NEXT_PUBLIC_FLOWOPS_API_URL ?? "https://flowops-backend-staging-2yfdh7pwpq-as.a.run.app";
|
|
15879
|
+
fetch(`${apiUrl}/api/public/sites/${subdomain}/content?path=${encodeURIComponent(pathname)}`, { cache: "no-store" }).then((r2) => r2.ok ? r2.json() : null).then((data) => {
|
|
15880
|
+
if (!data?.content) return;
|
|
15881
|
+
contentCache.set(subdomain, data.content);
|
|
15882
|
+
applyFromCache();
|
|
15883
|
+
}).catch(() => {
|
|
15884
|
+
});
|
|
15885
|
+
}
|
|
14890
15886
|
observer = new MutationObserver(scheduleApply);
|
|
14891
15887
|
observer.observe(document.body, { childList: true, subtree: true });
|
|
14892
15888
|
return () => {
|
|
@@ -14980,26 +15976,31 @@ function OhhwellsBridge() {
|
|
|
14980
15976
|
}, [isEditMode, pathname, subdomain, fetchState, resyncSelectedNavigationItem]);
|
|
14981
15977
|
useEffect12(() => {
|
|
14982
15978
|
if (!isEditMode) return;
|
|
15979
|
+
let lastPosted = 0;
|
|
14983
15980
|
const measure = () => {
|
|
14984
15981
|
const h = document.body.scrollHeight;
|
|
14985
|
-
if (h > 50
|
|
15982
|
+
if (h > 50 && Math.abs(h - lastPosted) > 1) {
|
|
15983
|
+
lastPosted = h;
|
|
15984
|
+
postToParent2({ type: "ow:height", height: h });
|
|
15985
|
+
}
|
|
15986
|
+
};
|
|
15987
|
+
let raf = null;
|
|
15988
|
+
const schedule = () => {
|
|
15989
|
+
if (raf != null) return;
|
|
15990
|
+
raf = requestAnimationFrame(() => {
|
|
15991
|
+
raf = null;
|
|
15992
|
+
measure();
|
|
15993
|
+
});
|
|
14986
15994
|
};
|
|
14987
15995
|
const t1 = setTimeout(measure, 50);
|
|
14988
15996
|
const t2 = setTimeout(measure, 500);
|
|
14989
|
-
|
|
14990
|
-
|
|
14991
|
-
const handleResize = () => {
|
|
14992
|
-
if (window.innerWidth === lastWidth) return;
|
|
14993
|
-
lastWidth = window.innerWidth;
|
|
14994
|
-
if (resizeTimer) clearTimeout(resizeTimer);
|
|
14995
|
-
resizeTimer = setTimeout(measure, 150);
|
|
14996
|
-
};
|
|
14997
|
-
window.addEventListener("resize", handleResize);
|
|
15997
|
+
const ro = new ResizeObserver(schedule);
|
|
15998
|
+
ro.observe(document.body);
|
|
14998
15999
|
return () => {
|
|
14999
16000
|
clearTimeout(t1);
|
|
15000
16001
|
clearTimeout(t2);
|
|
15001
|
-
if (
|
|
15002
|
-
|
|
16002
|
+
if (raf != null) cancelAnimationFrame(raf);
|
|
16003
|
+
ro.disconnect();
|
|
15003
16004
|
};
|
|
15004
16005
|
}, [pathname, isEditMode, postToParent2]);
|
|
15005
16006
|
useEffect12(() => {
|
|
@@ -15149,10 +16150,12 @@ function OhhwellsBridge() {
|
|
|
15149
16150
|
return;
|
|
15150
16151
|
}
|
|
15151
16152
|
const target = e.target;
|
|
16153
|
+
if (target.closest("[data-ohw-ai-review]")) return;
|
|
15152
16154
|
if (target.closest("[data-ohw-toolbar]")) return;
|
|
15153
16155
|
if (target.closest("[data-ohw-state-toggle]")) return;
|
|
15154
16156
|
if (target.closest("[data-ohw-max-badge]")) return;
|
|
15155
16157
|
if (isInsideLinkEditor(target)) return;
|
|
16158
|
+
if (isInsideFloatingPanel(target)) return;
|
|
15156
16159
|
if (target.closest('[data-ohw-edit-chrome], [data-ohw-item-interaction], [data-ohw-drag-handle-container], [data-slot="drag-handle"]')) {
|
|
15157
16160
|
const beneath = document.elementsFromPoint(e.clientX, e.clientY).find(
|
|
15158
16161
|
(el) => el instanceof HTMLElement && !el.closest("[data-ohw-bridge-root]") && el.closest("[data-ohw-section]") != null
|
|
@@ -15216,6 +16219,21 @@ function OhhwellsBridge() {
|
|
|
15216
16219
|
return;
|
|
15217
16220
|
}
|
|
15218
16221
|
}
|
|
16222
|
+
const logoEl = getLogoElement(target);
|
|
16223
|
+
if (logoEl) {
|
|
16224
|
+
e.preventDefault();
|
|
16225
|
+
e.stopPropagation();
|
|
16226
|
+
if (!logoHasUploadedImage(logoEl)) {
|
|
16227
|
+
deselectRef.current();
|
|
16228
|
+
deactivateRef.current();
|
|
16229
|
+
const identity = readLogoIdentityFromDom();
|
|
16230
|
+
postToParentRef.current({ type: "ow:open-logo-settings", ...identity });
|
|
16231
|
+
return;
|
|
16232
|
+
}
|
|
16233
|
+
selectLogoRef.current(logoEl);
|
|
16234
|
+
openLogoSizePanelRef.current(logoEl);
|
|
16235
|
+
return;
|
|
16236
|
+
}
|
|
15219
16237
|
const editable = target.closest("[data-ohw-editable]");
|
|
15220
16238
|
if (editable) {
|
|
15221
16239
|
if (editable.dataset.ohwEditable === "link") {
|
|
@@ -15368,10 +16386,12 @@ function OhhwellsBridge() {
|
|
|
15368
16386
|
};
|
|
15369
16387
|
const handleDblClick = (e) => {
|
|
15370
16388
|
const target = e.target;
|
|
16389
|
+
if (target.closest("[data-ohw-ai-review]")) return;
|
|
15371
16390
|
if (target.closest("[data-ohw-toolbar]")) return;
|
|
15372
16391
|
if (target.closest("[data-ohw-state-toggle]")) return;
|
|
15373
16392
|
if (target.closest("[data-ohw-max-badge]")) return;
|
|
15374
16393
|
if (isInsideLinkEditor(target)) return;
|
|
16394
|
+
if (isInsideFloatingPanel(target)) return;
|
|
15375
16395
|
if (target.closest('[data-ohw-edit-chrome], [data-ohw-item-interaction], [data-ohw-drag-handle-container], [data-slot="drag-handle"]')) {
|
|
15376
16396
|
return;
|
|
15377
16397
|
}
|
|
@@ -15399,11 +16419,14 @@ function OhhwellsBridge() {
|
|
|
15399
16419
|
setHoveredNavContainerRect(null);
|
|
15400
16420
|
return;
|
|
15401
16421
|
}
|
|
15402
|
-
if (document.documentElement.hasAttribute("data-ohw-panel-dragging") || target.
|
|
16422
|
+
if (document.documentElement.hasAttribute("data-ohw-panel-dragging") || isInsideFloatingPanel(target) || isPointOverFloatingPanel(e.clientX, e.clientY)) {
|
|
15403
16423
|
hoveredItemElRef.current = null;
|
|
15404
16424
|
setHoveredItemRect(null);
|
|
15405
16425
|
hoveredNavContainerRef.current = null;
|
|
15406
16426
|
setHoveredNavContainerRect(null);
|
|
16427
|
+
siblingHintElRef.current = null;
|
|
16428
|
+
setSiblingHintRect(null);
|
|
16429
|
+
setSiblingHintRects([]);
|
|
15407
16430
|
return;
|
|
15408
16431
|
}
|
|
15409
16432
|
{
|
|
@@ -15413,7 +16436,7 @@ function OhhwellsBridge() {
|
|
|
15413
16436
|
const allowFooterLinksHover = toolbarVariantRef.current !== "select-frame" || selectedIsFooterColumn;
|
|
15414
16437
|
if (allowNavContainerHover) {
|
|
15415
16438
|
const navContainer = target.closest("[data-ohw-nav-container]");
|
|
15416
|
-
if (navContainer && !getNavigationItemAnchor(target)) {
|
|
16439
|
+
if (navContainer && !getNavigationItemAnchor(target) && !getLogoElement(target)) {
|
|
15417
16440
|
hoveredNavContainerRef.current = navContainer;
|
|
15418
16441
|
setHoveredNavContainerRect(navContainer.getBoundingClientRect());
|
|
15419
16442
|
hoveredItemElRef.current = null;
|
|
@@ -15442,6 +16465,15 @@ function OhhwellsBridge() {
|
|
|
15442
16465
|
setHoveredNavContainerRect(null);
|
|
15443
16466
|
}
|
|
15444
16467
|
}
|
|
16468
|
+
const logoEl = getLogoElement(target);
|
|
16469
|
+
if (logoEl) {
|
|
16470
|
+
hoveredNavContainerRef.current = null;
|
|
16471
|
+
setHoveredNavContainerRect(null);
|
|
16472
|
+
if (selectedElRef.current === logoEl) return;
|
|
16473
|
+
hoveredItemElRef.current = logoEl;
|
|
16474
|
+
setHoveredItemRect(getLogoInteractionRect(logoEl));
|
|
16475
|
+
return;
|
|
16476
|
+
}
|
|
15445
16477
|
const navAnchor = getNavigationItemAnchor(target);
|
|
15446
16478
|
if (navAnchor) {
|
|
15447
16479
|
hoveredNavContainerRef.current = null;
|
|
@@ -15479,6 +16511,11 @@ function OhhwellsBridge() {
|
|
|
15479
16511
|
setHoveredItemRect(hoverTarget.getBoundingClientRect());
|
|
15480
16512
|
} else if (!isInsideNavigationItem(editable)) {
|
|
15481
16513
|
hoverTarget.setAttribute("data-ohw-hovered", "");
|
|
16514
|
+
if (editable.closest("footer") || editable.closest('[data-ohw-section="footer"]')) {
|
|
16515
|
+
hoveredNavContainerRef.current = null;
|
|
16516
|
+
setHoveredNavContainerRect(null);
|
|
16517
|
+
hoveredItemElRef.current = editable;
|
|
16518
|
+
}
|
|
15482
16519
|
}
|
|
15483
16520
|
}
|
|
15484
16521
|
};
|
|
@@ -15514,6 +16551,18 @@ function OhhwellsBridge() {
|
|
|
15514
16551
|
}
|
|
15515
16552
|
return;
|
|
15516
16553
|
}
|
|
16554
|
+
const logoEl = getLogoElement(target);
|
|
16555
|
+
if (logoEl) {
|
|
16556
|
+
const related2 = e.relatedTarget instanceof Element ? e.relatedTarget : null;
|
|
16557
|
+
if (related2 && (logoEl === related2 || logoEl.contains(related2) || related2.closest?.('[data-ohw-role="logo"], [data-ohw-logo]'))) {
|
|
16558
|
+
return;
|
|
16559
|
+
}
|
|
16560
|
+
if (hoveredItemElRef.current === logoEl) {
|
|
16561
|
+
hoveredItemElRef.current = null;
|
|
16562
|
+
setHoveredItemRect(null);
|
|
16563
|
+
}
|
|
16564
|
+
return;
|
|
16565
|
+
}
|
|
15517
16566
|
const editable = target.closest("[data-ohw-editable]");
|
|
15518
16567
|
if (!editable) return;
|
|
15519
16568
|
const related = e.relatedTarget instanceof Element ? e.relatedTarget : null;
|
|
@@ -15534,6 +16583,13 @@ function OhhwellsBridge() {
|
|
|
15534
16583
|
}
|
|
15535
16584
|
} else {
|
|
15536
16585
|
hoverTarget.removeAttribute("data-ohw-hovered");
|
|
16586
|
+
if (hoveredItemElRef.current === editable) {
|
|
16587
|
+
const stillOnEditable = related instanceof Element && related.closest("[data-ohw-editable]") === editable;
|
|
16588
|
+
if (!stillOnEditable) {
|
|
16589
|
+
hoveredItemElRef.current = null;
|
|
16590
|
+
setHoveredItemRect(null);
|
|
16591
|
+
}
|
|
16592
|
+
}
|
|
15537
16593
|
}
|
|
15538
16594
|
}
|
|
15539
16595
|
};
|
|
@@ -15650,6 +16706,26 @@ function OhhwellsBridge() {
|
|
|
15650
16706
|
hoveredNavContainerRef.current = null;
|
|
15651
16707
|
setHoveredNavContainerRect(null);
|
|
15652
16708
|
}
|
|
16709
|
+
const logoCandidates = [
|
|
16710
|
+
...document.querySelectorAll('[data-ohw-role="logo"], [data-ohw-logo]'),
|
|
16711
|
+
...document.querySelectorAll("nav a:not([data-ohw-href-key]), [data-ohw-nav-root] a:not([data-ohw-href-key])"),
|
|
16712
|
+
...document.querySelectorAll("footer img")
|
|
16713
|
+
];
|
|
16714
|
+
const seenLogos = /* @__PURE__ */ new Set();
|
|
16715
|
+
for (const candidate of logoCandidates) {
|
|
16716
|
+
const logo = getLogoElement(candidate);
|
|
16717
|
+
if (!logo || seenLogos.has(logo)) continue;
|
|
16718
|
+
seenLogos.add(logo);
|
|
16719
|
+
const r2 = logo.getBoundingClientRect();
|
|
16720
|
+
if (x < r2.left || x > r2.right || y < r2.top || y > r2.bottom) continue;
|
|
16721
|
+
hoveredNavContainerRef.current = null;
|
|
16722
|
+
setHoveredNavContainerRect(null);
|
|
16723
|
+
if (selectedElRef.current !== logo) {
|
|
16724
|
+
hoveredItemElRef.current = logo;
|
|
16725
|
+
setHoveredItemRect(getLogoInteractionRect(logo));
|
|
16726
|
+
}
|
|
16727
|
+
return;
|
|
16728
|
+
}
|
|
15653
16729
|
const navContainers = Array.from(
|
|
15654
16730
|
document.querySelectorAll("[data-ohw-nav-container]")
|
|
15655
16731
|
);
|
|
@@ -15735,7 +16811,7 @@ function OhhwellsBridge() {
|
|
|
15735
16811
|
}
|
|
15736
16812
|
};
|
|
15737
16813
|
const probeImageAt = (clientX, clientY, isDragOver = false, fromParentViewport = false) => {
|
|
15738
|
-
if (linkPopoverOpenRef.current) {
|
|
16814
|
+
if (linkPopoverOpenRef.current || floatingPanelOpenRef.current && isPointOverFloatingPanel(clientX, clientY)) {
|
|
15739
16815
|
if (hoveredImageRef.current) {
|
|
15740
16816
|
hoveredImageRef.current = null;
|
|
15741
16817
|
hoveredImageHasTextOverlapRef.current = false;
|
|
@@ -15989,7 +17065,7 @@ function OhhwellsBridge() {
|
|
|
15989
17065
|
}
|
|
15990
17066
|
};
|
|
15991
17067
|
const probeHoverCardsAt = (clientX, clientY, fromParentViewport = false) => {
|
|
15992
|
-
if (linkPopoverOpenRef.current || document.documentElement.hasAttribute("data-ohw-section-picking")) {
|
|
17068
|
+
if (linkPopoverOpenRef.current || floatingPanelOpenRef.current && isPointOverFloatingPanel(clientX, clientY) || document.documentElement.hasAttribute("data-ohw-section-picking")) {
|
|
15993
17069
|
if (activeStateElRef.current) {
|
|
15994
17070
|
activeStateElRef.current.removeAttribute("data-ohw-state-hovered");
|
|
15995
17071
|
activeStateElRef.current = null;
|
|
@@ -16055,16 +17131,21 @@ function OhhwellsBridge() {
|
|
|
16055
17131
|
setSectionGap(null);
|
|
16056
17132
|
}
|
|
16057
17133
|
};
|
|
16058
|
-
const pointOwnedByFloatingPanel = (clientX, clientY) => {
|
|
16059
|
-
if (document.documentElement.hasAttribute("data-ohw-panel-dragging")) return true;
|
|
16060
|
-
const panel = document.querySelector("[data-ohw-floating-panel]");
|
|
16061
|
-
if (!panel) return false;
|
|
16062
|
-
const rect = panel.getBoundingClientRect();
|
|
16063
|
-
return clientX >= rect.left && clientX <= rect.right && clientY >= rect.top && clientY <= rect.bottom;
|
|
16064
|
-
};
|
|
16065
17134
|
const handleMouseMove = (e) => {
|
|
16066
17135
|
const { clientX, clientY } = e;
|
|
16067
|
-
if (
|
|
17136
|
+
if (document.documentElement.hasAttribute("data-ohw-panel-dragging") || floatingPanelOpenRef.current && isPointOverFloatingPanel(clientX, clientY)) {
|
|
17137
|
+
hoveredItemElRef.current = null;
|
|
17138
|
+
setHoveredItemRect(null);
|
|
17139
|
+
hoveredNavContainerRef.current = null;
|
|
17140
|
+
setHoveredNavContainerRect(null);
|
|
17141
|
+
siblingHintElRef.current = null;
|
|
17142
|
+
setSiblingHintRect(null);
|
|
17143
|
+
setSiblingHintRects([]);
|
|
17144
|
+
dismissImageHover();
|
|
17145
|
+
clearImageHover();
|
|
17146
|
+
setSectionGap(null);
|
|
17147
|
+
return;
|
|
17148
|
+
}
|
|
16068
17149
|
probeSectionGapAt(clientX, clientY);
|
|
16069
17150
|
probeImageAt(clientX, clientY);
|
|
16070
17151
|
probeHoverCardsAt(clientX, clientY);
|
|
@@ -16073,7 +17154,11 @@ function OhhwellsBridge() {
|
|
|
16073
17154
|
if (e.data?.type !== "ow:pointer-sync") return;
|
|
16074
17155
|
const { clientX, clientY } = e.data;
|
|
16075
17156
|
if (typeof clientX !== "number" || typeof clientY !== "number") return;
|
|
16076
|
-
if (
|
|
17157
|
+
if (document.documentElement.hasAttribute("data-ohw-panel-dragging") || floatingPanelOpenRef.current && isPointOverFloatingPanel(clientX, clientY)) {
|
|
17158
|
+
dismissImageHover();
|
|
17159
|
+
clearImageHover();
|
|
17160
|
+
return;
|
|
17161
|
+
}
|
|
16077
17162
|
probeSectionGapAt(clientX, clientY);
|
|
16078
17163
|
probeImageAt(clientX, clientY);
|
|
16079
17164
|
probeHoverCardsAt(clientX, clientY);
|
|
@@ -16323,6 +17408,15 @@ function OhhwellsBridge() {
|
|
|
16323
17408
|
aiSectionsRef.current = content[AI_SECTIONS_KEY];
|
|
16324
17409
|
applyAiSectionsToDom(parseAiSectionsState(content[AI_SECTIONS_KEY]));
|
|
16325
17410
|
}
|
|
17411
|
+
if (typeof content[BRAND_KIT_KEY] === "string") {
|
|
17412
|
+
brandKitRef.current = content[BRAND_KIT_KEY];
|
|
17413
|
+
applyBrandToDom(parseBrandKit(content[BRAND_KIT_KEY]));
|
|
17414
|
+
}
|
|
17415
|
+
if (typeof content[STYLE_STORE_KEY] === "string") {
|
|
17416
|
+
stylesRef.current = content[STYLE_STORE_KEY];
|
|
17417
|
+
applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
|
|
17418
|
+
}
|
|
17419
|
+
applyBrandChrome(content);
|
|
16326
17420
|
let sectionsJson = null;
|
|
16327
17421
|
for (const [key, val] of Object.entries(content)) {
|
|
16328
17422
|
if (key === "__ohw_sections") {
|
|
@@ -16330,6 +17424,11 @@ function OhhwellsBridge() {
|
|
|
16330
17424
|
continue;
|
|
16331
17425
|
}
|
|
16332
17426
|
if (key === AI_SECTIONS_KEY) continue;
|
|
17427
|
+
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
17428
|
+
if (LOGO_IMAGE_KEYS.includes(key) && !String(val ?? "").trim()) continue;
|
|
17429
|
+
if (key === BRAND_KIT_KEY) continue;
|
|
17430
|
+
if (key === STYLE_STORE_KEY) continue;
|
|
17431
|
+
if (BRAND_CHROME_KEYS.has(key)) continue;
|
|
16333
17432
|
if (applyVideoSettingNode(key, val)) continue;
|
|
16334
17433
|
if (applyCarouselNode(key, val)) continue;
|
|
16335
17434
|
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
@@ -16349,6 +17448,8 @@ function OhhwellsBridge() {
|
|
|
16349
17448
|
});
|
|
16350
17449
|
applyLinkByKey(key, val);
|
|
16351
17450
|
}
|
|
17451
|
+
applyLogoFromContent(content);
|
|
17452
|
+
applyLogoSizes(content);
|
|
16352
17453
|
if (sectionsJson) {
|
|
16353
17454
|
initSectionsFromContent({ __ohw_sections: sectionsJson }, true);
|
|
16354
17455
|
sectionsLoadedRef.current = true;
|
|
@@ -16364,6 +17465,58 @@ function OhhwellsBridge() {
|
|
|
16364
17465
|
if (hydratedHeight > 50) postToParentRef.current({ type: "ow:height", height: hydratedHeight });
|
|
16365
17466
|
postToParentRef.current({ type: "ow:hydrate-done" });
|
|
16366
17467
|
};
|
|
17468
|
+
const handleUpdateLogoIdentity = (e) => {
|
|
17469
|
+
if (e.data?.type !== "ow:update-logo-identity") return;
|
|
17470
|
+
const rawText = typeof e.data.text === "string" ? e.data.text : "";
|
|
17471
|
+
const alt = typeof e.data.alt === "string" ? e.data.alt : rawText;
|
|
17472
|
+
const href = typeof e.data.href === "string" ? e.data.href : void 0;
|
|
17473
|
+
const imageProvided = "image" in e.data;
|
|
17474
|
+
const imageUrl = imageProvided && typeof e.data.image === "string" && e.data.image.trim() ? e.data.image.trim() : imageProvided ? null : void 0;
|
|
17475
|
+
let isPlaceholder = e.data.isPlaceholder !== false;
|
|
17476
|
+
if (imageUrl) isPlaceholder = false;
|
|
17477
|
+
else if (imageProvided && imageUrl === null) {
|
|
17478
|
+
isPlaceholder = e.data.isPlaceholder === true || !rawText.trim() || resolveLogoDisplayText(rawText) === PLACEHOLDER_BUSINESS_NAME;
|
|
17479
|
+
}
|
|
17480
|
+
const display = applyLogoIdentity(rawText, isPlaceholder);
|
|
17481
|
+
const displayAlt = resolveLogoDisplayText(alt || display);
|
|
17482
|
+
if (imageUrl !== void 0) {
|
|
17483
|
+
applyLogoImage(imageUrl, displayAlt);
|
|
17484
|
+
} else {
|
|
17485
|
+
for (const key of LOGO_IMAGE_KEYS) {
|
|
17486
|
+
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
17487
|
+
const img = el instanceof HTMLImageElement ? el : el.querySelector("img");
|
|
17488
|
+
if (img) img.alt = displayAlt;
|
|
17489
|
+
});
|
|
17490
|
+
}
|
|
17491
|
+
}
|
|
17492
|
+
if (href !== void 0) {
|
|
17493
|
+
applyLogoHref(href);
|
|
17494
|
+
applyLinkByKey("nav-logo-href", href);
|
|
17495
|
+
applyLinkByKey("footer-logo-href", href);
|
|
17496
|
+
applyLinkByKey("logo-href", href);
|
|
17497
|
+
}
|
|
17498
|
+
const nodes = [
|
|
17499
|
+
...LOGO_TEXT_KEYS.map((key) => ({ key, text: display })),
|
|
17500
|
+
{ key: LOGO_PLACEHOLDER_KEY, text: isPlaceholder ? "true" : "false" },
|
|
17501
|
+
{ key: LOGO_ALT_KEY, text: displayAlt }
|
|
17502
|
+
];
|
|
17503
|
+
if (imageUrl !== void 0) {
|
|
17504
|
+
if (imageUrl) {
|
|
17505
|
+
for (const key of LOGO_IMAGE_KEYS) nodes.push({ key, text: imageUrl });
|
|
17506
|
+
} else {
|
|
17507
|
+
for (const key of LOGO_IMAGE_KEYS) nodes.push({ key, text: "" });
|
|
17508
|
+
}
|
|
17509
|
+
}
|
|
17510
|
+
if (href !== void 0) {
|
|
17511
|
+
for (const key of LOGO_HREF_KEYS) nodes.push({ key, text: href.trim() || "/" });
|
|
17512
|
+
}
|
|
17513
|
+
editContentRef.current = {
|
|
17514
|
+
...editContentRef.current,
|
|
17515
|
+
...Object.fromEntries(nodes.map(({ key, text }) => [key, text]))
|
|
17516
|
+
};
|
|
17517
|
+
applyLogoSizes(editContentRef.current);
|
|
17518
|
+
postToParentRef.current({ type: "ow:change", nodes });
|
|
17519
|
+
};
|
|
16367
17520
|
window.addEventListener("message", handleHydrate);
|
|
16368
17521
|
const postAiSectionsChanged = () => {
|
|
16369
17522
|
postToParentRef.current({
|
|
@@ -16377,7 +17530,10 @@ function OhhwellsBridge() {
|
|
|
16377
17530
|
const payload = e.data.payload;
|
|
16378
17531
|
if (!payload || typeof payload.id !== "string" || !isRenderableTree(payload.tree)) return;
|
|
16379
17532
|
const previous = aiSectionsRef.current;
|
|
16380
|
-
const nextState = applyTreeToState(parseAiSectionsState(previous),
|
|
17533
|
+
const nextState = applyTreeToState(parseAiSectionsState(previous), {
|
|
17534
|
+
...payload,
|
|
17535
|
+
path: payload.path ?? window.location.pathname
|
|
17536
|
+
});
|
|
16381
17537
|
const nextValue = serializeAiSectionsState(nextState);
|
|
16382
17538
|
aiSectionsRef.current = nextValue;
|
|
16383
17539
|
applyAiSectionsToDom(nextState);
|
|
@@ -16414,12 +17570,42 @@ function OhhwellsBridge() {
|
|
|
16414
17570
|
const value = typeof e.data.value === "string" ? e.data.value : "";
|
|
16415
17571
|
aiSectionsRef.current = value;
|
|
16416
17572
|
applyAiSectionsToDom(parseAiSectionsState(value));
|
|
17573
|
+
applyStylesToDom(parseStyleStore(stylesRef.current));
|
|
16417
17574
|
const restoredHeight = document.documentElement.scrollHeight;
|
|
16418
17575
|
if (restoredHeight > 50) postToParentRef.current({ type: "ow:height", height: restoredHeight });
|
|
16419
17576
|
postToParentRef.current({ type: "ow:change", nodes: [{ key: AI_SECTIONS_KEY, text: value }] });
|
|
16420
17577
|
postAiSectionsChanged();
|
|
16421
17578
|
};
|
|
16422
17579
|
window.addEventListener("message", handleAiSetSections);
|
|
17580
|
+
const handleAiSetBrand = (e) => {
|
|
17581
|
+
if (e.data?.type !== "ow:ai-set-brand") return;
|
|
17582
|
+
const value = typeof e.data.value === "string" ? e.data.value : "";
|
|
17583
|
+
const previous = brandKitRef.current;
|
|
17584
|
+
brandKitRef.current = value;
|
|
17585
|
+
applyBrandToDom(parseBrandKit(value));
|
|
17586
|
+
if (aiSectionsRef.current) applyAiSectionsToDom(parseAiSectionsState(aiSectionsRef.current));
|
|
17587
|
+
applyStylesToDom(parseStyleStore(stylesRef.current));
|
|
17588
|
+
postToParentRef.current({ type: "ow:change", nodes: [{ key: BRAND_KIT_KEY, text: value }] });
|
|
17589
|
+
postToParentRef.current({ type: "ow:ai-brand-applied", previous, value });
|
|
17590
|
+
};
|
|
17591
|
+
window.addEventListener("message", handleAiSetBrand);
|
|
17592
|
+
const handleAiSetStyles = (e) => {
|
|
17593
|
+
if (e.data?.type !== "ow:ai-set-styles") return;
|
|
17594
|
+
const value = typeof e.data.value === "string" ? e.data.value : "";
|
|
17595
|
+
const previous = stylesRef.current;
|
|
17596
|
+
stylesRef.current = value;
|
|
17597
|
+
applyStylesToDom(parseStyleStore(value));
|
|
17598
|
+
postToParentRef.current({ type: "ow:change", nodes: [{ key: STYLE_STORE_KEY, text: value }] });
|
|
17599
|
+
postToParentRef.current({ type: "ow:ai-styles-applied", previous, value });
|
|
17600
|
+
};
|
|
17601
|
+
window.addEventListener("message", handleAiSetStyles);
|
|
17602
|
+
const handleGetBrand = (e) => {
|
|
17603
|
+
if (e.data?.type !== "ow:get-brand") return;
|
|
17604
|
+
const template = deriveTemplateBrand();
|
|
17605
|
+
const value = brandKitRef.current || (template ? JSON.stringify(template) : "");
|
|
17606
|
+
postToParentRef.current({ type: "ow:brand-value", value });
|
|
17607
|
+
};
|
|
17608
|
+
window.addEventListener("message", handleGetBrand);
|
|
16423
17609
|
const handleDeactivate = (e) => {
|
|
16424
17610
|
if (e.data?.type !== "ow:deactivate") return;
|
|
16425
17611
|
if (Date.now() < linkPopoverGraceUntilRef.current) return;
|
|
@@ -16428,6 +17614,12 @@ function OhhwellsBridge() {
|
|
|
16428
17614
|
closeLinkPopoverRef.current();
|
|
16429
17615
|
return;
|
|
16430
17616
|
}
|
|
17617
|
+
if (floatingPanelOpenRef.current) {
|
|
17618
|
+
setFloatingPanelRef.current(null);
|
|
17619
|
+
deselectRef.current();
|
|
17620
|
+
deactivateRef.current();
|
|
17621
|
+
return;
|
|
17622
|
+
}
|
|
16431
17623
|
deselectRef.current();
|
|
16432
17624
|
deactivateRef.current();
|
|
16433
17625
|
};
|
|
@@ -16481,6 +17673,10 @@ function OhhwellsBridge() {
|
|
|
16481
17673
|
return;
|
|
16482
17674
|
}
|
|
16483
17675
|
if (selectedElRef.current) {
|
|
17676
|
+
if (toolbarVariantRef.current === "logo") {
|
|
17677
|
+
deselectRef.current();
|
|
17678
|
+
return;
|
|
17679
|
+
}
|
|
16484
17680
|
if (toolbarVariantRef.current === "select-frame") {
|
|
16485
17681
|
const parent2 = getNavigationSelectionParent(selectedElRef.current);
|
|
16486
17682
|
if (parent2 && isNavigationContainer(parent2) && isFooterLinksContainer(parent2) && !isFooterLinksContainer(selectedElRef.current)) {
|
|
@@ -16520,6 +17716,10 @@ function OhhwellsBridge() {
|
|
|
16520
17716
|
return;
|
|
16521
17717
|
}
|
|
16522
17718
|
if (e.key === "Escape" && selectedElRef.current && !activeElRef.current) {
|
|
17719
|
+
if (toolbarVariantRef.current === "logo") {
|
|
17720
|
+
deselectRef.current();
|
|
17721
|
+
return;
|
|
17722
|
+
}
|
|
16523
17723
|
if (toolbarVariantRef.current === "select-frame") {
|
|
16524
17724
|
const parent2 = getNavigationSelectionParent(selectedElRef.current);
|
|
16525
17725
|
if (parent2 && isNavigationContainer(parent2) && isFooterLinksContainer(parent2) && !isFooterLinksContainer(selectedElRef.current)) {
|
|
@@ -16597,7 +17797,8 @@ function OhhwellsBridge() {
|
|
|
16597
17797
|
const handleScroll = () => {
|
|
16598
17798
|
const focusEl = activeElRef.current ?? selectedElRef.current;
|
|
16599
17799
|
if (focusEl) {
|
|
16600
|
-
const
|
|
17800
|
+
const measureEl = activeElRef.current ? getEditMeasureEl(activeElRef.current) : toolbarVariantRef.current === "logo" ? null : focusEl;
|
|
17801
|
+
const r2 = measureEl ? measureEl.getBoundingClientRect() : toolbarVariantRef.current === "logo" ? getLogoInteractionRect(focusEl) : focusEl.getBoundingClientRect();
|
|
16601
17802
|
applyToolbarPos(r2);
|
|
16602
17803
|
setToolbarRect(r2);
|
|
16603
17804
|
setMaxBadge((prev) => prev && activeElRef.current ? { ...prev, rect: r2 } : prev);
|
|
@@ -16607,7 +17808,9 @@ function OhhwellsBridge() {
|
|
|
16607
17808
|
setToggleState((prev) => prev ? { ...prev, rect } : null);
|
|
16608
17809
|
}
|
|
16609
17810
|
if (hoveredItemElRef.current) {
|
|
16610
|
-
|
|
17811
|
+
const hoverEl = hoveredItemElRef.current;
|
|
17812
|
+
const logo = getLogoElement(hoverEl);
|
|
17813
|
+
setHoveredItemRect(logo ? getLogoInteractionRect(logo) : hoverEl.getBoundingClientRect());
|
|
16611
17814
|
}
|
|
16612
17815
|
if (hoveredNavContainerRef.current) {
|
|
16613
17816
|
setHoveredNavContainerRect(hoveredNavContainerRef.current.getBoundingClientRect());
|
|
@@ -16651,6 +17854,12 @@ function OhhwellsBridge() {
|
|
|
16651
17854
|
if (aiSectionsRef.current) {
|
|
16652
17855
|
nodes.push({ key: AI_SECTIONS_KEY, type: "sections", text: aiSectionsRef.current });
|
|
16653
17856
|
}
|
|
17857
|
+
if (stylesRef.current) {
|
|
17858
|
+
nodes.push({ key: STYLE_STORE_KEY, type: "styles", text: stylesRef.current });
|
|
17859
|
+
}
|
|
17860
|
+
if (brandKitRef.current) {
|
|
17861
|
+
nodes.push({ key: BRAND_KIT_KEY, type: "brand", text: brandKitRef.current });
|
|
17862
|
+
}
|
|
16654
17863
|
postToParentRef.current({ type: "ow:save-result", nodes });
|
|
16655
17864
|
};
|
|
16656
17865
|
const handleInsertSection = (e) => {
|
|
@@ -16661,8 +17870,12 @@ function OhhwellsBridge() {
|
|
|
16661
17870
|
if (inserted) {
|
|
16662
17871
|
const tracker = getSectionsTracker();
|
|
16663
17872
|
postToParentRef.current({ type: "ow:change", nodes: [{ key: "__ohw_sections", text: tracker.textContent ?? "[]" }] });
|
|
16664
|
-
const
|
|
16665
|
-
|
|
17873
|
+
const reportHeight = () => {
|
|
17874
|
+
const h = document.body.scrollHeight;
|
|
17875
|
+
if (h > 50) postToParentRef.current({ type: "ow:height", height: h });
|
|
17876
|
+
};
|
|
17877
|
+
reportHeight();
|
|
17878
|
+
setTimeout(reportHeight, 500);
|
|
16666
17879
|
}
|
|
16667
17880
|
};
|
|
16668
17881
|
const handleSwitchSchedule = (e) => {
|
|
@@ -16855,13 +18068,17 @@ function OhhwellsBridge() {
|
|
|
16855
18068
|
if (e.data?.type !== "ow:parent-scroll") return;
|
|
16856
18069
|
const { iframeOffsetTop, headerH, canvasH } = e.data;
|
|
16857
18070
|
parentScrollRef.current = { iframeOffsetTop, headerH, canvasH };
|
|
18071
|
+
if (floatingPanelOpenRef.current) {
|
|
18072
|
+
setParentScrollSnap({ iframeOffsetTop, headerH, canvasH });
|
|
18073
|
+
}
|
|
16858
18074
|
if (visibleViewportRef.current) {
|
|
16859
18075
|
applyVisibleViewport(visibleViewportRef.current, parentScrollRef.current);
|
|
16860
18076
|
}
|
|
16861
18077
|
const focusEl = activeElRef.current ?? selectedElRef.current;
|
|
16862
18078
|
if (focusEl) {
|
|
16863
|
-
const measureEl = activeElRef.current ? getEditMeasureEl(activeElRef.current) : focusEl;
|
|
16864
|
-
|
|
18079
|
+
const measureEl = activeElRef.current ? getEditMeasureEl(activeElRef.current) : toolbarVariantRef.current === "logo" ? null : focusEl;
|
|
18080
|
+
const r2 = measureEl ? measureEl.getBoundingClientRect() : toolbarVariantRef.current === "logo" ? getLogoInteractionRect(focusEl) : focusEl.getBoundingClientRect();
|
|
18081
|
+
applyToolbarPos(r2);
|
|
16865
18082
|
}
|
|
16866
18083
|
};
|
|
16867
18084
|
const handleClickAt = (e) => {
|
|
@@ -16886,6 +18103,25 @@ function OhhwellsBridge() {
|
|
|
16886
18103
|
postToParentRef.current({ type: "ow:image-pick", key: stateCardImage.dataset.ohwKey ?? "", elementType: stateCardImage.dataset.ohwEditable ?? "image" });
|
|
16887
18104
|
return;
|
|
16888
18105
|
}
|
|
18106
|
+
const logoAtPoint = Array.from(
|
|
18107
|
+
document.querySelectorAll('[data-ohw-role="logo"], [data-ohw-logo]')
|
|
18108
|
+
).map((el) => getLogoElement(el)).find((logo) => {
|
|
18109
|
+
if (!logo) return false;
|
|
18110
|
+
const r2 = logo.getBoundingClientRect();
|
|
18111
|
+
return clientX >= r2.left && clientX <= r2.right && clientY >= r2.top && clientY <= r2.bottom;
|
|
18112
|
+
});
|
|
18113
|
+
if (logoAtPoint) {
|
|
18114
|
+
if (!logoHasUploadedImage(logoAtPoint)) {
|
|
18115
|
+
deselectRef.current();
|
|
18116
|
+
deactivateRef.current();
|
|
18117
|
+
const identity = readLogoIdentityFromDom();
|
|
18118
|
+
postToParentRef.current({ type: "ow:open-logo-settings", ...identity });
|
|
18119
|
+
return;
|
|
18120
|
+
}
|
|
18121
|
+
selectLogoRef.current(logoAtPoint);
|
|
18122
|
+
openLogoSizePanelRef.current(logoAtPoint);
|
|
18123
|
+
return;
|
|
18124
|
+
}
|
|
16889
18125
|
const textEditable = Array.from(
|
|
16890
18126
|
document.querySelectorAll(NON_MEDIA_SELECTOR)
|
|
16891
18127
|
).find((el) => {
|
|
@@ -16957,6 +18193,14 @@ function OhhwellsBridge() {
|
|
|
16957
18193
|
window.addEventListener("message", handleParentScroll);
|
|
16958
18194
|
window.addEventListener("message", handlePointerSync);
|
|
16959
18195
|
window.addEventListener("message", handleClickAt);
|
|
18196
|
+
window.addEventListener("message", handleUpdateLogoIdentity);
|
|
18197
|
+
const handleViewMode = (e) => {
|
|
18198
|
+
if (e.data?.type !== "ow:view-mode") return;
|
|
18199
|
+
const mode = e.data.mode === "Mobile" || e.data.mode === "mobile" ? "mobile" : "desktop";
|
|
18200
|
+
setEditorViewport(mode);
|
|
18201
|
+
applyLogoSizes(editContentRef.current);
|
|
18202
|
+
};
|
|
18203
|
+
window.addEventListener("message", handleViewMode);
|
|
16960
18204
|
const handleViewportResize = () => {
|
|
16961
18205
|
if (visibleViewportRef.current) {
|
|
16962
18206
|
applyVisibleViewport(visibleViewportRef.current, parentScrollRef.current);
|
|
@@ -17012,10 +18256,15 @@ function OhhwellsBridge() {
|
|
|
17012
18256
|
window.removeEventListener("resize", handleViewportResize);
|
|
17013
18257
|
window.removeEventListener("message", handlePointerSync);
|
|
17014
18258
|
window.removeEventListener("message", handleClickAt);
|
|
18259
|
+
window.removeEventListener("message", handleUpdateLogoIdentity);
|
|
18260
|
+
window.removeEventListener("message", handleViewMode);
|
|
17015
18261
|
window.removeEventListener("message", handleHydrate);
|
|
17016
18262
|
window.removeEventListener("message", handleAiApplyTree);
|
|
17017
18263
|
window.removeEventListener("message", handleAiDeleteSection);
|
|
17018
18264
|
window.removeEventListener("message", handleAiSetSections);
|
|
18265
|
+
window.removeEventListener("message", handleAiSetBrand);
|
|
18266
|
+
window.removeEventListener("message", handleAiSetStyles);
|
|
18267
|
+
window.removeEventListener("message", handleGetBrand);
|
|
17019
18268
|
window.removeEventListener("message", handleDeactivate);
|
|
17020
18269
|
window.removeEventListener("message", handleToastAction);
|
|
17021
18270
|
window.removeEventListener("message", handleUiEscape);
|
|
@@ -17219,7 +18468,7 @@ function OhhwellsBridge() {
|
|
|
17219
18468
|
postToParent2({
|
|
17220
18469
|
type: "ow:ready",
|
|
17221
18470
|
version: "1",
|
|
17222
|
-
bridgeVersion: "0.1.
|
|
18471
|
+
bridgeVersion: "0.1.61",
|
|
17223
18472
|
path: pathname,
|
|
17224
18473
|
nodes: collectEditableNodes(editContentRef.current),
|
|
17225
18474
|
sections
|
|
@@ -17614,10 +18863,10 @@ function OhhwellsBridge() {
|
|
|
17614
18863
|
[postToParent2]
|
|
17615
18864
|
);
|
|
17616
18865
|
return bridgeRoot ? createPortal2(
|
|
17617
|
-
/* @__PURE__ */
|
|
17618
|
-
/* @__PURE__ */
|
|
17619
|
-
isEditMode && /* @__PURE__ */
|
|
17620
|
-
Object.entries(uploadingRects).map(([key, { rect, fadingOut }]) => /* @__PURE__ */
|
|
18866
|
+
/* @__PURE__ */ jsxs20(Fragment8, { children: [
|
|
18867
|
+
/* @__PURE__ */ jsx33("div", { ref: attachVisibleViewport, "data-ohw-visible-viewport": "", "aria-hidden": true }),
|
|
18868
|
+
isEditMode && /* @__PURE__ */ jsx33(AiSectionOverlay, { postToParent: postToParent2, apiRef: aiSectionApiRef }),
|
|
18869
|
+
Object.entries(uploadingRects).map(([key, { rect, fadingOut }]) => /* @__PURE__ */ jsx33(
|
|
17621
18870
|
MediaOverlay,
|
|
17622
18871
|
{
|
|
17623
18872
|
hover: { key, rect, elementType: "image", isDragOver: false, hasTextOverlap: false },
|
|
@@ -17628,7 +18877,7 @@ function OhhwellsBridge() {
|
|
|
17628
18877
|
},
|
|
17629
18878
|
`uploading-${key}`
|
|
17630
18879
|
)),
|
|
17631
|
-
mediaHover && !(mediaHover.key in uploadingRects) && /* @__PURE__ */
|
|
18880
|
+
mediaHover && !(mediaHover.key in uploadingRects) && /* @__PURE__ */ jsx33(
|
|
17632
18881
|
MediaOverlay,
|
|
17633
18882
|
{
|
|
17634
18883
|
hover: mediaHover,
|
|
@@ -17637,11 +18886,11 @@ function OhhwellsBridge() {
|
|
|
17637
18886
|
onVideoSettingsChange: handleVideoSettingsChange
|
|
17638
18887
|
}
|
|
17639
18888
|
),
|
|
17640
|
-
carouselHover && !linkPopover && !isItemDragging && /* @__PURE__ */
|
|
17641
|
-
siblingHintRect && !linkPopover && !isItemDragging && siblingHintRects.length === 0 && /* @__PURE__ */
|
|
17642
|
-
siblingHintRects.length > 0 && !linkPopover && !isItemDragging && siblingHintRects.map((rect, i) => /* @__PURE__ */
|
|
17643
|
-
isItemDragging && draggedItemRect && selectedElRef.current !== footerDragRef.current?.draggedEl && selectedElRef.current !== navDragRef.current?.draggedEl && /* @__PURE__ */
|
|
17644
|
-
isItemDragging && footerDropSlots.map((slot, i) => /* @__PURE__ */
|
|
18889
|
+
carouselHover && !linkPopover && !isItemDragging && /* @__PURE__ */ jsx33(CarouselOverlay, { hover: carouselHover, onEdit: handleEditCarousel }),
|
|
18890
|
+
siblingHintRect && !linkPopover && !isItemDragging && siblingHintRects.length === 0 && /* @__PURE__ */ jsx33(ItemInteractionLayer, { rect: siblingHintRect, state: "sibling-hint" }),
|
|
18891
|
+
siblingHintRects.length > 0 && !linkPopover && !isItemDragging && siblingHintRects.map((rect, i) => /* @__PURE__ */ jsx33(ItemInteractionLayer, { rect, state: "sibling-hint" }, `sibling-hint-${i}`)),
|
|
18892
|
+
isItemDragging && draggedItemRect && selectedElRef.current !== footerDragRef.current?.draggedEl && selectedElRef.current !== navDragRef.current?.draggedEl && /* @__PURE__ */ jsx33(ItemInteractionLayer, { rect: draggedItemRect, state: "dragging" }),
|
|
18893
|
+
isItemDragging && footerDropSlots.map((slot, i) => /* @__PURE__ */ jsx33(
|
|
17645
18894
|
"div",
|
|
17646
18895
|
{
|
|
17647
18896
|
className: "pointer-events-none fixed z-2147483646",
|
|
@@ -17651,7 +18900,7 @@ function OhhwellsBridge() {
|
|
|
17651
18900
|
width: slot.width,
|
|
17652
18901
|
height: slot.height
|
|
17653
18902
|
},
|
|
17654
|
-
children: /* @__PURE__ */
|
|
18903
|
+
children: /* @__PURE__ */ jsx33(
|
|
17655
18904
|
DropIndicator,
|
|
17656
18905
|
{
|
|
17657
18906
|
direction: slot.direction,
|
|
@@ -17662,7 +18911,7 @@ function OhhwellsBridge() {
|
|
|
17662
18911
|
},
|
|
17663
18912
|
`footer-drop-${slot.direction}-${slot.columnIndex}-${slot.insertIndex}-${i}`
|
|
17664
18913
|
)),
|
|
17665
|
-
isItemDragging && navDropSlots.map((slot, i) => /* @__PURE__ */
|
|
18914
|
+
isItemDragging && navDropSlots.map((slot, i) => /* @__PURE__ */ jsx33(
|
|
17666
18915
|
"div",
|
|
17667
18916
|
{
|
|
17668
18917
|
className: "pointer-events-none fixed z-2147483646",
|
|
@@ -17672,7 +18921,7 @@ function OhhwellsBridge() {
|
|
|
17672
18921
|
width: slot.width,
|
|
17673
18922
|
height: slot.height
|
|
17674
18923
|
},
|
|
17675
|
-
children: /* @__PURE__ */
|
|
18924
|
+
children: /* @__PURE__ */ jsx33(
|
|
17676
18925
|
DropIndicator,
|
|
17677
18926
|
{
|
|
17678
18927
|
direction: slot.direction,
|
|
@@ -17683,11 +18932,11 @@ function OhhwellsBridge() {
|
|
|
17683
18932
|
},
|
|
17684
18933
|
`nav-drop-${slot.direction}-${slot.parentId ?? "root"}-${slot.insertIndex}-${i}`
|
|
17685
18934
|
)),
|
|
17686
|
-
hoveredNavContainerRect && (toolbarVariant !== "select-frame" || isFooterFrameSelection) && !linkPopover && !isItemDragging && /* @__PURE__ */
|
|
17687
|
-
hoveredItemRect && !linkPopover && !hoveredNavContainerRect && !isItemDragging && hoveredItemElRef.current !== selectedElRef.current && /* @__PURE__ */
|
|
17688
|
-
hoveredTextRect && !isItemDragging && toolbarVariant !== "rich-text" && /* @__PURE__ */
|
|
17689
|
-
toolbarVariant === "select-frame" && toolbarRect && !linkPopover && !isItemDragging && !isFooterFrameSelection && selectedElRef.current && isNavbarLinksContainer2(selectedElRef.current) && /* @__PURE__ */
|
|
17690
|
-
toolbarVariant === "select-frame" && toolbarRect && !linkPopover && !isItemDragging && !isFooterFrameSelection && selectedElRef.current && isFooterLinksContainer(selectedElRef.current) && /* @__PURE__ */
|
|
18935
|
+
hoveredNavContainerRect && (toolbarVariant !== "select-frame" || isFooterFrameSelection) && !linkPopover && !isItemDragging && /* @__PURE__ */ jsx33(ItemInteractionLayer, { rect: hoveredNavContainerRect, state: "hover" }),
|
|
18936
|
+
hoveredItemRect && !linkPopover && !hoveredNavContainerRect && !isItemDragging && hoveredItemElRef.current !== selectedElRef.current && /* @__PURE__ */ jsx33(ItemInteractionLayer, { rect: hoveredItemRect, state: "hover" }),
|
|
18937
|
+
hoveredTextRect && !isItemDragging && toolbarVariant !== "rich-text" && /* @__PURE__ */ jsx33(ItemInteractionLayer, { rect: hoveredTextRect, state: "hover" }),
|
|
18938
|
+
toolbarVariant === "select-frame" && toolbarRect && !linkPopover && !isItemDragging && !isFooterFrameSelection && selectedElRef.current && isNavbarLinksContainer2(selectedElRef.current) && /* @__PURE__ */ jsx33(NavbarContainerChrome, { rect: toolbarRect, onAdd: handleAddTopLevelNavItem }),
|
|
18939
|
+
toolbarVariant === "select-frame" && toolbarRect && !linkPopover && !isItemDragging && !isFooterFrameSelection && selectedElRef.current && isFooterLinksContainer(selectedElRef.current) && /* @__PURE__ */ jsx33(
|
|
17691
18940
|
FooterContainerChrome,
|
|
17692
18941
|
{
|
|
17693
18942
|
rect: toolbarRect,
|
|
@@ -17695,7 +18944,7 @@ function OhhwellsBridge() {
|
|
|
17695
18944
|
addDisabled: !canAddFooterColumn()
|
|
17696
18945
|
}
|
|
17697
18946
|
),
|
|
17698
|
-
toolbarRect && !linkPopover && (toolbarVariant === "link-action" || toolbarVariant === "select-frame") && /* @__PURE__ */
|
|
18947
|
+
toolbarRect && !linkPopover && (toolbarVariant === "link-action" || toolbarVariant === "select-frame" || toolbarVariant === "logo") && /* @__PURE__ */ jsx33(
|
|
17699
18948
|
ItemInteractionLayer,
|
|
17700
18949
|
{
|
|
17701
18950
|
rect: isItemDragging && draggedItemRect && (footerDragRef.current?.wasSelected || navDragRef.current?.wasSelected) ? draggedItemRect : toolbarRect,
|
|
@@ -17707,10 +18956,10 @@ function OhhwellsBridge() {
|
|
|
17707
18956
|
dragHandleLabel: reorderHrefKey ? `Reorder ${reorderHrefKey}` : "Reorder item",
|
|
17708
18957
|
onDragHandleDragStart: handleItemDragStart,
|
|
17709
18958
|
onDragHandleDragEnd: handleItemDragEnd,
|
|
17710
|
-
onItemPointerDown: handleItemChromePointerDown,
|
|
17711
|
-
onItemClick: handleItemChromeClick,
|
|
17712
|
-
itemDragSurface: !isFooterFrameSelection,
|
|
17713
|
-
toolbar: toolbarVariant === "link-action" && !isItemDragging || toolbarVariant === "select-frame" && (isFooterFrameSelection || selectedIsSocialsRow) && !isItemDragging ? /* @__PURE__ */
|
|
18959
|
+
onItemPointerDown: toolbarVariant === "logo" ? void 0 : handleItemChromePointerDown,
|
|
18960
|
+
onItemClick: toolbarVariant === "logo" ? void 0 : handleItemChromeClick,
|
|
18961
|
+
itemDragSurface: toolbarVariant !== "logo" && !isFooterFrameSelection,
|
|
18962
|
+
toolbar: toolbarVariant === "link-action" && !isItemDragging || toolbarVariant === "select-frame" && (isFooterFrameSelection || selectedIsSocialsRow) && !isItemDragging ? /* @__PURE__ */ jsx33(
|
|
17714
18963
|
ItemActionToolbar,
|
|
17715
18964
|
{
|
|
17716
18965
|
onEditLink: openLinkPopoverForSelected,
|
|
@@ -17746,8 +18995,8 @@ function OhhwellsBridge() {
|
|
|
17746
18995
|
) : void 0
|
|
17747
18996
|
}
|
|
17748
18997
|
),
|
|
17749
|
-
toolbarRect && toolbarVariant === "rich-text" && !linkPopover && /* @__PURE__ */
|
|
17750
|
-
/* @__PURE__ */
|
|
18998
|
+
toolbarRect && toolbarVariant === "rich-text" && !linkPopover && /* @__PURE__ */ jsxs20(Fragment8, { children: [
|
|
18999
|
+
/* @__PURE__ */ jsx33(
|
|
17751
19000
|
EditGlowChrome,
|
|
17752
19001
|
{
|
|
17753
19002
|
rect: toolbarRect,
|
|
@@ -17757,7 +19006,7 @@ function OhhwellsBridge() {
|
|
|
17757
19006
|
hideHandle: isItemDragging
|
|
17758
19007
|
}
|
|
17759
19008
|
),
|
|
17760
|
-
/* @__PURE__ */
|
|
19009
|
+
/* @__PURE__ */ jsx33(
|
|
17761
19010
|
FloatingToolbar,
|
|
17762
19011
|
{
|
|
17763
19012
|
rect: toolbarRect,
|
|
@@ -17770,7 +19019,7 @@ function OhhwellsBridge() {
|
|
|
17770
19019
|
}
|
|
17771
19020
|
)
|
|
17772
19021
|
] }),
|
|
17773
|
-
maxBadge && /* @__PURE__ */
|
|
19022
|
+
maxBadge && /* @__PURE__ */ jsxs20(
|
|
17774
19023
|
"div",
|
|
17775
19024
|
{
|
|
17776
19025
|
"data-ohw-max-badge": "",
|
|
@@ -17796,7 +19045,7 @@ function OhhwellsBridge() {
|
|
|
17796
19045
|
]
|
|
17797
19046
|
}
|
|
17798
19047
|
),
|
|
17799
|
-
toggleState && !linkPopover && /* @__PURE__ */
|
|
19048
|
+
toggleState && !linkPopover && /* @__PURE__ */ jsx33(
|
|
17800
19049
|
StateToggle,
|
|
17801
19050
|
{
|
|
17802
19051
|
rect: toggleState.rect,
|
|
@@ -17805,15 +19054,15 @@ function OhhwellsBridge() {
|
|
|
17805
19054
|
onStateChange: handleStateChange
|
|
17806
19055
|
}
|
|
17807
19056
|
),
|
|
17808
|
-
sectionGap && !linkPopover && /* @__PURE__ */
|
|
19057
|
+
sectionGap && !linkPopover && /* @__PURE__ */ jsxs20(
|
|
17809
19058
|
"div",
|
|
17810
19059
|
{
|
|
17811
19060
|
"data-ohw-section-insert-line": "",
|
|
17812
19061
|
className: "fixed left-0 w-full z-2147483646 flex items-center pointer-events-none",
|
|
17813
19062
|
style: { top: sectionGap.y, transform: "translateY(-50%)" },
|
|
17814
19063
|
children: [
|
|
17815
|
-
/* @__PURE__ */
|
|
17816
|
-
/* @__PURE__ */
|
|
19064
|
+
/* @__PURE__ */ jsx33("div", { className: "flex-1 bg-primary", style: { height: 3 } }),
|
|
19065
|
+
/* @__PURE__ */ jsx33(
|
|
17817
19066
|
Badge,
|
|
17818
19067
|
{
|
|
17819
19068
|
className: "px-8 py-1 bg-primary hover:bg-primary text-primary-foreground text-xs font-medium shrink-0 rounded-full cursor-pointer pointer-events-auto",
|
|
@@ -17830,11 +19079,11 @@ function OhhwellsBridge() {
|
|
|
17830
19079
|
children: "Add Section"
|
|
17831
19080
|
}
|
|
17832
19081
|
),
|
|
17833
|
-
/* @__PURE__ */
|
|
19082
|
+
/* @__PURE__ */ jsx33("div", { className: "flex-1 bg-primary", style: { height: 3 } })
|
|
17834
19083
|
]
|
|
17835
19084
|
}
|
|
17836
19085
|
),
|
|
17837
|
-
linkPopover && dialogPortalContainer ? /* @__PURE__ */
|
|
19086
|
+
linkPopover && dialogPortalContainer ? /* @__PURE__ */ jsx33(
|
|
17838
19087
|
LinkPopover,
|
|
17839
19088
|
{
|
|
17840
19089
|
panelRef: linkPopoverPanelRef,
|
|
@@ -17851,7 +19100,7 @@ function OhhwellsBridge() {
|
|
|
17851
19100
|
},
|
|
17852
19101
|
linkPopover.key
|
|
17853
19102
|
) : null,
|
|
17854
|
-
floatingPanel && floatingPanel.kind === "socials-display" ? /* @__PURE__ */
|
|
19103
|
+
floatingPanel && floatingPanel.kind === "socials-display" ? /* @__PURE__ */ jsx33(
|
|
17855
19104
|
FloatingPanel,
|
|
17856
19105
|
{
|
|
17857
19106
|
open: true,
|
|
@@ -17861,7 +19110,7 @@ function OhhwellsBridge() {
|
|
|
17861
19110
|
onPositionChange: setFloatingPanelPos,
|
|
17862
19111
|
parentScroll: parentScrollSnap ?? parentScrollRef.current,
|
|
17863
19112
|
onClose: closeFloatingPanelOnly,
|
|
17864
|
-
children: /* @__PURE__ */
|
|
19113
|
+
children: /* @__PURE__ */ jsx33(
|
|
17865
19114
|
SocialsDisplayPanel,
|
|
17866
19115
|
{
|
|
17867
19116
|
display: socialsDisplayFor(floatingPanel.row, editContentRef.current),
|
|
@@ -17872,11 +19121,115 @@ function OhhwellsBridge() {
|
|
|
17872
19121
|
}
|
|
17873
19122
|
)
|
|
17874
19123
|
}
|
|
19124
|
+
) : null,
|
|
19125
|
+
floatingPanel && floatingPanel.kind === "logo-size" && logoSizeDraft ? /* @__PURE__ */ jsx33(
|
|
19126
|
+
FloatingPanel,
|
|
19127
|
+
{
|
|
19128
|
+
open: true,
|
|
19129
|
+
title: floatingPanel.title,
|
|
19130
|
+
context: floatingPanel.context,
|
|
19131
|
+
position: floatingPanelPos,
|
|
19132
|
+
onPositionChange: setFloatingPanelPos,
|
|
19133
|
+
parentScroll: parentScrollSnap ?? parentScrollRef.current,
|
|
19134
|
+
onClose: closeFloatingPanelAndDeselect,
|
|
19135
|
+
children: /* @__PURE__ */ jsx33(
|
|
19136
|
+
LogoSizePanel,
|
|
19137
|
+
{
|
|
19138
|
+
viewport: editorViewport,
|
|
19139
|
+
sizePx: editorViewport === "mobile" && !logoSizeDraft.mobileFollowing ? logoSizeDraft.mobilePx : logoSizeDraft.desktopPx,
|
|
19140
|
+
mobileFollowing: logoSizeDraft.mobileFollowing,
|
|
19141
|
+
onSizeChange: (px) => {
|
|
19142
|
+
const next = editorViewport === "mobile" ? { ...logoSizeDraft, mobilePx: px, mobileFollowing: false } : {
|
|
19143
|
+
...logoSizeDraft,
|
|
19144
|
+
desktopPx: px,
|
|
19145
|
+
mobilePx: logoSizeDraft.mobileFollowing ? px : logoSizeDraft.mobilePx
|
|
19146
|
+
};
|
|
19147
|
+
setLogoSizeDraft(next);
|
|
19148
|
+
persistLogoSizeDraft(floatingPanel.placement, next);
|
|
19149
|
+
},
|
|
19150
|
+
onCustomizeMobile: () => {
|
|
19151
|
+
const next = {
|
|
19152
|
+
...logoSizeDraft,
|
|
19153
|
+
mobileFollowing: false,
|
|
19154
|
+
mobilePx: logoSizeDraft.desktopPx
|
|
19155
|
+
};
|
|
19156
|
+
setLogoSizeDraft(next);
|
|
19157
|
+
persistLogoSizeDraft(floatingPanel.placement, next);
|
|
19158
|
+
},
|
|
19159
|
+
onResetMobile: () => {
|
|
19160
|
+
const next = {
|
|
19161
|
+
...logoSizeDraft,
|
|
19162
|
+
mobileFollowing: true,
|
|
19163
|
+
mobilePx: logoSizeDraft.desktopPx
|
|
19164
|
+
};
|
|
19165
|
+
setLogoSizeDraft(next);
|
|
19166
|
+
persistLogoSizeDraft(floatingPanel.placement, next);
|
|
19167
|
+
},
|
|
19168
|
+
onUpdateEverywhere: () => {
|
|
19169
|
+
const identity = readLogoIdentityFromDom();
|
|
19170
|
+
postToParent2({ type: "ow:open-logo-settings", ...identity });
|
|
19171
|
+
}
|
|
19172
|
+
}
|
|
19173
|
+
)
|
|
19174
|
+
}
|
|
17875
19175
|
) : null
|
|
17876
19176
|
] }),
|
|
17877
19177
|
bridgeRoot
|
|
17878
19178
|
) : null;
|
|
17879
19179
|
}
|
|
19180
|
+
|
|
19181
|
+
// src/ui/EmptySection.tsx
|
|
19182
|
+
import Link4 from "next/link";
|
|
19183
|
+
import { Fragment as Fragment9, jsx as jsx34, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
19184
|
+
function EmptySection({ title, homeHref = "/", eyebrowKey, titleKey, subtitleKey }) {
|
|
19185
|
+
return /* @__PURE__ */ jsxs21(Fragment9, { children: [
|
|
19186
|
+
/* @__PURE__ */ jsx34(
|
|
19187
|
+
"p",
|
|
19188
|
+
{
|
|
19189
|
+
style: {
|
|
19190
|
+
fontFamily: "var(--brand-font-body)",
|
|
19191
|
+
fontSize: "0.75rem",
|
|
19192
|
+
fontWeight: 500,
|
|
19193
|
+
letterSpacing: "0.15em",
|
|
19194
|
+
textTransform: "uppercase",
|
|
19195
|
+
color: "var(--brand-accent)",
|
|
19196
|
+
marginBottom: "1.5rem"
|
|
19197
|
+
},
|
|
19198
|
+
children: /* @__PURE__ */ jsx34(Link4, { href: homeHref, style: { color: "inherit" }, children: /* @__PURE__ */ jsx34("span", { ...eyebrowKey ? { "data-ohw-editable": "text", "data-ohw-key": eyebrowKey } : {}, children: "Home" }) })
|
|
19199
|
+
}
|
|
19200
|
+
),
|
|
19201
|
+
/* @__PURE__ */ jsx34(
|
|
19202
|
+
"h1",
|
|
19203
|
+
{
|
|
19204
|
+
style: {
|
|
19205
|
+
fontFamily: "var(--brand-font-heading)",
|
|
19206
|
+
fontSize: "clamp(2rem, 3.5vw, 2.75rem)",
|
|
19207
|
+
lineHeight: 1.1,
|
|
19208
|
+
letterSpacing: "-0.025em",
|
|
19209
|
+
color: "var(--brand-text)",
|
|
19210
|
+
marginBottom: "1rem"
|
|
19211
|
+
},
|
|
19212
|
+
...titleKey ? { "data-ohw-editable": "text", "data-ohw-key": titleKey, "data-ohw-max-length": 80 } : {},
|
|
19213
|
+
children: title
|
|
19214
|
+
}
|
|
19215
|
+
),
|
|
19216
|
+
/* @__PURE__ */ jsx34(
|
|
19217
|
+
"p",
|
|
19218
|
+
{
|
|
19219
|
+
style: {
|
|
19220
|
+
fontFamily: "var(--brand-font-body)",
|
|
19221
|
+
fontSize: "1rem",
|
|
19222
|
+
lineHeight: 1.7,
|
|
19223
|
+
fontWeight: 300,
|
|
19224
|
+
color: "var(--brand-text-muted)",
|
|
19225
|
+
maxWidth: "340px"
|
|
19226
|
+
},
|
|
19227
|
+
...subtitleKey ? { "data-ohw-editable": "text", "data-ohw-key": subtitleKey, "data-ohw-max-length": 160 } : {},
|
|
19228
|
+
children: "This page doesn't have any content yet."
|
|
19229
|
+
}
|
|
19230
|
+
)
|
|
19231
|
+
] });
|
|
19232
|
+
}
|
|
17880
19233
|
export {
|
|
17881
19234
|
AI_DEFAULT_BRAND,
|
|
17882
19235
|
AI_TREE_SCHEMA_VERSIONS,
|
|
@@ -17893,6 +19246,7 @@ export {
|
|
|
17893
19246
|
DropdownMenuItem,
|
|
17894
19247
|
DropdownMenuSeparator,
|
|
17895
19248
|
DropdownMenuTrigger,
|
|
19249
|
+
EmptySection,
|
|
17896
19250
|
ItemActionToolbar,
|
|
17897
19251
|
ItemInteractionLayer,
|
|
17898
19252
|
LinkEditorPanel,
|