@ohhwells/bridge 0.1.76-next.230 → 0.1.77
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 +211 -1210
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -18
- package/dist/index.d.ts +4 -18
- package/dist/index.js +211 -1209
- package/dist/index.js.map +1 -1
- package/dist/styles.css +0 -58
- package/package.json +3 -8
- package/dist/pages.cjs +0 -141
- package/dist/pages.cjs.map +0 -1
- package/dist/pages.d.cts +0 -45
- package/dist/pages.d.ts +0 -45
- package/dist/pages.js +0 -107
- package/dist/pages.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -83,12 +83,7 @@ function parseAiSectionsState(raw) {
|
|
|
83
83
|
media: entry.media && typeof entry.media === "object" ? entry.media : {}
|
|
84
84
|
}));
|
|
85
85
|
const removed = Array.isArray(parsed.removed) ? parsed.removed.filter((id) => typeof id === "string" && id.length > 0) : [];
|
|
86
|
-
return {
|
|
87
|
-
v: 1,
|
|
88
|
-
sections,
|
|
89
|
-
...removed.length ? { removed } : {},
|
|
90
|
-
...parsed.hideTemplate === true ? { hideTemplate: true } : {}
|
|
91
|
-
};
|
|
86
|
+
return { v: 1, sections, ...removed.length ? { removed } : {} };
|
|
92
87
|
} catch {
|
|
93
88
|
return EMPTY_AI_SECTIONS;
|
|
94
89
|
}
|
|
@@ -101,7 +96,6 @@ function applyTreeToState(state, payload) {
|
|
|
101
96
|
const entry = {
|
|
102
97
|
id: payload.id,
|
|
103
98
|
label: payload.label ?? "Generated section",
|
|
104
|
-
...typeof payload.path === "string" && payload.path ? { path: payload.path } : {},
|
|
105
99
|
afterSection: payload.mode === "insert" && !insertBefore ? payload.targetSectionId ?? null : null,
|
|
106
100
|
...insertBefore && payload.targetSectionId ? { beforeSection: payload.targetSectionId } : {},
|
|
107
101
|
...payload.mode === "replace" && payload.targetSectionId ? { replaces: payload.targetSectionId } : {},
|
|
@@ -124,317 +118,6 @@ function deleteSectionFromState(state, sectionId) {
|
|
|
124
118
|
return { ...state, v: 1, sections: state.sections, removed: [...removed, sectionId] };
|
|
125
119
|
}
|
|
126
120
|
|
|
127
|
-
// src/lib/brand-chrome.ts
|
|
128
|
-
var BRAND_NAME_KEY = "__ohw_brand_name";
|
|
129
|
-
var BRAND_TITLE_KEY = "__ohw_site_title";
|
|
130
|
-
var BRAND_FAVICON_LETTER_KEY = "__ohw_favicon_letter";
|
|
131
|
-
var BRAND_CHROME_KEYS = /* @__PURE__ */ new Set([
|
|
132
|
-
BRAND_NAME_KEY,
|
|
133
|
-
BRAND_TITLE_KEY,
|
|
134
|
-
BRAND_FAVICON_LETTER_KEY
|
|
135
|
-
]);
|
|
136
|
-
function upsertMeta(selector, attr, token, value) {
|
|
137
|
-
let el = document.head.querySelector(selector);
|
|
138
|
-
if (!el) {
|
|
139
|
-
el = document.createElement("meta");
|
|
140
|
-
el.setAttribute(attr, token);
|
|
141
|
-
document.head.appendChild(el);
|
|
142
|
-
}
|
|
143
|
-
if (el.getAttribute("content") !== value) el.setAttribute("content", value);
|
|
144
|
-
}
|
|
145
|
-
function escapeXml(value) {
|
|
146
|
-
return value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
147
|
-
}
|
|
148
|
-
function applyLetterFavicon(letter) {
|
|
149
|
-
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>`;
|
|
150
|
-
const href = `data:image/svg+xml,${encodeURIComponent(svg)}`;
|
|
151
|
-
let link = document.head.querySelector('link[rel="icon"]');
|
|
152
|
-
if (!link) {
|
|
153
|
-
link = document.createElement("link");
|
|
154
|
-
link.rel = "icon";
|
|
155
|
-
document.head.appendChild(link);
|
|
156
|
-
}
|
|
157
|
-
link.type = "image/svg+xml";
|
|
158
|
-
if (link.href !== href) link.href = href;
|
|
159
|
-
}
|
|
160
|
-
function applyBrandChrome(content) {
|
|
161
|
-
const name = content[BRAND_NAME_KEY];
|
|
162
|
-
if (typeof name === "string" && name.length > 0) {
|
|
163
|
-
document.querySelectorAll("[data-ohw-wordmark]").forEach((el) => {
|
|
164
|
-
if (el.textContent !== name) el.textContent = name;
|
|
165
|
-
if (el.getAttribute("title") !== name) el.setAttribute("title", name);
|
|
166
|
-
});
|
|
167
|
-
}
|
|
168
|
-
const title = content[BRAND_TITLE_KEY];
|
|
169
|
-
if (typeof title === "string" && title.length > 0) {
|
|
170
|
-
if (document.title !== title) document.title = title;
|
|
171
|
-
upsertMeta('meta[property="og:title"]', "property", "og:title", title);
|
|
172
|
-
upsertMeta('meta[name="twitter:title"]', "name", "twitter:title", title);
|
|
173
|
-
}
|
|
174
|
-
const letter = content[BRAND_FAVICON_LETTER_KEY];
|
|
175
|
-
if (typeof letter === "string" && letter.length > 0) {
|
|
176
|
-
applyLetterFavicon(letter);
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
// src/lib/brand-kit.ts
|
|
181
|
-
var BRAND_KIT_KEY = "__ohw_brand";
|
|
182
|
-
var BRAND_VAR_PREFIX = "--ohw-brand-";
|
|
183
|
-
var BRAND_VAR_NAMES = ["primary", "accent", "light", "dark", "surface", "border", "muted"].map(
|
|
184
|
-
(role) => `${BRAND_VAR_PREFIX}${role}`
|
|
185
|
-
);
|
|
186
|
-
var FONT_VARS = {
|
|
187
|
-
heading: ["--font-heading", "--font-display", "--brand-font-heading"],
|
|
188
|
-
body: ["--font-body", "--brand-font-body"]
|
|
189
|
-
};
|
|
190
|
-
var BRAND_FONT_LINK_ID = "ohw-brand-fonts";
|
|
191
|
-
function brandColorVars(kit) {
|
|
192
|
-
const { dark, primary, accent, light } = kit.palette;
|
|
193
|
-
const mix = (a, aPct, b) => `color-mix(in srgb, ${a} ${aPct}%, ${b})`;
|
|
194
|
-
return {
|
|
195
|
-
[`${BRAND_VAR_PREFIX}primary`]: primary,
|
|
196
|
-
[`${BRAND_VAR_PREFIX}accent`]: accent,
|
|
197
|
-
[`${BRAND_VAR_PREFIX}light`]: light,
|
|
198
|
-
[`${BRAND_VAR_PREFIX}dark`]: dark,
|
|
199
|
-
[`${BRAND_VAR_PREFIX}surface`]: mix(light, 95, dark),
|
|
200
|
-
[`${BRAND_VAR_PREFIX}border`]: mix(light, 85, dark),
|
|
201
|
-
[`${BRAND_VAR_PREFIX}muted`]: mix(dark, 62, light)
|
|
202
|
-
};
|
|
203
|
-
}
|
|
204
|
-
function parseBrandKit(raw) {
|
|
205
|
-
if (!raw) return null;
|
|
206
|
-
try {
|
|
207
|
-
const parsed = JSON.parse(raw);
|
|
208
|
-
const p = parsed?.palette;
|
|
209
|
-
const f = parsed?.fonts;
|
|
210
|
-
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") {
|
|
211
|
-
return null;
|
|
212
|
-
}
|
|
213
|
-
return {
|
|
214
|
-
palette: { dark: p.dark, primary: p.primary, accent: p.accent, light: p.light },
|
|
215
|
-
fonts: { heading: f.heading, body: f.body }
|
|
216
|
-
};
|
|
217
|
-
} catch {
|
|
218
|
-
return null;
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
function familyOf(stack) {
|
|
222
|
-
const first = stack.split(",")[0]?.trim() ?? "";
|
|
223
|
-
return first.replace(/^['"]|['"]$/g, "");
|
|
224
|
-
}
|
|
225
|
-
function loadBrandFonts(families) {
|
|
226
|
-
const unique = [...new Set(families.map((f) => f.trim()).filter(Boolean))];
|
|
227
|
-
if (unique.length === 0) return;
|
|
228
|
-
const spec = unique.map((f) => `${f.replace(/ /g, "+")}:400,500,600,700`).join("|");
|
|
229
|
-
const href = `https://fonts.googleapis.com/css?family=${spec}&display=swap`;
|
|
230
|
-
let link = document.getElementById(BRAND_FONT_LINK_ID);
|
|
231
|
-
if (!link) {
|
|
232
|
-
link = document.createElement("link");
|
|
233
|
-
link.id = BRAND_FONT_LINK_ID;
|
|
234
|
-
link.rel = "stylesheet";
|
|
235
|
-
document.head.appendChild(link);
|
|
236
|
-
}
|
|
237
|
-
if (link.href !== href) link.href = href;
|
|
238
|
-
}
|
|
239
|
-
function applyBrandToDom(kit) {
|
|
240
|
-
const root = document.documentElement;
|
|
241
|
-
if (!kit) {
|
|
242
|
-
for (const name of BRAND_VAR_NAMES) root.style.removeProperty(name);
|
|
243
|
-
for (const name of [...FONT_VARS.heading, ...FONT_VARS.body]) root.style.removeProperty(name);
|
|
244
|
-
document.getElementById(BRAND_FONT_LINK_ID)?.remove();
|
|
245
|
-
return;
|
|
246
|
-
}
|
|
247
|
-
for (const [name, value] of Object.entries(brandColorVars(kit))) root.style.setProperty(name, value);
|
|
248
|
-
for (const name of FONT_VARS.heading) root.style.setProperty(name, kit.fonts.heading);
|
|
249
|
-
for (const name of FONT_VARS.body) root.style.setProperty(name, kit.fonts.body);
|
|
250
|
-
loadBrandFonts([familyOf(kit.fonts.heading), familyOf(kit.fonts.body)]);
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
// src/lib/section-styles.ts
|
|
254
|
-
var STYLE_STORE_KEY = "__ohw_styles";
|
|
255
|
-
var STYLE_SHEET_ID = "ohw-section-styles";
|
|
256
|
-
function parseStyleStore(raw) {
|
|
257
|
-
if (!raw) return null;
|
|
258
|
-
try {
|
|
259
|
-
const parsed = JSON.parse(raw);
|
|
260
|
-
if (parsed?.v !== 1) return null;
|
|
261
|
-
return {
|
|
262
|
-
v: 1,
|
|
263
|
-
sections: typeof parsed.sections === "object" && parsed.sections ? parsed.sections : {},
|
|
264
|
-
nodes: typeof parsed.nodes === "object" && parsed.nodes ? parsed.nodes : {}
|
|
265
|
-
};
|
|
266
|
-
} catch {
|
|
267
|
-
return null;
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
var BG_VALUES = {
|
|
271
|
-
surface: "color-mix(in srgb, var(--ohw-brand-light, var(--color-light, #ECECEB)) 94%, var(--ohw-brand-dark, var(--color-dark, #0C0A09)))",
|
|
272
|
-
accent: "var(--ohw-brand-primary, var(--color-primary, #0078E5))",
|
|
273
|
-
"accent-soft": "color-mix(in srgb, var(--ohw-brand-primary, var(--color-primary, #0078E5)) 12%, var(--ohw-brand-light, var(--color-light, #FFFFFF)))"
|
|
274
|
-
};
|
|
275
|
-
var HEADLINE_SIZES = { md: 24, lg: 32, xl: 40, display: 56 };
|
|
276
|
-
function styleSheetCss() {
|
|
277
|
-
const rules = [];
|
|
278
|
-
for (const [tone, value] of Object.entries(BG_VALUES)) {
|
|
279
|
-
rules.push(`[data-ohw-style-bg="${tone}"] { background: ${value} !important; }`);
|
|
280
|
-
}
|
|
281
|
-
rules.push(
|
|
282
|
-
`[data-ohw-style-bg="accent"] { color: var(--ohw-brand-light, var(--color-light, #FFFFFF)) !important; }`
|
|
283
|
-
);
|
|
284
|
-
rules.push(
|
|
285
|
-
`[data-ohw-style-distribution="space-between"] { display: flex !important; flex-direction: column; justify-content: space-between; }`,
|
|
286
|
-
`[data-ohw-style-distribution="center"] { display: flex !important; flex-direction: column; justify-content: center; }`
|
|
287
|
-
);
|
|
288
|
-
for (const [scale, size] of Object.entries(HEADLINE_SIZES)) {
|
|
289
|
-
rules.push(
|
|
290
|
-
`[data-ohw-style-headline="${scale}"] :is(h1, h2, h3) { font-size: ${size}px !important; line-height: 1.15 !important; }`
|
|
291
|
-
);
|
|
292
|
-
}
|
|
293
|
-
rules.push(
|
|
294
|
-
`[data-ohw-style-aspect="fill-height"] img { height: 100% !important; aspect-ratio: auto !important; object-fit: cover; }`
|
|
295
|
-
);
|
|
296
|
-
for (const aspect of ["1:1", "4:5", "3:4", "3:2", "16:9", "2:1", "3:1"]) {
|
|
297
|
-
rules.push(
|
|
298
|
-
`[data-ohw-style-aspect="${aspect.replace(":", "-")}"] img { aspect-ratio: ${aspect.replace(":", " / ")} !important; height: auto !important; object-fit: cover; }`
|
|
299
|
-
);
|
|
300
|
-
}
|
|
301
|
-
const pad = { tight: 40, balanced: 64, airy: 96 };
|
|
302
|
-
for (const [spacing, px] of Object.entries(pad)) {
|
|
303
|
-
rules.push(
|
|
304
|
-
`[data-ohw-style-spacing="${spacing}"] { padding-top: ${px}px !important; padding-bottom: ${px}px !important; }`
|
|
305
|
-
);
|
|
306
|
-
}
|
|
307
|
-
return rules.join("\n");
|
|
308
|
-
}
|
|
309
|
-
var STYLE_FONT_LINK_ID = "ohw-style-fonts";
|
|
310
|
-
function loadStyleFonts(families) {
|
|
311
|
-
const unique = [...new Set(families.map((f) => f.trim()).filter(Boolean))];
|
|
312
|
-
const existing = document.getElementById(STYLE_FONT_LINK_ID);
|
|
313
|
-
if (unique.length === 0) {
|
|
314
|
-
existing?.remove();
|
|
315
|
-
return;
|
|
316
|
-
}
|
|
317
|
-
const spec = unique.map((f) => `${f.replace(/ /g, "+")}:400,500,600,700`).join("|");
|
|
318
|
-
const href = `https://fonts.googleapis.com/css?family=${spec}&display=swap`;
|
|
319
|
-
let link = existing;
|
|
320
|
-
if (!link) {
|
|
321
|
-
link = document.createElement("link");
|
|
322
|
-
link.id = STYLE_FONT_LINK_ID;
|
|
323
|
-
link.rel = "stylesheet";
|
|
324
|
-
document.head.appendChild(link);
|
|
325
|
-
}
|
|
326
|
-
if (link.href !== href) link.href = href;
|
|
327
|
-
}
|
|
328
|
-
var SECTION_ATTRS = {
|
|
329
|
-
sectionBackground: "data-ohw-style-bg",
|
|
330
|
-
textDistribution: "data-ohw-style-distribution",
|
|
331
|
-
headlineScale: "data-ohw-style-headline",
|
|
332
|
-
imageAspect: "data-ohw-style-aspect",
|
|
333
|
-
spacing: "data-ohw-style-spacing"
|
|
334
|
-
};
|
|
335
|
-
var NODE_WROTE_ATTR = "data-ohw-style-node";
|
|
336
|
-
var NODE_PROPS = ["color", "font-family", "font-size", "background"];
|
|
337
|
-
function saveInline(el, prop) {
|
|
338
|
-
const attr = `data-ohw-style-prev-${prop}`;
|
|
339
|
-
if (!el.hasAttribute(attr)) el.setAttribute(attr, el.style.getPropertyValue(prop));
|
|
340
|
-
}
|
|
341
|
-
function restoreInline(el, prop) {
|
|
342
|
-
const attr = `data-ohw-style-prev-${prop}`;
|
|
343
|
-
if (!el.hasAttribute(attr)) return;
|
|
344
|
-
const prev = el.getAttribute(attr) ?? "";
|
|
345
|
-
if (prev) el.style.setProperty(prop, prev);
|
|
346
|
-
else el.style.removeProperty(prop);
|
|
347
|
-
el.removeAttribute(attr);
|
|
348
|
-
}
|
|
349
|
-
function ensureStyleSheet() {
|
|
350
|
-
let el = document.getElementById(STYLE_SHEET_ID);
|
|
351
|
-
if (!el) {
|
|
352
|
-
el = document.createElement("style");
|
|
353
|
-
el.id = STYLE_SHEET_ID;
|
|
354
|
-
document.head.appendChild(el);
|
|
355
|
-
}
|
|
356
|
-
const css = styleSheetCss();
|
|
357
|
-
if (el.textContent !== css) el.textContent = css;
|
|
358
|
-
}
|
|
359
|
-
function clearSectionAttrs(root) {
|
|
360
|
-
for (const attr of Object.values(SECTION_ATTRS)) {
|
|
361
|
-
for (const el of Array.from(root.querySelectorAll(`[${attr}]`))) el.removeAttribute(attr);
|
|
362
|
-
}
|
|
363
|
-
for (const el of Array.from(root.querySelectorAll("[data-ohw-style-bgcolor]"))) {
|
|
364
|
-
restoreInline(el, "background");
|
|
365
|
-
el.removeAttribute("data-ohw-style-bgcolor");
|
|
366
|
-
}
|
|
367
|
-
}
|
|
368
|
-
function clearNodeProps(root) {
|
|
369
|
-
for (const el of Array.from(root.querySelectorAll(`[${NODE_WROTE_ATTR}]`))) {
|
|
370
|
-
const h = el;
|
|
371
|
-
for (const prop of NODE_PROPS) restoreInline(h, prop);
|
|
372
|
-
h.removeAttribute(NODE_WROTE_ATTR);
|
|
373
|
-
}
|
|
374
|
-
}
|
|
375
|
-
function buttonSurfaceOf(el) {
|
|
376
|
-
return el.closest("a, button") ?? el;
|
|
377
|
-
}
|
|
378
|
-
function applyStylesToDom(store) {
|
|
379
|
-
ensureStyleSheet();
|
|
380
|
-
clearSectionAttrs(document);
|
|
381
|
-
clearNodeProps(document);
|
|
382
|
-
loadStyleFonts(
|
|
383
|
-
store ? Object.values(store.nodes).flatMap((n) => n.fontFamily ? [n.fontFamily] : []) : []
|
|
384
|
-
);
|
|
385
|
-
if (!store) return;
|
|
386
|
-
for (const [sectionId, override] of Object.entries(store.sections)) {
|
|
387
|
-
const sections = document.querySelectorAll(
|
|
388
|
-
`[data-ohw-section="${CSS.escape(sectionId)}"]`
|
|
389
|
-
);
|
|
390
|
-
for (const section of Array.from(sections)) {
|
|
391
|
-
for (const [prop, attr] of Object.entries(SECTION_ATTRS)) {
|
|
392
|
-
const value = override[prop];
|
|
393
|
-
if (value === void 0) continue;
|
|
394
|
-
if (prop === "sectionBackground" && override.sectionBackgroundColor !== void 0) continue;
|
|
395
|
-
section.setAttribute(attr, String(value).replace(":", "-"));
|
|
396
|
-
}
|
|
397
|
-
if (override.sectionBackgroundColor !== void 0) {
|
|
398
|
-
saveInline(section, "background");
|
|
399
|
-
section.style.setProperty("background", override.sectionBackgroundColor, "important");
|
|
400
|
-
section.setAttribute("data-ohw-style-bgcolor", "");
|
|
401
|
-
}
|
|
402
|
-
}
|
|
403
|
-
}
|
|
404
|
-
for (const [key, override] of Object.entries(store.nodes)) {
|
|
405
|
-
const nodes = document.querySelectorAll(`[data-ohw-key="${CSS.escape(key)}"]`);
|
|
406
|
-
for (const el of Array.from(nodes)) {
|
|
407
|
-
if (override.color !== void 0) {
|
|
408
|
-
saveInline(el, "color");
|
|
409
|
-
el.style.setProperty("color", override.color, "important");
|
|
410
|
-
el.setAttribute(NODE_WROTE_ATTR, "");
|
|
411
|
-
}
|
|
412
|
-
if (override.fontFamily !== void 0) {
|
|
413
|
-
saveInline(el, "font-family");
|
|
414
|
-
el.style.setProperty("font-family", `'${override.fontFamily}'`, "important");
|
|
415
|
-
el.setAttribute(NODE_WROTE_ATTR, "");
|
|
416
|
-
}
|
|
417
|
-
if (override.fontSize !== void 0) {
|
|
418
|
-
saveInline(el, "font-size");
|
|
419
|
-
el.style.setProperty("font-size", `${override.fontSize}px`, "important");
|
|
420
|
-
el.setAttribute(NODE_WROTE_ATTR, "");
|
|
421
|
-
}
|
|
422
|
-
if (override.buttonBackground !== void 0 || override.buttonText !== void 0) {
|
|
423
|
-
const surface = buttonSurfaceOf(el);
|
|
424
|
-
if (override.buttonBackground !== void 0) {
|
|
425
|
-
saveInline(surface, "background");
|
|
426
|
-
surface.style.setProperty("background", override.buttonBackground, "important");
|
|
427
|
-
}
|
|
428
|
-
if (override.buttonText !== void 0) {
|
|
429
|
-
saveInline(surface, "color");
|
|
430
|
-
surface.style.setProperty("color", override.buttonText, "important");
|
|
431
|
-
}
|
|
432
|
-
surface.setAttribute(NODE_WROTE_ATTR, "");
|
|
433
|
-
}
|
|
434
|
-
}
|
|
435
|
-
}
|
|
436
|
-
}
|
|
437
|
-
|
|
438
121
|
// src/ui/ai-tree/aiSectionsManager.tsx
|
|
439
122
|
import { flushSync } from "react-dom";
|
|
440
123
|
import { createRoot } from "react-dom/client";
|
|
@@ -449,8 +132,7 @@ function lucideByName(name) {
|
|
|
449
132
|
}
|
|
450
133
|
var typeStyle = (spec, font) => ({
|
|
451
134
|
fontFamily: font,
|
|
452
|
-
|
|
453
|
-
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,
|
|
135
|
+
fontSize: spec.size,
|
|
454
136
|
lineHeight: spec.line,
|
|
455
137
|
fontWeight: spec.weight
|
|
456
138
|
});
|
|
@@ -459,60 +141,12 @@ var featureLines = (value) => value.split(/\n|<br\s*\/?>/i).map((line) => line.t
|
|
|
459
141
|
var CHECK_MASK = `data:image/svg+xml,${encodeURIComponent(
|
|
460
142
|
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6 9 17l-5-5"/></svg>'
|
|
461
143
|
)}`;
|
|
462
|
-
var AI_MOBILE_CSS = [
|
|
463
|
-
"@media (max-width: 768px){",
|
|
464
|
-
"[data-ai-section]{overflow-x:hidden}",
|
|
465
|
-
"[data-ai-container]{padding:0 20px !important}",
|
|
466
|
-
"[data-ai-row]{display:flex !important;flex-direction:column !important;align-items:stretch !important}",
|
|
467
|
-
"[data-ai-cell]{width:100%;min-width:0}",
|
|
468
|
-
"[data-ai-grid]{grid-template-columns:1fr !important}",
|
|
469
|
-
// Group containers flatten to a column on phones; span placements come along for free.
|
|
470
|
-
"[data-ai-group]{display:flex !important;flex-direction:column !important}",
|
|
471
|
-
"[data-ai-group] > *{grid-column:auto !important}",
|
|
472
|
-
// The 50:50 form collapses to a single stacked column on phones.
|
|
473
|
-
"[data-ai-form]{grid-template-columns:1fr !important}",
|
|
474
|
-
"[data-ai-section] img{max-width:100%}",
|
|
475
|
-
"}",
|
|
476
|
-
"@media (min-width: 769px) and (max-width: 1024px){",
|
|
477
|
-
"[data-ai-grid]{grid-template-columns:repeat(2, 1fr) !important}",
|
|
478
|
-
"}"
|
|
479
|
-
].join("");
|
|
480
144
|
var FEATURE_LINE_CSS = [
|
|
481
145
|
"[data-ai-features]>div{position:relative;padding-left:40px;min-height:24px}",
|
|
482
146
|
'[data-ai-features]>div::before{content:"";position:absolute;left:0;top:1px;width:24px;height:24px;',
|
|
483
147
|
`background-color:currentColor;-webkit-mask:url("${CHECK_MASK}") no-repeat 0 0/24px 24px;`,
|
|
484
148
|
`mask:url("${CHECK_MASK}") no-repeat 0 0/24px 24px}`
|
|
485
149
|
].join("");
|
|
486
|
-
function hexLuminance(color) {
|
|
487
|
-
const m = /^#([0-9a-f]{6})$/i.exec(color.trim());
|
|
488
|
-
if (!m) return null;
|
|
489
|
-
const [r2, g, b] = [0, 2, 4].map((i) => {
|
|
490
|
-
const c = parseInt(m[1].slice(i, i + 2), 16) / 255;
|
|
491
|
-
return c <= 0.03928 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4);
|
|
492
|
-
});
|
|
493
|
-
return 0.2126 * r2 + 0.7152 * g + 0.0722 * b;
|
|
494
|
-
}
|
|
495
|
-
function hexContrast(a, b) {
|
|
496
|
-
const la = hexLuminance(a);
|
|
497
|
-
const lb = hexLuminance(b);
|
|
498
|
-
if (la === null || lb === null) return null;
|
|
499
|
-
const [hi, lo] = la > lb ? [la, lb] : [lb, la];
|
|
500
|
-
return (hi + 0.05) / (lo + 0.05);
|
|
501
|
-
}
|
|
502
|
-
function accentBandContext(brand) {
|
|
503
|
-
const p = brand.palette;
|
|
504
|
-
const lightWins = (hexContrast(p.light, p.primary) ?? 99) >= (hexContrast(p.dark, p.primary) ?? 0);
|
|
505
|
-
if (lightWins) {
|
|
506
|
-
return {
|
|
507
|
-
brand: { ...brand, palette: { dark: p.light, primary: p.light, accent: p.light, light: p.primary } },
|
|
508
|
-
buttonLabel: p.primary
|
|
509
|
-
};
|
|
510
|
-
}
|
|
511
|
-
return {
|
|
512
|
-
brand: { ...brand, palette: { dark: p.dark, primary: p.dark, accent: p.dark, light: p.light } },
|
|
513
|
-
buttonLabel: p.light
|
|
514
|
-
};
|
|
515
|
-
}
|
|
516
150
|
function textAttrs(ctx, path) {
|
|
517
151
|
return ctx.keyFor ? { "data-ohw-key": ctx.keyFor(path), "data-ohw-editable": "text" } : {};
|
|
518
152
|
}
|
|
@@ -524,12 +158,7 @@ var AI_RESPONSIVE_CSS = [
|
|
|
524
158
|
"@media (max-width: 640px) {",
|
|
525
159
|
" [data-ai-responsive] [data-ai-grid] { grid-template-columns: 1fr !important; }",
|
|
526
160
|
" [data-ai-responsive] [data-ai-columns] > * { grid-column: 1 / -1 !important; }",
|
|
527
|
-
// Group containers flatten to a column on phones; span placements come along for free.
|
|
528
|
-
" [data-ai-responsive] [data-ai-group] { display: flex !important; flex-direction: column !important; }",
|
|
529
|
-
" [data-ai-responsive] [data-ai-group] > * { grid-column: auto !important; }",
|
|
530
161
|
" [data-ai-responsive] [data-ai-section-inner] { padding-left: 20px !important; padding-right: 20px !important; }",
|
|
531
|
-
" [data-ai-responsive] { overflow-x: hidden; }",
|
|
532
|
-
" [data-ai-responsive] img { max-width: 100%; }",
|
|
533
162
|
"}"
|
|
534
163
|
].join("\n");
|
|
535
164
|
var TRANSPARENT_PX = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7";
|
|
@@ -607,7 +236,7 @@ function ButtonEl({
|
|
|
607
236
|
}) {
|
|
608
237
|
const secondary = slots.variant === "secondary";
|
|
609
238
|
const href = str(slots.href);
|
|
610
|
-
const linkAttrs = ctx.keyFor && path ? { "data-ohw-href-key": ctx.keyFor(`${path}.href`)
|
|
239
|
+
const linkAttrs = ctx.keyFor && path ? { "data-ohw-href-key": ctx.keyFor(`${path}.href`) } : {};
|
|
611
240
|
return /* @__PURE__ */ jsx(
|
|
612
241
|
"a",
|
|
613
242
|
{
|
|
@@ -623,7 +252,7 @@ function ButtonEl({
|
|
|
623
252
|
textDecoration: "none",
|
|
624
253
|
cursor: "pointer",
|
|
625
254
|
...typeStyle(AI_TREE_TOKENS.type.button, ctx.brand.fonts.body),
|
|
626
|
-
...secondary ? { border: `1px solid ${ctx.brand.palette.dark}`, color: ctx.brand.palette.dark } : { background: ctx.brand.palette.primary, color:
|
|
255
|
+
...secondary ? { border: `1px solid ${ctx.brand.palette.dark}`, color: ctx.brand.palette.dark } : { background: ctx.brand.palette.primary, color: AI_TREE_TOKENS.textPrimaryForeground }
|
|
627
256
|
},
|
|
628
257
|
children: /* @__PURE__ */ jsx("span", { ...path ? textAttrs(ctx, `${path}.label`) : {}, children: str(slots.label) })
|
|
629
258
|
}
|
|
@@ -1129,24 +758,7 @@ function CardBlock({ node, ctx, path }) {
|
|
|
1129
758
|
minWidth: 0
|
|
1130
759
|
},
|
|
1131
760
|
children: [
|
|
1132
|
-
media && (horizontal ? /* @__PURE__ */ jsx(
|
|
1133
|
-
"div",
|
|
1134
|
-
{
|
|
1135
|
-
style: (
|
|
1136
|
-
// An icon hugs its glyph — flex:1 gave a 48px icon half the card and pushed the
|
|
1137
|
-
// text to the far side. Photos keep the half-and-half split. The inset has no
|
|
1138
|
-
// inner padding (the photo split absorbed that), so the icon carries its own gap.
|
|
1139
|
-
/^(lucide|simple):/.test(mediaRef) ? {
|
|
1140
|
-
flexShrink: 0,
|
|
1141
|
-
display: "flex",
|
|
1142
|
-
alignItems: "center",
|
|
1143
|
-
padding: mediaInset,
|
|
1144
|
-
[mediaPosition === "right" ? "marginLeft" : "marginRight"]: 20
|
|
1145
|
-
} : { flex: 1, minWidth: 0, display: "flex", alignItems: "center", padding: mediaInset }
|
|
1146
|
-
),
|
|
1147
|
-
children: media
|
|
1148
|
-
}
|
|
1149
|
-
) : /* @__PURE__ */ jsx(
|
|
761
|
+
media && (horizontal ? /* @__PURE__ */ jsx("div", { style: { flex: 1, minWidth: 0, display: "flex", alignItems: "center", padding: mediaInset }, children: media }) : /* @__PURE__ */ jsx(
|
|
1150
762
|
"div",
|
|
1151
763
|
{
|
|
1152
764
|
style: /^(lucide|simple):/.test(mediaRef) ? { padding: `${AI_TREE_TOKENS.paddingBlock}px ${AI_TREE_TOKENS.paddingBlock}px 0` } : hasBg ? void 0 : { borderRadius: AI_TREE_TOKENS.radiusCard, overflow: "hidden" },
|
|
@@ -1237,44 +849,13 @@ function AccordionBlock({ node, ctx, path }) {
|
|
|
1237
849
|
) })
|
|
1238
850
|
] }, i)) });
|
|
1239
851
|
}
|
|
1240
|
-
function useIsMobile() {
|
|
1241
|
-
const [mobile, setMobile] = React.useState(
|
|
1242
|
-
() => typeof window !== "undefined" && window.matchMedia("(max-width: 768px)").matches
|
|
1243
|
-
);
|
|
1244
|
-
React.useEffect(() => {
|
|
1245
|
-
const mq = window.matchMedia("(max-width: 768px)");
|
|
1246
|
-
const update = () => setMobile(mq.matches);
|
|
1247
|
-
update();
|
|
1248
|
-
mq.addEventListener("change", update);
|
|
1249
|
-
return () => mq.removeEventListener("change", update);
|
|
1250
|
-
}, []);
|
|
1251
|
-
return mobile;
|
|
1252
|
-
}
|
|
1253
852
|
function Carousel({ items, itemsPerRow, ctx }) {
|
|
1254
|
-
const isMobile = useIsMobile();
|
|
1255
|
-
const perPage = isMobile ? 1 : itemsPerRow;
|
|
1256
|
-
const pages = Math.max(1, Math.ceil(items.length / perPage));
|
|
1257
853
|
const [page, setPage] = React.useState(0);
|
|
854
|
+
const pages = Math.max(1, Math.ceil(items.length / itemsPerRow));
|
|
1258
855
|
const current = Math.min(page, pages - 1);
|
|
1259
|
-
if (pages <= 1) {
|
|
1260
|
-
const cols = Math.max(1, Math.min(items.length, itemsPerRow));
|
|
1261
|
-
return /* @__PURE__ */ jsx(
|
|
1262
|
-
"div",
|
|
1263
|
-
{
|
|
1264
|
-
"data-ai-grid": String(cols),
|
|
1265
|
-
style: {
|
|
1266
|
-
display: "grid",
|
|
1267
|
-
gridTemplateColumns: `repeat(${cols}, 1fr)`,
|
|
1268
|
-
gap: AI_TREE_TOKENS.spacing8,
|
|
1269
|
-
alignItems: "start"
|
|
1270
|
-
},
|
|
1271
|
-
children: items
|
|
1272
|
-
}
|
|
1273
|
-
);
|
|
1274
|
-
}
|
|
1275
856
|
const pageGroups = Array.from(
|
|
1276
857
|
{ length: pages },
|
|
1277
|
-
(_, p) => items.slice(p *
|
|
858
|
+
(_, p) => items.slice(p * itemsPerRow, (p + 1) * itemsPerRow)
|
|
1278
859
|
);
|
|
1279
860
|
const chrome = (enabled) => ({
|
|
1280
861
|
border: `1px solid ${ctx.brand.palette.dark}`,
|
|
@@ -1299,69 +880,55 @@ function Carousel({ items, itemsPerRow, ctx }) {
|
|
|
1299
880
|
cursor: "pointer",
|
|
1300
881
|
padding: 0
|
|
1301
882
|
});
|
|
1302
|
-
|
|
1303
|
-
"div",
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
883
|
+
return /* @__PURE__ */ jsxs("div", { "data-ai-carousel": "", style: { display: "flex", flexDirection: "column", gap: AI_TREE_TOKENS.spacing8, alignItems: "center" }, children: [
|
|
884
|
+
/* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: AI_TREE_TOKENS.spacing6, width: "100%" }, children: [
|
|
885
|
+
/* @__PURE__ */ jsx(
|
|
886
|
+
"button",
|
|
887
|
+
{
|
|
888
|
+
type: "button",
|
|
889
|
+
"aria-label": "Previous",
|
|
890
|
+
onClick: () => setPage((p) => Math.max(0, p - 1)),
|
|
891
|
+
style: chrome(current > 0),
|
|
892
|
+
children: /* @__PURE__ */ jsx(ArrowLeft, { size: 24, strokeWidth: 1.5, "aria-hidden": true })
|
|
893
|
+
}
|
|
894
|
+
),
|
|
895
|
+
/* @__PURE__ */ jsx("div", { style: { flex: 1, minWidth: 0, overflow: "hidden" }, children: /* @__PURE__ */ jsx(
|
|
1311
896
|
"div",
|
|
1312
897
|
{
|
|
1313
|
-
"data-ai-grid": String(perPage),
|
|
1314
898
|
style: {
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
gap: AI_TREE_TOKENS.spacing8,
|
|
1319
|
-
alignItems: "start"
|
|
899
|
+
display: "flex",
|
|
900
|
+
transform: `translateX(-${current * 100}%)`,
|
|
901
|
+
transition: "transform 0.4s ease"
|
|
1320
902
|
},
|
|
1321
|
-
children: group
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
if (isMobile) {
|
|
1349
|
-
return /* @__PURE__ */ jsxs("div", { "data-ai-carousel": "", style: { display: "flex", flexDirection: "column", gap: AI_TREE_TOKENS.spacing6, alignItems: "center" }, children: [
|
|
1350
|
-
viewport,
|
|
1351
|
-
/* @__PURE__ */ jsxs("div", { style: { display: "flex", gap: AI_TREE_TOKENS.spacing6, justifyContent: "center" }, children: [
|
|
1352
|
-
prevBtn,
|
|
1353
|
-
nextBtn
|
|
1354
|
-
] }),
|
|
1355
|
-
dots
|
|
1356
|
-
] });
|
|
1357
|
-
}
|
|
1358
|
-
return /* @__PURE__ */ jsxs("div", { "data-ai-carousel": "", style: { display: "flex", flexDirection: "column", gap: AI_TREE_TOKENS.spacing8, alignItems: "center" }, children: [
|
|
1359
|
-
/* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: AI_TREE_TOKENS.spacing6, width: "100%" }, children: [
|
|
1360
|
-
prevBtn,
|
|
1361
|
-
viewport,
|
|
1362
|
-
nextBtn
|
|
903
|
+
children: pageGroups.map((group, p) => /* @__PURE__ */ jsx(
|
|
904
|
+
"div",
|
|
905
|
+
{
|
|
906
|
+
"data-ai-grid": String(itemsPerRow),
|
|
907
|
+
style: {
|
|
908
|
+
flex: "0 0 100%",
|
|
909
|
+
display: "grid",
|
|
910
|
+
gridTemplateColumns: `repeat(${itemsPerRow}, 1fr)`,
|
|
911
|
+
gap: AI_TREE_TOKENS.spacing8,
|
|
912
|
+
alignItems: "start"
|
|
913
|
+
},
|
|
914
|
+
children: group
|
|
915
|
+
},
|
|
916
|
+
p
|
|
917
|
+
))
|
|
918
|
+
}
|
|
919
|
+
) }),
|
|
920
|
+
/* @__PURE__ */ jsx(
|
|
921
|
+
"button",
|
|
922
|
+
{
|
|
923
|
+
type: "button",
|
|
924
|
+
"aria-label": "Next",
|
|
925
|
+
onClick: () => setPage((p) => Math.min(pages - 1, p + 1)),
|
|
926
|
+
style: chrome(current < pages - 1),
|
|
927
|
+
children: /* @__PURE__ */ jsx(ArrowRight, { size: 24, strokeWidth: 1.5, "aria-hidden": true })
|
|
928
|
+
}
|
|
929
|
+
)
|
|
1363
930
|
] }),
|
|
1364
|
-
|
|
931
|
+
pages > 1 && /* @__PURE__ */ jsx("div", { style: { display: "flex", gap: 9, justifyContent: "center" }, children: pageGroups.map((_, p) => /* @__PURE__ */ jsx("button", { type: "button", "aria-label": `Page ${p + 1}`, onClick: () => setPage(p), style: dot(p === current) }, p)) })
|
|
1365
932
|
] });
|
|
1366
933
|
}
|
|
1367
934
|
function CollectionBlock({ node, ctx, path }) {
|
|
@@ -1455,49 +1022,6 @@ function renderNode(node, ctx, path) {
|
|
|
1455
1022
|
switch (node.type) {
|
|
1456
1023
|
case "text":
|
|
1457
1024
|
return /* @__PURE__ */ jsx(TextBlock, { slots, ctx, path });
|
|
1458
|
-
// Layout container: arranges child blocks, contributes no content of its own. `grid` is a
|
|
1459
|
-
// nested 12-column grid the children span (a collage is 3–5 media on it, bottom-aligned so
|
|
1460
|
-
// mixed aspects read as a composition); `split` is exactly two children at a ratio; `stack`
|
|
1461
|
-
// is a column. Children render through this same dispatcher, so edit markers, media
|
|
1462
|
-
// resolution, and copy paths all work unchanged inside a group.
|
|
1463
|
-
case "group": {
|
|
1464
|
-
const layout = str(slots.layout);
|
|
1465
|
-
const gap = slots.spacing === "tight" ? AI_TREE_TOKENS.spacing3 : slots.spacing === "airy" ? AI_TREE_TOKENS.spacing8 : AI_TREE_TOKENS.spacing6;
|
|
1466
|
-
const kids = (node.children ?? []).map((child, i) => /* @__PURE__ */ jsx(
|
|
1467
|
-
"div",
|
|
1468
|
-
{
|
|
1469
|
-
style: layout === "grid" ? {
|
|
1470
|
-
gridColumn: `span ${typeof child.span === "number" ? Math.min(12, Math.max(1, child.span)) : 12}`,
|
|
1471
|
-
minWidth: 0
|
|
1472
|
-
} : { minWidth: 0 },
|
|
1473
|
-
children: renderNode(child, ctx, `${path}.c${i}`)
|
|
1474
|
-
},
|
|
1475
|
-
i
|
|
1476
|
-
));
|
|
1477
|
-
if (layout === "grid") {
|
|
1478
|
-
return /* @__PURE__ */ jsx(
|
|
1479
|
-
"div",
|
|
1480
|
-
{
|
|
1481
|
-
"data-ai-group": "grid",
|
|
1482
|
-
style: { display: "grid", gridTemplateColumns: "repeat(12, 1fr)", gap, alignItems: "end" },
|
|
1483
|
-
children: kids
|
|
1484
|
-
}
|
|
1485
|
-
);
|
|
1486
|
-
}
|
|
1487
|
-
if (layout === "split") {
|
|
1488
|
-
const ratio = str(slots.ratio);
|
|
1489
|
-
const cols = ratio === "3:5" ? "3fr 5fr" : ratio === "5:3" ? "5fr 3fr" : "1fr 1fr";
|
|
1490
|
-
return /* @__PURE__ */ jsx(
|
|
1491
|
-
"div",
|
|
1492
|
-
{
|
|
1493
|
-
"data-ai-group": "split",
|
|
1494
|
-
style: { display: "grid", gridTemplateColumns: cols, gap, alignItems: "center" },
|
|
1495
|
-
children: kids
|
|
1496
|
-
}
|
|
1497
|
-
);
|
|
1498
|
-
}
|
|
1499
|
-
return /* @__PURE__ */ jsx("div", { "data-ai-group": "stack", style: { display: "flex", flexDirection: "column", gap }, children: kids });
|
|
1500
|
-
}
|
|
1501
1025
|
case "button":
|
|
1502
1026
|
return /* @__PURE__ */ jsx(ButtonEl, { slots, ctx, path });
|
|
1503
1027
|
case "button-row":
|
|
@@ -1578,102 +1102,33 @@ function renderNode(node, ctx, path) {
|
|
|
1578
1102
|
}
|
|
1579
1103
|
);
|
|
1580
1104
|
}
|
|
1581
|
-
case "form":
|
|
1582
|
-
|
|
1583
|
-
"
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
...typeStyle(AI_TREE_TOKENS.type.bodyM, ctx.brand.fonts.body)
|
|
1597
|
-
};
|
|
1598
|
-
const labelStyle = {
|
|
1599
|
-
...typeStyle(AI_TREE_TOKENS.type.bodyMBold, ctx.brand.fonts.body),
|
|
1600
|
-
color: ctx.brand.palette.dark
|
|
1601
|
-
};
|
|
1602
|
-
return /* @__PURE__ */ jsx(
|
|
1603
|
-
"form",
|
|
1604
|
-
{
|
|
1605
|
-
...formAttrs,
|
|
1606
|
-
"data-ai-form": "",
|
|
1607
|
-
style: {
|
|
1608
|
-
display: "grid",
|
|
1609
|
-
gridTemplateColumns: "repeat(2, minmax(0, 1fr))",
|
|
1610
|
-
columnGap: 64,
|
|
1611
|
-
rowGap: AI_TREE_TOKENS.spacing4
|
|
1612
|
-
},
|
|
1613
|
-
children: (node.children ?? []).map((child, i) => {
|
|
1614
|
-
if (child.type === "input") {
|
|
1615
|
-
const cs2 = child.slots ?? {};
|
|
1616
|
-
const kind = str(cs2.kind);
|
|
1617
|
-
const label = str(cs2.label);
|
|
1618
|
-
const placeholder = str(cs2.placeholder);
|
|
1619
|
-
const name = label.toLowerCase().replace(/[^a-z0-9]+/gu, "-").replace(/^-+|-+$/gu, "") || `field-${i}`;
|
|
1620
|
-
const isTextarea = kind === "textarea";
|
|
1621
|
-
return /* @__PURE__ */ jsxs(
|
|
1622
|
-
"div",
|
|
1623
|
-
{
|
|
1624
|
-
style: {
|
|
1625
|
-
display: "flex",
|
|
1626
|
-
flexDirection: "column",
|
|
1627
|
-
gap: 8,
|
|
1628
|
-
...isTextarea ? { gridColumn: "1 / -1", maxWidth: 780 } : {}
|
|
1629
|
-
},
|
|
1630
|
-
children: [
|
|
1631
|
-
/* @__PURE__ */ jsx("label", { ...textAttrs(ctx, `${path}.c${i}.label`), style: labelStyle, children: label }),
|
|
1632
|
-
isTextarea ? /* @__PURE__ */ jsx(
|
|
1633
|
-
"textarea",
|
|
1634
|
-
{
|
|
1635
|
-
name,
|
|
1636
|
-
placeholder,
|
|
1637
|
-
style: { ...fieldStyle, height: 140, resize: "vertical" }
|
|
1638
|
-
}
|
|
1639
|
-
) : /* @__PURE__ */ jsx(
|
|
1640
|
-
"input",
|
|
1641
|
-
{
|
|
1642
|
-
name,
|
|
1643
|
-
type: kind === "email" ? "email" : "text",
|
|
1644
|
-
placeholder,
|
|
1645
|
-
style: { ...fieldStyle, height: 48 }
|
|
1646
|
-
}
|
|
1647
|
-
)
|
|
1648
|
-
]
|
|
1649
|
-
},
|
|
1650
|
-
i
|
|
1651
|
-
);
|
|
1652
|
-
}
|
|
1653
|
-
const cs = child.slots ?? {};
|
|
1654
|
-
return /* @__PURE__ */ jsx(
|
|
1655
|
-
"button",
|
|
1105
|
+
case "form":
|
|
1106
|
+
return /* @__PURE__ */ jsx("div", { style: { display: "flex", flexDirection: "column", gap: AI_TREE_TOKENS.spacing4 }, children: (node.children ?? []).map((child, i) => {
|
|
1107
|
+
if (child.type === "input") {
|
|
1108
|
+
const cs = child.slots ?? {};
|
|
1109
|
+
return /* @__PURE__ */ jsxs("div", { children: [
|
|
1110
|
+
/* @__PURE__ */ jsx(
|
|
1111
|
+
"div",
|
|
1112
|
+
{
|
|
1113
|
+
...textAttrs(ctx, `${path}.c${i}.label`),
|
|
1114
|
+
style: { ...typeStyle(AI_TREE_TOKENS.type.bodyMBold, ctx.brand.fonts.body), color: ctx.brand.palette.dark, marginBottom: 6 },
|
|
1115
|
+
children: str(cs.label)
|
|
1116
|
+
}
|
|
1117
|
+
),
|
|
1118
|
+
/* @__PURE__ */ jsx(
|
|
1119
|
+
"div",
|
|
1656
1120
|
{
|
|
1657
|
-
type: "submit",
|
|
1658
1121
|
style: {
|
|
1659
|
-
|
|
1660
|
-
justifySelf: "start",
|
|
1661
|
-
border: "none",
|
|
1662
|
-
cursor: "pointer",
|
|
1663
|
-
padding: `${AI_TREE_TOKENS.spacing3}px ${AI_TREE_TOKENS.spacing6}px`,
|
|
1122
|
+
border: `1px solid ${ctx.brand.palette.accent}`,
|
|
1664
1123
|
borderRadius: AI_TREE_TOKENS.radiusButton,
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
},
|
|
1671
|
-
i
|
|
1672
|
-
);
|
|
1673
|
-
})
|
|
1124
|
+
height: cs.kind === "textarea" ? 96 : 42
|
|
1125
|
+
}
|
|
1126
|
+
}
|
|
1127
|
+
)
|
|
1128
|
+
] }, i);
|
|
1674
1129
|
}
|
|
1675
|
-
|
|
1676
|
-
|
|
1130
|
+
return /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(ButtonEl, { slots: child.slots ?? {}, ctx, path: `${path}.c${i}` }) }, i);
|
|
1131
|
+
}) });
|
|
1677
1132
|
case "schedule-widget":
|
|
1678
1133
|
return /* @__PURE__ */ jsx(
|
|
1679
1134
|
"div",
|
|
@@ -1699,14 +1154,11 @@ function AiTreeRenderer({ tree, brand, resolveMedia, editKeyPrefix }) {
|
|
|
1699
1154
|
return null;
|
|
1700
1155
|
}
|
|
1701
1156
|
const resolvedBrand = brand ?? AI_DEFAULT_BRAND;
|
|
1702
|
-
const band = (tree.settings ?? {}).sectionBackground === "accent" ? accentBandContext(resolvedBrand) : null;
|
|
1703
|
-
const blockBrand = band?.brand ?? resolvedBrand;
|
|
1704
1157
|
const ctx = {
|
|
1705
|
-
brand:
|
|
1158
|
+
brand: resolvedBrand,
|
|
1706
1159
|
resolveMedia: resolveMedia ?? (() => null),
|
|
1707
|
-
cardSurface:
|
|
1708
|
-
keyFor: editKeyPrefix ? (path) => `${editKeyPrefix}.${path}` : null
|
|
1709
|
-
...band ? { buttonLabel: band.buttonLabel } : {}
|
|
1160
|
+
cardSurface: resolvedBrand.palette.light.toUpperCase() === AI_DEFAULT_BRAND.palette.light.toUpperCase() ? "#ECECEB" : `color-mix(in srgb, ${resolvedBrand.palette.light} 90%, ${resolvedBrand.palette.dark})`,
|
|
1161
|
+
keyFor: editKeyPrefix ? (path) => `${editKeyPrefix}.${path}` : null
|
|
1710
1162
|
};
|
|
1711
1163
|
const settings = tree.settings ?? {};
|
|
1712
1164
|
const pad = AI_TREE_TOKENS.sectionPadding[settings.spacing ?? "balanced"];
|
|
@@ -1714,20 +1166,6 @@ function AiTreeRenderer({ tree, brand, resolveMedia, editKeyPrefix }) {
|
|
|
1714
1166
|
const overlayAlpha = { low: 0.25, medium: 0.45, high: 0.65 }[settings.overlayIntensity ?? "medium"];
|
|
1715
1167
|
const backgroundUrl = isOverlay && settings.backgroundMedia ? ctx.resolveMedia(settings.backgroundMedia) : null;
|
|
1716
1168
|
const bgAttrs = ctx.keyFor && isOverlay && settings.backgroundMedia ? { "data-ohw-key": ctx.keyFor("settings.backgroundMedia"), "data-ohw-editable": "bg-image" } : {};
|
|
1717
|
-
const toneBackground = (() => {
|
|
1718
|
-
const { dark, primary, light } = resolvedBrand.palette;
|
|
1719
|
-
switch (settings.sectionBackground) {
|
|
1720
|
-
case "surface":
|
|
1721
|
-
return `color-mix(in srgb, ${light} 94%, ${dark})`;
|
|
1722
|
-
case "accent":
|
|
1723
|
-
return primary;
|
|
1724
|
-
case "accent-soft":
|
|
1725
|
-
return `color-mix(in srgb, ${primary} 12%, ${light})`;
|
|
1726
|
-
default:
|
|
1727
|
-
return void 0;
|
|
1728
|
-
}
|
|
1729
|
-
})();
|
|
1730
|
-
const distributed = !isOverlay && settings.textDistribution;
|
|
1731
1169
|
return /* @__PURE__ */ jsxs(
|
|
1732
1170
|
"section",
|
|
1733
1171
|
{
|
|
@@ -1737,15 +1175,13 @@ function AiTreeRenderer({ tree, brand, resolveMedia, editKeyPrefix }) {
|
|
|
1737
1175
|
style: {
|
|
1738
1176
|
position: "relative",
|
|
1739
1177
|
padding: `${pad}px 0`,
|
|
1740
|
-
background:
|
|
1178
|
+
background: isOverlay && !backgroundUrl ? "#DBEAFE" : void 0,
|
|
1741
1179
|
backgroundImage: backgroundUrl ? `url(${backgroundUrl})` : void 0,
|
|
1742
1180
|
backgroundSize: "cover",
|
|
1743
|
-
backgroundPosition: "center"
|
|
1744
|
-
color: settings.sectionBackground === "accent" ? blockBrand.palette.dark : void 0
|
|
1181
|
+
backgroundPosition: "center"
|
|
1745
1182
|
},
|
|
1746
1183
|
children: [
|
|
1747
1184
|
/* @__PURE__ */ jsx("style", { children: AI_RESPONSIVE_CSS }),
|
|
1748
|
-
/* @__PURE__ */ jsx("style", { children: AI_MOBILE_CSS }),
|
|
1749
1185
|
isOverlay && backgroundUrl && /* @__PURE__ */ jsx("div", { style: { position: "absolute", inset: 0, background: `rgba(255,255,255,${overlayAlpha})` } }),
|
|
1750
1186
|
/* @__PURE__ */ jsx(
|
|
1751
1187
|
"div",
|
|
@@ -1766,24 +1202,10 @@ function AiTreeRenderer({ tree, brand, resolveMedia, editKeyPrefix }) {
|
|
|
1766
1202
|
display: "grid",
|
|
1767
1203
|
gridTemplateColumns: "repeat(12, 1fr)",
|
|
1768
1204
|
gap: AI_TREE_TOKENS.spacing6,
|
|
1769
|
-
alignItems:
|
|
1205
|
+
alignItems: settings.verticalPosition === "top" ? "start" : "center",
|
|
1770
1206
|
marginTop: r2 > 0 ? AI_TREE_TOKENS.spacing8 : 0
|
|
1771
1207
|
},
|
|
1772
|
-
children: (row.blocks ?? []).map((block, b) => /* @__PURE__ */ jsx(
|
|
1773
|
-
"div",
|
|
1774
|
-
{
|
|
1775
|
-
"data-ai-cell": "",
|
|
1776
|
-
style: {
|
|
1777
|
-
gridColumn: `span ${Math.min(12, Math.max(1, block.span))}`,
|
|
1778
|
-
minWidth: 0,
|
|
1779
|
-
// space-between: each column becomes a flex column whose content spreads over
|
|
1780
|
-
// the full row height instead of clumping at the top.
|
|
1781
|
-
...distributed === "space-between" ? { display: "flex", flexDirection: "column", justifyContent: "space-between" } : {}
|
|
1782
|
-
},
|
|
1783
|
-
children: renderNode(block, ctx, `r${r2}.b${b}`)
|
|
1784
|
-
},
|
|
1785
|
-
b
|
|
1786
|
-
))
|
|
1208
|
+
children: (row.blocks ?? []).map((block, b) => /* @__PURE__ */ jsx("div", { style: { gridColumn: `span ${Math.min(12, Math.max(1, block.span))}`, minWidth: 0 }, children: renderNode(block, ctx, `r${r2}.b${b}`) }, b))
|
|
1787
1209
|
},
|
|
1788
1210
|
r2
|
|
1789
1211
|
))
|
|
@@ -1799,36 +1221,17 @@ import { jsx as jsx2 } from "react/jsx-runtime";
|
|
|
1799
1221
|
var CONTAINER_ATTR = "data-ohw-ai-generated";
|
|
1800
1222
|
var REPLACED_ATTR = "data-ohw-ai-replaced-by";
|
|
1801
1223
|
var REMOVED_ATTR = "data-ohw-ai-removed";
|
|
1802
|
-
var TEMPLATE_HIDDEN_ATTR = "data-ohw-ai-template-hidden";
|
|
1803
|
-
var CHROME_SECTION_IDS = /* @__PURE__ */ new Set(["navbar", "footer"]);
|
|
1804
|
-
function readRootVar(name) {
|
|
1805
|
-
if (typeof document === "undefined") return "";
|
|
1806
|
-
return getComputedStyle(document.documentElement).getPropertyValue(name).trim();
|
|
1807
|
-
}
|
|
1808
|
-
function deriveBrandOverride() {
|
|
1809
|
-
const dark = readRootVar("--ohw-brand-dark");
|
|
1810
|
-
const primary = readRootVar("--ohw-brand-primary");
|
|
1811
|
-
const light = readRootVar("--ohw-brand-light");
|
|
1812
|
-
if (!dark || !primary || !light) return null;
|
|
1813
|
-
const accent = readRootVar("--ohw-brand-accent");
|
|
1814
|
-
const heading = readRootVar("--font-heading") || readRootVar("--font-display");
|
|
1815
|
-
const body = readRootVar("--font-body");
|
|
1816
|
-
return {
|
|
1817
|
-
palette: { dark, primary, accent: accent || dark, light },
|
|
1818
|
-
fonts: {
|
|
1819
|
-
heading: heading || AI_DEFAULT_BRAND.fonts.heading,
|
|
1820
|
-
body: body || AI_DEFAULT_BRAND.fonts.body
|
|
1821
|
-
}
|
|
1822
|
-
};
|
|
1823
|
-
}
|
|
1824
1224
|
function deriveTemplateBrand() {
|
|
1825
|
-
|
|
1826
|
-
const
|
|
1827
|
-
const
|
|
1225
|
+
if (typeof document === "undefined") return null;
|
|
1226
|
+
const cs = getComputedStyle(document.documentElement);
|
|
1227
|
+
const read = (name) => cs.getPropertyValue(name).trim();
|
|
1228
|
+
const dark = read("--color-dark");
|
|
1229
|
+
const primary = read("--color-primary");
|
|
1230
|
+
const light = read("--color-light");
|
|
1828
1231
|
if (!dark || !primary || !light) return null;
|
|
1829
|
-
const accent =
|
|
1830
|
-
const heading =
|
|
1831
|
-
const body =
|
|
1232
|
+
const accent = read("--color-accent");
|
|
1233
|
+
const heading = read("--font-heading") || read("--font-display");
|
|
1234
|
+
const body = read("--font-body");
|
|
1832
1235
|
return {
|
|
1833
1236
|
palette: { dark, primary, accent: accent || dark, light },
|
|
1834
1237
|
fonts: {
|
|
@@ -1900,24 +1303,6 @@ function syncRemovedSections(state) {
|
|
|
1900
1303
|
}
|
|
1901
1304
|
}
|
|
1902
1305
|
}
|
|
1903
|
-
function syncTemplateHidden(state, pageHasSections) {
|
|
1904
|
-
const hide = state.hideTemplate === true && pageHasSections;
|
|
1905
|
-
for (const el of Array.from(document.querySelectorAll(`[${TEMPLATE_HIDDEN_ATTR}]`))) {
|
|
1906
|
-
if (!hide) {
|
|
1907
|
-
el.style.removeProperty("display");
|
|
1908
|
-
el.removeAttribute(TEMPLATE_HIDDEN_ATTR);
|
|
1909
|
-
}
|
|
1910
|
-
}
|
|
1911
|
-
if (!hide) return;
|
|
1912
|
-
for (const el of Array.from(document.querySelectorAll("[data-ohw-section]"))) {
|
|
1913
|
-
if (el.hasAttribute(CONTAINER_ATTR)) continue;
|
|
1914
|
-
if (CHROME_SECTION_IDS.has(el.getAttribute("data-ohw-section") ?? "")) continue;
|
|
1915
|
-
if (el.parentElement?.closest("[data-ohw-section]")) continue;
|
|
1916
|
-
if (el.hasAttribute(REPLACED_ATTR) || el.hasAttribute(REMOVED_ATTR)) continue;
|
|
1917
|
-
el.style.display = "none";
|
|
1918
|
-
el.setAttribute(TEMPLATE_HIDDEN_ATTR, "");
|
|
1919
|
-
}
|
|
1920
|
-
}
|
|
1921
1306
|
function syncReplacedOriginals(state) {
|
|
1922
1307
|
for (const el of document.querySelectorAll(`[${REPLACED_ATTR}]`)) {
|
|
1923
1308
|
const byId = el.getAttribute(REPLACED_ATTR) ?? "";
|
|
@@ -1936,63 +1321,10 @@ function syncReplacedOriginals(state) {
|
|
|
1936
1321
|
}
|
|
1937
1322
|
}
|
|
1938
1323
|
}
|
|
1939
|
-
var sectionOrderIndex = /* @__PURE__ */ new Map();
|
|
1940
|
-
function setAiSectionOrder(raw, currentPath) {
|
|
1941
|
-
const next = /* @__PURE__ */ new Map();
|
|
1942
|
-
if (raw) {
|
|
1943
|
-
try {
|
|
1944
|
-
const entries = JSON.parse(raw);
|
|
1945
|
-
for (const entry of entries) {
|
|
1946
|
-
if (!entry.pagePath || entry.pagePath === currentPath) next.set(entry.instanceId, entry.order);
|
|
1947
|
-
}
|
|
1948
|
-
} catch {
|
|
1949
|
-
}
|
|
1950
|
-
}
|
|
1951
|
-
sectionOrderIndex = next;
|
|
1952
|
-
}
|
|
1953
|
-
function applyExplicitOrder(entries) {
|
|
1954
|
-
if (sectionOrderIndex.size === 0) return entries;
|
|
1955
|
-
return entries.map((entry, index) => ({ entry, index, order: sectionOrderIndex.get(entry.id) })).sort((a, b) => {
|
|
1956
|
-
if (a.order === void 0 && b.order === void 0) return a.index - b.index;
|
|
1957
|
-
if (a.order === void 0) return 1;
|
|
1958
|
-
if (b.order === void 0) return -1;
|
|
1959
|
-
return a.order - b.order;
|
|
1960
|
-
}).map((item) => item.entry);
|
|
1961
|
-
}
|
|
1962
|
-
function orderByChain(sections) {
|
|
1963
|
-
const ids = new Set(sections.map((entry) => entry.id));
|
|
1964
|
-
const after = /* @__PURE__ */ new Map();
|
|
1965
|
-
const roots = [];
|
|
1966
|
-
for (const entry of sections) {
|
|
1967
|
-
const anchor = entry.replaces ?? entry.beforeSection ?? entry.afterSection ?? null;
|
|
1968
|
-
if (anchor && ids.has(anchor)) {
|
|
1969
|
-
const bucket = after.get(anchor);
|
|
1970
|
-
if (bucket) bucket.push(entry);
|
|
1971
|
-
else after.set(anchor, [entry]);
|
|
1972
|
-
} else {
|
|
1973
|
-
roots.push(entry);
|
|
1974
|
-
}
|
|
1975
|
-
}
|
|
1976
|
-
const out = [];
|
|
1977
|
-
const seen = /* @__PURE__ */ new Set();
|
|
1978
|
-
const visit = (entry) => {
|
|
1979
|
-
if (seen.has(entry.id)) return;
|
|
1980
|
-
seen.add(entry.id);
|
|
1981
|
-
out.push(entry);
|
|
1982
|
-
for (const child of after.get(entry.id) ?? []) visit(child);
|
|
1983
|
-
};
|
|
1984
|
-
for (const root of roots) visit(root);
|
|
1985
|
-
return out.length === sections.length ? out : sections;
|
|
1986
|
-
}
|
|
1987
1324
|
function applyAiSectionsToDom(state, options) {
|
|
1988
1325
|
if (typeof document === "undefined") return;
|
|
1989
|
-
const brandOverride = deriveBrandOverride();
|
|
1990
1326
|
const templateBrand = deriveTemplateBrand();
|
|
1991
|
-
const
|
|
1992
|
-
const pagePath = window.location.pathname;
|
|
1993
|
-
const pageSections = state.sections.filter((entry) => (entry.path ?? "/") === pagePath);
|
|
1994
|
-
const activeIds = new Set(pageSections.map((entry) => entry.id));
|
|
1995
|
-
const ordered = state.hideTemplate === true ? applyExplicitOrder(orderByChain(pageSections)) : pageSections;
|
|
1327
|
+
const activeIds = new Set(state.sections.map((entry) => entry.id));
|
|
1996
1328
|
for (const [id, section] of mounted) {
|
|
1997
1329
|
if (!activeIds.has(id)) {
|
|
1998
1330
|
section.root.unmount();
|
|
@@ -2000,8 +1332,8 @@ function applyAiSectionsToDom(state, options) {
|
|
|
2000
1332
|
mounted.delete(id);
|
|
2001
1333
|
}
|
|
2002
1334
|
}
|
|
2003
|
-
for (const entry of
|
|
2004
|
-
const serialized = JSON.stringify(entry)
|
|
1335
|
+
for (const entry of state.sections) {
|
|
1336
|
+
const serialized = JSON.stringify(entry);
|
|
2005
1337
|
const existing = mounted.get(entry.id);
|
|
2006
1338
|
if (existing && existing.serialized === serialized && existing.container.isConnected) {
|
|
2007
1339
|
continue;
|
|
@@ -2026,7 +1358,7 @@ function applyAiSectionsToDom(state, options) {
|
|
|
2026
1358
|
AiTreeRenderer,
|
|
2027
1359
|
{
|
|
2028
1360
|
tree: entry.tree,
|
|
2029
|
-
brand:
|
|
1361
|
+
brand: entry.brand ?? options?.brand ?? templateBrand ?? void 0,
|
|
2030
1362
|
resolveMedia,
|
|
2031
1363
|
editKeyPrefix: `ai.${entry.id}`
|
|
2032
1364
|
}
|
|
@@ -2035,20 +1367,8 @@ function applyAiSectionsToDom(state, options) {
|
|
|
2035
1367
|
});
|
|
2036
1368
|
mounted.set(entry.id, { root, container, serialized });
|
|
2037
1369
|
}
|
|
2038
|
-
if (state.hideTemplate === true) {
|
|
2039
|
-
let prev = null;
|
|
2040
|
-
for (const entry of ordered) {
|
|
2041
|
-
const el = mounted.get(entry.id)?.container;
|
|
2042
|
-
if (!el) continue;
|
|
2043
|
-
if (prev && !(prev.compareDocumentPosition(el) & Node.DOCUMENT_POSITION_FOLLOWING)) {
|
|
2044
|
-
prev.insertAdjacentElement("afterend", el);
|
|
2045
|
-
}
|
|
2046
|
-
prev = el;
|
|
2047
|
-
}
|
|
2048
|
-
}
|
|
2049
1370
|
syncReplacedOriginals(state);
|
|
2050
1371
|
syncRemovedSections(state);
|
|
2051
|
-
syncTemplateHidden(state, pageSections.length > 0);
|
|
2052
1372
|
}
|
|
2053
1373
|
|
|
2054
1374
|
// src/useLinkHrefGuardian.ts
|
|
@@ -2655,7 +1975,7 @@ function SchedulingWidget({ notifyOnConnect = false, initialScheduleId, insertAf
|
|
|
2655
1975
|
const autoId = useId();
|
|
2656
1976
|
const insertAfter = insertAfterProp ?? autoId;
|
|
2657
1977
|
const [schedule, setSchedule] = useState2(null);
|
|
2658
|
-
const [loading, setLoading] = useState2(
|
|
1978
|
+
const [loading, setLoading] = useState2(true);
|
|
2659
1979
|
const [inEditor, setInEditor] = useState2(false);
|
|
2660
1980
|
const [isHovered, setIsHovered] = useState2(false);
|
|
2661
1981
|
const [modalState, setModalState] = useState2(null);
|
|
@@ -2829,10 +2149,8 @@ function SchedulingWidget({ notifyOnConnect = false, initialScheduleId, insertAf
|
|
|
2829
2149
|
"*"
|
|
2830
2150
|
);
|
|
2831
2151
|
};
|
|
2152
|
+
if (!inEditor && !loading && !schedule) return null;
|
|
2832
2153
|
const sectionId = `scheduling-${insertAfter}`;
|
|
2833
|
-
if (!inEditor && !loading && !schedule) {
|
|
2834
|
-
return /* @__PURE__ */ jsx4("section", { "data-ohw-section": sectionId, "data-ohw-scheduling-anchor": insertAfter, style: { display: "none" } });
|
|
2835
|
-
}
|
|
2836
2154
|
return /* @__PURE__ */ jsxs3(
|
|
2837
2155
|
"section",
|
|
2838
2156
|
{
|
|
@@ -7749,17 +7067,13 @@ function MediaOverlay({
|
|
|
7749
7067
|
hover,
|
|
7750
7068
|
isUploading,
|
|
7751
7069
|
fadingOut = false,
|
|
7752
|
-
selected = false,
|
|
7753
|
-
hovered = false,
|
|
7754
7070
|
onFadeOutComplete,
|
|
7755
7071
|
onReplace,
|
|
7756
|
-
onSelect,
|
|
7757
7072
|
onVideoSettingsChange
|
|
7758
7073
|
}) {
|
|
7759
7074
|
const { rect } = hover;
|
|
7760
7075
|
const skeletonRef = React8.useRef(null);
|
|
7761
7076
|
const isVideo = hover.elementType === "video";
|
|
7762
|
-
const showChrome = !selected || hovered;
|
|
7763
7077
|
const autoplay = hover.videoAutoplay ?? true;
|
|
7764
7078
|
const muted = hover.videoMuted ?? true;
|
|
7765
7079
|
const probeRef = React8.useRef(null);
|
|
@@ -7773,7 +7087,6 @@ function MediaOverlay({
|
|
|
7773
7087
|
(prev) => prev && prev.fullWidth === width && prev.height === height ? prev : { fullWidth: width, height }
|
|
7774
7088
|
);
|
|
7775
7089
|
}, [isVideo]);
|
|
7776
|
-
const replaceLabel = isVideo ? "Replace video" : hover.elementType === "bg-image" ? "Replace background" : "Replace image";
|
|
7777
7090
|
const replaceMode = buttonSize ? replaceButtonMode({ width: rect.width, height: rect.height }, buttonSize) : "none";
|
|
7778
7091
|
const box = {
|
|
7779
7092
|
position: "fixed",
|
|
@@ -7807,7 +7120,7 @@ function MediaOverlay({
|
|
|
7807
7120
|
}
|
|
7808
7121
|
);
|
|
7809
7122
|
}
|
|
7810
|
-
const settingsBar = isVideo && !hover.isDragOver
|
|
7123
|
+
const settingsBar = isVideo && !hover.isDragOver ? /* @__PURE__ */ jsxs7(
|
|
7811
7124
|
"div",
|
|
7812
7125
|
{
|
|
7813
7126
|
"data-ohw-bridge": "",
|
|
@@ -7877,12 +7190,10 @@ function MediaOverlay({
|
|
|
7877
7190
|
// in-document, pointer-events does it natively. The button below opts back in, so
|
|
7878
7191
|
// Replace still works.
|
|
7879
7192
|
pointerEvents: hover.hasTextOverlap ? "none" : "auto",
|
|
7880
|
-
|
|
7881
|
-
|
|
7882
|
-
boxShadow: selected ? "inset 0 0 0 2px var(--color-primary)" : "inset 0 0 0 1.5px var(--color-primary)",
|
|
7883
|
-
background: selected ? "transparent" : "color-mix(in srgb, var(--color-primary) 20%, transparent)"
|
|
7193
|
+
boxShadow: "inset 0 0 0 1.5px var(--color-primary)",
|
|
7194
|
+
background: "color-mix(in srgb, var(--color-primary) 20%, transparent)"
|
|
7884
7195
|
},
|
|
7885
|
-
onClick: () =>
|
|
7196
|
+
onClick: () => onReplace(hover.key),
|
|
7886
7197
|
children: [
|
|
7887
7198
|
/* @__PURE__ */ jsxs7(
|
|
7888
7199
|
Button,
|
|
@@ -7903,17 +7214,17 @@ function MediaOverlay({
|
|
|
7903
7214
|
},
|
|
7904
7215
|
children: [
|
|
7905
7216
|
isVideo ? /* @__PURE__ */ jsx15(Film, { size: 14 }) : /* @__PURE__ */ jsx15(ImageIcon, { size: 14 }),
|
|
7906
|
-
|
|
7217
|
+
isVideo ? "Replace video" : "Replace image"
|
|
7907
7218
|
]
|
|
7908
7219
|
}
|
|
7909
7220
|
),
|
|
7910
|
-
|
|
7221
|
+
replaceMode === "none" ? null : /* @__PURE__ */ jsxs7(
|
|
7911
7222
|
Button,
|
|
7912
7223
|
{
|
|
7913
7224
|
"data-ohw-media-overlay": "",
|
|
7914
7225
|
variant: "outline",
|
|
7915
7226
|
size: "sm",
|
|
7916
|
-
"aria-label":
|
|
7227
|
+
"aria-label": isVideo ? "Replace video" : "Replace image",
|
|
7917
7228
|
className: "gap-1.5 cursor-pointer hover:bg-background",
|
|
7918
7229
|
style: {
|
|
7919
7230
|
...OVERLAY_BUTTON_STYLE,
|
|
@@ -7936,7 +7247,7 @@ function MediaOverlay({
|
|
|
7936
7247
|
},
|
|
7937
7248
|
children: [
|
|
7938
7249
|
isVideo ? /* @__PURE__ */ jsx15(Film, { size: 14 }) : /* @__PURE__ */ jsx15(ImageIcon, { size: 14 }),
|
|
7939
|
-
replaceMode === "full" ?
|
|
7250
|
+
replaceMode === "full" ? isVideo ? "Replace video" : "Replace image" : null
|
|
7940
7251
|
]
|
|
7941
7252
|
}
|
|
7942
7253
|
)
|
|
@@ -8020,8 +7331,6 @@ function parseSectionsFromRoot(root) {
|
|
|
8020
7331
|
const id = el.getAttribute("data-ohw-section") ?? "";
|
|
8021
7332
|
if (!id || seen.has(id) || LINK_PICKER_EXCLUDED_IDS.has(id)) continue;
|
|
8022
7333
|
if (el.parentElement?.closest("[data-ohw-section]")) continue;
|
|
8023
|
-
if (el.hasAttribute("data-ohw-ai-template-hidden") || el.hasAttribute("data-ohw-ai-removed") || el.hasAttribute("data-ohw-ai-replaced-by"))
|
|
8024
|
-
continue;
|
|
8025
7334
|
seen.add(id);
|
|
8026
7335
|
const label = el.getAttribute("data-ohw-section-label") ?? titleCaseSectionId(id);
|
|
8027
7336
|
sections.push({ id, label });
|
|
@@ -8051,10 +7360,6 @@ function topLevelSections() {
|
|
|
8051
7360
|
function instanceIdOf(el) {
|
|
8052
7361
|
return el.dataset.ohwInstance ?? el.dataset.ohwSection ?? "";
|
|
8053
7362
|
}
|
|
8054
|
-
function findByInstanceId(instanceId) {
|
|
8055
|
-
const escapedId = CSS.escape(instanceId);
|
|
8056
|
-
return document.querySelector(`[data-ohw-instance="${escapedId}"]`) ?? document.querySelector(`[data-ohw-section="${escapedId}"]:not([data-ohw-instance])`);
|
|
8057
|
-
}
|
|
8058
7363
|
function planSectionMove(instanceId, targetIndex, currentPath) {
|
|
8059
7364
|
const sections = topLevelSections();
|
|
8060
7365
|
const index = sections.findIndex((el) => instanceIdOf(el) === instanceId);
|
|
@@ -8090,7 +7395,7 @@ function syncRemovedFlags(entries) {
|
|
|
8090
7395
|
}
|
|
8091
7396
|
});
|
|
8092
7397
|
for (const id of removedIds) {
|
|
8093
|
-
const el =
|
|
7398
|
+
const el = document.querySelector(`[data-ohw-instance="${CSS.escape(id)}"]`);
|
|
8094
7399
|
if (el) {
|
|
8095
7400
|
el.style.display = "none";
|
|
8096
7401
|
el.setAttribute(REMOVED_ATTR2, "");
|
|
@@ -8118,7 +7423,9 @@ function applyPersistedOrder(entries) {
|
|
|
8118
7423
|
}
|
|
8119
7424
|
}
|
|
8120
7425
|
function setSectionRemoved(instanceId, currentPath, existingEntries, removed) {
|
|
8121
|
-
|
|
7426
|
+
const escapedId = CSS.escape(instanceId);
|
|
7427
|
+
if (!document.querySelector(`[data-ohw-instance="${escapedId}"]`) && !document.querySelector(`[data-ohw-section="${escapedId}"]:not([data-ohw-instance])`))
|
|
7428
|
+
return null;
|
|
8122
7429
|
const byId = new Map(existingEntries.map((e) => [e.instanceId, e]));
|
|
8123
7430
|
const allSections = Array.from(document.querySelectorAll("[data-ohw-section]")).filter(
|
|
8124
7431
|
(el) => !el.parentElement?.closest("[data-ohw-section]") && !isChromeSection(el)
|
|
@@ -8307,7 +7614,6 @@ function AiSectionOverlay({
|
|
|
8307
7614
|
}) {
|
|
8308
7615
|
const [selectedId, setSelectedId] = useState5(null);
|
|
8309
7616
|
const [reviewId, setReviewId] = useState5(null);
|
|
8310
|
-
const [reviewButtonsHidden, setReviewButtonsHidden] = useState5(false);
|
|
8311
7617
|
const reviewIdRef = useRef4(null);
|
|
8312
7618
|
reviewIdRef.current = reviewId;
|
|
8313
7619
|
const selectedIdRef = useRef4(null);
|
|
@@ -8369,7 +7675,6 @@ function AiSectionOverlay({
|
|
|
8369
7675
|
}
|
|
8370
7676
|
const found = readRect(sectionId) != null;
|
|
8371
7677
|
setReviewId(found ? sectionId : null);
|
|
8372
|
-
setReviewButtonsHidden(e.data.hideButtons === true);
|
|
8373
7678
|
postToParent2({ type: "ow:ai-review-started", sectionId, found });
|
|
8374
7679
|
if (found) {
|
|
8375
7680
|
document.querySelector(`[data-ohw-instance="${CSS.escape(sectionId)}"]`)?.scrollIntoView({ behavior: "smooth", block: "nearest" });
|
|
@@ -8497,16 +7802,13 @@ function AiSectionOverlay({
|
|
|
8497
7802
|
border: `2px solid ${PRIMARY2}`,
|
|
8498
7803
|
borderRadius: edgeAwareRadius(reviewRect),
|
|
8499
7804
|
zIndex: 2147483200,
|
|
8500
|
-
// The veil itself: swallows clicks so the section stays locked until decided.
|
|
8501
|
-
// stopPropagation only guards the bubble phase; the bridge's capture-phase click
|
|
8502
|
-
// handlers additionally bail on `[data-ohw-ai-review]`, without which a click on
|
|
8503
|
-
// Accept/Discard resolves to the media beneath and opens the file picker.
|
|
7805
|
+
// The veil itself: swallows clicks so the section stays locked until decided.
|
|
8504
7806
|
background: "rgba(8, 133, 254, 0.04)",
|
|
8505
7807
|
pointerEvents: "auto",
|
|
8506
7808
|
cursor: "default"
|
|
8507
7809
|
},
|
|
8508
7810
|
onClick: (e) => e.stopPropagation(),
|
|
8509
|
-
children:
|
|
7811
|
+
children: /* @__PURE__ */ jsxs9(
|
|
8510
7812
|
"div",
|
|
8511
7813
|
{
|
|
8512
7814
|
style: {
|
|
@@ -11073,13 +10375,8 @@ function referenceBox(slot) {
|
|
|
11073
10375
|
const neighbour = row ? Array.from(row.querySelectorAll('[data-ohw-editable="icon"]')).find(
|
|
11074
10376
|
(el) => el !== slot && !el.hasAttribute("data-ohw-social-icon-placeholder")
|
|
11075
10377
|
) : null;
|
|
11076
|
-
|
|
11077
|
-
|
|
11078
|
-
if (box2?.width && box2.height) return box2;
|
|
11079
|
-
}
|
|
11080
|
-
const own = slot.getBoundingClientRect();
|
|
11081
|
-
if (own.width && own.height) return own;
|
|
11082
|
-
const box = slot.querySelector(GLYPH_SELECTOR)?.getBoundingClientRect() ?? null;
|
|
10378
|
+
const source = (neighbour ?? slot).querySelector(GLYPH_SELECTOR);
|
|
10379
|
+
const box = source?.getBoundingClientRect() ?? null;
|
|
11083
10380
|
return box?.width && box.height ? box : null;
|
|
11084
10381
|
}
|
|
11085
10382
|
function iconMarkupSizedFor(slot, markup) {
|
|
@@ -12880,7 +12177,6 @@ function readLogoSizeState(content, placement) {
|
|
|
12880
12177
|
function getLogoElement(el) {
|
|
12881
12178
|
const marked = el.closest('[data-ohw-role="logo"], [data-ohw-logo]');
|
|
12882
12179
|
if (marked) return marked;
|
|
12883
|
-
if (el.closest('[data-ohw-editable="icon"]')) return null;
|
|
12884
12180
|
const root = el.closest("nav, [data-ohw-nav-root], footer");
|
|
12885
12181
|
if (!root) return null;
|
|
12886
12182
|
const anchor = el.closest("a");
|
|
@@ -13955,7 +13251,6 @@ function useSectionDrag({
|
|
|
13955
13251
|
}
|
|
13956
13252
|
const orderJson = JSON.stringify(entries);
|
|
13957
13253
|
editContentRef.current = { ...editContentRef.current, [SECTION_ORDER_KEY]: orderJson };
|
|
13958
|
-
setAiSectionOrder(orderJson, window.location.pathname);
|
|
13959
13254
|
postToParentRef.current({ type: "ow:change", nodes: [{ key: SECTION_ORDER_KEY, text: orderJson }] });
|
|
13960
13255
|
applyPersistedOrder(entries);
|
|
13961
13256
|
clearSectionDragVisuals();
|
|
@@ -14815,10 +14110,21 @@ function parseSchedulingInsertAfter(insertAfter) {
|
|
|
14815
14110
|
insertBefore: insertAfter.slice(idx + INSERT_BEFORE_MARKER.length)
|
|
14816
14111
|
};
|
|
14817
14112
|
}
|
|
14818
|
-
function
|
|
14819
|
-
|
|
14820
|
-
const
|
|
14821
|
-
|
|
14113
|
+
function resolveSchedulingInsert(insertAfter, explicitInsertBefore) {
|
|
14114
|
+
const parsed = parseSchedulingInsertAfter(insertAfter);
|
|
14115
|
+
const insertBefore = explicitInsertBefore ?? parsed.insertBefore;
|
|
14116
|
+
const effectiveInsertAfter = insertBefore && parsed.insertBefore === null ? `${insertAfter}${INSERT_BEFORE_MARKER}${insertBefore}` : insertAfter;
|
|
14117
|
+
return { effectiveInsertAfter, insertBefore };
|
|
14118
|
+
}
|
|
14119
|
+
function getSchedulingMountPoint(insertAfter) {
|
|
14120
|
+
const { anchor } = parseSchedulingInsertAfter(insertAfter);
|
|
14121
|
+
let anchorEl = document.querySelector(`[data-ohw-section="${anchor}"]`);
|
|
14122
|
+
if (!anchorEl && anchor === "scheduling") {
|
|
14123
|
+
const widgets = Array.from(document.querySelectorAll('[data-ohw-section^="scheduling-"]'));
|
|
14124
|
+
anchorEl = widgets.at(-1) ?? null;
|
|
14125
|
+
}
|
|
14126
|
+
if (!anchorEl) return null;
|
|
14127
|
+
return anchorEl.closest('[data-ohw-section-container="scheduling"]') ?? anchorEl;
|
|
14822
14128
|
}
|
|
14823
14129
|
function schedulingMountDepth(insertAfter) {
|
|
14824
14130
|
if (!insertAfter.includes(INSERT_BEFORE_MARKER)) return 0;
|
|
@@ -14835,7 +14141,8 @@ function getPageSchedulingEntries(raw) {
|
|
|
14835
14141
|
}
|
|
14836
14142
|
}
|
|
14837
14143
|
function isSchedulingWidgetMissing(entry) {
|
|
14838
|
-
|
|
14144
|
+
const { effectiveInsertAfter } = resolveSchedulingInsert(entry.insertAfter);
|
|
14145
|
+
return !document.querySelector(`[data-ohw-section="${schedulingSectionId(effectiveInsertAfter)}"]`);
|
|
14839
14146
|
}
|
|
14840
14147
|
function hasMissingSchedulingWidgets(entries) {
|
|
14841
14148
|
return entries.some(isSchedulingWidgetMissing);
|
|
@@ -14865,17 +14172,16 @@ function initSectionsFromContent(content, removeExisting = false) {
|
|
|
14865
14172
|
} catch {
|
|
14866
14173
|
}
|
|
14867
14174
|
}
|
|
14868
|
-
function mountSchedulingWidget(
|
|
14869
|
-
const
|
|
14870
|
-
const sectionId = schedulingSectionId(
|
|
14175
|
+
function mountSchedulingWidget(insertAfter, notifyOnConnect = false, scheduleId, explicitInsertBefore) {
|
|
14176
|
+
const { effectiveInsertAfter, insertBefore } = resolveSchedulingInsert(insertAfter, explicitInsertBefore);
|
|
14177
|
+
const sectionId = schedulingSectionId(effectiveInsertAfter);
|
|
14871
14178
|
if (document.querySelector(`[data-ohw-section="${sectionId}"]`)) return false;
|
|
14872
|
-
const
|
|
14873
|
-
if (!
|
|
14874
|
-
const mountPoint = anchorEl.closest('[data-ohw-section-container="scheduling"]') ?? anchorEl;
|
|
14179
|
+
const mountPoint = getSchedulingMountPoint(effectiveInsertAfter);
|
|
14180
|
+
if (!mountPoint) return false;
|
|
14875
14181
|
const container = document.createElement("div");
|
|
14876
14182
|
container.dataset.ohwSectionContainer = "scheduling";
|
|
14877
|
-
if (
|
|
14878
|
-
const beforeAnchor = document.querySelector(`[data-ohw-section="${
|
|
14183
|
+
if (insertBefore) {
|
|
14184
|
+
const beforeAnchor = document.querySelector(`[data-ohw-section="${insertBefore}"]`);
|
|
14879
14185
|
const beforePoint = beforeAnchor?.closest('[data-ohw-section-container="scheduling"]') ?? beforeAnchor;
|
|
14880
14186
|
if (!beforePoint) return false;
|
|
14881
14187
|
beforePoint.insertAdjacentElement("beforebegin", container);
|
|
@@ -14886,25 +14192,19 @@ function mountSchedulingWidget(anchorId, notifyOnConnect = false, scheduleId, be
|
|
|
14886
14192
|
}
|
|
14887
14193
|
tail.insertAdjacentElement("afterend", container);
|
|
14888
14194
|
}
|
|
14889
|
-
|
|
14890
|
-
|
|
14891
|
-
|
|
14892
|
-
|
|
14893
|
-
|
|
14894
|
-
|
|
14895
|
-
|
|
14896
|
-
|
|
14897
|
-
|
|
14898
|
-
|
|
14899
|
-
|
|
14900
|
-
|
|
14901
|
-
|
|
14902
|
-
});
|
|
14903
|
-
} catch (err) {
|
|
14904
|
-
console.error("[ow:scheduling] render threw", err);
|
|
14905
|
-
container.remove();
|
|
14906
|
-
return false;
|
|
14907
|
-
}
|
|
14195
|
+
const root = createRoot2(container);
|
|
14196
|
+
flushSync2(() => {
|
|
14197
|
+
root.render(
|
|
14198
|
+
/* @__PURE__ */ jsx33(
|
|
14199
|
+
SchedulingWidget,
|
|
14200
|
+
{
|
|
14201
|
+
notifyOnConnect,
|
|
14202
|
+
initialScheduleId: scheduleId,
|
|
14203
|
+
insertAfter: effectiveInsertAfter
|
|
14204
|
+
}
|
|
14205
|
+
)
|
|
14206
|
+
);
|
|
14207
|
+
});
|
|
14908
14208
|
const tracker = getSectionsTracker();
|
|
14909
14209
|
let sections = [];
|
|
14910
14210
|
try {
|
|
@@ -14912,12 +14212,10 @@ function mountSchedulingWidget(anchorId, notifyOnConnect = false, scheduleId, be
|
|
|
14912
14212
|
} catch {
|
|
14913
14213
|
}
|
|
14914
14214
|
const inEditor = typeof window !== "undefined" && window.self !== window.top;
|
|
14915
|
-
if (inEditor && !sections.find((s) => s.type === "scheduling" && s.insertAfter ===
|
|
14215
|
+
if (inEditor && !sections.find((s) => s.type === "scheduling" && s.insertAfter === effectiveInsertAfter)) {
|
|
14916
14216
|
sections.push({
|
|
14917
14217
|
type: "scheduling",
|
|
14918
|
-
insertAfter:
|
|
14919
|
-
anchorId,
|
|
14920
|
-
beforeId: beforeId ?? null,
|
|
14218
|
+
insertAfter: effectiveInsertAfter,
|
|
14921
14219
|
pagePath: window.location.pathname,
|
|
14922
14220
|
...scheduleId ? { scheduleId } : {}
|
|
14923
14221
|
});
|
|
@@ -14931,8 +14229,7 @@ function mountSchedulingEntries(entries, notifyOnConnect = false) {
|
|
|
14931
14229
|
for (let i = pending.length - 1; i >= 0; i--) {
|
|
14932
14230
|
const entry = pending[i];
|
|
14933
14231
|
const shouldNotify = typeof notifyOnConnect === "function" ? notifyOnConnect(entry) : notifyOnConnect;
|
|
14934
|
-
|
|
14935
|
-
if (mountSchedulingWidget(anchorId, shouldNotify, entry.scheduleId ?? null, beforeId, entry.insertAfter)) {
|
|
14232
|
+
if (mountSchedulingWidget(entry.insertAfter, shouldNotify, entry.scheduleId)) {
|
|
14936
14233
|
pending.splice(i, 1);
|
|
14937
14234
|
}
|
|
14938
14235
|
}
|
|
@@ -15090,11 +14387,6 @@ function applyLinkByKey(key, val) {
|
|
|
15090
14387
|
hrefAnchors.forEach((el) => applyLinkHref(el, val));
|
|
15091
14388
|
}
|
|
15092
14389
|
}
|
|
15093
|
-
function isInsideLinkEditor(target) {
|
|
15094
|
-
return Boolean(
|
|
15095
|
-
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"]')
|
|
15096
|
-
);
|
|
15097
|
-
}
|
|
15098
14390
|
function isInsideFloatingPanel(target) {
|
|
15099
14391
|
return Boolean(target.closest("[data-ohw-floating-panel]"));
|
|
15100
14392
|
}
|
|
@@ -15102,6 +14394,11 @@ function isPointOverFloatingPanel(clientX, clientY) {
|
|
|
15102
14394
|
const el = document.elementFromPoint(clientX, clientY);
|
|
15103
14395
|
return Boolean(el instanceof Element && el.closest("[data-ohw-floating-panel]"));
|
|
15104
14396
|
}
|
|
14397
|
+
function isInsideLinkEditor(target) {
|
|
14398
|
+
return Boolean(
|
|
14399
|
+
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"]')
|
|
14400
|
+
);
|
|
14401
|
+
}
|
|
15105
14402
|
function getHrefKeyFromElement(el) {
|
|
15106
14403
|
if (!el) return null;
|
|
15107
14404
|
const anchor = el.closest("[data-ohw-href-key]");
|
|
@@ -15360,7 +14657,7 @@ function getNavigationSelectionParent(el) {
|
|
|
15360
14657
|
if (!isFooterLinksContainer(el) && (el.hasAttribute("data-ohw-footer-col") || el.hasAttribute("data-ohw-footer-column") || isInferredFooterGroup2(el))) {
|
|
15361
14658
|
return getFooterLinksContainer();
|
|
15362
14659
|
}
|
|
15363
|
-
if (el.hasAttribute("data-ohw-nav-container") || el.hasAttribute("data-ohw-nav-drawer") ||
|
|
14660
|
+
if (el.hasAttribute("data-ohw-nav-container") || el.hasAttribute("data-ohw-nav-drawer") || isFooterLinksContainer(el)) {
|
|
15364
14661
|
return getNavigationRoot(el);
|
|
15365
14662
|
}
|
|
15366
14663
|
return null;
|
|
@@ -15575,6 +14872,7 @@ var ICONS = {
|
|
|
15575
14872
|
insertUnorderedList: '<line x1="8" y1="6" x2="21" y2="6"/><line x1="8" y1="12" x2="21" y2="12"/><line x1="8" y1="18" x2="21" y2="18"/><line x1="3" y1="6" x2="3.01" y2="6"/><line x1="3" y1="12" x2="3.01" y2="12"/><line x1="3" y1="18" x2="3.01" y2="18"/>',
|
|
15576
14873
|
insertOrderedList: '<line x1="10" y1="6" x2="21" y2="6"/><line x1="10" y1="12" x2="21" y2="12"/><line x1="10" y1="18" x2="21" y2="18"/><path d="M4 6h1v4"/><path d="M4 10h2"/><path d="M6 18H4c0-1 2-2 2-3s-1-1.5-2-1"/>'
|
|
15577
14874
|
};
|
|
14875
|
+
var HEIGHT_SETTLE_DELAYS = [150, 400, 800];
|
|
15578
14876
|
var SELECTION_CHROME_GAP2 = 4;
|
|
15579
14877
|
var TOOLBAR_STROKE_GAP2 = 4;
|
|
15580
14878
|
var TOOLBAR_OFFSET_FROM_ELEMENT = SELECTION_CHROME_GAP2 + TOOLBAR_STROKE_GAP2;
|
|
@@ -15954,7 +15252,6 @@ function StateToggle({
|
|
|
15954
15252
|
);
|
|
15955
15253
|
}
|
|
15956
15254
|
var contentCache = /* @__PURE__ */ new Map();
|
|
15957
|
-
var fetchedContentPaths = /* @__PURE__ */ new Set();
|
|
15958
15255
|
var OHW_LOADER_STYLE = {
|
|
15959
15256
|
position: "fixed",
|
|
15960
15257
|
inset: 0,
|
|
@@ -16073,70 +15370,6 @@ function OhhwellsBridge() {
|
|
|
16073
15370
|
const hoveredImageHasTextOverlapRef = useRef10(false);
|
|
16074
15371
|
const dragOverElRef = useRef10(null);
|
|
16075
15372
|
const [mediaHover, setMediaHover] = useState13(null);
|
|
16076
|
-
const [selectedMedia, setSelectedMedia] = useState13(null);
|
|
16077
|
-
const selectedMediaElRef = useRef10(null);
|
|
16078
|
-
const clearMediaSelection = useCallback8(() => {
|
|
16079
|
-
const prev = selectedMediaElRef.current;
|
|
16080
|
-
selectedMediaElRef.current = null;
|
|
16081
|
-
setSelectedMedia(null);
|
|
16082
|
-
const sectionEl = prev?.closest("[data-ohw-section]") ?? null;
|
|
16083
|
-
if (sectionEl) {
|
|
16084
|
-
postToParentRef.current({
|
|
16085
|
-
type: "ow:section-selected",
|
|
16086
|
-
sectionId: sectionEl.dataset.ohwSection ?? null,
|
|
16087
|
-
sectionLabel: sectionEl.dataset.ohwSectionLabel ?? titleCaseSectionId(sectionEl.dataset.ohwSection ?? ""),
|
|
16088
|
-
key: null
|
|
16089
|
-
});
|
|
16090
|
-
}
|
|
16091
|
-
}, []);
|
|
16092
|
-
const clearMediaSelectionRef = useRef10(clearMediaSelection);
|
|
16093
|
-
clearMediaSelectionRef.current = clearMediaSelection;
|
|
16094
|
-
const selectMediaElement = useCallback8((el) => {
|
|
16095
|
-
const r2 = el.getBoundingClientRect();
|
|
16096
|
-
const video = el.dataset.ohwEditable === "video" ? el.querySelector("video") : null;
|
|
16097
|
-
selectedMediaElRef.current = el;
|
|
16098
|
-
setSelectedMedia({
|
|
16099
|
-
key: el.dataset.ohwKey ?? "",
|
|
16100
|
-
rect: { top: r2.top, left: r2.left, width: r2.width, height: r2.height },
|
|
16101
|
-
elementType: el.dataset.ohwEditable ?? "image",
|
|
16102
|
-
hasTextOverlap: false,
|
|
16103
|
-
isDragOver: false,
|
|
16104
|
-
...video ? { videoAutoplay: video.autoplay, videoMuted: video.muted } : {}
|
|
16105
|
-
});
|
|
16106
|
-
const sectionEl = el.closest("[data-ohw-section]");
|
|
16107
|
-
aiSectionApiRef.current?.selectFromElement(el, { report: false });
|
|
16108
|
-
postToParentRef.current({
|
|
16109
|
-
type: "ow:section-selected",
|
|
16110
|
-
sectionId: sectionEl?.dataset.ohwSection ?? null,
|
|
16111
|
-
sectionLabel: sectionEl ? sectionEl.dataset.ohwSectionLabel ?? titleCaseSectionId(sectionEl.dataset.ohwSection ?? "") : null,
|
|
16112
|
-
key: el.dataset.ohwKey ?? null,
|
|
16113
|
-
// Display name for the pill — the raw key prettifies into fragments ("Img"); the
|
|
16114
|
-
// bridge knows what the node IS, so it names it.
|
|
16115
|
-
keyLabel: el.dataset.ohwEditable === "video" ? "Video" : el.dataset.ohwEditable === "bg-image" ? "Background" : "Image"
|
|
16116
|
-
});
|
|
16117
|
-
}, []);
|
|
16118
|
-
const selectMediaElementRef = useRef10(selectMediaElement);
|
|
16119
|
-
selectMediaElementRef.current = selectMediaElement;
|
|
16120
|
-
useEffect13(() => {
|
|
16121
|
-
if (!selectedMedia) return;
|
|
16122
|
-
const update = () => {
|
|
16123
|
-
const el = selectedMediaElRef.current;
|
|
16124
|
-
if (!el || !el.isConnected) {
|
|
16125
|
-
clearMediaSelection();
|
|
16126
|
-
return;
|
|
16127
|
-
}
|
|
16128
|
-
const r2 = el.getBoundingClientRect();
|
|
16129
|
-
setSelectedMedia(
|
|
16130
|
-
(prev) => prev ? { ...prev, rect: { top: r2.top, left: r2.left, width: r2.width, height: r2.height } } : prev
|
|
16131
|
-
);
|
|
16132
|
-
};
|
|
16133
|
-
window.addEventListener("scroll", update, true);
|
|
16134
|
-
window.addEventListener("resize", update);
|
|
16135
|
-
return () => {
|
|
16136
|
-
window.removeEventListener("scroll", update, true);
|
|
16137
|
-
window.removeEventListener("resize", update);
|
|
16138
|
-
};
|
|
16139
|
-
}, [selectedMedia !== null]);
|
|
16140
15373
|
const [carouselHover, setCarouselHover] = useState13(null);
|
|
16141
15374
|
const [uploadingRects, setUploadingRects] = useState13({});
|
|
16142
15375
|
const hoveredGapRef = useRef10(null);
|
|
@@ -16399,6 +15632,13 @@ function OhhwellsBridge() {
|
|
|
16399
15632
|
const [isItemDragging, setIsItemDragging] = useState13(false);
|
|
16400
15633
|
const [isFooterFrameSelection, setIsFooterFrameSelection] = useState13(false);
|
|
16401
15634
|
isFooterFrameSelectionRef.current = isFooterFrameSelection;
|
|
15635
|
+
const [floatingPanel, setFloatingPanel] = useState13(null);
|
|
15636
|
+
const floatingPanelOpenRef = useRef10(false);
|
|
15637
|
+
floatingPanelOpenRef.current = floatingPanel !== null;
|
|
15638
|
+
const [floatingPanelPos, setFloatingPanelPos] = useState13(null);
|
|
15639
|
+
const [logoSizeDraft, setLogoSizeDraft] = useState13(null);
|
|
15640
|
+
const [editorViewport, setEditorViewport] = useState13("desktop");
|
|
15641
|
+
const [parentScrollSnap, setParentScrollSnap] = useState13(null);
|
|
16402
15642
|
const [navDropdownPreviewOpen, setNavDropdownPreviewOpen] = useState13(null);
|
|
16403
15643
|
const [footerHeadingVisible, setFooterHeadingVisible] = useState13(null);
|
|
16404
15644
|
const footerDragRef = useRef10(null);
|
|
@@ -16413,16 +15653,7 @@ function OhhwellsBridge() {
|
|
|
16413
15653
|
const addNavAfterAnchorRef = useRef10(null);
|
|
16414
15654
|
const editContentRef = useRef10({});
|
|
16415
15655
|
const aiSectionsRef = useRef10("");
|
|
16416
|
-
const brandKitRef = useRef10("");
|
|
16417
|
-
const stylesRef = useRef10("");
|
|
16418
15656
|
const pendingDeleteUndoRef = useRef10(null);
|
|
16419
|
-
const [floatingPanel, setFloatingPanel] = useState13(null);
|
|
16420
|
-
const floatingPanelOpenRef = useRef10(false);
|
|
16421
|
-
const setFloatingPanelRef = useRef10(setFloatingPanel);
|
|
16422
|
-
const [floatingPanelPos, setFloatingPanelPos] = useState13(null);
|
|
16423
|
-
const [logoSizeDraft, setLogoSizeDraft] = useState13(null);
|
|
16424
|
-
const [editorViewport, setEditorViewport] = useState13("desktop");
|
|
16425
|
-
const [parentScrollSnap, setParentScrollSnap] = useState13(null);
|
|
16426
15657
|
const [sitePages, setSitePages] = useState13([]);
|
|
16427
15658
|
const [sectionsByPath, setSectionsByPath] = useState13({});
|
|
16428
15659
|
const sectionsPrefetchGenRef = useRef10(0);
|
|
@@ -16431,18 +15662,7 @@ function OhhwellsBridge() {
|
|
|
16431
15662
|
const linkPopoverOpenRef = useRef10(false);
|
|
16432
15663
|
const linkPopoverGraceUntilRef = useRef10(0);
|
|
16433
15664
|
setLinkPopoverRef.current = setLinkPopover;
|
|
16434
|
-
setFloatingPanelRef.current = setFloatingPanel;
|
|
16435
15665
|
linkPopoverSessionRef.current = linkPopover;
|
|
16436
|
-
floatingPanelOpenRef.current = Boolean(floatingPanel);
|
|
16437
|
-
useEffect13(() => {
|
|
16438
|
-
const syncViewport = () => {
|
|
16439
|
-
const next = window.innerWidth <= 480 ? "mobile" : "desktop";
|
|
16440
|
-
setEditorViewport((prev) => prev === next ? prev : next);
|
|
16441
|
-
};
|
|
16442
|
-
syncViewport();
|
|
16443
|
-
window.addEventListener("resize", syncViewport);
|
|
16444
|
-
return () => window.removeEventListener("resize", syncViewport);
|
|
16445
|
-
}, []);
|
|
16446
15666
|
const {
|
|
16447
15667
|
navDragRef,
|
|
16448
15668
|
navDropSlots,
|
|
@@ -17753,31 +16973,15 @@ function OhhwellsBridge() {
|
|
|
17753
16973
|
}
|
|
17754
16974
|
const applyContent = (content) => {
|
|
17755
16975
|
const imageLoads = [];
|
|
17756
|
-
if (typeof content[BRAND_KIT_KEY] === "string") {
|
|
17757
|
-
brandKitRef.current = content[BRAND_KIT_KEY];
|
|
17758
|
-
applyBrandToDom(parseBrandKit(content[BRAND_KIT_KEY]));
|
|
17759
|
-
} else {
|
|
17760
|
-
brandKitRef.current = "";
|
|
17761
|
-
applyBrandToDom(null);
|
|
17762
|
-
}
|
|
17763
16976
|
if (typeof content[AI_SECTIONS_KEY] === "string") {
|
|
17764
16977
|
aiSectionsRef.current = content[AI_SECTIONS_KEY];
|
|
17765
|
-
setAiSectionOrder(content[SECTION_ORDER_KEY], window.location.pathname);
|
|
17766
16978
|
applyAiSectionsToDom(parseAiSectionsState(content[AI_SECTIONS_KEY]));
|
|
17767
16979
|
}
|
|
17768
|
-
if (typeof content[STYLE_STORE_KEY] === "string") {
|
|
17769
|
-
stylesRef.current = content[STYLE_STORE_KEY];
|
|
17770
|
-
applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
|
|
17771
|
-
}
|
|
17772
|
-
applyBrandChrome(content);
|
|
17773
16980
|
for (const [key, val] of Object.entries(content)) {
|
|
17774
16981
|
if (key === "__ohw_sections") continue;
|
|
17775
16982
|
if (key === AI_SECTIONS_KEY) continue;
|
|
17776
16983
|
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
17777
16984
|
if (LOGO_IMAGE_KEYS.includes(key)) continue;
|
|
17778
|
-
if (key === BRAND_KIT_KEY) continue;
|
|
17779
|
-
if (key === STYLE_STORE_KEY) continue;
|
|
17780
|
-
if (BRAND_CHROME_KEYS.has(key)) continue;
|
|
17781
16985
|
if (applyVideoSettingNode(key, val)) continue;
|
|
17782
16986
|
if (applyCarouselNode(key, val)) continue;
|
|
17783
16987
|
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
@@ -17843,9 +17047,7 @@ function OhhwellsBridge() {
|
|
|
17843
17047
|
let cancelled = false;
|
|
17844
17048
|
setFetchState("loading");
|
|
17845
17049
|
const apiUrl = process.env.NEXT_PUBLIC_FLOWOPS_API_URL ?? "https://flowops-backend-staging-2yfdh7pwpq-as.a.run.app";
|
|
17846
|
-
|
|
17847
|
-
fetchedContentPaths.add(`${subdomain}::${initialPath}`);
|
|
17848
|
-
fetch(`${apiUrl}/api/public/sites/${subdomain}/content?path=${encodeURIComponent(initialPath)}`, { cache: "no-store" }).then((r2) => r2.ok ? r2.json() : null).then((data) => {
|
|
17050
|
+
fetch(`${apiUrl}/api/public/sites/${subdomain}/content`, { cache: "no-store" }).then((r2) => r2.ok ? r2.json() : null).then((data) => {
|
|
17849
17051
|
if (cancelled) return;
|
|
17850
17052
|
const content = data?.content ?? {};
|
|
17851
17053
|
contentCache.set(subdomain, content);
|
|
@@ -17965,28 +17167,10 @@ function OhhwellsBridge() {
|
|
|
17965
17167
|
initSectionInstancesFromContent(content, window.location.pathname);
|
|
17966
17168
|
observer?.disconnect();
|
|
17967
17169
|
try {
|
|
17968
|
-
applyBrandChrome(content);
|
|
17969
|
-
if (typeof content[BRAND_KIT_KEY] === "string") {
|
|
17970
|
-
applyBrandToDom(parseBrandKit(content[BRAND_KIT_KEY]));
|
|
17971
|
-
} else {
|
|
17972
|
-
applyBrandToDom(null);
|
|
17973
|
-
}
|
|
17974
|
-
if (typeof content[AI_SECTIONS_KEY] === "string") {
|
|
17975
|
-
setAiSectionOrder(content[SECTION_ORDER_KEY], window.location.pathname);
|
|
17976
|
-
applyAiSectionsToDom(parseAiSectionsState(content[AI_SECTIONS_KEY]));
|
|
17977
|
-
}
|
|
17978
|
-
if (typeof content[STYLE_STORE_KEY] === "string") {
|
|
17979
|
-
applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
|
|
17980
|
-
}
|
|
17981
17170
|
for (const [key, val] of Object.entries(content)) {
|
|
17982
17171
|
if (key === "__ohw_sections") continue;
|
|
17983
|
-
if (key === AI_SECTIONS_KEY) continue;
|
|
17984
17172
|
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
17985
17173
|
if (LOGO_IMAGE_KEYS.includes(key)) continue;
|
|
17986
|
-
if (key === BRAND_KIT_KEY) continue;
|
|
17987
|
-
if (key === STYLE_STORE_KEY) continue;
|
|
17988
|
-
if (key === STYLE_STORE_KEY) continue;
|
|
17989
|
-
if (BRAND_CHROME_KEYS.has(key)) continue;
|
|
17990
17174
|
if (applyVideoSettingNode(key, val)) continue;
|
|
17991
17175
|
if (applyCarouselNode(key, val)) continue;
|
|
17992
17176
|
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
@@ -18032,17 +17216,6 @@ function OhhwellsBridge() {
|
|
|
18032
17216
|
debounceTimer = setTimeout(applyFromCache, 150);
|
|
18033
17217
|
};
|
|
18034
17218
|
applyFromCache();
|
|
18035
|
-
const pathCacheKey = `${subdomain}::${pathname}`;
|
|
18036
|
-
if (!fetchedContentPaths.has(pathCacheKey)) {
|
|
18037
|
-
fetchedContentPaths.add(pathCacheKey);
|
|
18038
|
-
const apiUrl = process.env.NEXT_PUBLIC_FLOWOPS_API_URL ?? "https://flowops-backend-staging-2yfdh7pwpq-as.a.run.app";
|
|
18039
|
-
fetch(`${apiUrl}/api/public/sites/${subdomain}/content?path=${encodeURIComponent(pathname)}`, { cache: "no-store" }).then((r2) => r2.ok ? r2.json() : null).then((data) => {
|
|
18040
|
-
if (!data?.content) return;
|
|
18041
|
-
contentCache.set(subdomain, data.content);
|
|
18042
|
-
applyFromCache();
|
|
18043
|
-
}).catch(() => {
|
|
18044
|
-
});
|
|
18045
|
-
}
|
|
18046
17219
|
observer = new MutationObserver(scheduleApply);
|
|
18047
17220
|
observer.observe(document.body, { childList: true, subtree: true });
|
|
18048
17221
|
return () => {
|
|
@@ -18138,31 +17311,30 @@ function OhhwellsBridge() {
|
|
|
18138
17311
|
}, [isEditMode, pathname, subdomain, fetchState, resyncSelectedNavigationItem]);
|
|
18139
17312
|
useEffect13(() => {
|
|
18140
17313
|
if (!isEditMode) return;
|
|
18141
|
-
let lastPosted = 0;
|
|
18142
17314
|
const measure = () => {
|
|
18143
17315
|
const h = document.body.scrollHeight;
|
|
18144
|
-
if (h > 50
|
|
18145
|
-
lastPosted = h;
|
|
18146
|
-
postToParent2({ type: "ow:height", height: h });
|
|
18147
|
-
}
|
|
18148
|
-
};
|
|
18149
|
-
let raf = null;
|
|
18150
|
-
const schedule = () => {
|
|
18151
|
-
if (raf != null) return;
|
|
18152
|
-
raf = requestAnimationFrame(() => {
|
|
18153
|
-
raf = null;
|
|
18154
|
-
measure();
|
|
18155
|
-
});
|
|
17316
|
+
if (h > 50) postToParent2({ type: "ow:height", height: h });
|
|
18156
17317
|
};
|
|
18157
17318
|
const t1 = setTimeout(measure, 50);
|
|
18158
17319
|
const t2 = setTimeout(measure, 500);
|
|
18159
|
-
|
|
18160
|
-
|
|
17320
|
+
let lastWidth = window.innerWidth;
|
|
17321
|
+
let resizeTimers = [];
|
|
17322
|
+
const clearResizeTimers = () => {
|
|
17323
|
+
resizeTimers.forEach(clearTimeout);
|
|
17324
|
+
resizeTimers = [];
|
|
17325
|
+
};
|
|
17326
|
+
const handleResize = () => {
|
|
17327
|
+
if (window.innerWidth === lastWidth) return;
|
|
17328
|
+
lastWidth = window.innerWidth;
|
|
17329
|
+
clearResizeTimers();
|
|
17330
|
+
resizeTimers = HEIGHT_SETTLE_DELAYS.map((delay) => setTimeout(measure, delay));
|
|
17331
|
+
};
|
|
17332
|
+
window.addEventListener("resize", handleResize);
|
|
18161
17333
|
return () => {
|
|
18162
17334
|
clearTimeout(t1);
|
|
18163
17335
|
clearTimeout(t2);
|
|
18164
|
-
|
|
18165
|
-
|
|
17336
|
+
clearResizeTimers();
|
|
17337
|
+
window.removeEventListener("resize", handleResize);
|
|
18166
17338
|
};
|
|
18167
17339
|
}, [pathname, isEditMode, postToParent2]);
|
|
18168
17340
|
useEffect13(() => {
|
|
@@ -18403,7 +17575,6 @@ function OhhwellsBridge() {
|
|
|
18403
17575
|
return;
|
|
18404
17576
|
}
|
|
18405
17577
|
const target = e.target;
|
|
18406
|
-
if (target.closest("[data-ohw-ai-review]")) return;
|
|
18407
17578
|
if (target.closest("[data-ohw-toolbar]")) return;
|
|
18408
17579
|
if (target.closest("[data-ohw-state-toggle]")) return;
|
|
18409
17580
|
if (target.closest("[data-ohw-max-badge]")) return;
|
|
@@ -18415,9 +17586,6 @@ function OhhwellsBridge() {
|
|
|
18415
17586
|
)) {
|
|
18416
17587
|
return;
|
|
18417
17588
|
}
|
|
18418
|
-
if (selectedMediaElRef.current && !selectedMediaElRef.current.contains(target) && !target.closest("[data-ohw-media-overlay], [data-ohw-edit-chrome], [data-ohw-item-interaction]")) {
|
|
18419
|
-
clearMediaSelectionRef.current();
|
|
18420
|
-
}
|
|
18421
17589
|
{
|
|
18422
17590
|
const formEl = getFormElement(target);
|
|
18423
17591
|
const onSuccessText = target.closest(`[${SUCCESS_TEXT_ATTR}]`);
|
|
@@ -18569,14 +17737,19 @@ function OhhwellsBridge() {
|
|
|
18569
17737
|
}
|
|
18570
17738
|
const clickedButton = findClosestButtonLike(target);
|
|
18571
17739
|
const buttonOnMedia = Boolean(clickedButton && isMediaEditable(editable) && editable.contains(clickedButton));
|
|
17740
|
+
console.log("[click-debug]", {
|
|
17741
|
+
editableType: editable.dataset.ohwEditable,
|
|
17742
|
+
editableTag: editable.tagName,
|
|
17743
|
+
targetTag: target.tagName,
|
|
17744
|
+
clickedButtonTag: clickedButton?.tagName ?? null,
|
|
17745
|
+
buttonOnMedia,
|
|
17746
|
+
isMediaEditableEditable: isMediaEditable(editable)
|
|
17747
|
+
});
|
|
18572
17748
|
if (isMediaEditable(editable) && !buttonOnMedia) {
|
|
18573
17749
|
e.preventDefault();
|
|
18574
17750
|
e.stopPropagation();
|
|
18575
|
-
|
|
18576
|
-
|
|
18577
|
-
} else {
|
|
18578
|
-
selectMediaElementRef.current(editable);
|
|
18579
|
-
}
|
|
17751
|
+
aiSectionApiRef.current?.selectFromElement(editable);
|
|
17752
|
+
postToParentRef.current({ type: "ow:image-pick", key: editable.dataset.ohwKey ?? "", elementType: editable.dataset.ohwEditable ?? "image" });
|
|
18580
17753
|
return;
|
|
18581
17754
|
}
|
|
18582
17755
|
const socialItem = getSocialItem(editable);
|
|
@@ -18595,6 +17768,11 @@ function OhhwellsBridge() {
|
|
|
18595
17768
|
const hrefLookupTarget = buttonOnMedia ? clickedButton : editable;
|
|
18596
17769
|
const hrefCtx = getHrefKeyFromElement(hrefLookupTarget);
|
|
18597
17770
|
const navAnchor = hrefCtx ? getNavigationItemAnchor(hrefCtx.anchor) : null;
|
|
17771
|
+
console.log("[click-debug 2]", {
|
|
17772
|
+
hrefLookupTargetTag: hrefLookupTarget.tagName,
|
|
17773
|
+
hrefCtx: hrefCtx ? { key: hrefCtx.key } : null,
|
|
17774
|
+
navAnchorTag: navAnchor?.tagName ?? null
|
|
17775
|
+
});
|
|
18598
17776
|
if (navAnchor) {
|
|
18599
17777
|
e.preventDefault();
|
|
18600
17778
|
e.stopPropagation();
|
|
@@ -18712,7 +17890,6 @@ function OhhwellsBridge() {
|
|
|
18712
17890
|
};
|
|
18713
17891
|
const handleDblClick = (e) => {
|
|
18714
17892
|
const target = e.target;
|
|
18715
|
-
if (target.closest("[data-ohw-ai-review]")) return;
|
|
18716
17893
|
if (target.closest("[data-ohw-toolbar]")) return;
|
|
18717
17894
|
if (target.closest("[data-ohw-state-toggle]")) return;
|
|
18718
17895
|
if (target.closest("[data-ohw-max-badge]")) return;
|
|
@@ -18764,9 +17941,6 @@ function OhhwellsBridge() {
|
|
|
18764
17941
|
setHoveredItemRect(null);
|
|
18765
17942
|
hoveredNavContainerRef.current = null;
|
|
18766
17943
|
setHoveredNavContainerRect(null);
|
|
18767
|
-
siblingHintElRef.current = null;
|
|
18768
|
-
setSiblingHintRect(null);
|
|
18769
|
-
setSiblingHintRects([]);
|
|
18770
17944
|
return;
|
|
18771
17945
|
}
|
|
18772
17946
|
{
|
|
@@ -18885,6 +18059,7 @@ function OhhwellsBridge() {
|
|
|
18885
18059
|
hoveredNavContainerRef.current = null;
|
|
18886
18060
|
setHoveredNavContainerRect(null);
|
|
18887
18061
|
hoveredItemElRef.current = editable;
|
|
18062
|
+
setHoveredItemRect(isSelectedForHoverRef.current(editable) ? null : editable.getBoundingClientRect());
|
|
18888
18063
|
}
|
|
18889
18064
|
}
|
|
18890
18065
|
}
|
|
@@ -19181,7 +18356,7 @@ function OhhwellsBridge() {
|
|
|
19181
18356
|
}
|
|
19182
18357
|
};
|
|
19183
18358
|
const probeImageAt = (clientX, clientY, isDragOver = false, fromParentViewport = false) => {
|
|
19184
|
-
if (linkPopoverOpenRef.current
|
|
18359
|
+
if (linkPopoverOpenRef.current) {
|
|
19185
18360
|
if (hoveredImageRef.current) {
|
|
19186
18361
|
hoveredImageRef.current = null;
|
|
19187
18362
|
hoveredImageHasTextOverlapRef.current = false;
|
|
@@ -19515,9 +18690,7 @@ function OhhwellsBridge() {
|
|
|
19515
18690
|
return;
|
|
19516
18691
|
}
|
|
19517
18692
|
const { y } = toProbeCoords(clientX, clientY, fromParentViewport);
|
|
19518
|
-
const sections = Array.from(document.querySelectorAll("[data-ohw-section]")).
|
|
19519
|
-
(el) => !el.hasAttribute("data-ohw-ai-template-hidden") && !el.hasAttribute("data-ohw-ai-removed") && !el.hasAttribute("data-ohw-ai-replaced-by") && el.getBoundingClientRect().height > 0
|
|
19520
|
-
).sort((a, b) => a.getBoundingClientRect().top - b.getBoundingClientRect().top);
|
|
18693
|
+
const sections = Array.from(document.querySelectorAll("[data-ohw-section]")).sort((a, b) => a.getBoundingClientRect().top - b.getBoundingClientRect().top);
|
|
19521
18694
|
const ZONE = 20;
|
|
19522
18695
|
for (let i = 0; i < sections.length; i++) {
|
|
19523
18696
|
const a = sections[i];
|
|
@@ -19546,7 +18719,8 @@ function OhhwellsBridge() {
|
|
|
19546
18719
|
};
|
|
19547
18720
|
const handleMouseMove = (e) => {
|
|
19548
18721
|
const { clientX, clientY } = e;
|
|
19549
|
-
if (
|
|
18722
|
+
if (pointOwnedByFloatingPanel(clientX, clientY)) return;
|
|
18723
|
+
if (isOverEditorChrome(clientX, clientY)) {
|
|
19550
18724
|
document.querySelectorAll("[data-ohw-hovered]").forEach((el) => el.removeAttribute("data-ohw-hovered"));
|
|
19551
18725
|
formHoverElRef.current = null;
|
|
19552
18726
|
setFormHoverRect(null);
|
|
@@ -19554,12 +18728,6 @@ function OhhwellsBridge() {
|
|
|
19554
18728
|
setHoveredItemRect(null);
|
|
19555
18729
|
hoveredNavContainerRef.current = null;
|
|
19556
18730
|
setHoveredNavContainerRect(null);
|
|
19557
|
-
siblingHintElRef.current = null;
|
|
19558
|
-
setSiblingHintRect(null);
|
|
19559
|
-
setSiblingHintRects([]);
|
|
19560
|
-
dismissImageHover();
|
|
19561
|
-
clearImageHover();
|
|
19562
|
-
setSectionGap(null);
|
|
19563
18731
|
return;
|
|
19564
18732
|
}
|
|
19565
18733
|
if (probeSocialsRowAt(clientX, clientY)) return;
|
|
@@ -19571,11 +18739,7 @@ function OhhwellsBridge() {
|
|
|
19571
18739
|
if (e.data?.type !== "ow:pointer-sync") return;
|
|
19572
18740
|
const { clientX, clientY } = e.data;
|
|
19573
18741
|
if (typeof clientX !== "number" || typeof clientY !== "number") return;
|
|
19574
|
-
if (
|
|
19575
|
-
dismissImageHover();
|
|
19576
|
-
clearImageHover();
|
|
19577
|
-
return;
|
|
19578
|
-
}
|
|
18742
|
+
if (pointOwnedByFloatingPanel(clientX, clientY)) return;
|
|
19579
18743
|
if (probeSocialsRowAt(clientX, clientY)) return;
|
|
19580
18744
|
probeSectionGapAt(clientX, clientY);
|
|
19581
18745
|
probeImageAt(clientX, clientY);
|
|
@@ -19858,23 +19022,10 @@ function OhhwellsBridge() {
|
|
|
19858
19022
|
if (e.data?.type !== "ow:hydrate") return;
|
|
19859
19023
|
const content = e.data.content;
|
|
19860
19024
|
if (!content) return;
|
|
19861
|
-
if (typeof content[BRAND_KIT_KEY] === "string") {
|
|
19862
|
-
brandKitRef.current = content[BRAND_KIT_KEY];
|
|
19863
|
-
applyBrandToDom(parseBrandKit(content[BRAND_KIT_KEY]));
|
|
19864
|
-
} else {
|
|
19865
|
-
brandKitRef.current = "";
|
|
19866
|
-
applyBrandToDom(null);
|
|
19867
|
-
}
|
|
19868
19025
|
if (typeof content[AI_SECTIONS_KEY] === "string") {
|
|
19869
19026
|
aiSectionsRef.current = content[AI_SECTIONS_KEY];
|
|
19870
|
-
setAiSectionOrder(content[SECTION_ORDER_KEY], window.location.pathname);
|
|
19871
19027
|
applyAiSectionsToDom(parseAiSectionsState(content[AI_SECTIONS_KEY]));
|
|
19872
19028
|
}
|
|
19873
|
-
if (typeof content[STYLE_STORE_KEY] === "string") {
|
|
19874
|
-
stylesRef.current = content[STYLE_STORE_KEY];
|
|
19875
|
-
applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
|
|
19876
|
-
}
|
|
19877
|
-
applyBrandChrome(content);
|
|
19878
19029
|
let sectionsJson = null;
|
|
19879
19030
|
for (const [key, val] of Object.entries(content)) {
|
|
19880
19031
|
if (key === "__ohw_sections") {
|
|
@@ -19884,9 +19035,6 @@ function OhhwellsBridge() {
|
|
|
19884
19035
|
if (key === AI_SECTIONS_KEY) continue;
|
|
19885
19036
|
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
19886
19037
|
if (LOGO_IMAGE_KEYS.includes(key) && !String(val ?? "").trim()) continue;
|
|
19887
|
-
if (key === BRAND_KIT_KEY) continue;
|
|
19888
|
-
if (key === STYLE_STORE_KEY) continue;
|
|
19889
|
-
if (BRAND_CHROME_KEYS.has(key)) continue;
|
|
19890
19038
|
if (applyVideoSettingNode(key, val)) continue;
|
|
19891
19039
|
if (applyCarouselNode(key, val)) continue;
|
|
19892
19040
|
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
@@ -19900,8 +19048,6 @@ function OhhwellsBridge() {
|
|
|
19900
19048
|
if (video && video.src !== val) applyVideoSrc(video, val);
|
|
19901
19049
|
} else if (el.dataset.ohwEditable === "link") {
|
|
19902
19050
|
applyLinkHref(el, val);
|
|
19903
|
-
} else if (el.dataset.ohwEditable === "icon") {
|
|
19904
|
-
applyIconMarkup(el, val);
|
|
19905
19051
|
} else if (isIconMarkupValue(val)) {
|
|
19906
19052
|
} else {
|
|
19907
19053
|
el.innerHTML = val;
|
|
@@ -19986,21 +19132,12 @@ function OhhwellsBridge() {
|
|
|
19986
19132
|
nodes: collectEditableNodes(editContentRef.current)
|
|
19987
19133
|
});
|
|
19988
19134
|
};
|
|
19989
|
-
const clearInteractionChrome = () => {
|
|
19990
|
-
deactivateRef.current();
|
|
19991
|
-
deselectRef.current();
|
|
19992
|
-
clearMediaSelectionRef.current();
|
|
19993
|
-
};
|
|
19994
19135
|
const handleAiApplyTree = (e) => {
|
|
19995
19136
|
if (e.data?.type !== "ow:ai-apply-tree") return;
|
|
19996
19137
|
const payload = e.data.payload;
|
|
19997
19138
|
if (!payload || typeof payload.id !== "string" || !isRenderableTree(payload.tree)) return;
|
|
19998
|
-
clearInteractionChrome();
|
|
19999
19139
|
const previous = aiSectionsRef.current;
|
|
20000
|
-
const nextState = applyTreeToState(parseAiSectionsState(previous),
|
|
20001
|
-
...payload,
|
|
20002
|
-
path: payload.path ?? window.location.pathname
|
|
20003
|
-
});
|
|
19140
|
+
const nextState = applyTreeToState(parseAiSectionsState(previous), payload);
|
|
20004
19141
|
const nextValue = serializeAiSectionsState(nextState);
|
|
20005
19142
|
aiSectionsRef.current = nextValue;
|
|
20006
19143
|
applyAiSectionsToDom(nextState);
|
|
@@ -20021,7 +19158,6 @@ function OhhwellsBridge() {
|
|
|
20021
19158
|
const exists = document.querySelector(`[data-ohw-section="${CSS.escape(sectionId)}"]`);
|
|
20022
19159
|
if (!exists) return;
|
|
20023
19160
|
if (isPageFrameSection(exists)) return;
|
|
20024
|
-
clearInteractionChrome();
|
|
20025
19161
|
const previous = aiSectionsRef.current;
|
|
20026
19162
|
const nextState = deleteSectionFromState(parseAiSectionsState(previous), sectionId);
|
|
20027
19163
|
const nextValue = serializeAiSectionsState(nextState);
|
|
@@ -20037,10 +19173,8 @@ function OhhwellsBridge() {
|
|
|
20037
19173
|
const handleAiSetSections = (e) => {
|
|
20038
19174
|
if (e.data?.type !== "ow:ai-set-sections") return;
|
|
20039
19175
|
const value = typeof e.data.value === "string" ? e.data.value : "";
|
|
20040
|
-
clearInteractionChrome();
|
|
20041
19176
|
aiSectionsRef.current = value;
|
|
20042
19177
|
applyAiSectionsToDom(parseAiSectionsState(value));
|
|
20043
|
-
applyStylesToDom(parseStyleStore(stylesRef.current));
|
|
20044
19178
|
const restoredHeight = document.body.scrollHeight;
|
|
20045
19179
|
if (restoredHeight > 50) postToParentRef.current({ type: "ow:height", height: restoredHeight });
|
|
20046
19180
|
postToParentRef.current({ type: "ow:change", nodes: [{ key: AI_SECTIONS_KEY, text: value }] });
|
|
@@ -20056,40 +19190,10 @@ function OhhwellsBridge() {
|
|
|
20056
19190
|
if (!entries) return;
|
|
20057
19191
|
const orderJson = JSON.stringify(entries);
|
|
20058
19192
|
editContentRef.current = { ...editContentRef.current, [SECTION_ORDER_KEY]: orderJson };
|
|
20059
|
-
setAiSectionOrder(orderJson, window.location.pathname);
|
|
20060
19193
|
postToParentRef.current({ type: "ow:change", nodes: [{ key: SECTION_ORDER_KEY, text: orderJson }] });
|
|
20061
19194
|
window.dispatchEvent(new Event("resize"));
|
|
20062
19195
|
};
|
|
20063
19196
|
window.addEventListener("message", handleMoveSection);
|
|
20064
|
-
const handleAiSetBrand = (e) => {
|
|
20065
|
-
if (e.data?.type !== "ow:ai-set-brand") return;
|
|
20066
|
-
const value = typeof e.data.value === "string" ? e.data.value : "";
|
|
20067
|
-
const previous = brandKitRef.current;
|
|
20068
|
-
brandKitRef.current = value;
|
|
20069
|
-
applyBrandToDom(parseBrandKit(value));
|
|
20070
|
-
if (aiSectionsRef.current) applyAiSectionsToDom(parseAiSectionsState(aiSectionsRef.current));
|
|
20071
|
-
applyStylesToDom(parseStyleStore(stylesRef.current));
|
|
20072
|
-
postToParentRef.current({ type: "ow:change", nodes: [{ key: BRAND_KIT_KEY, text: value }] });
|
|
20073
|
-
postToParentRef.current({ type: "ow:ai-brand-applied", previous, value });
|
|
20074
|
-
};
|
|
20075
|
-
window.addEventListener("message", handleAiSetBrand);
|
|
20076
|
-
const handleAiSetStyles = (e) => {
|
|
20077
|
-
if (e.data?.type !== "ow:ai-set-styles") return;
|
|
20078
|
-
const value = typeof e.data.value === "string" ? e.data.value : "";
|
|
20079
|
-
const previous = stylesRef.current;
|
|
20080
|
-
stylesRef.current = value;
|
|
20081
|
-
applyStylesToDom(parseStyleStore(value));
|
|
20082
|
-
postToParentRef.current({ type: "ow:change", nodes: [{ key: STYLE_STORE_KEY, text: value }] });
|
|
20083
|
-
postToParentRef.current({ type: "ow:ai-styles-applied", previous, value });
|
|
20084
|
-
};
|
|
20085
|
-
window.addEventListener("message", handleAiSetStyles);
|
|
20086
|
-
const handleGetBrand = (e) => {
|
|
20087
|
-
if (e.data?.type !== "ow:get-brand") return;
|
|
20088
|
-
const template = deriveTemplateBrand();
|
|
20089
|
-
const value = brandKitRef.current || (template ? JSON.stringify(template) : "");
|
|
20090
|
-
postToParentRef.current({ type: "ow:brand-value", value });
|
|
20091
|
-
};
|
|
20092
|
-
window.addEventListener("message", handleGetBrand);
|
|
20093
19197
|
const handlePanelDragging = (e) => {
|
|
20094
19198
|
if (e.data?.type !== "ow:panel-dragging") return;
|
|
20095
19199
|
if (e.data.dragging) document.documentElement.setAttribute("data-ohw-panel-dragging", "");
|
|
@@ -20147,15 +19251,8 @@ function OhhwellsBridge() {
|
|
|
20147
19251
|
closeLinkPopoverRef.current();
|
|
20148
19252
|
return;
|
|
20149
19253
|
}
|
|
20150
|
-
if (floatingPanelOpenRef.current) {
|
|
20151
|
-
setFloatingPanelRef.current(null);
|
|
20152
|
-
deselectRef.current();
|
|
20153
|
-
deactivateRef.current();
|
|
20154
|
-
return;
|
|
20155
|
-
}
|
|
20156
19254
|
deselectRef.current();
|
|
20157
19255
|
deactivateRef.current();
|
|
20158
|
-
clearMediaSelectionRef.current();
|
|
20159
19256
|
};
|
|
20160
19257
|
window.addEventListener("message", handleDeactivate);
|
|
20161
19258
|
const handleToastAction = (e) => {
|
|
@@ -20241,10 +19338,6 @@ function OhhwellsBridge() {
|
|
|
20241
19338
|
const handleKeyDown = (e) => {
|
|
20242
19339
|
if (e.key === "Escape" && document.querySelector("[data-ohw-section-picker]")) return;
|
|
20243
19340
|
if (e.key === "Escape" && document.querySelector("[data-ohw-more-menu]")) return;
|
|
20244
|
-
if (e.key === "Escape" && selectedMediaElRef.current) {
|
|
20245
|
-
clearMediaSelectionRef.current();
|
|
20246
|
-
return;
|
|
20247
|
-
}
|
|
20248
19341
|
if ((e.ctrlKey || e.metaKey) && e.key.toLowerCase() === "a" && activeElRef.current) {
|
|
20249
19342
|
e.preventDefault();
|
|
20250
19343
|
selectAllTextInEditable(activeElRef.current);
|
|
@@ -20404,12 +19497,6 @@ function OhhwellsBridge() {
|
|
|
20404
19497
|
if (aiSectionsRef.current) {
|
|
20405
19498
|
nodes.push({ key: AI_SECTIONS_KEY, type: "sections", text: aiSectionsRef.current });
|
|
20406
19499
|
}
|
|
20407
|
-
if (stylesRef.current) {
|
|
20408
|
-
nodes.push({ key: STYLE_STORE_KEY, type: "styles", text: stylesRef.current });
|
|
20409
|
-
}
|
|
20410
|
-
if (brandKitRef.current) {
|
|
20411
|
-
nodes.push({ key: BRAND_KIT_KEY, type: "brand", text: brandKitRef.current });
|
|
20412
|
-
}
|
|
20413
19500
|
document.querySelectorAll('[data-ohw-editable="form"]').forEach((form) => {
|
|
20414
19501
|
const formKey = formKeyOf(form);
|
|
20415
19502
|
if (!formKey) return;
|
|
@@ -20427,12 +19514,8 @@ function OhhwellsBridge() {
|
|
|
20427
19514
|
if (inserted) {
|
|
20428
19515
|
const tracker = getSectionsTracker();
|
|
20429
19516
|
postToParentRef.current({ type: "ow:change", nodes: [{ key: "__ohw_sections", text: tracker.textContent ?? "[]" }] });
|
|
20430
|
-
const
|
|
20431
|
-
|
|
20432
|
-
if (h > 50) postToParentRef.current({ type: "ow:height", height: h });
|
|
20433
|
-
};
|
|
20434
|
-
reportHeight();
|
|
20435
|
-
setTimeout(reportHeight, 500);
|
|
19517
|
+
const h = document.body.scrollHeight;
|
|
19518
|
+
if (h > 50) postToParentRef.current({ type: "ow:height", height: h });
|
|
20436
19519
|
}
|
|
20437
19520
|
};
|
|
20438
19521
|
const handleSwitchSchedule = (e) => {
|
|
@@ -20829,16 +19912,13 @@ function OhhwellsBridge() {
|
|
|
20829
19912
|
window.removeEventListener("message", handleAiDeleteSection);
|
|
20830
19913
|
window.removeEventListener("message", handleAiSetSections);
|
|
20831
19914
|
window.removeEventListener("message", handleMoveSection);
|
|
20832
|
-
window.removeEventListener("message", handleAiSetBrand);
|
|
20833
|
-
window.removeEventListener("message", handleAiSetStyles);
|
|
20834
|
-
window.removeEventListener("message", handleGetBrand);
|
|
20835
19915
|
window.removeEventListener("message", handlePanelDragging);
|
|
20836
19916
|
window.removeEventListener("message", handleDeleteSection);
|
|
20837
19917
|
window.removeEventListener("message", handleDeactivate);
|
|
19918
|
+
document.documentElement.removeAttribute("data-ohw-panel-dragging");
|
|
20838
19919
|
window.removeEventListener("message", handleToastAction);
|
|
20839
19920
|
window.removeEventListener("message", handleFormCount);
|
|
20840
19921
|
window.removeEventListener("message", handleUiEscape);
|
|
20841
|
-
document.documentElement.removeAttribute("data-ohw-panel-dragging");
|
|
20842
19922
|
autoSaveTimers.current.forEach(clearTimeout);
|
|
20843
19923
|
autoSaveTimers.current.clear();
|
|
20844
19924
|
if (imageUnhoverTimerRef.current) clearTimeout(imageUnhoverTimerRef.current);
|
|
@@ -21448,22 +20528,11 @@ function OhhwellsBridge() {
|
|
|
21448
20528
|
const showEditLink = toolbarShowEditLink;
|
|
21449
20529
|
const currentSections = sectionsByPath[pathname] ?? [];
|
|
21450
20530
|
linkPopoverOpenRef.current = linkPopover !== null;
|
|
21451
|
-
const handleMediaSelect = useCallback8((key) => {
|
|
21452
|
-
const el = hoveredImageRef.current?.dataset.ohwKey === key ? hoveredImageRef.current : Array.from(document.querySelectorAll(MEDIA_SELECTOR)).find(
|
|
21453
|
-
(m) => (m.dataset.ohwKey ?? "") === key
|
|
21454
|
-
) ?? null;
|
|
21455
|
-
if (!el) return;
|
|
21456
|
-
selectMediaElementRef.current(el);
|
|
21457
|
-
}, []);
|
|
21458
20531
|
const handleMediaReplace = useCallback8(
|
|
21459
20532
|
(key) => {
|
|
21460
|
-
postToParent2({
|
|
21461
|
-
type: "ow:image-pick",
|
|
21462
|
-
key,
|
|
21463
|
-
elementType: mediaHover?.elementType ?? selectedMedia?.elementType ?? "image"
|
|
21464
|
-
});
|
|
20533
|
+
postToParent2({ type: "ow:image-pick", key, elementType: mediaHover?.elementType ?? "image" });
|
|
21465
20534
|
},
|
|
21466
|
-
[postToParent2, mediaHover?.elementType
|
|
20535
|
+
[postToParent2, mediaHover?.elementType]
|
|
21467
20536
|
);
|
|
21468
20537
|
const handleEditCarousel = useCallback8(
|
|
21469
20538
|
(key) => {
|
|
@@ -21535,25 +20604,12 @@ function OhhwellsBridge() {
|
|
|
21535
20604
|
},
|
|
21536
20605
|
`uploading-${key}`
|
|
21537
20606
|
)),
|
|
21538
|
-
mediaHover && !(mediaHover.key in uploadingRects) &&
|
|
20607
|
+
mediaHover && !(mediaHover.key in uploadingRects) && /* @__PURE__ */ jsx33(
|
|
21539
20608
|
MediaOverlay,
|
|
21540
20609
|
{
|
|
21541
20610
|
hover: mediaHover,
|
|
21542
20611
|
isUploading: false,
|
|
21543
20612
|
onReplace: handleMediaReplace,
|
|
21544
|
-
onSelect: handleMediaSelect,
|
|
21545
|
-
onVideoSettingsChange: handleVideoSettingsChange
|
|
21546
|
-
}
|
|
21547
|
-
),
|
|
21548
|
-
selectedMedia && !(selectedMedia.key in uploadingRects) && !linkPopover && /* @__PURE__ */ jsx33(
|
|
21549
|
-
MediaOverlay,
|
|
21550
|
-
{
|
|
21551
|
-
hover: selectedMedia,
|
|
21552
|
-
selected: true,
|
|
21553
|
-
hovered: mediaHover?.key === selectedMedia.key,
|
|
21554
|
-
isUploading: false,
|
|
21555
|
-
onReplace: handleMediaReplace,
|
|
21556
|
-
onSelect: handleMediaSelect,
|
|
21557
20613
|
onVideoSettingsChange: handleVideoSettingsChange
|
|
21558
20614
|
}
|
|
21559
20615
|
),
|
|
@@ -21959,59 +21015,6 @@ function OhhwellsBridge() {
|
|
|
21959
21015
|
) : null
|
|
21960
21016
|
] });
|
|
21961
21017
|
}
|
|
21962
|
-
|
|
21963
|
-
// src/ui/EmptySection.tsx
|
|
21964
|
-
import Link3 from "next/link";
|
|
21965
|
-
import { Fragment as Fragment9, jsx as jsx34, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
21966
|
-
function EmptySection({ title, homeHref = "/", eyebrowKey, titleKey, subtitleKey }) {
|
|
21967
|
-
return /* @__PURE__ */ jsxs21(Fragment9, { children: [
|
|
21968
|
-
/* @__PURE__ */ jsx34(
|
|
21969
|
-
"p",
|
|
21970
|
-
{
|
|
21971
|
-
style: {
|
|
21972
|
-
fontFamily: "var(--brand-font-body)",
|
|
21973
|
-
fontSize: "0.75rem",
|
|
21974
|
-
fontWeight: 500,
|
|
21975
|
-
letterSpacing: "0.15em",
|
|
21976
|
-
textTransform: "uppercase",
|
|
21977
|
-
color: "var(--brand-accent)",
|
|
21978
|
-
marginBottom: "1.5rem"
|
|
21979
|
-
},
|
|
21980
|
-
children: /* @__PURE__ */ jsx34(Link3, { href: homeHref, style: { color: "inherit" }, children: /* @__PURE__ */ jsx34("span", { ...eyebrowKey ? { "data-ohw-editable": "text", "data-ohw-key": eyebrowKey } : {}, children: "Home" }) })
|
|
21981
|
-
}
|
|
21982
|
-
),
|
|
21983
|
-
/* @__PURE__ */ jsx34(
|
|
21984
|
-
"h1",
|
|
21985
|
-
{
|
|
21986
|
-
style: {
|
|
21987
|
-
fontFamily: "var(--brand-font-heading)",
|
|
21988
|
-
fontSize: "clamp(2rem, 3.5vw, 2.75rem)",
|
|
21989
|
-
lineHeight: 1.1,
|
|
21990
|
-
letterSpacing: "-0.025em",
|
|
21991
|
-
color: "var(--brand-text)",
|
|
21992
|
-
marginBottom: "1rem"
|
|
21993
|
-
},
|
|
21994
|
-
...titleKey ? { "data-ohw-editable": "text", "data-ohw-key": titleKey, "data-ohw-max-length": 80 } : {},
|
|
21995
|
-
children: title
|
|
21996
|
-
}
|
|
21997
|
-
),
|
|
21998
|
-
/* @__PURE__ */ jsx34(
|
|
21999
|
-
"p",
|
|
22000
|
-
{
|
|
22001
|
-
style: {
|
|
22002
|
-
fontFamily: "var(--brand-font-body)",
|
|
22003
|
-
fontSize: "1rem",
|
|
22004
|
-
lineHeight: 1.7,
|
|
22005
|
-
fontWeight: 300,
|
|
22006
|
-
color: "var(--brand-text-muted)",
|
|
22007
|
-
maxWidth: "340px"
|
|
22008
|
-
},
|
|
22009
|
-
...subtitleKey ? { "data-ohw-editable": "text", "data-ohw-key": subtitleKey, "data-ohw-max-length": 160 } : {},
|
|
22010
|
-
children: "This page doesn't have any content yet."
|
|
22011
|
-
}
|
|
22012
|
-
)
|
|
22013
|
-
] });
|
|
22014
|
-
}
|
|
22015
21018
|
export {
|
|
22016
21019
|
AI_DEFAULT_BRAND,
|
|
22017
21020
|
AI_TREE_SCHEMA_VERSIONS,
|
|
@@ -22028,7 +21031,6 @@ export {
|
|
|
22028
21031
|
DropdownMenuItem,
|
|
22029
21032
|
DropdownMenuSeparator,
|
|
22030
21033
|
DropdownMenuTrigger,
|
|
22031
|
-
EmptySection,
|
|
22032
21034
|
ItemActionToolbar,
|
|
22033
21035
|
ItemInteractionLayer,
|
|
22034
21036
|
LinkEditorPanel,
|