@ohhwells/bridge 0.1.59 → 0.1.60-next.171
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 +1649 -188
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +17 -3
- package/dist/index.d.ts +17 -3
- package/dist/index.js +1646 -186
- package/dist/index.js.map +1 -1
- package/dist/pages.cjs +141 -0
- package/dist/pages.cjs.map +1 -0
- package/dist/pages.js +107 -0
- package/dist/pages.js.map +1 -0
- package/dist/styles.css +61 -0
- package/package.json +6 -1
package/dist/index.js
CHANGED
|
@@ -96,6 +96,7 @@ function applyTreeToState(state, payload) {
|
|
|
96
96
|
const entry = {
|
|
97
97
|
id: payload.id,
|
|
98
98
|
label: payload.label ?? "Generated section",
|
|
99
|
+
...typeof payload.path === "string" && payload.path ? { path: payload.path } : {},
|
|
99
100
|
afterSection: payload.mode === "insert" && !insertBefore ? payload.targetSectionId ?? null : null,
|
|
100
101
|
...insertBefore && payload.targetSectionId ? { beforeSection: payload.targetSectionId } : {},
|
|
101
102
|
...payload.mode === "replace" && payload.targetSectionId ? { replaces: payload.targetSectionId } : {},
|
|
@@ -118,6 +119,272 @@ function deleteSectionFromState(state, sectionId) {
|
|
|
118
119
|
return { ...state, v: 1, sections: state.sections, removed: [...removed, sectionId] };
|
|
119
120
|
}
|
|
120
121
|
|
|
122
|
+
// src/lib/brand-chrome.ts
|
|
123
|
+
var BRAND_NAME_KEY = "__ohw_brand_name";
|
|
124
|
+
var BRAND_TITLE_KEY = "__ohw_site_title";
|
|
125
|
+
var BRAND_FAVICON_LETTER_KEY = "__ohw_favicon_letter";
|
|
126
|
+
var BRAND_CHROME_KEYS = /* @__PURE__ */ new Set([
|
|
127
|
+
BRAND_NAME_KEY,
|
|
128
|
+
BRAND_TITLE_KEY,
|
|
129
|
+
BRAND_FAVICON_LETTER_KEY
|
|
130
|
+
]);
|
|
131
|
+
function upsertMeta(selector, attr, token, value) {
|
|
132
|
+
let el = document.head.querySelector(selector);
|
|
133
|
+
if (!el) {
|
|
134
|
+
el = document.createElement("meta");
|
|
135
|
+
el.setAttribute(attr, token);
|
|
136
|
+
document.head.appendChild(el);
|
|
137
|
+
}
|
|
138
|
+
if (el.getAttribute("content") !== value) el.setAttribute("content", value);
|
|
139
|
+
}
|
|
140
|
+
function escapeXml(value) {
|
|
141
|
+
return value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
142
|
+
}
|
|
143
|
+
function applyLetterFavicon(letter) {
|
|
144
|
+
const svg = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><rect width="64" height="64" rx="12" fill="#111827"/><text x="32" y="46" font-family="system-ui,-apple-system,Segoe UI,sans-serif" font-size="40" font-weight="700" text-anchor="middle" fill="#ffffff">${escapeXml(letter)}</text></svg>`;
|
|
145
|
+
const href = `data:image/svg+xml,${encodeURIComponent(svg)}`;
|
|
146
|
+
let link = document.head.querySelector('link[rel="icon"]');
|
|
147
|
+
if (!link) {
|
|
148
|
+
link = document.createElement("link");
|
|
149
|
+
link.rel = "icon";
|
|
150
|
+
document.head.appendChild(link);
|
|
151
|
+
}
|
|
152
|
+
link.type = "image/svg+xml";
|
|
153
|
+
if (link.href !== href) link.href = href;
|
|
154
|
+
}
|
|
155
|
+
function applyBrandChrome(content) {
|
|
156
|
+
const name = content[BRAND_NAME_KEY];
|
|
157
|
+
if (typeof name === "string" && name.length > 0) {
|
|
158
|
+
document.querySelectorAll("[data-ohw-wordmark]").forEach((el) => {
|
|
159
|
+
if (el.textContent !== name) el.textContent = name;
|
|
160
|
+
if (el.getAttribute("title") !== name) el.setAttribute("title", name);
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
const title = content[BRAND_TITLE_KEY];
|
|
164
|
+
if (typeof title === "string" && title.length > 0) {
|
|
165
|
+
if (document.title !== title) document.title = title;
|
|
166
|
+
upsertMeta('meta[property="og:title"]', "property", "og:title", title);
|
|
167
|
+
upsertMeta('meta[name="twitter:title"]', "name", "twitter:title", title);
|
|
168
|
+
}
|
|
169
|
+
const letter = content[BRAND_FAVICON_LETTER_KEY];
|
|
170
|
+
if (typeof letter === "string" && letter.length > 0) {
|
|
171
|
+
applyLetterFavicon(letter);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// src/lib/brand-kit.ts
|
|
176
|
+
var BRAND_KIT_KEY = "__ohw_brand";
|
|
177
|
+
var BRAND_VAR_PREFIX = "--ohw-brand-";
|
|
178
|
+
var BRAND_VAR_NAMES = ["primary", "accent", "light", "dark", "surface", "border", "muted"].map(
|
|
179
|
+
(role) => `${BRAND_VAR_PREFIX}${role}`
|
|
180
|
+
);
|
|
181
|
+
var FONT_VARS = { heading: ["--font-heading", "--font-display"], body: ["--font-body"] };
|
|
182
|
+
var BRAND_FONT_LINK_ID = "ohw-brand-fonts";
|
|
183
|
+
function brandColorVars(kit) {
|
|
184
|
+
const { dark, primary, accent, light } = kit.palette;
|
|
185
|
+
const mix = (a, aPct, b) => `color-mix(in srgb, ${a} ${aPct}%, ${b})`;
|
|
186
|
+
return {
|
|
187
|
+
[`${BRAND_VAR_PREFIX}primary`]: primary,
|
|
188
|
+
[`${BRAND_VAR_PREFIX}accent`]: accent,
|
|
189
|
+
[`${BRAND_VAR_PREFIX}light`]: light,
|
|
190
|
+
[`${BRAND_VAR_PREFIX}dark`]: dark,
|
|
191
|
+
[`${BRAND_VAR_PREFIX}surface`]: mix(light, 95, dark),
|
|
192
|
+
[`${BRAND_VAR_PREFIX}border`]: mix(light, 85, dark),
|
|
193
|
+
[`${BRAND_VAR_PREFIX}muted`]: mix(dark, 62, light)
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
function parseBrandKit(raw) {
|
|
197
|
+
if (!raw) return null;
|
|
198
|
+
try {
|
|
199
|
+
const parsed = JSON.parse(raw);
|
|
200
|
+
const p = parsed?.palette;
|
|
201
|
+
const f = parsed?.fonts;
|
|
202
|
+
if (!p || !f || typeof p.dark !== "string" || typeof p.primary !== "string" || typeof p.accent !== "string" || typeof p.light !== "string" || typeof f.heading !== "string" || typeof f.body !== "string") {
|
|
203
|
+
return null;
|
|
204
|
+
}
|
|
205
|
+
return {
|
|
206
|
+
palette: { dark: p.dark, primary: p.primary, accent: p.accent, light: p.light },
|
|
207
|
+
fonts: { heading: f.heading, body: f.body }
|
|
208
|
+
};
|
|
209
|
+
} catch {
|
|
210
|
+
return null;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
function familyOf(stack) {
|
|
214
|
+
const first = stack.split(",")[0]?.trim() ?? "";
|
|
215
|
+
return first.replace(/^['"]|['"]$/g, "");
|
|
216
|
+
}
|
|
217
|
+
function loadBrandFonts(families) {
|
|
218
|
+
const unique = [...new Set(families.map((f) => f.trim()).filter(Boolean))];
|
|
219
|
+
if (unique.length === 0) return;
|
|
220
|
+
const spec = unique.map((f) => `${f.replace(/ /g, "+")}:400,500,600,700`).join("|");
|
|
221
|
+
const href = `https://fonts.googleapis.com/css?family=${spec}&display=swap`;
|
|
222
|
+
let link = document.getElementById(BRAND_FONT_LINK_ID);
|
|
223
|
+
if (!link) {
|
|
224
|
+
link = document.createElement("link");
|
|
225
|
+
link.id = BRAND_FONT_LINK_ID;
|
|
226
|
+
link.rel = "stylesheet";
|
|
227
|
+
document.head.appendChild(link);
|
|
228
|
+
}
|
|
229
|
+
if (link.href !== href) link.href = href;
|
|
230
|
+
}
|
|
231
|
+
function applyBrandToDom(kit) {
|
|
232
|
+
const root = document.documentElement;
|
|
233
|
+
if (!kit) {
|
|
234
|
+
for (const name of BRAND_VAR_NAMES) root.style.removeProperty(name);
|
|
235
|
+
for (const name of [...FONT_VARS.heading, ...FONT_VARS.body]) root.style.removeProperty(name);
|
|
236
|
+
document.getElementById(BRAND_FONT_LINK_ID)?.remove();
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
for (const [name, value] of Object.entries(brandColorVars(kit))) root.style.setProperty(name, value);
|
|
240
|
+
for (const name of FONT_VARS.heading) root.style.setProperty(name, kit.fonts.heading);
|
|
241
|
+
for (const name of FONT_VARS.body) root.style.setProperty(name, kit.fonts.body);
|
|
242
|
+
loadBrandFonts([familyOf(kit.fonts.heading), familyOf(kit.fonts.body)]);
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
// src/lib/section-styles.ts
|
|
246
|
+
var STYLE_STORE_KEY = "__ohw_styles";
|
|
247
|
+
var STYLE_SHEET_ID = "ohw-section-styles";
|
|
248
|
+
function parseStyleStore(raw) {
|
|
249
|
+
if (!raw) return null;
|
|
250
|
+
try {
|
|
251
|
+
const parsed = JSON.parse(raw);
|
|
252
|
+
if (parsed?.v !== 1) return null;
|
|
253
|
+
return {
|
|
254
|
+
v: 1,
|
|
255
|
+
sections: typeof parsed.sections === "object" && parsed.sections ? parsed.sections : {},
|
|
256
|
+
nodes: typeof parsed.nodes === "object" && parsed.nodes ? parsed.nodes : {}
|
|
257
|
+
};
|
|
258
|
+
} catch {
|
|
259
|
+
return null;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
var BG_VALUES = {
|
|
263
|
+
surface: "color-mix(in srgb, var(--ohw-brand-light, var(--color-light, #ECECEB)) 94%, var(--ohw-brand-dark, var(--color-dark, #0C0A09)))",
|
|
264
|
+
accent: "var(--ohw-brand-primary, var(--color-primary, #0078E5))",
|
|
265
|
+
"accent-soft": "color-mix(in srgb, var(--ohw-brand-primary, var(--color-primary, #0078E5)) 12%, var(--ohw-brand-light, var(--color-light, #FFFFFF)))"
|
|
266
|
+
};
|
|
267
|
+
var HEADLINE_SIZES = { md: 24, lg: 32, xl: 40, display: 56 };
|
|
268
|
+
function styleSheetCss() {
|
|
269
|
+
const rules = [];
|
|
270
|
+
for (const [tone, value] of Object.entries(BG_VALUES)) {
|
|
271
|
+
rules.push(`[data-ohw-style-bg="${tone}"] { background: ${value} !important; }`);
|
|
272
|
+
}
|
|
273
|
+
rules.push(
|
|
274
|
+
`[data-ohw-style-bg="accent"] { color: var(--ohw-brand-light, var(--color-light, #FFFFFF)) !important; }`
|
|
275
|
+
);
|
|
276
|
+
rules.push(
|
|
277
|
+
`[data-ohw-style-distribution="space-between"] { display: flex !important; flex-direction: column; justify-content: space-between; }`,
|
|
278
|
+
`[data-ohw-style-distribution="center"] { display: flex !important; flex-direction: column; justify-content: center; }`
|
|
279
|
+
);
|
|
280
|
+
for (const [scale, size] of Object.entries(HEADLINE_SIZES)) {
|
|
281
|
+
rules.push(
|
|
282
|
+
`[data-ohw-style-headline="${scale}"] :is(h1, h2, h3) { font-size: ${size}px !important; line-height: 1.15 !important; }`
|
|
283
|
+
);
|
|
284
|
+
}
|
|
285
|
+
rules.push(
|
|
286
|
+
`[data-ohw-style-aspect="fill-height"] img { height: 100% !important; aspect-ratio: auto !important; object-fit: cover; }`
|
|
287
|
+
);
|
|
288
|
+
for (const aspect of ["1:1", "4:5", "3:4", "3:2", "16:9", "2:1", "3:1"]) {
|
|
289
|
+
rules.push(
|
|
290
|
+
`[data-ohw-style-aspect="${aspect.replace(":", "-")}"] img { aspect-ratio: ${aspect.replace(":", " / ")} !important; height: auto !important; object-fit: cover; }`
|
|
291
|
+
);
|
|
292
|
+
}
|
|
293
|
+
const pad = { tight: 40, balanced: 64, airy: 96 };
|
|
294
|
+
for (const [spacing, px] of Object.entries(pad)) {
|
|
295
|
+
rules.push(
|
|
296
|
+
`[data-ohw-style-spacing="${spacing}"] { padding-top: ${px}px !important; padding-bottom: ${px}px !important; }`
|
|
297
|
+
);
|
|
298
|
+
}
|
|
299
|
+
return rules.join("\n");
|
|
300
|
+
}
|
|
301
|
+
var SECTION_ATTRS = {
|
|
302
|
+
sectionBackground: "data-ohw-style-bg",
|
|
303
|
+
textDistribution: "data-ohw-style-distribution",
|
|
304
|
+
headlineScale: "data-ohw-style-headline",
|
|
305
|
+
imageAspect: "data-ohw-style-aspect",
|
|
306
|
+
spacing: "data-ohw-style-spacing"
|
|
307
|
+
};
|
|
308
|
+
var NODE_WROTE_ATTR = "data-ohw-style-node";
|
|
309
|
+
function ensureStyleSheet() {
|
|
310
|
+
let el = document.getElementById(STYLE_SHEET_ID);
|
|
311
|
+
if (!el) {
|
|
312
|
+
el = document.createElement("style");
|
|
313
|
+
el.id = STYLE_SHEET_ID;
|
|
314
|
+
document.head.appendChild(el);
|
|
315
|
+
}
|
|
316
|
+
const css = styleSheetCss();
|
|
317
|
+
if (el.textContent !== css) el.textContent = css;
|
|
318
|
+
}
|
|
319
|
+
function clearSectionAttrs(root) {
|
|
320
|
+
for (const attr of Object.values(SECTION_ATTRS)) {
|
|
321
|
+
for (const el of Array.from(root.querySelectorAll(`[${attr}]`))) el.removeAttribute(attr);
|
|
322
|
+
}
|
|
323
|
+
for (const el of Array.from(root.querySelectorAll("[data-ohw-style-bgcolor]"))) {
|
|
324
|
+
;
|
|
325
|
+
el.style.removeProperty("background");
|
|
326
|
+
el.removeAttribute("data-ohw-style-bgcolor");
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
function clearNodeProps(root) {
|
|
330
|
+
for (const el of Array.from(root.querySelectorAll(`[${NODE_WROTE_ATTR}]`))) {
|
|
331
|
+
const h = el;
|
|
332
|
+
h.style.removeProperty("color");
|
|
333
|
+
h.style.removeProperty("font-size");
|
|
334
|
+
h.style.removeProperty("background");
|
|
335
|
+
h.removeAttribute(NODE_WROTE_ATTR);
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
function buttonSurfaceOf(el) {
|
|
339
|
+
return el.closest("a, button") ?? el;
|
|
340
|
+
}
|
|
341
|
+
function applyStylesToDom(store) {
|
|
342
|
+
ensureStyleSheet();
|
|
343
|
+
clearSectionAttrs(document);
|
|
344
|
+
clearNodeProps(document);
|
|
345
|
+
if (!store) return;
|
|
346
|
+
for (const [sectionId, override] of Object.entries(store.sections)) {
|
|
347
|
+
const sections = document.querySelectorAll(
|
|
348
|
+
`[data-ohw-section="${CSS.escape(sectionId)}"]`
|
|
349
|
+
);
|
|
350
|
+
for (const section of Array.from(sections)) {
|
|
351
|
+
for (const [prop, attr] of Object.entries(SECTION_ATTRS)) {
|
|
352
|
+
const value = override[prop];
|
|
353
|
+
if (value === void 0) continue;
|
|
354
|
+
if (prop === "sectionBackground" && override.sectionBackgroundColor !== void 0) continue;
|
|
355
|
+
section.setAttribute(attr, String(value).replace(":", "-"));
|
|
356
|
+
}
|
|
357
|
+
if (override.sectionBackgroundColor !== void 0) {
|
|
358
|
+
section.style.setProperty("background", override.sectionBackgroundColor, "important");
|
|
359
|
+
section.setAttribute("data-ohw-style-bgcolor", "");
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
for (const [key, override] of Object.entries(store.nodes)) {
|
|
364
|
+
const nodes = document.querySelectorAll(`[data-ohw-key="${CSS.escape(key)}"]`);
|
|
365
|
+
for (const el of Array.from(nodes)) {
|
|
366
|
+
if (override.color !== void 0) {
|
|
367
|
+
el.style.setProperty("color", override.color, "important");
|
|
368
|
+
el.setAttribute(NODE_WROTE_ATTR, "");
|
|
369
|
+
}
|
|
370
|
+
if (override.fontSize !== void 0) {
|
|
371
|
+
el.style.setProperty("font-size", `${override.fontSize}px`, "important");
|
|
372
|
+
el.setAttribute(NODE_WROTE_ATTR, "");
|
|
373
|
+
}
|
|
374
|
+
if (override.buttonBackground !== void 0 || override.buttonText !== void 0) {
|
|
375
|
+
const surface = buttonSurfaceOf(el);
|
|
376
|
+
if (override.buttonBackground !== void 0) {
|
|
377
|
+
surface.style.setProperty("background", override.buttonBackground, "important");
|
|
378
|
+
}
|
|
379
|
+
if (override.buttonText !== void 0) {
|
|
380
|
+
surface.style.setProperty("color", override.buttonText, "important");
|
|
381
|
+
}
|
|
382
|
+
surface.setAttribute(NODE_WROTE_ATTR, "");
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
|
|
121
388
|
// src/ui/ai-tree/aiSectionsManager.tsx
|
|
122
389
|
import { flushSync } from "react-dom";
|
|
123
390
|
import { createRoot } from "react-dom/client";
|
|
@@ -132,7 +399,8 @@ function lucideByName(name) {
|
|
|
132
399
|
}
|
|
133
400
|
var typeStyle = (spec, font) => ({
|
|
134
401
|
fontFamily: font,
|
|
135
|
-
|
|
402
|
+
// Headings shrink with the viewport (reaching full size around ~900px wide); body copy stays put.
|
|
403
|
+
fontSize: spec.size >= 24 ? `clamp(${Math.max(18, Math.round(spec.size * 0.6))}px, ${(spec.size / 9).toFixed(2)}vw, ${spec.size}px)` : spec.size,
|
|
136
404
|
lineHeight: spec.line,
|
|
137
405
|
fontWeight: spec.weight
|
|
138
406
|
});
|
|
@@ -150,6 +418,19 @@ var FEATURE_LINE_CSS = [
|
|
|
150
418
|
function textAttrs(ctx, path) {
|
|
151
419
|
return ctx.keyFor ? { "data-ohw-key": ctx.keyFor(path), "data-ohw-editable": "text" } : {};
|
|
152
420
|
}
|
|
421
|
+
var AI_RESPONSIVE_CSS = [
|
|
422
|
+
"@media (max-width: 960px) {",
|
|
423
|
+
" [data-ai-responsive] [data-ai-grid] { grid-template-columns: repeat(2, 1fr) !important; }",
|
|
424
|
+
' [data-ai-responsive] [data-ai-grid="1"] { grid-template-columns: 1fr !important; }',
|
|
425
|
+
"}",
|
|
426
|
+
"@media (max-width: 640px) {",
|
|
427
|
+
" [data-ai-responsive] [data-ai-grid] { grid-template-columns: 1fr !important; }",
|
|
428
|
+
" [data-ai-responsive] [data-ai-columns] > * { grid-column: 1 / -1 !important; }",
|
|
429
|
+
" [data-ai-responsive] [data-ai-section-inner] { padding-left: 20px !important; padding-right: 20px !important; }",
|
|
430
|
+
" [data-ai-responsive] { overflow-x: hidden; }",
|
|
431
|
+
" [data-ai-responsive] img { max-width: 100%; }",
|
|
432
|
+
"}"
|
|
433
|
+
].join("\n");
|
|
153
434
|
var TRANSPARENT_PX = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7";
|
|
154
435
|
function MediaBox({
|
|
155
436
|
refValue,
|
|
@@ -892,6 +1173,7 @@ function Carousel({ items, itemsPerRow, ctx }) {
|
|
|
892
1173
|
children: pageGroups.map((group, p) => /* @__PURE__ */ jsx(
|
|
893
1174
|
"div",
|
|
894
1175
|
{
|
|
1176
|
+
"data-ai-grid": String(itemsPerRow),
|
|
895
1177
|
style: {
|
|
896
1178
|
flex: "0 0 100%",
|
|
897
1179
|
display: "grid",
|
|
@@ -995,6 +1277,7 @@ function CollectionBlock({ node, ctx, path }) {
|
|
|
995
1277
|
return /* @__PURE__ */ jsx(
|
|
996
1278
|
"div",
|
|
997
1279
|
{
|
|
1280
|
+
"data-ai-grid": String(itemsPerRow),
|
|
998
1281
|
style: {
|
|
999
1282
|
display: "grid",
|
|
1000
1283
|
gridTemplateColumns: `repeat(${itemsPerRow}, 1fr)`,
|
|
@@ -1153,24 +1436,42 @@ function AiTreeRenderer({ tree, brand, resolveMedia, editKeyPrefix }) {
|
|
|
1153
1436
|
const overlayAlpha = { low: 0.25, medium: 0.45, high: 0.65 }[settings.overlayIntensity ?? "medium"];
|
|
1154
1437
|
const backgroundUrl = isOverlay && settings.backgroundMedia ? ctx.resolveMedia(settings.backgroundMedia) : null;
|
|
1155
1438
|
const bgAttrs = ctx.keyFor && isOverlay && settings.backgroundMedia ? { "data-ohw-key": ctx.keyFor("settings.backgroundMedia"), "data-ohw-editable": "bg-image" } : {};
|
|
1439
|
+
const toneBackground = (() => {
|
|
1440
|
+
const { dark, primary, light } = resolvedBrand.palette;
|
|
1441
|
+
switch (settings.sectionBackground) {
|
|
1442
|
+
case "surface":
|
|
1443
|
+
return `color-mix(in srgb, ${light} 94%, ${dark})`;
|
|
1444
|
+
case "accent":
|
|
1445
|
+
return primary;
|
|
1446
|
+
case "accent-soft":
|
|
1447
|
+
return `color-mix(in srgb, ${primary} 12%, ${light})`;
|
|
1448
|
+
default:
|
|
1449
|
+
return void 0;
|
|
1450
|
+
}
|
|
1451
|
+
})();
|
|
1452
|
+
const distributed = !isOverlay && settings.textDistribution;
|
|
1156
1453
|
return /* @__PURE__ */ jsxs(
|
|
1157
1454
|
"section",
|
|
1158
1455
|
{
|
|
1159
1456
|
"data-ai-section": tree.tag ?? "",
|
|
1160
1457
|
...bgAttrs,
|
|
1458
|
+
"data-ai-responsive": "",
|
|
1161
1459
|
style: {
|
|
1162
1460
|
position: "relative",
|
|
1163
1461
|
padding: `${pad}px 0`,
|
|
1164
|
-
background: isOverlay && !backgroundUrl ? "#DBEAFE" : void 0,
|
|
1462
|
+
background: toneBackground ?? (isOverlay && !backgroundUrl ? "#DBEAFE" : void 0),
|
|
1165
1463
|
backgroundImage: backgroundUrl ? `url(${backgroundUrl})` : void 0,
|
|
1166
1464
|
backgroundSize: "cover",
|
|
1167
|
-
backgroundPosition: "center"
|
|
1465
|
+
backgroundPosition: "center",
|
|
1466
|
+
color: settings.sectionBackground === "accent" ? resolvedBrand.palette.light : void 0
|
|
1168
1467
|
},
|
|
1169
1468
|
children: [
|
|
1469
|
+
/* @__PURE__ */ jsx("style", { children: AI_RESPONSIVE_CSS }),
|
|
1170
1470
|
isOverlay && backgroundUrl && /* @__PURE__ */ jsx("div", { style: { position: "absolute", inset: 0, background: `rgba(255,255,255,${overlayAlpha})` } }),
|
|
1171
1471
|
/* @__PURE__ */ jsx(
|
|
1172
1472
|
"div",
|
|
1173
1473
|
{
|
|
1474
|
+
"data-ai-section-inner": "",
|
|
1174
1475
|
style: {
|
|
1175
1476
|
position: "relative",
|
|
1176
1477
|
maxWidth: AI_TREE_TOKENS.sectionMaxWidth,
|
|
@@ -1181,14 +1482,29 @@ function AiTreeRenderer({ tree, brand, resolveMedia, editKeyPrefix }) {
|
|
|
1181
1482
|
children: tree.rows.map((row, r2) => /* @__PURE__ */ jsx(
|
|
1182
1483
|
"div",
|
|
1183
1484
|
{
|
|
1485
|
+
"data-ai-columns": "",
|
|
1184
1486
|
style: {
|
|
1185
1487
|
display: "grid",
|
|
1186
1488
|
gridTemplateColumns: "repeat(12, 1fr)",
|
|
1187
1489
|
gap: AI_TREE_TOKENS.spacing6,
|
|
1188
|
-
alignItems: settings.verticalPosition === "top" ? "start" : "center",
|
|
1490
|
+
alignItems: distributed === "space-between" ? "stretch" : (distributed ?? settings.verticalPosition) === "top" ? "start" : "center",
|
|
1189
1491
|
marginTop: r2 > 0 ? AI_TREE_TOKENS.spacing8 : 0
|
|
1190
1492
|
},
|
|
1191
|
-
children: (row.blocks ?? []).map((block, b) => /* @__PURE__ */ jsx(
|
|
1493
|
+
children: (row.blocks ?? []).map((block, b) => /* @__PURE__ */ jsx(
|
|
1494
|
+
"div",
|
|
1495
|
+
{
|
|
1496
|
+
"data-ai-cell": "",
|
|
1497
|
+
style: {
|
|
1498
|
+
gridColumn: `span ${Math.min(12, Math.max(1, block.span))}`,
|
|
1499
|
+
minWidth: 0,
|
|
1500
|
+
// space-between: each column becomes a flex column whose content spreads over
|
|
1501
|
+
// the full row height instead of clumping at the top.
|
|
1502
|
+
...distributed === "space-between" ? { display: "flex", flexDirection: "column", justifyContent: "space-between" } : {}
|
|
1503
|
+
},
|
|
1504
|
+
children: renderNode(block, ctx, `r${r2}.b${b}`)
|
|
1505
|
+
},
|
|
1506
|
+
b
|
|
1507
|
+
))
|
|
1192
1508
|
},
|
|
1193
1509
|
r2
|
|
1194
1510
|
))
|
|
@@ -1204,17 +1520,34 @@ import { jsx as jsx2 } from "react/jsx-runtime";
|
|
|
1204
1520
|
var CONTAINER_ATTR = "data-ohw-ai-generated";
|
|
1205
1521
|
var REPLACED_ATTR = "data-ohw-ai-replaced-by";
|
|
1206
1522
|
var REMOVED_ATTR = "data-ohw-ai-removed";
|
|
1523
|
+
function readRootVar(name) {
|
|
1524
|
+
if (typeof document === "undefined") return "";
|
|
1525
|
+
return getComputedStyle(document.documentElement).getPropertyValue(name).trim();
|
|
1526
|
+
}
|
|
1527
|
+
function deriveBrandOverride() {
|
|
1528
|
+
const dark = readRootVar("--ohw-brand-dark");
|
|
1529
|
+
const primary = readRootVar("--ohw-brand-primary");
|
|
1530
|
+
const light = readRootVar("--ohw-brand-light");
|
|
1531
|
+
if (!dark || !primary || !light) return null;
|
|
1532
|
+
const accent = readRootVar("--ohw-brand-accent");
|
|
1533
|
+
const heading = readRootVar("--font-heading") || readRootVar("--font-display");
|
|
1534
|
+
const body = readRootVar("--font-body");
|
|
1535
|
+
return {
|
|
1536
|
+
palette: { dark, primary, accent: accent || dark, light },
|
|
1537
|
+
fonts: {
|
|
1538
|
+
heading: heading || AI_DEFAULT_BRAND.fonts.heading,
|
|
1539
|
+
body: body || AI_DEFAULT_BRAND.fonts.body
|
|
1540
|
+
}
|
|
1541
|
+
};
|
|
1542
|
+
}
|
|
1207
1543
|
function deriveTemplateBrand() {
|
|
1208
|
-
|
|
1209
|
-
const
|
|
1210
|
-
const
|
|
1211
|
-
const dark = read("--color-dark");
|
|
1212
|
-
const primary = read("--color-primary");
|
|
1213
|
-
const light = read("--color-light");
|
|
1544
|
+
const dark = readRootVar("--color-dark");
|
|
1545
|
+
const primary = readRootVar("--color-primary");
|
|
1546
|
+
const light = readRootVar("--color-light");
|
|
1214
1547
|
if (!dark || !primary || !light) return null;
|
|
1215
|
-
const accent =
|
|
1216
|
-
const heading =
|
|
1217
|
-
const body =
|
|
1548
|
+
const accent = readRootVar("--color-accent");
|
|
1549
|
+
const heading = readRootVar("--font-heading") || readRootVar("--font-display");
|
|
1550
|
+
const body = readRootVar("--font-body");
|
|
1218
1551
|
return {
|
|
1219
1552
|
palette: { dark, primary, accent: accent || dark, light },
|
|
1220
1553
|
fonts: {
|
|
@@ -1306,8 +1639,12 @@ function syncReplacedOriginals(state) {
|
|
|
1306
1639
|
}
|
|
1307
1640
|
function applyAiSectionsToDom(state, options) {
|
|
1308
1641
|
if (typeof document === "undefined") return;
|
|
1642
|
+
const brandOverride = deriveBrandOverride();
|
|
1309
1643
|
const templateBrand = deriveTemplateBrand();
|
|
1310
|
-
const
|
|
1644
|
+
const brandKey = brandOverride ? JSON.stringify(brandOverride) : "";
|
|
1645
|
+
const pagePath = window.location.pathname;
|
|
1646
|
+
const pageSections = state.sections.filter((entry) => !entry.path || entry.path === pagePath);
|
|
1647
|
+
const activeIds = new Set(pageSections.map((entry) => entry.id));
|
|
1311
1648
|
for (const [id, section] of mounted) {
|
|
1312
1649
|
if (!activeIds.has(id)) {
|
|
1313
1650
|
section.root.unmount();
|
|
@@ -1315,8 +1652,8 @@ function applyAiSectionsToDom(state, options) {
|
|
|
1315
1652
|
mounted.delete(id);
|
|
1316
1653
|
}
|
|
1317
1654
|
}
|
|
1318
|
-
for (const entry of
|
|
1319
|
-
const serialized = JSON.stringify(entry);
|
|
1655
|
+
for (const entry of pageSections) {
|
|
1656
|
+
const serialized = JSON.stringify(entry) + brandKey;
|
|
1320
1657
|
const existing = mounted.get(entry.id);
|
|
1321
1658
|
if (existing && existing.serialized === serialized && existing.container.isConnected) {
|
|
1322
1659
|
continue;
|
|
@@ -1330,6 +1667,7 @@ function applyAiSectionsToDom(state, options) {
|
|
|
1330
1667
|
mounted.delete(entry.id);
|
|
1331
1668
|
}
|
|
1332
1669
|
container.setAttribute("data-ohw-section", entry.id);
|
|
1670
|
+
container.setAttribute("data-ohw-instance", entry.id);
|
|
1333
1671
|
container.setAttribute("data-ohw-section-label", entry.label);
|
|
1334
1672
|
placeContainer(container, entry);
|
|
1335
1673
|
const root = mounted.get(entry.id)?.root ?? createRoot(container);
|
|
@@ -1340,7 +1678,7 @@ function applyAiSectionsToDom(state, options) {
|
|
|
1340
1678
|
AiTreeRenderer,
|
|
1341
1679
|
{
|
|
1342
1680
|
tree: entry.tree,
|
|
1343
|
-
brand: entry.brand ?? options?.brand ?? templateBrand ?? void 0,
|
|
1681
|
+
brand: brandOverride ?? entry.brand ?? options?.brand ?? templateBrand ?? void 0,
|
|
1344
1682
|
resolveMedia,
|
|
1345
1683
|
editKeyPrefix: `ai.${entry.id}`
|
|
1346
1684
|
}
|
|
@@ -1957,7 +2295,7 @@ function SchedulingWidget({ notifyOnConnect = false, initialScheduleId, insertAf
|
|
|
1957
2295
|
const autoId = useId();
|
|
1958
2296
|
const insertAfter = insertAfterProp ?? autoId;
|
|
1959
2297
|
const [schedule, setSchedule] = useState2(null);
|
|
1960
|
-
const [loading, setLoading] = useState2(
|
|
2298
|
+
const [loading, setLoading] = useState2(initialScheduleId !== null);
|
|
1961
2299
|
const [inEditor, setInEditor] = useState2(false);
|
|
1962
2300
|
const [isHovered, setIsHovered] = useState2(false);
|
|
1963
2301
|
const [modalState, setModalState] = useState2(null);
|
|
@@ -2131,8 +2469,10 @@ function SchedulingWidget({ notifyOnConnect = false, initialScheduleId, insertAf
|
|
|
2131
2469
|
"*"
|
|
2132
2470
|
);
|
|
2133
2471
|
};
|
|
2134
|
-
if (!inEditor && !loading && !schedule) return null;
|
|
2135
2472
|
const sectionId = `scheduling-${insertAfter}`;
|
|
2473
|
+
if (!inEditor && !loading && !schedule) {
|
|
2474
|
+
return /* @__PURE__ */ jsx4("section", { "data-ohw-section": sectionId, "data-ohw-scheduling-anchor": insertAfter, style: { display: "none" } });
|
|
2475
|
+
}
|
|
2136
2476
|
return /* @__PURE__ */ jsxs3(
|
|
2137
2477
|
"section",
|
|
2138
2478
|
{
|
|
@@ -6086,6 +6426,7 @@ var FOCUS_RING = `0 0 0 4px color-mix(in srgb, ${PRIMARY} 12%, transparent)`;
|
|
|
6086
6426
|
var DRAG_SHADOW = "0px 4px 6px -1px rgba(0, 0, 0, 0.1), 0px 2px 4px -2px rgba(0, 0, 0, 0.1)";
|
|
6087
6427
|
var TOOLBAR_EDGE_MARGIN = 4;
|
|
6088
6428
|
var SELECTION_CHROME_GAP = 4;
|
|
6429
|
+
var HOVER_CHROME_GAP = 2;
|
|
6089
6430
|
var TOOLBAR_STROKE_GAP = 4;
|
|
6090
6431
|
function getChromeZIndex(state) {
|
|
6091
6432
|
switch (state) {
|
|
@@ -6241,10 +6582,11 @@ function ItemInteractionLayer({
|
|
|
6241
6582
|
onItemPointerDown,
|
|
6242
6583
|
onItemClick,
|
|
6243
6584
|
itemDragSurface = true,
|
|
6244
|
-
chromeGap
|
|
6585
|
+
chromeGap,
|
|
6245
6586
|
className
|
|
6246
6587
|
}) {
|
|
6247
6588
|
if (state === "default") return null;
|
|
6589
|
+
const gap = chromeGap ?? (state === "hover" ? HOVER_CHROME_GAP : SELECTION_CHROME_GAP);
|
|
6248
6590
|
const isActive = state === "active-top" || state === "active-bottom";
|
|
6249
6591
|
const isDragging = state === "dragging";
|
|
6250
6592
|
const showToolbar = isActive && toolbar;
|
|
@@ -6260,10 +6602,10 @@ function ItemInteractionLayer({
|
|
|
6260
6602
|
className: cn("pointer-events-none", className),
|
|
6261
6603
|
style: {
|
|
6262
6604
|
position: "fixed",
|
|
6263
|
-
top: rect.top -
|
|
6264
|
-
left: rect.left -
|
|
6265
|
-
width: rect.width +
|
|
6266
|
-
height: rect.height +
|
|
6605
|
+
top: rect.top - gap,
|
|
6606
|
+
left: rect.left - gap,
|
|
6607
|
+
width: rect.width + gap * 2,
|
|
6608
|
+
height: rect.height + gap * 2,
|
|
6267
6609
|
zIndex: getChromeZIndex(state)
|
|
6268
6610
|
},
|
|
6269
6611
|
children: [
|
|
@@ -6649,8 +6991,12 @@ function parseSectionsFromHtml(html) {
|
|
|
6649
6991
|
|
|
6650
6992
|
// src/ui/ai-section/AiSectionOverlay.tsx
|
|
6651
6993
|
import { Fragment as Fragment5, jsx as jsx16, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
6652
|
-
function
|
|
6653
|
-
const
|
|
6994
|
+
function findSectionElement(instanceId) {
|
|
6995
|
+
const escaped = CSS.escape(instanceId);
|
|
6996
|
+
return document.querySelector(`[data-ohw-instance="${escaped}"]`) ?? document.querySelector(`[data-ohw-section="${escaped}"]:not([data-ohw-instance])`);
|
|
6997
|
+
}
|
|
6998
|
+
function readRect(instanceId) {
|
|
6999
|
+
const el = findSectionElement(instanceId);
|
|
6654
7000
|
if (!el) return null;
|
|
6655
7001
|
const r2 = el.getBoundingClientRect();
|
|
6656
7002
|
if (r2.width <= 0 || r2.height <= 0) return null;
|
|
@@ -6673,7 +7019,7 @@ function useLiveSectionRect(sectionId) {
|
|
|
6673
7019
|
const opts = { capture: true, passive: true };
|
|
6674
7020
|
window.addEventListener("scroll", update, opts);
|
|
6675
7021
|
window.addEventListener("resize", update);
|
|
6676
|
-
const el =
|
|
7022
|
+
const el = findSectionElement(sectionId);
|
|
6677
7023
|
const ro = el ? new ResizeObserver(update) : null;
|
|
6678
7024
|
if (el && ro) ro.observe(el);
|
|
6679
7025
|
const interval = setInterval(update, 500);
|
|
@@ -6686,6 +7032,14 @@ function useLiveSectionRect(sectionId) {
|
|
|
6686
7032
|
}, [sectionId]);
|
|
6687
7033
|
return rect;
|
|
6688
7034
|
}
|
|
7035
|
+
function computeSectionBoundaryFlags(instanceId) {
|
|
7036
|
+
const topLevel = Array.from(document.querySelectorAll("[data-ohw-section]")).filter(
|
|
7037
|
+
(el) => !el.parentElement?.closest("[data-ohw-section]")
|
|
7038
|
+
);
|
|
7039
|
+
const index = topLevel.findIndex((el) => (el.dataset.ohwInstance ?? el.dataset.ohwSection) === instanceId);
|
|
7040
|
+
if (index === -1) return { isFirst: true, isLast: true };
|
|
7041
|
+
return { isFirst: index === 0, isLast: index === topLevel.length - 1 };
|
|
7042
|
+
}
|
|
6689
7043
|
var PRIMARY2 = "#0885FE";
|
|
6690
7044
|
function edgeAwareRadius(rect) {
|
|
6691
7045
|
const container = window.innerWidth <= 480 ? 16 : 24;
|
|
@@ -6767,7 +7121,7 @@ function AiSectionOverlay({
|
|
|
6767
7121
|
(el) => {
|
|
6768
7122
|
postToParent2({
|
|
6769
7123
|
type: "ow:section-selected",
|
|
6770
|
-
sectionId: el
|
|
7124
|
+
sectionId: el ? el.dataset.ohwInstance ?? el.dataset.ohwSection ?? null : null,
|
|
6771
7125
|
sectionLabel: el ? el.dataset.ohwSectionLabel ?? titleCaseSectionId(el.dataset.ohwSection ?? "") : null
|
|
6772
7126
|
});
|
|
6773
7127
|
},
|
|
@@ -6776,7 +7130,7 @@ function AiSectionOverlay({
|
|
|
6776
7130
|
const selectFromElement = useCallback2(
|
|
6777
7131
|
(el, options) => {
|
|
6778
7132
|
const sectionEl = el?.closest("[data-ohw-section]") ?? null;
|
|
6779
|
-
const id = sectionEl
|
|
7133
|
+
const id = sectionEl ? sectionEl.dataset.ohwInstance ?? sectionEl.dataset.ohwSection ?? null : null;
|
|
6780
7134
|
if (id === selectedIdRef.current) return;
|
|
6781
7135
|
setSelectedId(id);
|
|
6782
7136
|
if (options?.report !== false) report(sectionEl);
|
|
@@ -6819,7 +7173,7 @@ function AiSectionOverlay({
|
|
|
6819
7173
|
setReviewId(found ? sectionId : null);
|
|
6820
7174
|
postToParent2({ type: "ow:ai-review-started", sectionId, found });
|
|
6821
7175
|
if (found) {
|
|
6822
|
-
document.querySelector(`[data-ohw-
|
|
7176
|
+
document.querySelector(`[data-ohw-instance="${CSS.escape(sectionId)}"]`)?.scrollIntoView({ behavior: "smooth", block: "nearest" });
|
|
6823
7177
|
}
|
|
6824
7178
|
}
|
|
6825
7179
|
};
|
|
@@ -6838,7 +7192,7 @@ function AiSectionOverlay({
|
|
|
6838
7192
|
return;
|
|
6839
7193
|
}
|
|
6840
7194
|
const sec = t.closest("[data-ohw-section]");
|
|
6841
|
-
setHoveredId(sec
|
|
7195
|
+
setHoveredId(sec ? sec.dataset.ohwInstance ?? sec.dataset.ohwSection ?? null : null);
|
|
6842
7196
|
};
|
|
6843
7197
|
const onLeave = () => setHoveredId(null);
|
|
6844
7198
|
document.addEventListener("mousemove", onMove, { passive: true });
|
|
@@ -6870,9 +7224,29 @@ function AiSectionOverlay({
|
|
|
6870
7224
|
},
|
|
6871
7225
|
[postToParent2]
|
|
6872
7226
|
);
|
|
6873
|
-
const
|
|
7227
|
+
const activeSelectionId = reviewId ? null : selectedId;
|
|
7228
|
+
const selectionRect = useLiveSectionRect(activeSelectionId);
|
|
6874
7229
|
const reviewRect = useLiveSectionRect(reviewId);
|
|
6875
7230
|
const hoverRect = useLiveSectionRect(reviewId || hoveredId === selectedId ? null : hoveredId);
|
|
7231
|
+
useEffect4(() => {
|
|
7232
|
+
if (!activeSelectionId || !selectionRect) {
|
|
7233
|
+
postToParent2({ type: "ow:section-rect", instanceId: null, rect: null });
|
|
7234
|
+
return;
|
|
7235
|
+
}
|
|
7236
|
+
const { isFirst, isLast } = computeSectionBoundaryFlags(activeSelectionId);
|
|
7237
|
+
postToParent2({
|
|
7238
|
+
type: "ow:section-rect",
|
|
7239
|
+
instanceId: activeSelectionId,
|
|
7240
|
+
rect: {
|
|
7241
|
+
top: selectionRect.top + window.scrollY,
|
|
7242
|
+
left: selectionRect.left + window.scrollX,
|
|
7243
|
+
width: selectionRect.width,
|
|
7244
|
+
height: selectionRect.height
|
|
7245
|
+
},
|
|
7246
|
+
isFirst,
|
|
7247
|
+
isLast
|
|
7248
|
+
});
|
|
7249
|
+
}, [activeSelectionId, selectionRect, postToParent2]);
|
|
6876
7250
|
return /* @__PURE__ */ jsxs8(Fragment5, { children: [
|
|
6877
7251
|
hoverRect && /* @__PURE__ */ jsx16(
|
|
6878
7252
|
"div",
|
|
@@ -6923,7 +7297,10 @@ function AiSectionOverlay({
|
|
|
6923
7297
|
border: `2px solid ${PRIMARY2}`,
|
|
6924
7298
|
borderRadius: edgeAwareRadius(reviewRect),
|
|
6925
7299
|
zIndex: 2147483200,
|
|
6926
|
-
// The veil itself: swallows clicks so the section stays locked until decided.
|
|
7300
|
+
// The veil itself: swallows clicks so the section stays locked until decided. This
|
|
7301
|
+
// stopPropagation only guards the bubble phase; the bridge's capture-phase click
|
|
7302
|
+
// handlers additionally bail on `[data-ohw-ai-review]`, without which a click on
|
|
7303
|
+
// Accept/Discard resolves to the media beneath and opens the file picker.
|
|
6927
7304
|
background: "rgba(8, 133, 254, 0.04)",
|
|
6928
7305
|
pointerEvents: "auto",
|
|
6929
7306
|
cursor: "default"
|
|
@@ -9617,6 +9994,10 @@ function isSocialsRow(el) {
|
|
|
9617
9994
|
const anchors = Array.from(el.querySelectorAll("a"));
|
|
9618
9995
|
return anchors.length > 0 && anchors.every((anchor) => isSocialItem(anchor));
|
|
9619
9996
|
}
|
|
9997
|
+
var MAX_SOCIAL_ITEMS_PER_ROW = 7;
|
|
9998
|
+
function canAddSocialItem(row) {
|
|
9999
|
+
return listSocialItems(row).length < MAX_SOCIAL_ITEMS_PER_ROW;
|
|
10000
|
+
}
|
|
9620
10001
|
function listSocialItems(row) {
|
|
9621
10002
|
return Array.from(row.children).map((child) => {
|
|
9622
10003
|
if (!(child instanceof HTMLElement)) return null;
|
|
@@ -9976,6 +10357,7 @@ function ensureIconSlot(item) {
|
|
|
9976
10357
|
// src/lib/footer-items.ts
|
|
9977
10358
|
var FOOTER_ORDER_KEY = "__ohw_footer_order";
|
|
9978
10359
|
var MAX_FOOTER_COLUMNS = 18;
|
|
10360
|
+
var MAX_FOOTER_ITEMS_PER_COLUMN = 7;
|
|
9979
10361
|
var FOOTER_HREF_RE = /^footer-(\d+)-(\d+)-href$/;
|
|
9980
10362
|
function parseFooterHrefKey(key) {
|
|
9981
10363
|
if (!key) return null;
|
|
@@ -10193,6 +10575,13 @@ function getNextFooterColumnIndex() {
|
|
|
10193
10575
|
function canAddFooterColumn() {
|
|
10194
10576
|
return listFooterColumns().length < MAX_FOOTER_COLUMNS;
|
|
10195
10577
|
}
|
|
10578
|
+
function canAddFooterItem(column) {
|
|
10579
|
+
return listFooterLinksInColumn(column).length < MAX_FOOTER_ITEMS_PER_COLUMN;
|
|
10580
|
+
}
|
|
10581
|
+
function resolveFooterColumnForAdd(selected) {
|
|
10582
|
+
if (selected.hasAttribute("data-ohw-footer-col")) return selected;
|
|
10583
|
+
return selected.closest("[data-ohw-footer-col]") ?? (listFooterColumns().includes(selected) ? selected : null);
|
|
10584
|
+
}
|
|
10196
10585
|
function buildFooterHeading(colIndex, text) {
|
|
10197
10586
|
const heading = document.createElement("p");
|
|
10198
10587
|
heading.setAttribute("data-ohw-editable", "text");
|
|
@@ -10817,6 +11206,329 @@ function deleteFooterColumn(column) {
|
|
|
10817
11206
|
};
|
|
10818
11207
|
}
|
|
10819
11208
|
|
|
11209
|
+
// src/lib/logo-identity.ts
|
|
11210
|
+
var LOGO_TEXT_KEYS = ["nav-logo-text", "footer-logo-text", "logo-text"];
|
|
11211
|
+
var LOGO_IMAGE_KEYS = ["nav-logo-image", "footer-logo", "footer-logo-image"];
|
|
11212
|
+
var LOGO_HREF_KEYS = ["nav-logo-href", "footer-logo-href", "logo-href"];
|
|
11213
|
+
var LOGO_PLACEHOLDER_KEY = "logo-is-placeholder";
|
|
11214
|
+
var LOGO_ALT_KEY = "logo-alt";
|
|
11215
|
+
var LOGO_IMAGE_URL_KEY = "nav-logo-image";
|
|
11216
|
+
var PLACEHOLDER_BUSINESS_NAME = "Business name";
|
|
11217
|
+
function resolveLogoDisplayText(text) {
|
|
11218
|
+
const trimmed = (text ?? "").trim();
|
|
11219
|
+
return trimmed || PLACEHOLDER_BUSINESS_NAME;
|
|
11220
|
+
}
|
|
11221
|
+
function isFooterLogoRoot(root) {
|
|
11222
|
+
return Boolean(root.closest("footer") || root.closest('[data-ohw-section="footer"]'));
|
|
11223
|
+
}
|
|
11224
|
+
function imageKeyForRoot(root) {
|
|
11225
|
+
return isFooterLogoRoot(root) ? "footer-logo" : "nav-logo-image";
|
|
11226
|
+
}
|
|
11227
|
+
function textKeyForRoot(root) {
|
|
11228
|
+
return isFooterLogoRoot(root) ? "footer-logo-text" : "nav-logo-text";
|
|
11229
|
+
}
|
|
11230
|
+
function ensureLogoHrefKey(root) {
|
|
11231
|
+
if (!(root instanceof HTMLAnchorElement)) return;
|
|
11232
|
+
if (root.hasAttribute("data-ohw-href-key")) return;
|
|
11233
|
+
root.setAttribute("data-ohw-href-key", isFooterLogoRoot(root) ? "footer-logo-href" : "nav-logo-href");
|
|
11234
|
+
}
|
|
11235
|
+
function applyLogoIdentity(text, isPlaceholder) {
|
|
11236
|
+
const display = resolveLogoDisplayText(text);
|
|
11237
|
+
const placeholder = isPlaceholder || !text.trim() || display === PLACEHOLDER_BUSINESS_NAME;
|
|
11238
|
+
for (const key of LOGO_TEXT_KEYS) {
|
|
11239
|
+
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
11240
|
+
if (el.textContent !== display) el.textContent = display;
|
|
11241
|
+
});
|
|
11242
|
+
}
|
|
11243
|
+
for (const key of LOGO_IMAGE_KEYS) {
|
|
11244
|
+
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
11245
|
+
const img = el instanceof HTMLImageElement ? el : el.querySelector("img");
|
|
11246
|
+
if (img) img.alt = display;
|
|
11247
|
+
});
|
|
11248
|
+
}
|
|
11249
|
+
document.querySelectorAll('[data-ohw-role="logo"], [data-ohw-logo]').forEach((el) => {
|
|
11250
|
+
if (placeholder) el.setAttribute("data-ohw-placeholder", "");
|
|
11251
|
+
else el.removeAttribute("data-ohw-placeholder");
|
|
11252
|
+
});
|
|
11253
|
+
return display;
|
|
11254
|
+
}
|
|
11255
|
+
function applyLogoImage(url, alt) {
|
|
11256
|
+
const displayAlt = resolveLogoDisplayText(alt);
|
|
11257
|
+
document.querySelectorAll('[data-ohw-role="logo"], [data-ohw-logo]').forEach((root) => {
|
|
11258
|
+
ensureLogoHrefKey(root);
|
|
11259
|
+
const imageKey = imageKeyForRoot(root);
|
|
11260
|
+
const textKey = textKeyForRoot(root);
|
|
11261
|
+
let img = root.querySelector(`img[data-ohw-key="${imageKey}"]`) ?? (root.querySelector(`[data-ohw-key="${imageKey}"]`) instanceof HTMLImageElement ? root.querySelector(`[data-ohw-key="${imageKey}"]`) : null) ?? root.querySelector("img");
|
|
11262
|
+
let textEl = root.querySelector(`[data-ohw-key="${textKey}"]`) ?? root.querySelector('[data-ohw-key="logo-text"]');
|
|
11263
|
+
if (url) {
|
|
11264
|
+
if (!img) {
|
|
11265
|
+
img = document.createElement("img");
|
|
11266
|
+
img.setAttribute("data-ohw-editable", "image");
|
|
11267
|
+
img.setAttribute("data-ohw-key", imageKey);
|
|
11268
|
+
img.alt = displayAlt;
|
|
11269
|
+
img.style.height = "";
|
|
11270
|
+
img.style.maxHeight = "none";
|
|
11271
|
+
img.style.width = "auto";
|
|
11272
|
+
img.style.display = "block";
|
|
11273
|
+
img.style.objectFit = "contain";
|
|
11274
|
+
root.insertBefore(img, root.firstChild);
|
|
11275
|
+
} else {
|
|
11276
|
+
img.setAttribute("data-ohw-editable", "image");
|
|
11277
|
+
img.setAttribute("data-ohw-key", imageKey);
|
|
11278
|
+
}
|
|
11279
|
+
img.removeAttribute("srcset");
|
|
11280
|
+
img.removeAttribute("sizes");
|
|
11281
|
+
img.src = url;
|
|
11282
|
+
img.alt = displayAlt;
|
|
11283
|
+
img.style.display = "block";
|
|
11284
|
+
if (textEl) textEl.style.display = "none";
|
|
11285
|
+
root.removeAttribute("data-ohw-placeholder");
|
|
11286
|
+
return;
|
|
11287
|
+
}
|
|
11288
|
+
if (img) {
|
|
11289
|
+
img.removeAttribute("src");
|
|
11290
|
+
img.removeAttribute("srcset");
|
|
11291
|
+
img.removeAttribute("sizes");
|
|
11292
|
+
img.alt = displayAlt;
|
|
11293
|
+
img.style.display = "none";
|
|
11294
|
+
}
|
|
11295
|
+
if (!textEl) {
|
|
11296
|
+
textEl = document.createElement("span");
|
|
11297
|
+
textEl.setAttribute("data-ohw-editable", "plain");
|
|
11298
|
+
textEl.setAttribute("data-ohw-key", textKey);
|
|
11299
|
+
root.appendChild(textEl);
|
|
11300
|
+
}
|
|
11301
|
+
textEl.style.display = "";
|
|
11302
|
+
if (textEl.textContent !== displayAlt) textEl.textContent = displayAlt;
|
|
11303
|
+
if (!displayAlt.trim() || displayAlt === PLACEHOLDER_BUSINESS_NAME) {
|
|
11304
|
+
root.setAttribute("data-ohw-placeholder", "");
|
|
11305
|
+
} else {
|
|
11306
|
+
root.removeAttribute("data-ohw-placeholder");
|
|
11307
|
+
}
|
|
11308
|
+
});
|
|
11309
|
+
}
|
|
11310
|
+
function applyLogoHref(href) {
|
|
11311
|
+
const target = href.trim() || "/";
|
|
11312
|
+
document.querySelectorAll('[data-ohw-role="logo"], [data-ohw-logo]').forEach((root) => {
|
|
11313
|
+
ensureLogoHrefKey(root);
|
|
11314
|
+
if (root instanceof HTMLAnchorElement) {
|
|
11315
|
+
root.setAttribute("href", target);
|
|
11316
|
+
}
|
|
11317
|
+
});
|
|
11318
|
+
for (const key of LOGO_HREF_KEYS) setStoredLinkHref(key, target);
|
|
11319
|
+
}
|
|
11320
|
+
function readLogoIdentityFromDom() {
|
|
11321
|
+
let imageUrl = null;
|
|
11322
|
+
for (const key of LOGO_IMAGE_KEYS) {
|
|
11323
|
+
const el = document.querySelector(`[data-ohw-key="${key}"]`);
|
|
11324
|
+
const img = el instanceof HTMLImageElement ? el : el?.querySelector("img");
|
|
11325
|
+
const attrSrc = img?.getAttribute("src")?.trim() ?? "";
|
|
11326
|
+
if (attrSrc && !attrSrc.startsWith("data:") && img && img.style.display !== "none") {
|
|
11327
|
+
imageUrl = img.currentSrc || img.src;
|
|
11328
|
+
break;
|
|
11329
|
+
}
|
|
11330
|
+
}
|
|
11331
|
+
let text = PLACEHOLDER_BUSINESS_NAME;
|
|
11332
|
+
let isPlaceholder = true;
|
|
11333
|
+
for (const key of LOGO_TEXT_KEYS) {
|
|
11334
|
+
const el = document.querySelector(`[data-ohw-key="${key}"]`);
|
|
11335
|
+
if (el?.textContent?.trim()) {
|
|
11336
|
+
text = el.textContent.trim();
|
|
11337
|
+
const logoRoot2 = el.closest('[data-ohw-role="logo"], [data-ohw-logo]');
|
|
11338
|
+
isPlaceholder = logoRoot2?.hasAttribute("data-ohw-placeholder") === true || text === PLACEHOLDER_BUSINESS_NAME;
|
|
11339
|
+
break;
|
|
11340
|
+
}
|
|
11341
|
+
}
|
|
11342
|
+
if (imageUrl) {
|
|
11343
|
+
const logoImg = document.querySelector(
|
|
11344
|
+
'[data-ohw-key="nav-logo-image"], [data-ohw-key="footer-logo"]'
|
|
11345
|
+
);
|
|
11346
|
+
const alt = logoImg?.alt?.trim() || text;
|
|
11347
|
+
isPlaceholder = false;
|
|
11348
|
+
const hrefEl = document.querySelector(
|
|
11349
|
+
'a[data-ohw-role="logo"], a[data-ohw-logo], [data-ohw-role="logo"]'
|
|
11350
|
+
);
|
|
11351
|
+
const href2 = (hrefEl instanceof HTMLAnchorElement ? hrefEl.getAttribute("href") : null) || hrefEl?.closest("a")?.getAttribute("href") || "/";
|
|
11352
|
+
return { text, isPlaceholder, imageUrl, href: href2, alt };
|
|
11353
|
+
}
|
|
11354
|
+
const logoRoot = document.querySelector('[data-ohw-role="logo"], [data-ohw-logo]');
|
|
11355
|
+
const href = (logoRoot instanceof HTMLAnchorElement ? logoRoot.getAttribute("href") : null) || logoRoot?.closest("a")?.getAttribute("href") || "/";
|
|
11356
|
+
return { text, isPlaceholder, imageUrl: null, href, alt: text };
|
|
11357
|
+
}
|
|
11358
|
+
function applyLogoFromContent(content) {
|
|
11359
|
+
const hasLogoIdentity = LOGO_PLACEHOLDER_KEY in content || LOGO_TEXT_KEYS.some((key) => key in content) || LOGO_IMAGE_KEYS.some((key) => key in content) || LOGO_ALT_KEY in content || LOGO_HREF_KEYS.some((key) => key in content);
|
|
11360
|
+
if (!hasLogoIdentity) return false;
|
|
11361
|
+
const logoText = content[LOGO_TEXT_KEYS[0]] ?? content[LOGO_TEXT_KEYS[1]] ?? readLogoIdentityFromDom().text;
|
|
11362
|
+
const logoAlt = content[LOGO_ALT_KEY] ?? logoText;
|
|
11363
|
+
const rawLogoImage = content[LOGO_IMAGE_URL_KEY] ?? content["footer-logo"] ?? content["footer-logo-image"] ?? null;
|
|
11364
|
+
const logoImageUrl = typeof rawLogoImage === "string" && rawLogoImage.trim() ? rawLogoImage.trim() : null;
|
|
11365
|
+
const imageExplicitlyCleared = LOGO_IMAGE_KEYS.some((key) => key in content) && !logoImageUrl;
|
|
11366
|
+
const logoIsPlaceholder = LOGO_PLACEHOLDER_KEY in content ? content[LOGO_PLACEHOLDER_KEY] !== "false" : !logoImageUrl && (!logoText.trim() || logoText === PLACEHOLDER_BUSINESS_NAME);
|
|
11367
|
+
if (logoImageUrl) {
|
|
11368
|
+
applyLogoImage(logoImageUrl, logoAlt);
|
|
11369
|
+
} else {
|
|
11370
|
+
if (imageExplicitlyCleared) applyLogoImage(null, logoAlt);
|
|
11371
|
+
applyLogoIdentity(logoText, logoIsPlaceholder);
|
|
11372
|
+
}
|
|
11373
|
+
const logoHref = content["nav-logo-href"] ?? content["footer-logo-href"] ?? content["logo-href"];
|
|
11374
|
+
if (typeof logoHref === "string" && logoHref.trim()) {
|
|
11375
|
+
applyLogoHref(logoHref);
|
|
11376
|
+
}
|
|
11377
|
+
return true;
|
|
11378
|
+
}
|
|
11379
|
+
|
|
11380
|
+
// src/lib/logo-size.ts
|
|
11381
|
+
var LOGO_SIZE_DEFAULTS = {
|
|
11382
|
+
navbar: 28,
|
|
11383
|
+
footer: 32
|
|
11384
|
+
};
|
|
11385
|
+
var LOGO_SIZE_MIN = 16;
|
|
11386
|
+
var LOGO_SIZE_MAX = 80;
|
|
11387
|
+
var LOGO_SIZE_DESKTOP_KEYS = {
|
|
11388
|
+
navbar: "nav-logo-size",
|
|
11389
|
+
footer: "footer-logo-size"
|
|
11390
|
+
};
|
|
11391
|
+
var LOGO_SIZE_MOBILE_KEYS = {
|
|
11392
|
+
navbar: "nav-logo-size-mobile",
|
|
11393
|
+
footer: "footer-logo-size-mobile"
|
|
11394
|
+
};
|
|
11395
|
+
var LOGO_SIZE_KEYS = [
|
|
11396
|
+
LOGO_SIZE_DESKTOP_KEYS.navbar,
|
|
11397
|
+
LOGO_SIZE_DESKTOP_KEYS.footer,
|
|
11398
|
+
LOGO_SIZE_MOBILE_KEYS.navbar,
|
|
11399
|
+
LOGO_SIZE_MOBILE_KEYS.footer
|
|
11400
|
+
];
|
|
11401
|
+
function isFooterLogoRoot2(root) {
|
|
11402
|
+
return Boolean(root.closest("footer") || root.closest('[data-ohw-section="footer"]'));
|
|
11403
|
+
}
|
|
11404
|
+
function getLogoPlacement(root) {
|
|
11405
|
+
return isFooterLogoRoot2(root) ? "footer" : "navbar";
|
|
11406
|
+
}
|
|
11407
|
+
function parseLogoSizePx(raw, fallback) {
|
|
11408
|
+
if (raw == null || raw === "") return fallback;
|
|
11409
|
+
const n = Number.parseFloat(raw);
|
|
11410
|
+
if (!Number.isFinite(n)) return fallback;
|
|
11411
|
+
return Math.min(LOGO_SIZE_MAX, Math.max(LOGO_SIZE_MIN, Math.round(n)));
|
|
11412
|
+
}
|
|
11413
|
+
function isMobileLogoSizeFollowing(content, placement) {
|
|
11414
|
+
const raw = content[LOGO_SIZE_MOBILE_KEYS[placement]];
|
|
11415
|
+
return raw == null || raw.trim() === "";
|
|
11416
|
+
}
|
|
11417
|
+
function resolveDesktopLogoSize(content, placement) {
|
|
11418
|
+
return parseLogoSizePx(content[LOGO_SIZE_DESKTOP_KEYS[placement]], LOGO_SIZE_DEFAULTS[placement]);
|
|
11419
|
+
}
|
|
11420
|
+
function resolveMobileLogoSize(content, placement) {
|
|
11421
|
+
if (isMobileLogoSizeFollowing(content, placement)) {
|
|
11422
|
+
return resolveDesktopLogoSize(content, placement);
|
|
11423
|
+
}
|
|
11424
|
+
return parseLogoSizePx(
|
|
11425
|
+
content[LOGO_SIZE_MOBILE_KEYS[placement]],
|
|
11426
|
+
resolveDesktopLogoSize(content, placement)
|
|
11427
|
+
);
|
|
11428
|
+
}
|
|
11429
|
+
function setRootSizeVars(root, desktopPx, mobilePx, following) {
|
|
11430
|
+
root.style.setProperty("--ohw-logo-size", `${desktopPx}px`);
|
|
11431
|
+
if (following) {
|
|
11432
|
+
root.style.removeProperty("--ohw-logo-size-mobile");
|
|
11433
|
+
} else {
|
|
11434
|
+
root.style.setProperty("--ohw-logo-size-mobile", `${mobilePx}px`);
|
|
11435
|
+
}
|
|
11436
|
+
root.querySelectorAll("img").forEach((img) => {
|
|
11437
|
+
img.style.height = "";
|
|
11438
|
+
img.style.maxHeight = "none";
|
|
11439
|
+
img.style.width = "auto";
|
|
11440
|
+
img.style.objectFit = "contain";
|
|
11441
|
+
});
|
|
11442
|
+
}
|
|
11443
|
+
function applyLogoSizes(content) {
|
|
11444
|
+
document.querySelectorAll('[data-ohw-role="logo"], [data-ohw-logo]').forEach((root) => {
|
|
11445
|
+
const placement = getLogoPlacement(root);
|
|
11446
|
+
const desktop = resolveDesktopLogoSize(content, placement);
|
|
11447
|
+
const following = isMobileLogoSizeFollowing(content, placement);
|
|
11448
|
+
const mobile = following ? desktop : resolveMobileLogoSize(content, placement);
|
|
11449
|
+
setRootSizeVars(root, desktop, mobile, following);
|
|
11450
|
+
});
|
|
11451
|
+
}
|
|
11452
|
+
function applyLogoSizeToPlacement(placement, desktopPx, mobilePx, following) {
|
|
11453
|
+
document.querySelectorAll('[data-ohw-role="logo"], [data-ohw-logo]').forEach((root) => {
|
|
11454
|
+
if (getLogoPlacement(root) !== placement) return;
|
|
11455
|
+
setRootSizeVars(root, desktopPx, mobilePx, following);
|
|
11456
|
+
});
|
|
11457
|
+
}
|
|
11458
|
+
function logoHasUploadedImage(logoEl) {
|
|
11459
|
+
if (logoEl.hasAttribute("data-ohw-placeholder")) return false;
|
|
11460
|
+
const img = logoEl.querySelector('img[data-ohw-key="nav-logo-image"], img[data-ohw-key="footer-logo"], img[data-ohw-key="footer-logo-image"]') ?? logoEl.querySelector("img");
|
|
11461
|
+
if (!img) return false;
|
|
11462
|
+
const src = img.getAttribute("src")?.trim() ?? "";
|
|
11463
|
+
if (!src || src.startsWith("data:")) return false;
|
|
11464
|
+
if (img.style.display === "none") return false;
|
|
11465
|
+
return true;
|
|
11466
|
+
}
|
|
11467
|
+
function getLogoInteractionRect(logoEl) {
|
|
11468
|
+
if (logoHasUploadedImage(logoEl)) {
|
|
11469
|
+
const img = logoEl.querySelector('img[data-ohw-key="nav-logo-image"], img[data-ohw-key="footer-logo"], img[data-ohw-key="footer-logo-image"]') ?? logoEl.querySelector("img");
|
|
11470
|
+
if (img) {
|
|
11471
|
+
const r2 = img.getBoundingClientRect();
|
|
11472
|
+
if (r2.width > 0 && r2.height > 0) return r2;
|
|
11473
|
+
}
|
|
11474
|
+
}
|
|
11475
|
+
const text = logoEl.querySelector(
|
|
11476
|
+
'[data-ohw-key="nav-logo-text"], [data-ohw-key="footer-logo-text"]'
|
|
11477
|
+
);
|
|
11478
|
+
if (text) {
|
|
11479
|
+
const style = window.getComputedStyle(text);
|
|
11480
|
+
if (style.display !== "none" && style.visibility !== "hidden") {
|
|
11481
|
+
const r2 = text.getBoundingClientRect();
|
|
11482
|
+
if (r2.width > 0 && r2.height > 0) return r2;
|
|
11483
|
+
}
|
|
11484
|
+
}
|
|
11485
|
+
return logoEl.getBoundingClientRect();
|
|
11486
|
+
}
|
|
11487
|
+
function readLogoSizeState(content, placement) {
|
|
11488
|
+
const desktopPx = resolveDesktopLogoSize(content, placement);
|
|
11489
|
+
const mobileFollowing = isMobileLogoSizeFollowing(content, placement);
|
|
11490
|
+
const mobilePx = mobileFollowing ? desktopPx : resolveMobileLogoSize(content, placement);
|
|
11491
|
+
return { desktopPx, mobilePx, mobileFollowing };
|
|
11492
|
+
}
|
|
11493
|
+
|
|
11494
|
+
// src/lib/site-wide-scope.ts
|
|
11495
|
+
function getLogoElement(el) {
|
|
11496
|
+
const marked = el.closest('[data-ohw-role="logo"], [data-ohw-logo]');
|
|
11497
|
+
if (marked) return marked;
|
|
11498
|
+
if (el.closest('[data-ohw-editable="icon"]')) return null;
|
|
11499
|
+
const root = el.closest("nav, [data-ohw-nav-root], footer");
|
|
11500
|
+
if (!root) return null;
|
|
11501
|
+
const anchor = el.closest("a");
|
|
11502
|
+
if (anchor && root.contains(anchor) && !anchor.hasAttribute("data-ohw-href-key") && !anchor.closest("[data-ohw-nav-container]") && Boolean(anchor.querySelector("img") || anchor.matches("img"))) {
|
|
11503
|
+
return anchor;
|
|
11504
|
+
}
|
|
11505
|
+
const img = el.matches("img") ? el : null;
|
|
11506
|
+
if (img && !img.closest("[data-ohw-href-key]") && !img.closest("[data-ohw-nav-container]") && (img.closest("footer") || img.closest("nav, [data-ohw-nav-root]"))) {
|
|
11507
|
+
return img;
|
|
11508
|
+
}
|
|
11509
|
+
return null;
|
|
11510
|
+
}
|
|
11511
|
+
function isInFooter(el) {
|
|
11512
|
+
if (!el) return false;
|
|
11513
|
+
return Boolean(el.closest("footer") || el.closest('[data-ohw-section="footer"]'));
|
|
11514
|
+
}
|
|
11515
|
+
function isSiteWideElement(el) {
|
|
11516
|
+
if (!el) return false;
|
|
11517
|
+
if (getLogoElement(el)) return true;
|
|
11518
|
+
if (isInFooter(el)) return true;
|
|
11519
|
+
if (el.hasAttribute("data-ohw-nav-container") || el.hasAttribute("data-ohw-nav-root")) {
|
|
11520
|
+
return true;
|
|
11521
|
+
}
|
|
11522
|
+
if (el.hasAttribute("data-ohw-href-key") && el.closest("nav, [data-ohw-nav-root], [data-ohw-nav-drawer], aside")) {
|
|
11523
|
+
return true;
|
|
11524
|
+
}
|
|
11525
|
+
if (el.closest('[data-ohw-role="navbar-button"]')) return true;
|
|
11526
|
+
return false;
|
|
11527
|
+
}
|
|
11528
|
+
function isSiteWideScopeActive(args) {
|
|
11529
|
+
return isSiteWideElement(args.selected) || isSiteWideElement(args.hoveredItem) || isSiteWideElement(args.hoveredNavContainer) || isSiteWideElement(args.active);
|
|
11530
|
+
}
|
|
11531
|
+
|
|
10820
11532
|
// src/lib/add-footer-column.ts
|
|
10821
11533
|
function buildFooterColumnEditContentPatch(result) {
|
|
10822
11534
|
return {
|
|
@@ -10928,6 +11640,7 @@ function FloatingPanel({
|
|
|
10928
11640
|
e.stopPropagation();
|
|
10929
11641
|
const el = e.currentTarget;
|
|
10930
11642
|
el.setPointerCapture(e.pointerId);
|
|
11643
|
+
document.documentElement.setAttribute("data-ohw-panel-dragging", "");
|
|
10931
11644
|
dragRef.current = {
|
|
10932
11645
|
pointerId: e.pointerId,
|
|
10933
11646
|
startX: e.clientX,
|
|
@@ -10960,11 +11673,17 @@ function FloatingPanel({
|
|
|
10960
11673
|
const drag = dragRef.current;
|
|
10961
11674
|
if (!drag || drag.pointerId !== e.pointerId) return;
|
|
10962
11675
|
dragRef.current = null;
|
|
11676
|
+
document.documentElement.removeAttribute("data-ohw-panel-dragging");
|
|
10963
11677
|
try {
|
|
10964
11678
|
e.currentTarget.releasePointerCapture(e.pointerId);
|
|
10965
11679
|
} catch {
|
|
10966
11680
|
}
|
|
10967
11681
|
}, []);
|
|
11682
|
+
useEffect9(() => {
|
|
11683
|
+
if (open) return;
|
|
11684
|
+
document.documentElement.removeAttribute("data-ohw-panel-dragging");
|
|
11685
|
+
}, [open]);
|
|
11686
|
+
useEffect9(() => () => document.documentElement.removeAttribute("data-ohw-panel-dragging"), []);
|
|
10968
11687
|
if (!open) return null;
|
|
10969
11688
|
return /* @__PURE__ */ jsxs16(
|
|
10970
11689
|
"div",
|
|
@@ -11031,16 +11750,127 @@ function FloatingPanel({
|
|
|
11031
11750
|
);
|
|
11032
11751
|
}
|
|
11033
11752
|
|
|
11034
|
-
// src/ui/
|
|
11753
|
+
// src/ui/logo-size-panel.tsx
|
|
11754
|
+
import { ArrowUpRight, Link as Link2 } from "lucide-react";
|
|
11035
11755
|
import { jsx as jsx27, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
11756
|
+
function SizeSlider({
|
|
11757
|
+
value,
|
|
11758
|
+
onChange
|
|
11759
|
+
}) {
|
|
11760
|
+
const pct = (value - LOGO_SIZE_MIN) / (LOGO_SIZE_MAX - LOGO_SIZE_MIN) * 100;
|
|
11761
|
+
return /* @__PURE__ */ jsxs17("div", { className: "flex w-full flex-col gap-3", children: [
|
|
11762
|
+
/* @__PURE__ */ jsxs17("div", { className: "flex w-full items-center gap-2 text-sm font-medium leading-5", children: [
|
|
11763
|
+
/* @__PURE__ */ jsx27("span", { className: "min-w-0 flex-1 text-foreground", children: "Size" }),
|
|
11764
|
+
/* @__PURE__ */ jsxs17("span", { className: "shrink-0 whitespace-nowrap text-muted-foreground", children: [
|
|
11765
|
+
value,
|
|
11766
|
+
" px"
|
|
11767
|
+
] })
|
|
11768
|
+
] }),
|
|
11769
|
+
/* @__PURE__ */ jsxs17("div", { className: "relative h-2 w-full rounded-full bg-primary-50", children: [
|
|
11770
|
+
/* @__PURE__ */ jsx27(
|
|
11771
|
+
"div",
|
|
11772
|
+
{
|
|
11773
|
+
className: "absolute inset-y-0 left-0 rounded-full bg-primary",
|
|
11774
|
+
style: { width: `${pct}%` }
|
|
11775
|
+
}
|
|
11776
|
+
),
|
|
11777
|
+
/* @__PURE__ */ jsx27(
|
|
11778
|
+
"input",
|
|
11779
|
+
{
|
|
11780
|
+
type: "range",
|
|
11781
|
+
min: LOGO_SIZE_MIN,
|
|
11782
|
+
max: LOGO_SIZE_MAX,
|
|
11783
|
+
step: 1,
|
|
11784
|
+
value,
|
|
11785
|
+
"aria-label": "Logo size",
|
|
11786
|
+
className: cn(
|
|
11787
|
+
"absolute inset-0 h-full w-full cursor-pointer appearance-none bg-transparent",
|
|
11788
|
+
"[&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:size-5",
|
|
11789
|
+
"[&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:border-2",
|
|
11790
|
+
"[&::-webkit-slider-thumb]:border-primary [&::-webkit-slider-thumb]:bg-background",
|
|
11791
|
+
"[&::-moz-range-thumb]:size-5 [&::-moz-range-thumb]:rounded-full",
|
|
11792
|
+
"[&::-moz-range-thumb]:border-2 [&::-moz-range-thumb]:border-primary",
|
|
11793
|
+
"[&::-moz-range-thumb]:bg-background"
|
|
11794
|
+
),
|
|
11795
|
+
onChange: (e) => onChange(Number(e.target.value))
|
|
11796
|
+
}
|
|
11797
|
+
)
|
|
11798
|
+
] })
|
|
11799
|
+
] });
|
|
11800
|
+
}
|
|
11801
|
+
function LogoSizePanel({
|
|
11802
|
+
viewport,
|
|
11803
|
+
sizePx,
|
|
11804
|
+
mobileFollowing = true,
|
|
11805
|
+
onSizeChange,
|
|
11806
|
+
onCustomizeMobile,
|
|
11807
|
+
onResetMobile,
|
|
11808
|
+
onUpdateEverywhere,
|
|
11809
|
+
className
|
|
11810
|
+
}) {
|
|
11811
|
+
const showFollowing = viewport === "mobile" && mobileFollowing;
|
|
11812
|
+
const showMobileSlider = viewport === "mobile" && !mobileFollowing;
|
|
11813
|
+
const showDesktopSlider = viewport === "desktop";
|
|
11814
|
+
return /* @__PURE__ */ jsxs17("div", { className: cn("flex w-full flex-col gap-4", className), children: [
|
|
11815
|
+
showFollowing ? /* @__PURE__ */ jsxs17("div", { className: "flex w-full flex-col gap-2", children: [
|
|
11816
|
+
/* @__PURE__ */ jsxs17("div", { className: "flex items-start gap-1", children: [
|
|
11817
|
+
/* @__PURE__ */ jsx27(Link2, { size: 16, className: "mt-0.5 shrink-0 text-foreground", "aria-hidden": true }),
|
|
11818
|
+
/* @__PURE__ */ jsx27("p", { className: "text-sm font-semibold leading-5 text-foreground", children: "Following desktop size" })
|
|
11819
|
+
] }),
|
|
11820
|
+
/* @__PURE__ */ jsx27("p", { className: "text-sm leading-5 text-muted-foreground", children: "Mobile uses the desktop size until you customize it. Change the desktop size and it follows automatically." }),
|
|
11821
|
+
/* @__PURE__ */ jsx27(
|
|
11822
|
+
Button,
|
|
11823
|
+
{
|
|
11824
|
+
type: "button",
|
|
11825
|
+
variant: "outline",
|
|
11826
|
+
size: "sm",
|
|
11827
|
+
className: "h-9 w-full min-w-0 cursor-pointer",
|
|
11828
|
+
onClick: onCustomizeMobile,
|
|
11829
|
+
children: "Customize for mobile"
|
|
11830
|
+
}
|
|
11831
|
+
)
|
|
11832
|
+
] }) : null,
|
|
11833
|
+
showDesktopSlider || showMobileSlider ? /* @__PURE__ */ jsx27(SizeSlider, { value: sizePx, onChange: onSizeChange }) : null,
|
|
11834
|
+
showMobileSlider ? /* @__PURE__ */ jsx27(
|
|
11835
|
+
Button,
|
|
11836
|
+
{
|
|
11837
|
+
type: "button",
|
|
11838
|
+
variant: "outline",
|
|
11839
|
+
size: "sm",
|
|
11840
|
+
className: "h-9 w-full min-w-0 cursor-pointer",
|
|
11841
|
+
onClick: onResetMobile,
|
|
11842
|
+
children: "Reset to desktop size"
|
|
11843
|
+
}
|
|
11844
|
+
) : null,
|
|
11845
|
+
/* @__PURE__ */ jsx27("div", { className: "h-px w-full bg-border", role: "separator" }),
|
|
11846
|
+
/* @__PURE__ */ jsxs17(
|
|
11847
|
+
Button,
|
|
11848
|
+
{
|
|
11849
|
+
type: "button",
|
|
11850
|
+
variant: "outline",
|
|
11851
|
+
size: "sm",
|
|
11852
|
+
className: "h-9 w-full min-w-0 cursor-pointer gap-1",
|
|
11853
|
+
onClick: onUpdateEverywhere,
|
|
11854
|
+
children: [
|
|
11855
|
+
"Update logo everywhere",
|
|
11856
|
+
/* @__PURE__ */ jsx27(ArrowUpRight, { size: 16, "aria-hidden": true })
|
|
11857
|
+
]
|
|
11858
|
+
}
|
|
11859
|
+
),
|
|
11860
|
+
/* @__PURE__ */ jsx27("p", { className: "text-sm leading-5 text-muted-foreground", children: "Matches the right version to your background." })
|
|
11861
|
+
] });
|
|
11862
|
+
}
|
|
11863
|
+
|
|
11864
|
+
// src/ui/socials-display-panel.tsx
|
|
11865
|
+
import { jsx as jsx28, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
11036
11866
|
function DisplaySwitch({
|
|
11037
11867
|
label,
|
|
11038
11868
|
checked,
|
|
11039
11869
|
disabled,
|
|
11040
11870
|
onChange
|
|
11041
11871
|
}) {
|
|
11042
|
-
return /* @__PURE__ */
|
|
11043
|
-
/* @__PURE__ */
|
|
11872
|
+
return /* @__PURE__ */ jsxs18("div", { className: "flex w-full items-center gap-2", children: [
|
|
11873
|
+
/* @__PURE__ */ jsx28(
|
|
11044
11874
|
"span",
|
|
11045
11875
|
{
|
|
11046
11876
|
className: cn(
|
|
@@ -11050,7 +11880,7 @@ function DisplaySwitch({
|
|
|
11050
11880
|
children: label
|
|
11051
11881
|
}
|
|
11052
11882
|
),
|
|
11053
|
-
/* @__PURE__ */
|
|
11883
|
+
/* @__PURE__ */ jsx28(
|
|
11054
11884
|
"button",
|
|
11055
11885
|
{
|
|
11056
11886
|
type: "button",
|
|
@@ -11064,7 +11894,7 @@ function DisplaySwitch({
|
|
|
11064
11894
|
checked ? "bg-primary" : "bg-primary-50",
|
|
11065
11895
|
disabled ? "cursor-default opacity-50" : "cursor-pointer"
|
|
11066
11896
|
),
|
|
11067
|
-
children: /* @__PURE__ */
|
|
11897
|
+
children: /* @__PURE__ */ jsx28(
|
|
11068
11898
|
"span",
|
|
11069
11899
|
{
|
|
11070
11900
|
className: cn(
|
|
@@ -11078,8 +11908,8 @@ function DisplaySwitch({
|
|
|
11078
11908
|
] });
|
|
11079
11909
|
}
|
|
11080
11910
|
function SocialsDisplayPanel({ display, onChange, className }) {
|
|
11081
|
-
return /* @__PURE__ */
|
|
11082
|
-
/* @__PURE__ */
|
|
11911
|
+
return /* @__PURE__ */ jsxs18("div", { className: cn("flex w-full flex-col gap-3", className), children: [
|
|
11912
|
+
/* @__PURE__ */ jsx28(
|
|
11083
11913
|
DisplaySwitch,
|
|
11084
11914
|
{
|
|
11085
11915
|
label: "Text",
|
|
@@ -11088,7 +11918,7 @@ function SocialsDisplayPanel({ display, onChange, className }) {
|
|
|
11088
11918
|
onChange: (text) => onChange({ ...display, text })
|
|
11089
11919
|
}
|
|
11090
11920
|
),
|
|
11091
|
-
/* @__PURE__ */
|
|
11921
|
+
/* @__PURE__ */ jsx28(
|
|
11092
11922
|
DisplaySwitch,
|
|
11093
11923
|
{
|
|
11094
11924
|
label: "Icon",
|
|
@@ -11649,7 +12479,7 @@ function useNavItemDrag({
|
|
|
11649
12479
|
|
|
11650
12480
|
// src/ui/footer-container-chrome.tsx
|
|
11651
12481
|
import { Plus as Plus2 } from "lucide-react";
|
|
11652
|
-
import { jsx as
|
|
12482
|
+
import { jsx as jsx29, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
11653
12483
|
function FooterContainerChrome({
|
|
11654
12484
|
rect,
|
|
11655
12485
|
onAdd,
|
|
@@ -11657,7 +12487,7 @@ function FooterContainerChrome({
|
|
|
11657
12487
|
}) {
|
|
11658
12488
|
const chromeGap = 6;
|
|
11659
12489
|
const buttonMargin = 7;
|
|
11660
|
-
return /* @__PURE__ */
|
|
12490
|
+
return /* @__PURE__ */ jsx29(TooltipProvider, { delayDuration: 0, children: /* @__PURE__ */ jsx29(
|
|
11661
12491
|
"div",
|
|
11662
12492
|
{
|
|
11663
12493
|
"data-ohw-footer-container-chrome": "",
|
|
@@ -11669,8 +12499,8 @@ function FooterContainerChrome({
|
|
|
11669
12499
|
width: rect.width + chromeGap * 2,
|
|
11670
12500
|
height: rect.height + chromeGap * 2
|
|
11671
12501
|
},
|
|
11672
|
-
children: /* @__PURE__ */
|
|
11673
|
-
/* @__PURE__ */
|
|
12502
|
+
children: /* @__PURE__ */ jsxs19(Tooltip, { children: [
|
|
12503
|
+
/* @__PURE__ */ jsx29(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx29(
|
|
11674
12504
|
"button",
|
|
11675
12505
|
{
|
|
11676
12506
|
type: "button",
|
|
@@ -11689,10 +12519,10 @@ function FooterContainerChrome({
|
|
|
11689
12519
|
if (addDisabled) return;
|
|
11690
12520
|
onAdd();
|
|
11691
12521
|
},
|
|
11692
|
-
children: /* @__PURE__ */
|
|
12522
|
+
children: /* @__PURE__ */ jsx29(Plus2, { className: "size-4 shrink-0 text-foreground", "aria-hidden": true })
|
|
11693
12523
|
}
|
|
11694
12524
|
) }),
|
|
11695
|
-
/* @__PURE__ */
|
|
12525
|
+
/* @__PURE__ */ jsx29(TooltipContent, { side: "bottom", sideOffset: 9, children: addDisabled ? "Maximum columns reached" : "Add item" })
|
|
11696
12526
|
] })
|
|
11697
12527
|
}
|
|
11698
12528
|
) });
|
|
@@ -11875,6 +12705,18 @@ function collectEditableNodes(extraContent, root = document) {
|
|
|
11875
12705
|
}
|
|
11876
12706
|
if (extraContent && !isScoped) {
|
|
11877
12707
|
applyNavFooterDeleteOverrides(byKey, extraContent);
|
|
12708
|
+
for (const key of LOGO_IMAGE_KEYS) {
|
|
12709
|
+
if (!(key in extraContent)) continue;
|
|
12710
|
+
byKey.set(key, { key, type: "image", text: extraContent[key] ?? "" });
|
|
12711
|
+
}
|
|
12712
|
+
for (const key of [LOGO_PLACEHOLDER_KEY, LOGO_ALT_KEY]) {
|
|
12713
|
+
if (!(key in extraContent)) continue;
|
|
12714
|
+
byKey.set(key, { key, type: "meta", text: extraContent[key] ?? "" });
|
|
12715
|
+
}
|
|
12716
|
+
for (const key of LOGO_SIZE_KEYS) {
|
|
12717
|
+
if (!(key in extraContent)) continue;
|
|
12718
|
+
byKey.set(key, { key, type: "meta", text: extraContent[key] ?? "" });
|
|
12719
|
+
}
|
|
11878
12720
|
}
|
|
11879
12721
|
return Array.from(byKey.values());
|
|
11880
12722
|
}
|
|
@@ -12141,13 +12983,13 @@ function deleteSelectedNavFooterItem(deps) {
|
|
|
12141
12983
|
|
|
12142
12984
|
// src/ui/navbar-container-chrome.tsx
|
|
12143
12985
|
import { Plus as Plus3 } from "lucide-react";
|
|
12144
|
-
import { jsx as
|
|
12986
|
+
import { jsx as jsx30 } from "react/jsx-runtime";
|
|
12145
12987
|
function NavbarContainerChrome({
|
|
12146
12988
|
rect,
|
|
12147
12989
|
onAdd
|
|
12148
12990
|
}) {
|
|
12149
12991
|
const chromeGap = 6;
|
|
12150
|
-
return /* @__PURE__ */
|
|
12992
|
+
return /* @__PURE__ */ jsx30(
|
|
12151
12993
|
"div",
|
|
12152
12994
|
{
|
|
12153
12995
|
"data-ohw-navbar-container-chrome": "",
|
|
@@ -12159,7 +13001,7 @@ function NavbarContainerChrome({
|
|
|
12159
13001
|
width: rect.width + chromeGap * 2,
|
|
12160
13002
|
height: rect.height + chromeGap * 2
|
|
12161
13003
|
},
|
|
12162
|
-
children: /* @__PURE__ */
|
|
13004
|
+
children: /* @__PURE__ */ jsx30(
|
|
12163
13005
|
"button",
|
|
12164
13006
|
{
|
|
12165
13007
|
type: "button",
|
|
@@ -12176,7 +13018,7 @@ function NavbarContainerChrome({
|
|
|
12176
13018
|
e.stopPropagation();
|
|
12177
13019
|
onAdd();
|
|
12178
13020
|
},
|
|
12179
|
-
children: /* @__PURE__ */
|
|
13021
|
+
children: /* @__PURE__ */ jsx30(Plus3, { className: "size-4 shrink-0 text-foreground", "aria-hidden": true })
|
|
12180
13022
|
}
|
|
12181
13023
|
)
|
|
12182
13024
|
}
|
|
@@ -12185,7 +13027,7 @@ function NavbarContainerChrome({
|
|
|
12185
13027
|
|
|
12186
13028
|
// src/ui/drop-indicator.tsx
|
|
12187
13029
|
import * as React10 from "react";
|
|
12188
|
-
import { jsx as
|
|
13030
|
+
import { jsx as jsx31 } from "react/jsx-runtime";
|
|
12189
13031
|
var dropIndicatorVariants = cva(
|
|
12190
13032
|
"ov-gap-line pointer-events-none shrink-0 transition-opacity duration-150",
|
|
12191
13033
|
{
|
|
@@ -12209,7 +13051,7 @@ var dropIndicatorVariants = cva(
|
|
|
12209
13051
|
);
|
|
12210
13052
|
var DropIndicator = React10.forwardRef(
|
|
12211
13053
|
({ className, direction, state, ...props }, ref) => {
|
|
12212
|
-
return /* @__PURE__ */
|
|
13054
|
+
return /* @__PURE__ */ jsx31(
|
|
12213
13055
|
"div",
|
|
12214
13056
|
{
|
|
12215
13057
|
ref,
|
|
@@ -12226,7 +13068,7 @@ var DropIndicator = React10.forwardRef(
|
|
|
12226
13068
|
DropIndicator.displayName = "DropIndicator";
|
|
12227
13069
|
|
|
12228
13070
|
// src/ui/badge.tsx
|
|
12229
|
-
import { jsx as
|
|
13071
|
+
import { jsx as jsx32 } from "react/jsx-runtime";
|
|
12230
13072
|
var badgeVariants = cva(
|
|
12231
13073
|
"inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
|
|
12232
13074
|
{
|
|
@@ -12244,12 +13086,12 @@ var badgeVariants = cva(
|
|
|
12244
13086
|
}
|
|
12245
13087
|
);
|
|
12246
13088
|
function Badge({ className, variant, ...props }) {
|
|
12247
|
-
return /* @__PURE__ */
|
|
13089
|
+
return /* @__PURE__ */ jsx32("div", { className: cn(badgeVariants({ variant }), className), ...props });
|
|
12248
13090
|
}
|
|
12249
13091
|
|
|
12250
13092
|
// src/OhhwellsBridge.tsx
|
|
12251
|
-
import { Link as
|
|
12252
|
-
import { Fragment as Fragment8, jsx as
|
|
13093
|
+
import { Link as Link3 } from "lucide-react";
|
|
13094
|
+
import { Fragment as Fragment8, jsx as jsx33, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
12253
13095
|
var PRIMARY3 = "#0885FE";
|
|
12254
13096
|
var IMAGE_FADE_MS = 300;
|
|
12255
13097
|
function runOpacityFade(el, onDone) {
|
|
@@ -12343,21 +13185,10 @@ function parseSchedulingInsertAfter(insertAfter) {
|
|
|
12343
13185
|
insertBefore: insertAfter.slice(idx + INSERT_BEFORE_MARKER.length)
|
|
12344
13186
|
};
|
|
12345
13187
|
}
|
|
12346
|
-
function
|
|
12347
|
-
|
|
12348
|
-
const
|
|
12349
|
-
|
|
12350
|
-
return { effectiveInsertAfter, insertBefore };
|
|
12351
|
-
}
|
|
12352
|
-
function getSchedulingMountPoint(insertAfter) {
|
|
12353
|
-
const { anchor } = parseSchedulingInsertAfter(insertAfter);
|
|
12354
|
-
let anchorEl = document.querySelector(`[data-ohw-section="${anchor}"]`);
|
|
12355
|
-
if (!anchorEl && anchor === "scheduling") {
|
|
12356
|
-
const widgets = Array.from(document.querySelectorAll('[data-ohw-section^="scheduling-"]'));
|
|
12357
|
-
anchorEl = widgets.at(-1) ?? null;
|
|
12358
|
-
}
|
|
12359
|
-
if (!anchorEl) return null;
|
|
12360
|
-
return anchorEl.closest('[data-ohw-section-container="scheduling"]') ?? anchorEl;
|
|
13188
|
+
function resolveEntryAnchor(entry) {
|
|
13189
|
+
if (entry.anchorId !== void 0) return { anchorId: entry.anchorId, beforeId: entry.beforeId ?? null };
|
|
13190
|
+
const parsed = parseSchedulingInsertAfter(entry.insertAfter);
|
|
13191
|
+
return { anchorId: parsed.anchor, beforeId: parsed.insertBefore };
|
|
12361
13192
|
}
|
|
12362
13193
|
function schedulingMountDepth(insertAfter) {
|
|
12363
13194
|
if (!insertAfter.includes(INSERT_BEFORE_MARKER)) return 0;
|
|
@@ -12374,8 +13205,7 @@ function getPageSchedulingEntries(raw) {
|
|
|
12374
13205
|
}
|
|
12375
13206
|
}
|
|
12376
13207
|
function isSchedulingWidgetMissing(entry) {
|
|
12377
|
-
|
|
12378
|
-
return !document.querySelector(`[data-ohw-section="${schedulingSectionId(effectiveInsertAfter)}"]`);
|
|
13208
|
+
return !document.querySelector(`[data-ohw-section="${schedulingSectionId(entry.insertAfter)}"]`);
|
|
12379
13209
|
}
|
|
12380
13210
|
function hasMissingSchedulingWidgets(entries) {
|
|
12381
13211
|
return entries.some(isSchedulingWidgetMissing);
|
|
@@ -12405,16 +13235,17 @@ function initSectionsFromContent(content, removeExisting = false) {
|
|
|
12405
13235
|
} catch {
|
|
12406
13236
|
}
|
|
12407
13237
|
}
|
|
12408
|
-
function mountSchedulingWidget(
|
|
12409
|
-
const
|
|
12410
|
-
const sectionId = schedulingSectionId(
|
|
13238
|
+
function mountSchedulingWidget(anchorId, notifyOnConnect = false, scheduleId, beforeId, existingWidgetId) {
|
|
13239
|
+
const widgetId = existingWidgetId ?? (beforeId ? `${anchorId}${INSERT_BEFORE_MARKER}${beforeId}` : anchorId);
|
|
13240
|
+
const sectionId = schedulingSectionId(widgetId);
|
|
12411
13241
|
if (document.querySelector(`[data-ohw-section="${sectionId}"]`)) return false;
|
|
12412
|
-
const
|
|
12413
|
-
if (!
|
|
13242
|
+
const anchorEl = document.querySelector(`[data-ohw-section="${anchorId}"]`);
|
|
13243
|
+
if (!anchorEl) return false;
|
|
13244
|
+
const mountPoint = anchorEl.closest('[data-ohw-section-container="scheduling"]') ?? anchorEl;
|
|
12414
13245
|
const container = document.createElement("div");
|
|
12415
13246
|
container.dataset.ohwSectionContainer = "scheduling";
|
|
12416
|
-
if (
|
|
12417
|
-
const beforeAnchor = document.querySelector(`[data-ohw-section="${
|
|
13247
|
+
if (beforeId) {
|
|
13248
|
+
const beforeAnchor = document.querySelector(`[data-ohw-section="${beforeId}"]`);
|
|
12418
13249
|
const beforePoint = beforeAnchor?.closest('[data-ohw-section-container="scheduling"]') ?? beforeAnchor;
|
|
12419
13250
|
if (!beforePoint) return false;
|
|
12420
13251
|
beforePoint.insertAdjacentElement("beforebegin", container);
|
|
@@ -12425,19 +13256,25 @@ function mountSchedulingWidget(insertAfter, notifyOnConnect = false, scheduleId,
|
|
|
12425
13256
|
}
|
|
12426
13257
|
tail.insertAdjacentElement("afterend", container);
|
|
12427
13258
|
}
|
|
12428
|
-
|
|
12429
|
-
|
|
12430
|
-
|
|
12431
|
-
|
|
12432
|
-
|
|
12433
|
-
|
|
12434
|
-
|
|
12435
|
-
|
|
12436
|
-
|
|
12437
|
-
|
|
12438
|
-
|
|
12439
|
-
|
|
12440
|
-
|
|
13259
|
+
try {
|
|
13260
|
+
const root = createRoot2(container);
|
|
13261
|
+
flushSync2(() => {
|
|
13262
|
+
root.render(
|
|
13263
|
+
/* @__PURE__ */ jsx33(
|
|
13264
|
+
SchedulingWidget,
|
|
13265
|
+
{
|
|
13266
|
+
notifyOnConnect,
|
|
13267
|
+
initialScheduleId: scheduleId,
|
|
13268
|
+
insertAfter: widgetId
|
|
13269
|
+
}
|
|
13270
|
+
)
|
|
13271
|
+
);
|
|
13272
|
+
});
|
|
13273
|
+
} catch (err) {
|
|
13274
|
+
console.error("[ow:scheduling] render threw", err);
|
|
13275
|
+
container.remove();
|
|
13276
|
+
return false;
|
|
13277
|
+
}
|
|
12441
13278
|
const tracker = getSectionsTracker();
|
|
12442
13279
|
let sections = [];
|
|
12443
13280
|
try {
|
|
@@ -12445,10 +13282,12 @@ function mountSchedulingWidget(insertAfter, notifyOnConnect = false, scheduleId,
|
|
|
12445
13282
|
} catch {
|
|
12446
13283
|
}
|
|
12447
13284
|
const inEditor = typeof window !== "undefined" && window.self !== window.top;
|
|
12448
|
-
if (inEditor && !sections.find((s) => s.type === "scheduling" && s.insertAfter ===
|
|
13285
|
+
if (inEditor && !sections.find((s) => s.type === "scheduling" && s.insertAfter === widgetId)) {
|
|
12449
13286
|
sections.push({
|
|
12450
13287
|
type: "scheduling",
|
|
12451
|
-
insertAfter:
|
|
13288
|
+
insertAfter: widgetId,
|
|
13289
|
+
anchorId,
|
|
13290
|
+
beforeId: beforeId ?? null,
|
|
12452
13291
|
pagePath: window.location.pathname,
|
|
12453
13292
|
...scheduleId ? { scheduleId } : {}
|
|
12454
13293
|
});
|
|
@@ -12462,7 +13301,8 @@ function mountSchedulingEntries(entries, notifyOnConnect = false) {
|
|
|
12462
13301
|
for (let i = pending.length - 1; i >= 0; i--) {
|
|
12463
13302
|
const entry = pending[i];
|
|
12464
13303
|
const shouldNotify = typeof notifyOnConnect === "function" ? notifyOnConnect(entry) : notifyOnConnect;
|
|
12465
|
-
|
|
13304
|
+
const { anchorId, beforeId } = resolveEntryAnchor(entry);
|
|
13305
|
+
if (mountSchedulingWidget(anchorId, shouldNotify, entry.scheduleId ?? null, beforeId, entry.insertAfter)) {
|
|
12466
13306
|
pending.splice(i, 1);
|
|
12467
13307
|
}
|
|
12468
13308
|
}
|
|
@@ -12606,6 +13446,13 @@ function isInsideLinkEditor(target) {
|
|
|
12606
13446
|
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"]')
|
|
12607
13447
|
);
|
|
12608
13448
|
}
|
|
13449
|
+
function isInsideFloatingPanel(target) {
|
|
13450
|
+
return Boolean(target.closest("[data-ohw-floating-panel]"));
|
|
13451
|
+
}
|
|
13452
|
+
function isPointOverFloatingPanel(clientX, clientY) {
|
|
13453
|
+
const el = document.elementFromPoint(clientX, clientY);
|
|
13454
|
+
return Boolean(el instanceof Element && el.closest("[data-ohw-floating-panel]"));
|
|
13455
|
+
}
|
|
12609
13456
|
function getHrefKeyFromElement(el) {
|
|
12610
13457
|
if (!el) return null;
|
|
12611
13458
|
const anchor = el.closest("[data-ohw-href-key]");
|
|
@@ -12743,6 +13590,11 @@ function isNavbarLinksContainer2(el) {
|
|
|
12743
13590
|
function getFooterColumn(el) {
|
|
12744
13591
|
return el.closest("[data-ohw-footer-col], [data-ohw-footer-column]");
|
|
12745
13592
|
}
|
|
13593
|
+
function isFooterAddItemDisabled(selected) {
|
|
13594
|
+
if (!selected) return false;
|
|
13595
|
+
const column = resolveFooterColumnForAdd(selected);
|
|
13596
|
+
return column ? !canAddFooterItem(column) : false;
|
|
13597
|
+
}
|
|
12746
13598
|
function resolveFooterColumnSelectionTarget(target, clientX, clientY) {
|
|
12747
13599
|
if (getNavigationItemAnchor(target)) return null;
|
|
12748
13600
|
const column = getFooterColumn(target);
|
|
@@ -12838,7 +13690,7 @@ function getNavigationSelectionParent(el) {
|
|
|
12838
13690
|
if (!isFooterLinksContainer(el) && (el.hasAttribute("data-ohw-footer-col") || el.hasAttribute("data-ohw-footer-column") || isInferredFooterGroup2(el))) {
|
|
12839
13691
|
return getFooterLinksContainer();
|
|
12840
13692
|
}
|
|
12841
|
-
if (el.hasAttribute("data-ohw-nav-container") || el.hasAttribute("data-ohw-nav-drawer") || isFooterLinksContainer(el)) {
|
|
13693
|
+
if (el.hasAttribute("data-ohw-nav-container") || el.hasAttribute("data-ohw-nav-drawer") || el.hasAttribute("data-ohw-footer-col") || el.hasAttribute("data-ohw-footer-column") || isFooterLinksContainer(el) || isInferredFooterGroup2(el)) {
|
|
12842
13694
|
return getNavigationRoot(el);
|
|
12843
13695
|
}
|
|
12844
13696
|
return null;
|
|
@@ -13056,6 +13908,9 @@ var ICONS = {
|
|
|
13056
13908
|
var SELECTION_CHROME_GAP2 = 4;
|
|
13057
13909
|
var TOOLBAR_STROKE_GAP2 = 4;
|
|
13058
13910
|
var TOOLBAR_OFFSET_FROM_ELEMENT = SELECTION_CHROME_GAP2 + TOOLBAR_STROKE_GAP2;
|
|
13911
|
+
var HOVER_STROKE_WIDTH = 1.5;
|
|
13912
|
+
var TEXT_HOVER_SIDE_PAD = 4;
|
|
13913
|
+
var CHROME_PRIMARY = `var(--ohw-primary, ${PRIMARY3})`;
|
|
13059
13914
|
var TOOLBAR_GROUPS = [
|
|
13060
13915
|
[
|
|
13061
13916
|
{ cmd: "bold", title: "Bold" },
|
|
@@ -13081,7 +13936,7 @@ function EditGlowChrome({
|
|
|
13081
13936
|
hideHandle = false
|
|
13082
13937
|
}) {
|
|
13083
13938
|
const GAP = SELECTION_CHROME_GAP2;
|
|
13084
|
-
return /* @__PURE__ */
|
|
13939
|
+
return /* @__PURE__ */ jsxs20(
|
|
13085
13940
|
"div",
|
|
13086
13941
|
{
|
|
13087
13942
|
ref: elRef,
|
|
@@ -13096,7 +13951,7 @@ function EditGlowChrome({
|
|
|
13096
13951
|
zIndex: 2147483646
|
|
13097
13952
|
},
|
|
13098
13953
|
children: [
|
|
13099
|
-
/* @__PURE__ */
|
|
13954
|
+
/* @__PURE__ */ jsx33(
|
|
13100
13955
|
"div",
|
|
13101
13956
|
{
|
|
13102
13957
|
style: {
|
|
@@ -13109,7 +13964,7 @@ function EditGlowChrome({
|
|
|
13109
13964
|
}
|
|
13110
13965
|
}
|
|
13111
13966
|
),
|
|
13112
|
-
reorderHrefKey && !hideHandle && /* @__PURE__ */
|
|
13967
|
+
reorderHrefKey && !hideHandle && /* @__PURE__ */ jsx33(
|
|
13113
13968
|
"div",
|
|
13114
13969
|
{
|
|
13115
13970
|
"data-ohw-drag-handle-container": "",
|
|
@@ -13121,7 +13976,7 @@ function EditGlowChrome({
|
|
|
13121
13976
|
transform: "translate(calc(-100% - 7px), -50%)",
|
|
13122
13977
|
pointerEvents: dragDisabled ? "none" : "auto"
|
|
13123
13978
|
},
|
|
13124
|
-
children: /* @__PURE__ */
|
|
13979
|
+
children: /* @__PURE__ */ jsx33(
|
|
13125
13980
|
DragHandle,
|
|
13126
13981
|
{
|
|
13127
13982
|
"aria-label": `Reorder ${reorderHrefKey}`,
|
|
@@ -13331,7 +14186,7 @@ function FloatingToolbar({
|
|
|
13331
14186
|
return () => ro.disconnect();
|
|
13332
14187
|
}, [showEditLink, activeCommands]);
|
|
13333
14188
|
const { top, left, transform } = calcToolbarPos(rect, parentScroll, measuredW);
|
|
13334
|
-
return /* @__PURE__ */
|
|
14189
|
+
return /* @__PURE__ */ jsx33(
|
|
13335
14190
|
"div",
|
|
13336
14191
|
{
|
|
13337
14192
|
ref: setRefs,
|
|
@@ -13343,12 +14198,12 @@ function FloatingToolbar({
|
|
|
13343
14198
|
zIndex: 2147483647,
|
|
13344
14199
|
pointerEvents: "auto"
|
|
13345
14200
|
},
|
|
13346
|
-
children: /* @__PURE__ */
|
|
13347
|
-
TOOLBAR_GROUPS.map((btns, gi) => /* @__PURE__ */
|
|
13348
|
-
gi > 0 && /* @__PURE__ */
|
|
14201
|
+
children: /* @__PURE__ */ jsxs20(CustomToolbar, { children: [
|
|
14202
|
+
TOOLBAR_GROUPS.map((btns, gi) => /* @__PURE__ */ jsxs20(React11.Fragment, { children: [
|
|
14203
|
+
gi > 0 && /* @__PURE__ */ jsx33(CustomToolbarDivider, {}),
|
|
13349
14204
|
btns.map((btn) => {
|
|
13350
14205
|
const isActive = activeCommands.has(btn.cmd);
|
|
13351
|
-
return /* @__PURE__ */
|
|
14206
|
+
return /* @__PURE__ */ jsx33(
|
|
13352
14207
|
CustomToolbarButton,
|
|
13353
14208
|
{
|
|
13354
14209
|
title: btn.title,
|
|
@@ -13357,7 +14212,7 @@ function FloatingToolbar({
|
|
|
13357
14212
|
e.preventDefault();
|
|
13358
14213
|
onCommand(btn.cmd);
|
|
13359
14214
|
},
|
|
13360
|
-
children: /* @__PURE__ */
|
|
14215
|
+
children: /* @__PURE__ */ jsx33(
|
|
13361
14216
|
"svg",
|
|
13362
14217
|
{
|
|
13363
14218
|
width: "16",
|
|
@@ -13378,7 +14233,7 @@ function FloatingToolbar({
|
|
|
13378
14233
|
);
|
|
13379
14234
|
})
|
|
13380
14235
|
] }, gi)),
|
|
13381
|
-
showEditLink ? /* @__PURE__ */
|
|
14236
|
+
showEditLink ? /* @__PURE__ */ jsx33(
|
|
13382
14237
|
CustomToolbarButton,
|
|
13383
14238
|
{
|
|
13384
14239
|
type: "button",
|
|
@@ -13392,7 +14247,7 @@ function FloatingToolbar({
|
|
|
13392
14247
|
e.preventDefault();
|
|
13393
14248
|
e.stopPropagation();
|
|
13394
14249
|
},
|
|
13395
|
-
children: /* @__PURE__ */
|
|
14250
|
+
children: /* @__PURE__ */ jsx33(Link3, { className: "size-4 shrink-0", "aria-hidden": true })
|
|
13396
14251
|
}
|
|
13397
14252
|
) : null
|
|
13398
14253
|
] })
|
|
@@ -13409,7 +14264,7 @@ function StateToggle({
|
|
|
13409
14264
|
states,
|
|
13410
14265
|
onStateChange
|
|
13411
14266
|
}) {
|
|
13412
|
-
return /* @__PURE__ */
|
|
14267
|
+
return /* @__PURE__ */ jsx33(
|
|
13413
14268
|
ToggleGroup,
|
|
13414
14269
|
{
|
|
13415
14270
|
"data-ohw-state-toggle": "",
|
|
@@ -13423,11 +14278,12 @@ function StateToggle({
|
|
|
13423
14278
|
left: rect.right - 8,
|
|
13424
14279
|
transform: "translateX(-100%)"
|
|
13425
14280
|
},
|
|
13426
|
-
children: states.map((state) => /* @__PURE__ */
|
|
14281
|
+
children: states.map((state) => /* @__PURE__ */ jsx33(ToggleGroupItem, { value: state, size: "sm", children: state }, state))
|
|
13427
14282
|
}
|
|
13428
14283
|
);
|
|
13429
14284
|
}
|
|
13430
14285
|
var contentCache = /* @__PURE__ */ new Map();
|
|
14286
|
+
var fetchedContentPaths = /* @__PURE__ */ new Set();
|
|
13431
14287
|
function resolveSubdomain(subdomainFromQuery) {
|
|
13432
14288
|
if (subdomainFromQuery) return subdomainFromQuery;
|
|
13433
14289
|
if (typeof window !== "undefined") {
|
|
@@ -13522,8 +14378,14 @@ function OhhwellsBridge() {
|
|
|
13522
14378
|
});
|
|
13523
14379
|
const selectFrameRef = useRef9(() => {
|
|
13524
14380
|
});
|
|
14381
|
+
const selectLogoRef = useRef9(() => {
|
|
14382
|
+
});
|
|
14383
|
+
const openLogoSizePanelRef = useRef9(() => {
|
|
14384
|
+
});
|
|
13525
14385
|
const deselectRef = useRef9(() => {
|
|
13526
14386
|
});
|
|
14387
|
+
const closeFloatingPanelOnlyRef = useRef9(() => {
|
|
14388
|
+
});
|
|
13527
14389
|
const reselectNavigationItemRef = useRef9(() => {
|
|
13528
14390
|
});
|
|
13529
14391
|
const commitNavigationTextEditRef = useRef9(() => {
|
|
@@ -13556,17 +14418,34 @@ function OhhwellsBridge() {
|
|
|
13556
14418
|
const [hoveredNavContainerRect, setHoveredNavContainerRect] = useState11(null);
|
|
13557
14419
|
const hoveredItemElRef = useRef9(null);
|
|
13558
14420
|
const [hoveredItemRect, setHoveredItemRect] = useState11(null);
|
|
14421
|
+
const [hoveredTextRect, setHoveredTextRect] = useState11(null);
|
|
14422
|
+
useEffect12(() => {
|
|
14423
|
+
const sync = () => {
|
|
14424
|
+
const el = document.querySelector(
|
|
14425
|
+
"[data-ohw-hovered]:not([contenteditable]):not([data-ohw-href-key])"
|
|
14426
|
+
);
|
|
14427
|
+
const target = el && !el.closest("[data-ohw-href-key]") ? el : null;
|
|
14428
|
+
if (!target) {
|
|
14429
|
+
setHoveredTextRect(null);
|
|
14430
|
+
return;
|
|
14431
|
+
}
|
|
14432
|
+
const r2 = target.getBoundingClientRect();
|
|
14433
|
+
setHoveredTextRect(new DOMRect(r2.x - TEXT_HOVER_SIDE_PAD, r2.y, r2.width + TEXT_HOVER_SIDE_PAD * 2, r2.height));
|
|
14434
|
+
};
|
|
14435
|
+
const observer = new MutationObserver(sync);
|
|
14436
|
+
observer.observe(document.documentElement, {
|
|
14437
|
+
attributes: true,
|
|
14438
|
+
attributeFilter: ["data-ohw-hovered"],
|
|
14439
|
+
subtree: true
|
|
14440
|
+
});
|
|
14441
|
+
return () => observer.disconnect();
|
|
14442
|
+
}, []);
|
|
13559
14443
|
const siblingHintElRef = useRef9(null);
|
|
13560
14444
|
const [siblingHintRect, setSiblingHintRect] = useState11(null);
|
|
13561
14445
|
const [siblingHintRects, setSiblingHintRects] = useState11([]);
|
|
13562
14446
|
const [isItemDragging, setIsItemDragging] = useState11(false);
|
|
13563
14447
|
const [isFooterFrameSelection, setIsFooterFrameSelection] = useState11(false);
|
|
13564
14448
|
isFooterFrameSelectionRef.current = isFooterFrameSelection;
|
|
13565
|
-
const [floatingPanel, setFloatingPanel] = useState11(null);
|
|
13566
|
-
const floatingPanelOpenRef = useRef9(false);
|
|
13567
|
-
floatingPanelOpenRef.current = floatingPanel !== null;
|
|
13568
|
-
const [floatingPanelPos, setFloatingPanelPos] = useState11(null);
|
|
13569
|
-
const [parentScrollSnap, setParentScrollSnap] = useState11(null);
|
|
13570
14449
|
const [navDropdownPreviewOpen, setNavDropdownPreviewOpen] = useState11(null);
|
|
13571
14450
|
const [footerHeadingVisible, setFooterHeadingVisible] = useState11(null);
|
|
13572
14451
|
const footerDragRef = useRef9(null);
|
|
@@ -13581,7 +14460,16 @@ function OhhwellsBridge() {
|
|
|
13581
14460
|
const addNavAfterAnchorRef = useRef9(null);
|
|
13582
14461
|
const editContentRef = useRef9({});
|
|
13583
14462
|
const aiSectionsRef = useRef9("");
|
|
14463
|
+
const brandKitRef = useRef9("");
|
|
14464
|
+
const stylesRef = useRef9("");
|
|
13584
14465
|
const pendingDeleteUndoRef = useRef9(null);
|
|
14466
|
+
const [floatingPanel, setFloatingPanel] = useState11(null);
|
|
14467
|
+
const floatingPanelOpenRef = useRef9(false);
|
|
14468
|
+
const setFloatingPanelRef = useRef9(setFloatingPanel);
|
|
14469
|
+
const [floatingPanelPos, setFloatingPanelPos] = useState11(null);
|
|
14470
|
+
const [logoSizeDraft, setLogoSizeDraft] = useState11(null);
|
|
14471
|
+
const [editorViewport, setEditorViewport] = useState11("desktop");
|
|
14472
|
+
const [parentScrollSnap, setParentScrollSnap] = useState11(null);
|
|
13585
14473
|
const [sitePages, setSitePages] = useState11([]);
|
|
13586
14474
|
const [sectionsByPath, setSectionsByPath] = useState11({});
|
|
13587
14475
|
const sectionsPrefetchGenRef = useRef9(0);
|
|
@@ -13590,7 +14478,18 @@ function OhhwellsBridge() {
|
|
|
13590
14478
|
const linkPopoverOpenRef = useRef9(false);
|
|
13591
14479
|
const linkPopoverGraceUntilRef = useRef9(0);
|
|
13592
14480
|
setLinkPopoverRef.current = setLinkPopover;
|
|
14481
|
+
setFloatingPanelRef.current = setFloatingPanel;
|
|
13593
14482
|
linkPopoverSessionRef.current = linkPopover;
|
|
14483
|
+
floatingPanelOpenRef.current = Boolean(floatingPanel);
|
|
14484
|
+
useEffect12(() => {
|
|
14485
|
+
const syncViewport = () => {
|
|
14486
|
+
const next = window.innerWidth <= 480 ? "mobile" : "desktop";
|
|
14487
|
+
setEditorViewport((prev) => prev === next ? prev : next);
|
|
14488
|
+
};
|
|
14489
|
+
syncViewport();
|
|
14490
|
+
window.addEventListener("resize", syncViewport);
|
|
14491
|
+
return () => window.removeEventListener("resize", syncViewport);
|
|
14492
|
+
}, []);
|
|
13594
14493
|
const {
|
|
13595
14494
|
navDragRef,
|
|
13596
14495
|
navDropSlots,
|
|
@@ -13813,6 +14712,10 @@ function OhhwellsBridge() {
|
|
|
13813
14712
|
setIsItemDragging(false);
|
|
13814
14713
|
hoveredNavContainerRef.current = null;
|
|
13815
14714
|
setHoveredNavContainerRect(null);
|
|
14715
|
+
hoveredItemElRef.current = null;
|
|
14716
|
+
setHoveredItemRect(null);
|
|
14717
|
+
setFloatingPanel(null);
|
|
14718
|
+
setLogoSizeDraft(null);
|
|
13816
14719
|
if (!activeElRef.current) {
|
|
13817
14720
|
setNavGroupForceOpen(null, false);
|
|
13818
14721
|
setToolbarRect(null);
|
|
@@ -14009,6 +14912,14 @@ function OhhwellsBridge() {
|
|
|
14009
14912
|
if (!selected) return;
|
|
14010
14913
|
const socialsRow = isSocialsRow(selected) ? selected : findSocialsRow(selected);
|
|
14011
14914
|
if (socialsRow) {
|
|
14915
|
+
if (!canAddSocialItem(socialsRow)) {
|
|
14916
|
+
postToParent2({
|
|
14917
|
+
type: "ow:toast",
|
|
14918
|
+
title: `Maximum ${MAX_SOCIAL_ITEMS_PER_ROW} social icons`,
|
|
14919
|
+
toastType: "error"
|
|
14920
|
+
});
|
|
14921
|
+
return;
|
|
14922
|
+
}
|
|
14012
14923
|
const after = getSocialItem(selected);
|
|
14013
14924
|
const result2 = insertSocialItem(socialsRow, after, editContentRef.current);
|
|
14014
14925
|
if (!result2) return;
|
|
@@ -14030,10 +14941,16 @@ function OhhwellsBridge() {
|
|
|
14030
14941
|
return;
|
|
14031
14942
|
}
|
|
14032
14943
|
if (toolbarVariantRef.current === "select-frame" && isFooterFrameSelection) {
|
|
14033
|
-
|
|
14034
|
-
}
|
|
14035
|
-
const column = (selected.hasAttribute("data-ohw-footer-col") ? selected : null) ?? selected.closest("[data-ohw-footer-col]") ?? (listFooterColumns().includes(selected) ? selected : null);
|
|
14944
|
+
const column = resolveFooterColumnForAdd(selected);
|
|
14036
14945
|
if (!column) return;
|
|
14946
|
+
if (!canAddFooterItem(column)) {
|
|
14947
|
+
postToParent2({
|
|
14948
|
+
type: "ow:toast",
|
|
14949
|
+
title: `Maximum ${MAX_FOOTER_ITEMS_PER_COLUMN} items per column`,
|
|
14950
|
+
toastType: "error"
|
|
14951
|
+
});
|
|
14952
|
+
return;
|
|
14953
|
+
}
|
|
14037
14954
|
const result2 = insertFooterItem(column, "/", "New link", null);
|
|
14038
14955
|
applyLinkByKey(result2.hrefKey, result2.href);
|
|
14039
14956
|
document.querySelectorAll(`[data-ohw-key="${result2.labelKey}"]`).forEach((el) => {
|
|
@@ -14504,6 +15421,8 @@ function OhhwellsBridge() {
|
|
|
14504
15421
|
setToolbarRect(anchor.getBoundingClientRect());
|
|
14505
15422
|
setToolbarShowEditLink(false);
|
|
14506
15423
|
setActiveCommands(/* @__PURE__ */ new Set());
|
|
15424
|
+
setFloatingPanel(null);
|
|
15425
|
+
setLogoSizeDraft(null);
|
|
14507
15426
|
}, [deactivate, markSelected]);
|
|
14508
15427
|
const selectFrame = useCallback7((el) => {
|
|
14509
15428
|
if (!isNavigationContainer(el)) return;
|
|
@@ -14553,7 +15472,51 @@ function OhhwellsBridge() {
|
|
|
14553
15472
|
setToolbarRect(el.getBoundingClientRect());
|
|
14554
15473
|
setToolbarShowEditLink(false);
|
|
14555
15474
|
setActiveCommands(/* @__PURE__ */ new Set());
|
|
15475
|
+
setFloatingPanel(null);
|
|
15476
|
+
setLogoSizeDraft(null);
|
|
14556
15477
|
}, [deactivate, markSelected, postToParent2]);
|
|
15478
|
+
const selectLogo = useCallback7(
|
|
15479
|
+
(logoEl) => {
|
|
15480
|
+
if (activeElRef.current) deactivate();
|
|
15481
|
+
selectedElRef.current = logoEl;
|
|
15482
|
+
selectedHrefKeyRef.current = null;
|
|
15483
|
+
selectedFooterColAttrRef.current = null;
|
|
15484
|
+
markSelected(logoEl);
|
|
15485
|
+
setSelectedIsCta(false);
|
|
15486
|
+
setSelectedIsSocial(false);
|
|
15487
|
+
setSelectedIsSocialsRow(false);
|
|
15488
|
+
clearHrefKeyHover(logoEl);
|
|
15489
|
+
hoveredNavContainerRef.current = null;
|
|
15490
|
+
setHoveredNavContainerRect(null);
|
|
15491
|
+
setHoveredItemRect(null);
|
|
15492
|
+
hoveredItemElRef.current = null;
|
|
15493
|
+
siblingHintElRef.current = null;
|
|
15494
|
+
setSiblingHintRect(null);
|
|
15495
|
+
setSiblingHintRects([]);
|
|
15496
|
+
setIsItemDragging(false);
|
|
15497
|
+
setReorderHrefKey(null);
|
|
15498
|
+
setReorderDragDisabled(false);
|
|
15499
|
+
setIsFooterFrameSelection(false);
|
|
15500
|
+
setToolbarVariant("logo");
|
|
15501
|
+
setToolbarRect(getLogoInteractionRect(logoEl));
|
|
15502
|
+
setToolbarShowEditLink(false);
|
|
15503
|
+
setActiveCommands(/* @__PURE__ */ new Set());
|
|
15504
|
+
},
|
|
15505
|
+
[deactivate, markSelected]
|
|
15506
|
+
);
|
|
15507
|
+
const openLogoSizePanel = useCallback7((logoEl) => {
|
|
15508
|
+
const placement = getLogoPlacement(logoEl);
|
|
15509
|
+
const draft = readLogoSizeState(editContentRef.current, placement);
|
|
15510
|
+
setLogoSizeDraft(draft);
|
|
15511
|
+
setParentScrollSnap(parentScrollRef.current);
|
|
15512
|
+
setFloatingPanel({
|
|
15513
|
+
key: `logo-size:${placement}`,
|
|
15514
|
+
title: "Logo",
|
|
15515
|
+
context: placement === "navbar" ? "Navbar" : "Footer",
|
|
15516
|
+
kind: "logo-size",
|
|
15517
|
+
placement
|
|
15518
|
+
});
|
|
15519
|
+
}, []);
|
|
14557
15520
|
const openSocialsDisplayPanel = useCallback7((row) => {
|
|
14558
15521
|
setParentScrollSnap(parentScrollRef.current);
|
|
14559
15522
|
setFloatingPanel({
|
|
@@ -14589,13 +15552,53 @@ function OhhwellsBridge() {
|
|
|
14589
15552
|
);
|
|
14590
15553
|
const closeFloatingPanelOnly = useCallback7(() => {
|
|
14591
15554
|
setFloatingPanel(null);
|
|
15555
|
+
setLogoSizeDraft(null);
|
|
14592
15556
|
}, []);
|
|
14593
|
-
const closeFloatingPanelOnlyRef = useRef9(closeFloatingPanelOnly);
|
|
14594
|
-
closeFloatingPanelOnlyRef.current = closeFloatingPanelOnly;
|
|
14595
15557
|
const closeFloatingPanelAndDeselect = useCallback7(() => {
|
|
14596
15558
|
setFloatingPanel(null);
|
|
15559
|
+
setLogoSizeDraft(null);
|
|
14597
15560
|
deselectRef.current();
|
|
14598
15561
|
}, []);
|
|
15562
|
+
const persistLogoSizeDraft = useCallback7(
|
|
15563
|
+
(placement, draft) => {
|
|
15564
|
+
const desktopKey = LOGO_SIZE_DESKTOP_KEYS[placement];
|
|
15565
|
+
const mobileKey = LOGO_SIZE_MOBILE_KEYS[placement];
|
|
15566
|
+
const nodes = [
|
|
15567
|
+
{ key: desktopKey, text: String(draft.desktopPx) }
|
|
15568
|
+
];
|
|
15569
|
+
if (draft.mobileFollowing) {
|
|
15570
|
+
nodes.push({ key: mobileKey, text: "" });
|
|
15571
|
+
} else {
|
|
15572
|
+
nodes.push({ key: mobileKey, text: String(draft.mobilePx) });
|
|
15573
|
+
}
|
|
15574
|
+
editContentRef.current = {
|
|
15575
|
+
...editContentRef.current,
|
|
15576
|
+
[desktopKey]: String(draft.desktopPx),
|
|
15577
|
+
[mobileKey]: draft.mobileFollowing ? "" : String(draft.mobilePx)
|
|
15578
|
+
};
|
|
15579
|
+
applyLogoSizeToPlacement(
|
|
15580
|
+
placement,
|
|
15581
|
+
draft.desktopPx,
|
|
15582
|
+
draft.mobileFollowing ? draft.desktopPx : draft.mobilePx,
|
|
15583
|
+
draft.mobileFollowing
|
|
15584
|
+
);
|
|
15585
|
+
postToParent2({ type: "ow:change", nodes });
|
|
15586
|
+
requestAnimationFrame(() => {
|
|
15587
|
+
const selected = selectedElRef.current;
|
|
15588
|
+
if (!selected || toolbarVariantRef.current !== "logo") return;
|
|
15589
|
+
const rect = getLogoInteractionRect(selected);
|
|
15590
|
+
setToolbarRect(rect);
|
|
15591
|
+
if (glowElRef.current) {
|
|
15592
|
+
const GAP = SELECTION_CHROME_GAP2;
|
|
15593
|
+
glowElRef.current.style.top = `${rect.top - GAP}px`;
|
|
15594
|
+
glowElRef.current.style.left = `${rect.left - GAP}px`;
|
|
15595
|
+
glowElRef.current.style.width = `${rect.width + GAP * 2}px`;
|
|
15596
|
+
glowElRef.current.style.height = `${rect.height + GAP * 2}px`;
|
|
15597
|
+
}
|
|
15598
|
+
});
|
|
15599
|
+
},
|
|
15600
|
+
[postToParent2]
|
|
15601
|
+
);
|
|
14599
15602
|
const activate = useCallback7((el, options) => {
|
|
14600
15603
|
if (activeElRef.current === el) return;
|
|
14601
15604
|
if (isIconEditable(el)) return;
|
|
@@ -14676,7 +15679,37 @@ function OhhwellsBridge() {
|
|
|
14676
15679
|
deactivateRef.current = deactivate;
|
|
14677
15680
|
selectRef.current = select;
|
|
14678
15681
|
selectFrameRef.current = selectFrame;
|
|
15682
|
+
selectLogoRef.current = selectLogo;
|
|
15683
|
+
openLogoSizePanelRef.current = openLogoSizePanel;
|
|
14679
15684
|
deselectRef.current = deselect;
|
|
15685
|
+
closeFloatingPanelOnlyRef.current = closeFloatingPanelOnly;
|
|
15686
|
+
const lastSiteWideScopeRef = useRef9(null);
|
|
15687
|
+
useEffect12(() => {
|
|
15688
|
+
if (!isEditMode) {
|
|
15689
|
+
if (lastSiteWideScopeRef.current !== false) {
|
|
15690
|
+
lastSiteWideScopeRef.current = false;
|
|
15691
|
+
postToParent2({ type: "ow:site-wide-scope", active: false });
|
|
15692
|
+
}
|
|
15693
|
+
return;
|
|
15694
|
+
}
|
|
15695
|
+
const active = isSiteWideScopeActive({
|
|
15696
|
+
selected: selectedElRef.current,
|
|
15697
|
+
hoveredItem: hoveredItemElRef.current,
|
|
15698
|
+
hoveredNavContainer: hoveredNavContainerRef.current,
|
|
15699
|
+
active: activeElRef.current
|
|
15700
|
+
});
|
|
15701
|
+
if (lastSiteWideScopeRef.current === active) return;
|
|
15702
|
+
lastSiteWideScopeRef.current = active;
|
|
15703
|
+
postToParent2({ type: "ow:site-wide-scope", active });
|
|
15704
|
+
}, [
|
|
15705
|
+
isEditMode,
|
|
15706
|
+
hoveredItemRect,
|
|
15707
|
+
hoveredNavContainerRect,
|
|
15708
|
+
toolbarVariant,
|
|
15709
|
+
toolbarRect,
|
|
15710
|
+
isFooterFrameSelection,
|
|
15711
|
+
postToParent2
|
|
15712
|
+
]);
|
|
14680
15713
|
useLayoutEffect4(() => {
|
|
14681
15714
|
if (!subdomain || isEditMode) {
|
|
14682
15715
|
setFetchState("done");
|
|
@@ -14688,9 +15721,23 @@ function OhhwellsBridge() {
|
|
|
14688
15721
|
aiSectionsRef.current = content[AI_SECTIONS_KEY];
|
|
14689
15722
|
applyAiSectionsToDom(parseAiSectionsState(content[AI_SECTIONS_KEY]));
|
|
14690
15723
|
}
|
|
15724
|
+
if (typeof content[BRAND_KIT_KEY] === "string") {
|
|
15725
|
+
brandKitRef.current = content[BRAND_KIT_KEY];
|
|
15726
|
+
applyBrandToDom(parseBrandKit(content[BRAND_KIT_KEY]));
|
|
15727
|
+
}
|
|
15728
|
+
if (typeof content[STYLE_STORE_KEY] === "string") {
|
|
15729
|
+
stylesRef.current = content[STYLE_STORE_KEY];
|
|
15730
|
+
applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
|
|
15731
|
+
}
|
|
15732
|
+
applyBrandChrome(content);
|
|
14691
15733
|
for (const [key, val] of Object.entries(content)) {
|
|
14692
15734
|
if (key === "__ohw_sections") continue;
|
|
14693
15735
|
if (key === AI_SECTIONS_KEY) continue;
|
|
15736
|
+
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
15737
|
+
if (LOGO_IMAGE_KEYS.includes(key)) continue;
|
|
15738
|
+
if (key === BRAND_KIT_KEY) continue;
|
|
15739
|
+
if (key === STYLE_STORE_KEY) continue;
|
|
15740
|
+
if (BRAND_CHROME_KEYS.has(key)) continue;
|
|
14694
15741
|
if (applyVideoSettingNode(key, val)) continue;
|
|
14695
15742
|
if (applyCarouselNode(key, val)) continue;
|
|
14696
15743
|
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
@@ -14725,6 +15772,8 @@ function OhhwellsBridge() {
|
|
|
14725
15772
|
});
|
|
14726
15773
|
applyLinkByKey(key, val);
|
|
14727
15774
|
}
|
|
15775
|
+
applyLogoFromContent(content);
|
|
15776
|
+
applyLogoSizes(content);
|
|
14728
15777
|
reconcileNavbarItemsFromContent(content);
|
|
14729
15778
|
reconcileFooterOrderFromContent(content);
|
|
14730
15779
|
reconcileSocialsFromContent(content);
|
|
@@ -14745,7 +15794,9 @@ function OhhwellsBridge() {
|
|
|
14745
15794
|
let cancelled = false;
|
|
14746
15795
|
setFetchState("loading");
|
|
14747
15796
|
const apiUrl = process.env.NEXT_PUBLIC_FLOWOPS_API_URL ?? "https://flowops-backend-staging-2yfdh7pwpq-as.a.run.app";
|
|
14748
|
-
|
|
15797
|
+
const initialPath = pathname;
|
|
15798
|
+
fetchedContentPaths.add(`${subdomain}::${initialPath}`);
|
|
15799
|
+
fetch(`${apiUrl}/api/public/sites/${subdomain}/content?path=${encodeURIComponent(initialPath)}`, { cache: "no-store" }).then((r2) => r2.ok ? r2.json() : null).then((data) => {
|
|
14749
15800
|
if (cancelled) return;
|
|
14750
15801
|
const content = data?.content ?? {};
|
|
14751
15802
|
contentCache.set(subdomain, content);
|
|
@@ -14769,8 +15820,21 @@ function OhhwellsBridge() {
|
|
|
14769
15820
|
initSectionInstancesFromContent(content, window.location.pathname);
|
|
14770
15821
|
observer?.disconnect();
|
|
14771
15822
|
try {
|
|
15823
|
+
applyBrandChrome(content);
|
|
15824
|
+
if (typeof content[BRAND_KIT_KEY] === "string") {
|
|
15825
|
+
applyBrandToDom(parseBrandKit(content[BRAND_KIT_KEY]));
|
|
15826
|
+
}
|
|
15827
|
+
if (typeof content[STYLE_STORE_KEY] === "string") {
|
|
15828
|
+
applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
|
|
15829
|
+
}
|
|
14772
15830
|
for (const [key, val] of Object.entries(content)) {
|
|
14773
15831
|
if (key === "__ohw_sections") continue;
|
|
15832
|
+
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
15833
|
+
if (LOGO_IMAGE_KEYS.includes(key)) continue;
|
|
15834
|
+
if (key === BRAND_KIT_KEY) continue;
|
|
15835
|
+
if (key === STYLE_STORE_KEY) continue;
|
|
15836
|
+
if (key === STYLE_STORE_KEY) continue;
|
|
15837
|
+
if (BRAND_CHROME_KEYS.has(key)) continue;
|
|
14774
15838
|
if (applyVideoSettingNode(key, val)) continue;
|
|
14775
15839
|
if (applyCarouselNode(key, val)) continue;
|
|
14776
15840
|
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
@@ -14791,6 +15855,7 @@ function OhhwellsBridge() {
|
|
|
14791
15855
|
});
|
|
14792
15856
|
applyLinkByKey(key, val);
|
|
14793
15857
|
}
|
|
15858
|
+
applyLogoFromContent(content);
|
|
14794
15859
|
reconcileNavbarItemsFromContent(content);
|
|
14795
15860
|
reconcileFooterOrderFromContent(content);
|
|
14796
15861
|
reconcileSocialsFromContent(content);
|
|
@@ -14805,6 +15870,17 @@ function OhhwellsBridge() {
|
|
|
14805
15870
|
debounceTimer = setTimeout(applyFromCache, 150);
|
|
14806
15871
|
};
|
|
14807
15872
|
applyFromCache();
|
|
15873
|
+
const pathCacheKey = `${subdomain}::${pathname}`;
|
|
15874
|
+
if (!fetchedContentPaths.has(pathCacheKey)) {
|
|
15875
|
+
fetchedContentPaths.add(pathCacheKey);
|
|
15876
|
+
const apiUrl = process.env.NEXT_PUBLIC_FLOWOPS_API_URL ?? "https://flowops-backend-staging-2yfdh7pwpq-as.a.run.app";
|
|
15877
|
+
fetch(`${apiUrl}/api/public/sites/${subdomain}/content?path=${encodeURIComponent(pathname)}`, { cache: "no-store" }).then((r2) => r2.ok ? r2.json() : null).then((data) => {
|
|
15878
|
+
if (!data?.content) return;
|
|
15879
|
+
contentCache.set(subdomain, data.content);
|
|
15880
|
+
applyFromCache();
|
|
15881
|
+
}).catch(() => {
|
|
15882
|
+
});
|
|
15883
|
+
}
|
|
14808
15884
|
observer = new MutationObserver(scheduleApply);
|
|
14809
15885
|
observer.observe(document.body, { childList: true, subtree: true });
|
|
14810
15886
|
return () => {
|
|
@@ -14898,26 +15974,31 @@ function OhhwellsBridge() {
|
|
|
14898
15974
|
}, [isEditMode, pathname, subdomain, fetchState, resyncSelectedNavigationItem]);
|
|
14899
15975
|
useEffect12(() => {
|
|
14900
15976
|
if (!isEditMode) return;
|
|
15977
|
+
let lastPosted = 0;
|
|
14901
15978
|
const measure = () => {
|
|
14902
15979
|
const h = document.body.scrollHeight;
|
|
14903
|
-
if (h > 50
|
|
15980
|
+
if (h > 50 && Math.abs(h - lastPosted) > 1) {
|
|
15981
|
+
lastPosted = h;
|
|
15982
|
+
postToParent2({ type: "ow:height", height: h });
|
|
15983
|
+
}
|
|
15984
|
+
};
|
|
15985
|
+
let raf = null;
|
|
15986
|
+
const schedule = () => {
|
|
15987
|
+
if (raf != null) return;
|
|
15988
|
+
raf = requestAnimationFrame(() => {
|
|
15989
|
+
raf = null;
|
|
15990
|
+
measure();
|
|
15991
|
+
});
|
|
14904
15992
|
};
|
|
14905
15993
|
const t1 = setTimeout(measure, 50);
|
|
14906
15994
|
const t2 = setTimeout(measure, 500);
|
|
14907
|
-
|
|
14908
|
-
|
|
14909
|
-
const handleResize = () => {
|
|
14910
|
-
if (window.innerWidth === lastWidth) return;
|
|
14911
|
-
lastWidth = window.innerWidth;
|
|
14912
|
-
if (resizeTimer) clearTimeout(resizeTimer);
|
|
14913
|
-
resizeTimer = setTimeout(measure, 150);
|
|
14914
|
-
};
|
|
14915
|
-
window.addEventListener("resize", handleResize);
|
|
15995
|
+
const ro = new ResizeObserver(schedule);
|
|
15996
|
+
ro.observe(document.body);
|
|
14916
15997
|
return () => {
|
|
14917
15998
|
clearTimeout(t1);
|
|
14918
15999
|
clearTimeout(t2);
|
|
14919
|
-
if (
|
|
14920
|
-
|
|
16000
|
+
if (raf != null) cancelAnimationFrame(raf);
|
|
16001
|
+
ro.disconnect();
|
|
14921
16002
|
};
|
|
14922
16003
|
}, [pathname, isEditMode, postToParent2]);
|
|
14923
16004
|
useEffect12(() => {
|
|
@@ -14987,9 +16068,12 @@ function OhhwellsBridge() {
|
|
|
14987
16068
|
[data-ohw-editable="video"], [data-ohw-editable="video"] *,
|
|
14988
16069
|
[data-ohw-editable="bg-image"], [data-ohw-editable="bg-image"] * { cursor: pointer !important; }
|
|
14989
16070
|
[data-ohw-editable="link"], [data-ohw-editable="link"] * { cursor: pointer !important; }
|
|
16071
|
+
/* Text hover chrome is drawn by the overlay (see hoveredTextRect) \u2014 the CSS outline
|
|
16072
|
+
that used to draw it dashes denser than the overlay border, so identical specs
|
|
16073
|
+
still read as two different frames (OHH-695). The attribute stays: hover paths
|
|
16074
|
+
and suppression rules key off it. */
|
|
14990
16075
|
[data-ohw-hovered]:not([contenteditable]):not([data-ohw-href-key]) {
|
|
14991
|
-
outline:
|
|
14992
|
-
outline-offset: 4px;
|
|
16076
|
+
outline: none !important;
|
|
14993
16077
|
}
|
|
14994
16078
|
[data-ohw-href-key] [data-ohw-hovered],
|
|
14995
16079
|
[data-ohw-href-key][data-ohw-hovered],
|
|
@@ -15042,8 +16126,11 @@ function OhhwellsBridge() {
|
|
|
15042
16126
|
stateViews.textContent = `
|
|
15043
16127
|
[data-ohw-state-view]:not([data-ohw-state-view="default"]) { display: none; }
|
|
15044
16128
|
[data-ohw-state-view="default"] [data-ohw-editable] { pointer-events: auto !important; }
|
|
15045
|
-
[data-ohw-state-hovered] { outline:
|
|
16129
|
+
[data-ohw-state-hovered] { outline: ${HOVER_STROKE_WIDTH}px dashed ${CHROME_PRIMARY} !important; outline-offset: ${HOVER_CHROME_GAP}px; }
|
|
15046
16130
|
[data-ohw-state-hovered]:has([data-ohw-hovered]) { outline: none !important; }
|
|
16131
|
+
/* :has() only sees descendants \u2014 when the card itself is the hovered text, the overlay
|
|
16132
|
+
already frames it, and the card outline doubled it (OHH-695). */
|
|
16133
|
+
[data-ohw-state-hovered][data-ohw-hovered] { outline: none !important; }
|
|
15047
16134
|
`;
|
|
15048
16135
|
document.head.appendChild(base);
|
|
15049
16136
|
document.head.appendChild(forceHover);
|
|
@@ -15061,10 +16148,12 @@ function OhhwellsBridge() {
|
|
|
15061
16148
|
return;
|
|
15062
16149
|
}
|
|
15063
16150
|
const target = e.target;
|
|
16151
|
+
if (target.closest("[data-ohw-ai-review]")) return;
|
|
15064
16152
|
if (target.closest("[data-ohw-toolbar]")) return;
|
|
15065
16153
|
if (target.closest("[data-ohw-state-toggle]")) return;
|
|
15066
16154
|
if (target.closest("[data-ohw-max-badge]")) return;
|
|
15067
16155
|
if (isInsideLinkEditor(target)) return;
|
|
16156
|
+
if (isInsideFloatingPanel(target)) return;
|
|
15068
16157
|
if (target.closest('[data-ohw-edit-chrome], [data-ohw-item-interaction], [data-ohw-drag-handle-container], [data-slot="drag-handle"]')) {
|
|
15069
16158
|
const beneath = document.elementsFromPoint(e.clientX, e.clientY).find(
|
|
15070
16159
|
(el) => el instanceof HTMLElement && !el.closest("[data-ohw-bridge-root]") && el.closest("[data-ohw-section]") != null
|
|
@@ -15128,6 +16217,21 @@ function OhhwellsBridge() {
|
|
|
15128
16217
|
return;
|
|
15129
16218
|
}
|
|
15130
16219
|
}
|
|
16220
|
+
const logoEl = getLogoElement(target);
|
|
16221
|
+
if (logoEl) {
|
|
16222
|
+
e.preventDefault();
|
|
16223
|
+
e.stopPropagation();
|
|
16224
|
+
if (!logoHasUploadedImage(logoEl)) {
|
|
16225
|
+
deselectRef.current();
|
|
16226
|
+
deactivateRef.current();
|
|
16227
|
+
const identity = readLogoIdentityFromDom();
|
|
16228
|
+
postToParentRef.current({ type: "ow:open-logo-settings", ...identity });
|
|
16229
|
+
return;
|
|
16230
|
+
}
|
|
16231
|
+
selectLogoRef.current(logoEl);
|
|
16232
|
+
openLogoSizePanelRef.current(logoEl);
|
|
16233
|
+
return;
|
|
16234
|
+
}
|
|
15131
16235
|
const editable = target.closest("[data-ohw-editable]");
|
|
15132
16236
|
if (editable) {
|
|
15133
16237
|
if (editable.dataset.ohwEditable === "link") {
|
|
@@ -15280,10 +16384,12 @@ function OhhwellsBridge() {
|
|
|
15280
16384
|
};
|
|
15281
16385
|
const handleDblClick = (e) => {
|
|
15282
16386
|
const target = e.target;
|
|
16387
|
+
if (target.closest("[data-ohw-ai-review]")) return;
|
|
15283
16388
|
if (target.closest("[data-ohw-toolbar]")) return;
|
|
15284
16389
|
if (target.closest("[data-ohw-state-toggle]")) return;
|
|
15285
16390
|
if (target.closest("[data-ohw-max-badge]")) return;
|
|
15286
16391
|
if (isInsideLinkEditor(target)) return;
|
|
16392
|
+
if (isInsideFloatingPanel(target)) return;
|
|
15287
16393
|
if (target.closest('[data-ohw-edit-chrome], [data-ohw-item-interaction], [data-ohw-drag-handle-container], [data-slot="drag-handle"]')) {
|
|
15288
16394
|
return;
|
|
15289
16395
|
}
|
|
@@ -15311,6 +16417,16 @@ function OhhwellsBridge() {
|
|
|
15311
16417
|
setHoveredNavContainerRect(null);
|
|
15312
16418
|
return;
|
|
15313
16419
|
}
|
|
16420
|
+
if (document.documentElement.hasAttribute("data-ohw-panel-dragging") || isInsideFloatingPanel(target) || isPointOverFloatingPanel(e.clientX, e.clientY)) {
|
|
16421
|
+
hoveredItemElRef.current = null;
|
|
16422
|
+
setHoveredItemRect(null);
|
|
16423
|
+
hoveredNavContainerRef.current = null;
|
|
16424
|
+
setHoveredNavContainerRect(null);
|
|
16425
|
+
siblingHintElRef.current = null;
|
|
16426
|
+
setSiblingHintRect(null);
|
|
16427
|
+
setSiblingHintRects([]);
|
|
16428
|
+
return;
|
|
16429
|
+
}
|
|
15314
16430
|
{
|
|
15315
16431
|
const selected2 = selectedElRef.current;
|
|
15316
16432
|
const selectedIsFooterColumn = Boolean(selected2) && !isFooterLinksContainer(selected2) && (selected2.hasAttribute("data-ohw-footer-col") || selected2.hasAttribute("data-ohw-footer-column") || Boolean(selected2.closest("footer") && isInferredFooterGroup2(selected2)));
|
|
@@ -15318,7 +16434,7 @@ function OhhwellsBridge() {
|
|
|
15318
16434
|
const allowFooterLinksHover = toolbarVariantRef.current !== "select-frame" || selectedIsFooterColumn;
|
|
15319
16435
|
if (allowNavContainerHover) {
|
|
15320
16436
|
const navContainer = target.closest("[data-ohw-nav-container]");
|
|
15321
|
-
if (navContainer && !getNavigationItemAnchor(target)) {
|
|
16437
|
+
if (navContainer && !getNavigationItemAnchor(target) && !getLogoElement(target)) {
|
|
15322
16438
|
hoveredNavContainerRef.current = navContainer;
|
|
15323
16439
|
setHoveredNavContainerRect(navContainer.getBoundingClientRect());
|
|
15324
16440
|
hoveredItemElRef.current = null;
|
|
@@ -15347,6 +16463,15 @@ function OhhwellsBridge() {
|
|
|
15347
16463
|
setHoveredNavContainerRect(null);
|
|
15348
16464
|
}
|
|
15349
16465
|
}
|
|
16466
|
+
const logoEl = getLogoElement(target);
|
|
16467
|
+
if (logoEl) {
|
|
16468
|
+
hoveredNavContainerRef.current = null;
|
|
16469
|
+
setHoveredNavContainerRect(null);
|
|
16470
|
+
if (selectedElRef.current === logoEl) return;
|
|
16471
|
+
hoveredItemElRef.current = logoEl;
|
|
16472
|
+
setHoveredItemRect(getLogoInteractionRect(logoEl));
|
|
16473
|
+
return;
|
|
16474
|
+
}
|
|
15350
16475
|
const navAnchor = getNavigationItemAnchor(target);
|
|
15351
16476
|
if (navAnchor) {
|
|
15352
16477
|
hoveredNavContainerRef.current = null;
|
|
@@ -15384,6 +16509,11 @@ function OhhwellsBridge() {
|
|
|
15384
16509
|
setHoveredItemRect(hoverTarget.getBoundingClientRect());
|
|
15385
16510
|
} else if (!isInsideNavigationItem(editable)) {
|
|
15386
16511
|
hoverTarget.setAttribute("data-ohw-hovered", "");
|
|
16512
|
+
if (editable.closest("footer") || editable.closest('[data-ohw-section="footer"]')) {
|
|
16513
|
+
hoveredNavContainerRef.current = null;
|
|
16514
|
+
setHoveredNavContainerRect(null);
|
|
16515
|
+
hoveredItemElRef.current = editable;
|
|
16516
|
+
}
|
|
15387
16517
|
}
|
|
15388
16518
|
}
|
|
15389
16519
|
};
|
|
@@ -15419,6 +16549,18 @@ function OhhwellsBridge() {
|
|
|
15419
16549
|
}
|
|
15420
16550
|
return;
|
|
15421
16551
|
}
|
|
16552
|
+
const logoEl = getLogoElement(target);
|
|
16553
|
+
if (logoEl) {
|
|
16554
|
+
const related2 = e.relatedTarget instanceof Element ? e.relatedTarget : null;
|
|
16555
|
+
if (related2 && (logoEl === related2 || logoEl.contains(related2) || related2.closest?.('[data-ohw-role="logo"], [data-ohw-logo]'))) {
|
|
16556
|
+
return;
|
|
16557
|
+
}
|
|
16558
|
+
if (hoveredItemElRef.current === logoEl) {
|
|
16559
|
+
hoveredItemElRef.current = null;
|
|
16560
|
+
setHoveredItemRect(null);
|
|
16561
|
+
}
|
|
16562
|
+
return;
|
|
16563
|
+
}
|
|
15422
16564
|
const editable = target.closest("[data-ohw-editable]");
|
|
15423
16565
|
if (!editable) return;
|
|
15424
16566
|
const related = e.relatedTarget instanceof Element ? e.relatedTarget : null;
|
|
@@ -15439,6 +16581,13 @@ function OhhwellsBridge() {
|
|
|
15439
16581
|
}
|
|
15440
16582
|
} else {
|
|
15441
16583
|
hoverTarget.removeAttribute("data-ohw-hovered");
|
|
16584
|
+
if (hoveredItemElRef.current === editable) {
|
|
16585
|
+
const stillOnEditable = related instanceof Element && related.closest("[data-ohw-editable]") === editable;
|
|
16586
|
+
if (!stillOnEditable) {
|
|
16587
|
+
hoveredItemElRef.current = null;
|
|
16588
|
+
setHoveredItemRect(null);
|
|
16589
|
+
}
|
|
16590
|
+
}
|
|
15442
16591
|
}
|
|
15443
16592
|
}
|
|
15444
16593
|
};
|
|
@@ -15555,6 +16704,26 @@ function OhhwellsBridge() {
|
|
|
15555
16704
|
hoveredNavContainerRef.current = null;
|
|
15556
16705
|
setHoveredNavContainerRect(null);
|
|
15557
16706
|
}
|
|
16707
|
+
const logoCandidates = [
|
|
16708
|
+
...document.querySelectorAll('[data-ohw-role="logo"], [data-ohw-logo]'),
|
|
16709
|
+
...document.querySelectorAll("nav a:not([data-ohw-href-key]), [data-ohw-nav-root] a:not([data-ohw-href-key])"),
|
|
16710
|
+
...document.querySelectorAll("footer img")
|
|
16711
|
+
];
|
|
16712
|
+
const seenLogos = /* @__PURE__ */ new Set();
|
|
16713
|
+
for (const candidate of logoCandidates) {
|
|
16714
|
+
const logo = getLogoElement(candidate);
|
|
16715
|
+
if (!logo || seenLogos.has(logo)) continue;
|
|
16716
|
+
seenLogos.add(logo);
|
|
16717
|
+
const r2 = logo.getBoundingClientRect();
|
|
16718
|
+
if (x < r2.left || x > r2.right || y < r2.top || y > r2.bottom) continue;
|
|
16719
|
+
hoveredNavContainerRef.current = null;
|
|
16720
|
+
setHoveredNavContainerRect(null);
|
|
16721
|
+
if (selectedElRef.current !== logo) {
|
|
16722
|
+
hoveredItemElRef.current = logo;
|
|
16723
|
+
setHoveredItemRect(getLogoInteractionRect(logo));
|
|
16724
|
+
}
|
|
16725
|
+
return;
|
|
16726
|
+
}
|
|
15558
16727
|
const navContainers = Array.from(
|
|
15559
16728
|
document.querySelectorAll("[data-ohw-nav-container]")
|
|
15560
16729
|
);
|
|
@@ -15640,7 +16809,7 @@ function OhhwellsBridge() {
|
|
|
15640
16809
|
}
|
|
15641
16810
|
};
|
|
15642
16811
|
const probeImageAt = (clientX, clientY, isDragOver = false, fromParentViewport = false) => {
|
|
15643
|
-
if (linkPopoverOpenRef.current) {
|
|
16812
|
+
if (linkPopoverOpenRef.current || floatingPanelOpenRef.current && isPointOverFloatingPanel(clientX, clientY)) {
|
|
15644
16813
|
if (hoveredImageRef.current) {
|
|
15645
16814
|
hoveredImageRef.current = null;
|
|
15646
16815
|
hoveredImageHasTextOverlapRef.current = false;
|
|
@@ -15894,7 +17063,7 @@ function OhhwellsBridge() {
|
|
|
15894
17063
|
}
|
|
15895
17064
|
};
|
|
15896
17065
|
const probeHoverCardsAt = (clientX, clientY, fromParentViewport = false) => {
|
|
15897
|
-
if (linkPopoverOpenRef.current || document.documentElement.hasAttribute("data-ohw-section-picking")) {
|
|
17066
|
+
if (linkPopoverOpenRef.current || floatingPanelOpenRef.current && isPointOverFloatingPanel(clientX, clientY) || document.documentElement.hasAttribute("data-ohw-section-picking")) {
|
|
15898
17067
|
if (activeStateElRef.current) {
|
|
15899
17068
|
activeStateElRef.current.removeAttribute("data-ohw-state-hovered");
|
|
15900
17069
|
activeStateElRef.current = null;
|
|
@@ -15962,6 +17131,19 @@ function OhhwellsBridge() {
|
|
|
15962
17131
|
};
|
|
15963
17132
|
const handleMouseMove = (e) => {
|
|
15964
17133
|
const { clientX, clientY } = e;
|
|
17134
|
+
if (document.documentElement.hasAttribute("data-ohw-panel-dragging") || floatingPanelOpenRef.current && isPointOverFloatingPanel(clientX, clientY)) {
|
|
17135
|
+
hoveredItemElRef.current = null;
|
|
17136
|
+
setHoveredItemRect(null);
|
|
17137
|
+
hoveredNavContainerRef.current = null;
|
|
17138
|
+
setHoveredNavContainerRect(null);
|
|
17139
|
+
siblingHintElRef.current = null;
|
|
17140
|
+
setSiblingHintRect(null);
|
|
17141
|
+
setSiblingHintRects([]);
|
|
17142
|
+
dismissImageHover();
|
|
17143
|
+
clearImageHover();
|
|
17144
|
+
setSectionGap(null);
|
|
17145
|
+
return;
|
|
17146
|
+
}
|
|
15965
17147
|
probeSectionGapAt(clientX, clientY);
|
|
15966
17148
|
probeImageAt(clientX, clientY);
|
|
15967
17149
|
probeHoverCardsAt(clientX, clientY);
|
|
@@ -15970,6 +17152,11 @@ function OhhwellsBridge() {
|
|
|
15970
17152
|
if (e.data?.type !== "ow:pointer-sync") return;
|
|
15971
17153
|
const { clientX, clientY } = e.data;
|
|
15972
17154
|
if (typeof clientX !== "number" || typeof clientY !== "number") return;
|
|
17155
|
+
if (document.documentElement.hasAttribute("data-ohw-panel-dragging") || floatingPanelOpenRef.current && isPointOverFloatingPanel(clientX, clientY)) {
|
|
17156
|
+
dismissImageHover();
|
|
17157
|
+
clearImageHover();
|
|
17158
|
+
return;
|
|
17159
|
+
}
|
|
15973
17160
|
probeSectionGapAt(clientX, clientY);
|
|
15974
17161
|
probeImageAt(clientX, clientY);
|
|
15975
17162
|
probeHoverCardsAt(clientX, clientY);
|
|
@@ -16219,6 +17406,15 @@ function OhhwellsBridge() {
|
|
|
16219
17406
|
aiSectionsRef.current = content[AI_SECTIONS_KEY];
|
|
16220
17407
|
applyAiSectionsToDom(parseAiSectionsState(content[AI_SECTIONS_KEY]));
|
|
16221
17408
|
}
|
|
17409
|
+
if (typeof content[BRAND_KIT_KEY] === "string") {
|
|
17410
|
+
brandKitRef.current = content[BRAND_KIT_KEY];
|
|
17411
|
+
applyBrandToDom(parseBrandKit(content[BRAND_KIT_KEY]));
|
|
17412
|
+
}
|
|
17413
|
+
if (typeof content[STYLE_STORE_KEY] === "string") {
|
|
17414
|
+
stylesRef.current = content[STYLE_STORE_KEY];
|
|
17415
|
+
applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
|
|
17416
|
+
}
|
|
17417
|
+
applyBrandChrome(content);
|
|
16222
17418
|
let sectionsJson = null;
|
|
16223
17419
|
for (const [key, val] of Object.entries(content)) {
|
|
16224
17420
|
if (key === "__ohw_sections") {
|
|
@@ -16226,6 +17422,11 @@ function OhhwellsBridge() {
|
|
|
16226
17422
|
continue;
|
|
16227
17423
|
}
|
|
16228
17424
|
if (key === AI_SECTIONS_KEY) continue;
|
|
17425
|
+
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
17426
|
+
if (LOGO_IMAGE_KEYS.includes(key) && !String(val ?? "").trim()) continue;
|
|
17427
|
+
if (key === BRAND_KIT_KEY) continue;
|
|
17428
|
+
if (key === STYLE_STORE_KEY) continue;
|
|
17429
|
+
if (BRAND_CHROME_KEYS.has(key)) continue;
|
|
16229
17430
|
if (applyVideoSettingNode(key, val)) continue;
|
|
16230
17431
|
if (applyCarouselNode(key, val)) continue;
|
|
16231
17432
|
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
@@ -16245,6 +17446,8 @@ function OhhwellsBridge() {
|
|
|
16245
17446
|
});
|
|
16246
17447
|
applyLinkByKey(key, val);
|
|
16247
17448
|
}
|
|
17449
|
+
applyLogoFromContent(content);
|
|
17450
|
+
applyLogoSizes(content);
|
|
16248
17451
|
if (sectionsJson) {
|
|
16249
17452
|
initSectionsFromContent({ __ohw_sections: sectionsJson }, true);
|
|
16250
17453
|
sectionsLoadedRef.current = true;
|
|
@@ -16260,6 +17463,58 @@ function OhhwellsBridge() {
|
|
|
16260
17463
|
if (hydratedHeight > 50) postToParentRef.current({ type: "ow:height", height: hydratedHeight });
|
|
16261
17464
|
postToParentRef.current({ type: "ow:hydrate-done" });
|
|
16262
17465
|
};
|
|
17466
|
+
const handleUpdateLogoIdentity = (e) => {
|
|
17467
|
+
if (e.data?.type !== "ow:update-logo-identity") return;
|
|
17468
|
+
const rawText = typeof e.data.text === "string" ? e.data.text : "";
|
|
17469
|
+
const alt = typeof e.data.alt === "string" ? e.data.alt : rawText;
|
|
17470
|
+
const href = typeof e.data.href === "string" ? e.data.href : void 0;
|
|
17471
|
+
const imageProvided = "image" in e.data;
|
|
17472
|
+
const imageUrl = imageProvided && typeof e.data.image === "string" && e.data.image.trim() ? e.data.image.trim() : imageProvided ? null : void 0;
|
|
17473
|
+
let isPlaceholder = e.data.isPlaceholder !== false;
|
|
17474
|
+
if (imageUrl) isPlaceholder = false;
|
|
17475
|
+
else if (imageProvided && imageUrl === null) {
|
|
17476
|
+
isPlaceholder = e.data.isPlaceholder === true || !rawText.trim() || resolveLogoDisplayText(rawText) === PLACEHOLDER_BUSINESS_NAME;
|
|
17477
|
+
}
|
|
17478
|
+
const display = applyLogoIdentity(rawText, isPlaceholder);
|
|
17479
|
+
const displayAlt = resolveLogoDisplayText(alt || display);
|
|
17480
|
+
if (imageUrl !== void 0) {
|
|
17481
|
+
applyLogoImage(imageUrl, displayAlt);
|
|
17482
|
+
} else {
|
|
17483
|
+
for (const key of LOGO_IMAGE_KEYS) {
|
|
17484
|
+
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
17485
|
+
const img = el instanceof HTMLImageElement ? el : el.querySelector("img");
|
|
17486
|
+
if (img) img.alt = displayAlt;
|
|
17487
|
+
});
|
|
17488
|
+
}
|
|
17489
|
+
}
|
|
17490
|
+
if (href !== void 0) {
|
|
17491
|
+
applyLogoHref(href);
|
|
17492
|
+
applyLinkByKey("nav-logo-href", href);
|
|
17493
|
+
applyLinkByKey("footer-logo-href", href);
|
|
17494
|
+
applyLinkByKey("logo-href", href);
|
|
17495
|
+
}
|
|
17496
|
+
const nodes = [
|
|
17497
|
+
...LOGO_TEXT_KEYS.map((key) => ({ key, text: display })),
|
|
17498
|
+
{ key: LOGO_PLACEHOLDER_KEY, text: isPlaceholder ? "true" : "false" },
|
|
17499
|
+
{ key: LOGO_ALT_KEY, text: displayAlt }
|
|
17500
|
+
];
|
|
17501
|
+
if (imageUrl !== void 0) {
|
|
17502
|
+
if (imageUrl) {
|
|
17503
|
+
for (const key of LOGO_IMAGE_KEYS) nodes.push({ key, text: imageUrl });
|
|
17504
|
+
} else {
|
|
17505
|
+
for (const key of LOGO_IMAGE_KEYS) nodes.push({ key, text: "" });
|
|
17506
|
+
}
|
|
17507
|
+
}
|
|
17508
|
+
if (href !== void 0) {
|
|
17509
|
+
for (const key of LOGO_HREF_KEYS) nodes.push({ key, text: href.trim() || "/" });
|
|
17510
|
+
}
|
|
17511
|
+
editContentRef.current = {
|
|
17512
|
+
...editContentRef.current,
|
|
17513
|
+
...Object.fromEntries(nodes.map(({ key, text }) => [key, text]))
|
|
17514
|
+
};
|
|
17515
|
+
applyLogoSizes(editContentRef.current);
|
|
17516
|
+
postToParentRef.current({ type: "ow:change", nodes });
|
|
17517
|
+
};
|
|
16263
17518
|
window.addEventListener("message", handleHydrate);
|
|
16264
17519
|
const postAiSectionsChanged = () => {
|
|
16265
17520
|
postToParentRef.current({
|
|
@@ -16273,7 +17528,10 @@ function OhhwellsBridge() {
|
|
|
16273
17528
|
const payload = e.data.payload;
|
|
16274
17529
|
if (!payload || typeof payload.id !== "string" || !isRenderableTree(payload.tree)) return;
|
|
16275
17530
|
const previous = aiSectionsRef.current;
|
|
16276
|
-
const nextState = applyTreeToState(parseAiSectionsState(previous),
|
|
17531
|
+
const nextState = applyTreeToState(parseAiSectionsState(previous), {
|
|
17532
|
+
...payload,
|
|
17533
|
+
path: payload.path ?? window.location.pathname
|
|
17534
|
+
});
|
|
16277
17535
|
const nextValue = serializeAiSectionsState(nextState);
|
|
16278
17536
|
aiSectionsRef.current = nextValue;
|
|
16279
17537
|
applyAiSectionsToDom(nextState);
|
|
@@ -16310,12 +17568,42 @@ function OhhwellsBridge() {
|
|
|
16310
17568
|
const value = typeof e.data.value === "string" ? e.data.value : "";
|
|
16311
17569
|
aiSectionsRef.current = value;
|
|
16312
17570
|
applyAiSectionsToDom(parseAiSectionsState(value));
|
|
17571
|
+
applyStylesToDom(parseStyleStore(stylesRef.current));
|
|
16313
17572
|
const restoredHeight = document.documentElement.scrollHeight;
|
|
16314
17573
|
if (restoredHeight > 50) postToParentRef.current({ type: "ow:height", height: restoredHeight });
|
|
16315
17574
|
postToParentRef.current({ type: "ow:change", nodes: [{ key: AI_SECTIONS_KEY, text: value }] });
|
|
16316
17575
|
postAiSectionsChanged();
|
|
16317
17576
|
};
|
|
16318
17577
|
window.addEventListener("message", handleAiSetSections);
|
|
17578
|
+
const handleAiSetBrand = (e) => {
|
|
17579
|
+
if (e.data?.type !== "ow:ai-set-brand") return;
|
|
17580
|
+
const value = typeof e.data.value === "string" ? e.data.value : "";
|
|
17581
|
+
const previous = brandKitRef.current;
|
|
17582
|
+
brandKitRef.current = value;
|
|
17583
|
+
applyBrandToDom(parseBrandKit(value));
|
|
17584
|
+
if (aiSectionsRef.current) applyAiSectionsToDom(parseAiSectionsState(aiSectionsRef.current));
|
|
17585
|
+
applyStylesToDom(parseStyleStore(stylesRef.current));
|
|
17586
|
+
postToParentRef.current({ type: "ow:change", nodes: [{ key: BRAND_KIT_KEY, text: value }] });
|
|
17587
|
+
postToParentRef.current({ type: "ow:ai-brand-applied", previous, value });
|
|
17588
|
+
};
|
|
17589
|
+
window.addEventListener("message", handleAiSetBrand);
|
|
17590
|
+
const handleAiSetStyles = (e) => {
|
|
17591
|
+
if (e.data?.type !== "ow:ai-set-styles") return;
|
|
17592
|
+
const value = typeof e.data.value === "string" ? e.data.value : "";
|
|
17593
|
+
const previous = stylesRef.current;
|
|
17594
|
+
stylesRef.current = value;
|
|
17595
|
+
applyStylesToDom(parseStyleStore(value));
|
|
17596
|
+
postToParentRef.current({ type: "ow:change", nodes: [{ key: STYLE_STORE_KEY, text: value }] });
|
|
17597
|
+
postToParentRef.current({ type: "ow:ai-styles-applied", previous, value });
|
|
17598
|
+
};
|
|
17599
|
+
window.addEventListener("message", handleAiSetStyles);
|
|
17600
|
+
const handleGetBrand = (e) => {
|
|
17601
|
+
if (e.data?.type !== "ow:get-brand") return;
|
|
17602
|
+
const template = deriveTemplateBrand();
|
|
17603
|
+
const value = brandKitRef.current || (template ? JSON.stringify(template) : "");
|
|
17604
|
+
postToParentRef.current({ type: "ow:brand-value", value });
|
|
17605
|
+
};
|
|
17606
|
+
window.addEventListener("message", handleGetBrand);
|
|
16319
17607
|
const handleDeactivate = (e) => {
|
|
16320
17608
|
if (e.data?.type !== "ow:deactivate") return;
|
|
16321
17609
|
if (Date.now() < linkPopoverGraceUntilRef.current) return;
|
|
@@ -16324,6 +17612,12 @@ function OhhwellsBridge() {
|
|
|
16324
17612
|
closeLinkPopoverRef.current();
|
|
16325
17613
|
return;
|
|
16326
17614
|
}
|
|
17615
|
+
if (floatingPanelOpenRef.current) {
|
|
17616
|
+
setFloatingPanelRef.current(null);
|
|
17617
|
+
deselectRef.current();
|
|
17618
|
+
deactivateRef.current();
|
|
17619
|
+
return;
|
|
17620
|
+
}
|
|
16327
17621
|
deselectRef.current();
|
|
16328
17622
|
deactivateRef.current();
|
|
16329
17623
|
};
|
|
@@ -16377,6 +17671,10 @@ function OhhwellsBridge() {
|
|
|
16377
17671
|
return;
|
|
16378
17672
|
}
|
|
16379
17673
|
if (selectedElRef.current) {
|
|
17674
|
+
if (toolbarVariantRef.current === "logo") {
|
|
17675
|
+
deselectRef.current();
|
|
17676
|
+
return;
|
|
17677
|
+
}
|
|
16380
17678
|
if (toolbarVariantRef.current === "select-frame") {
|
|
16381
17679
|
const parent2 = getNavigationSelectionParent(selectedElRef.current);
|
|
16382
17680
|
if (parent2 && isNavigationContainer(parent2) && isFooterLinksContainer(parent2) && !isFooterLinksContainer(selectedElRef.current)) {
|
|
@@ -16416,6 +17714,10 @@ function OhhwellsBridge() {
|
|
|
16416
17714
|
return;
|
|
16417
17715
|
}
|
|
16418
17716
|
if (e.key === "Escape" && selectedElRef.current && !activeElRef.current) {
|
|
17717
|
+
if (toolbarVariantRef.current === "logo") {
|
|
17718
|
+
deselectRef.current();
|
|
17719
|
+
return;
|
|
17720
|
+
}
|
|
16419
17721
|
if (toolbarVariantRef.current === "select-frame") {
|
|
16420
17722
|
const parent2 = getNavigationSelectionParent(selectedElRef.current);
|
|
16421
17723
|
if (parent2 && isNavigationContainer(parent2) && isFooterLinksContainer(parent2) && !isFooterLinksContainer(selectedElRef.current)) {
|
|
@@ -16493,7 +17795,8 @@ function OhhwellsBridge() {
|
|
|
16493
17795
|
const handleScroll = () => {
|
|
16494
17796
|
const focusEl = activeElRef.current ?? selectedElRef.current;
|
|
16495
17797
|
if (focusEl) {
|
|
16496
|
-
const
|
|
17798
|
+
const measureEl = activeElRef.current ? getEditMeasureEl(activeElRef.current) : toolbarVariantRef.current === "logo" ? null : focusEl;
|
|
17799
|
+
const r2 = measureEl ? measureEl.getBoundingClientRect() : toolbarVariantRef.current === "logo" ? getLogoInteractionRect(focusEl) : focusEl.getBoundingClientRect();
|
|
16497
17800
|
applyToolbarPos(r2);
|
|
16498
17801
|
setToolbarRect(r2);
|
|
16499
17802
|
setMaxBadge((prev) => prev && activeElRef.current ? { ...prev, rect: r2 } : prev);
|
|
@@ -16503,7 +17806,9 @@ function OhhwellsBridge() {
|
|
|
16503
17806
|
setToggleState((prev) => prev ? { ...prev, rect } : null);
|
|
16504
17807
|
}
|
|
16505
17808
|
if (hoveredItemElRef.current) {
|
|
16506
|
-
|
|
17809
|
+
const hoverEl = hoveredItemElRef.current;
|
|
17810
|
+
const logo = getLogoElement(hoverEl);
|
|
17811
|
+
setHoveredItemRect(logo ? getLogoInteractionRect(logo) : hoverEl.getBoundingClientRect());
|
|
16507
17812
|
}
|
|
16508
17813
|
if (hoveredNavContainerRef.current) {
|
|
16509
17814
|
setHoveredNavContainerRect(hoveredNavContainerRef.current.getBoundingClientRect());
|
|
@@ -16547,6 +17852,12 @@ function OhhwellsBridge() {
|
|
|
16547
17852
|
if (aiSectionsRef.current) {
|
|
16548
17853
|
nodes.push({ key: AI_SECTIONS_KEY, type: "sections", text: aiSectionsRef.current });
|
|
16549
17854
|
}
|
|
17855
|
+
if (stylesRef.current) {
|
|
17856
|
+
nodes.push({ key: STYLE_STORE_KEY, type: "styles", text: stylesRef.current });
|
|
17857
|
+
}
|
|
17858
|
+
if (brandKitRef.current) {
|
|
17859
|
+
nodes.push({ key: BRAND_KIT_KEY, type: "brand", text: brandKitRef.current });
|
|
17860
|
+
}
|
|
16550
17861
|
postToParentRef.current({ type: "ow:save-result", nodes });
|
|
16551
17862
|
};
|
|
16552
17863
|
const handleInsertSection = (e) => {
|
|
@@ -16557,8 +17868,12 @@ function OhhwellsBridge() {
|
|
|
16557
17868
|
if (inserted) {
|
|
16558
17869
|
const tracker = getSectionsTracker();
|
|
16559
17870
|
postToParentRef.current({ type: "ow:change", nodes: [{ key: "__ohw_sections", text: tracker.textContent ?? "[]" }] });
|
|
16560
|
-
const
|
|
16561
|
-
|
|
17871
|
+
const reportHeight = () => {
|
|
17872
|
+
const h = document.body.scrollHeight;
|
|
17873
|
+
if (h > 50) postToParentRef.current({ type: "ow:height", height: h });
|
|
17874
|
+
};
|
|
17875
|
+
reportHeight();
|
|
17876
|
+
setTimeout(reportHeight, 500);
|
|
16562
17877
|
}
|
|
16563
17878
|
};
|
|
16564
17879
|
const handleSwitchSchedule = (e) => {
|
|
@@ -16751,13 +18066,17 @@ function OhhwellsBridge() {
|
|
|
16751
18066
|
if (e.data?.type !== "ow:parent-scroll") return;
|
|
16752
18067
|
const { iframeOffsetTop, headerH, canvasH } = e.data;
|
|
16753
18068
|
parentScrollRef.current = { iframeOffsetTop, headerH, canvasH };
|
|
18069
|
+
if (floatingPanelOpenRef.current) {
|
|
18070
|
+
setParentScrollSnap({ iframeOffsetTop, headerH, canvasH });
|
|
18071
|
+
}
|
|
16754
18072
|
if (visibleViewportRef.current) {
|
|
16755
18073
|
applyVisibleViewport(visibleViewportRef.current, parentScrollRef.current);
|
|
16756
18074
|
}
|
|
16757
18075
|
const focusEl = activeElRef.current ?? selectedElRef.current;
|
|
16758
18076
|
if (focusEl) {
|
|
16759
|
-
const measureEl = activeElRef.current ? getEditMeasureEl(activeElRef.current) : focusEl;
|
|
16760
|
-
|
|
18077
|
+
const measureEl = activeElRef.current ? getEditMeasureEl(activeElRef.current) : toolbarVariantRef.current === "logo" ? null : focusEl;
|
|
18078
|
+
const r2 = measureEl ? measureEl.getBoundingClientRect() : toolbarVariantRef.current === "logo" ? getLogoInteractionRect(focusEl) : focusEl.getBoundingClientRect();
|
|
18079
|
+
applyToolbarPos(r2);
|
|
16761
18080
|
}
|
|
16762
18081
|
};
|
|
16763
18082
|
const handleClickAt = (e) => {
|
|
@@ -16782,6 +18101,25 @@ function OhhwellsBridge() {
|
|
|
16782
18101
|
postToParentRef.current({ type: "ow:image-pick", key: stateCardImage.dataset.ohwKey ?? "", elementType: stateCardImage.dataset.ohwEditable ?? "image" });
|
|
16783
18102
|
return;
|
|
16784
18103
|
}
|
|
18104
|
+
const logoAtPoint = Array.from(
|
|
18105
|
+
document.querySelectorAll('[data-ohw-role="logo"], [data-ohw-logo]')
|
|
18106
|
+
).map((el) => getLogoElement(el)).find((logo) => {
|
|
18107
|
+
if (!logo) return false;
|
|
18108
|
+
const r2 = logo.getBoundingClientRect();
|
|
18109
|
+
return clientX >= r2.left && clientX <= r2.right && clientY >= r2.top && clientY <= r2.bottom;
|
|
18110
|
+
});
|
|
18111
|
+
if (logoAtPoint) {
|
|
18112
|
+
if (!logoHasUploadedImage(logoAtPoint)) {
|
|
18113
|
+
deselectRef.current();
|
|
18114
|
+
deactivateRef.current();
|
|
18115
|
+
const identity = readLogoIdentityFromDom();
|
|
18116
|
+
postToParentRef.current({ type: "ow:open-logo-settings", ...identity });
|
|
18117
|
+
return;
|
|
18118
|
+
}
|
|
18119
|
+
selectLogoRef.current(logoAtPoint);
|
|
18120
|
+
openLogoSizePanelRef.current(logoAtPoint);
|
|
18121
|
+
return;
|
|
18122
|
+
}
|
|
16785
18123
|
const textEditable = Array.from(
|
|
16786
18124
|
document.querySelectorAll(NON_MEDIA_SELECTOR)
|
|
16787
18125
|
).find((el) => {
|
|
@@ -16853,6 +18191,14 @@ function OhhwellsBridge() {
|
|
|
16853
18191
|
window.addEventListener("message", handleParentScroll);
|
|
16854
18192
|
window.addEventListener("message", handlePointerSync);
|
|
16855
18193
|
window.addEventListener("message", handleClickAt);
|
|
18194
|
+
window.addEventListener("message", handleUpdateLogoIdentity);
|
|
18195
|
+
const handleViewMode = (e) => {
|
|
18196
|
+
if (e.data?.type !== "ow:view-mode") return;
|
|
18197
|
+
const mode = e.data.mode === "Mobile" || e.data.mode === "mobile" ? "mobile" : "desktop";
|
|
18198
|
+
setEditorViewport(mode);
|
|
18199
|
+
applyLogoSizes(editContentRef.current);
|
|
18200
|
+
};
|
|
18201
|
+
window.addEventListener("message", handleViewMode);
|
|
16856
18202
|
const handleViewportResize = () => {
|
|
16857
18203
|
if (visibleViewportRef.current) {
|
|
16858
18204
|
applyVisibleViewport(visibleViewportRef.current, parentScrollRef.current);
|
|
@@ -16908,10 +18254,15 @@ function OhhwellsBridge() {
|
|
|
16908
18254
|
window.removeEventListener("resize", handleViewportResize);
|
|
16909
18255
|
window.removeEventListener("message", handlePointerSync);
|
|
16910
18256
|
window.removeEventListener("message", handleClickAt);
|
|
18257
|
+
window.removeEventListener("message", handleUpdateLogoIdentity);
|
|
18258
|
+
window.removeEventListener("message", handleViewMode);
|
|
16911
18259
|
window.removeEventListener("message", handleHydrate);
|
|
16912
18260
|
window.removeEventListener("message", handleAiApplyTree);
|
|
16913
18261
|
window.removeEventListener("message", handleAiDeleteSection);
|
|
16914
18262
|
window.removeEventListener("message", handleAiSetSections);
|
|
18263
|
+
window.removeEventListener("message", handleAiSetBrand);
|
|
18264
|
+
window.removeEventListener("message", handleAiSetStyles);
|
|
18265
|
+
window.removeEventListener("message", handleGetBrand);
|
|
16915
18266
|
window.removeEventListener("message", handleDeactivate);
|
|
16916
18267
|
window.removeEventListener("message", handleToastAction);
|
|
16917
18268
|
window.removeEventListener("message", handleUiEscape);
|
|
@@ -16937,7 +18288,7 @@ function OhhwellsBridge() {
|
|
|
16937
18288
|
if (footerDragRef.current) return;
|
|
16938
18289
|
const target = e.target;
|
|
16939
18290
|
if (!target) return;
|
|
16940
|
-
if (target.closest('[data-ohw-drag-handle-container], [data-slot="drag-handle"], [data-ohw-toolbar], [data-ohw-item-toolbar-anchor], [data-ohw-link-popover-root]')) {
|
|
18291
|
+
if (target.closest('[data-ohw-drag-handle-container], [data-slot="drag-handle"], [data-ohw-toolbar], [data-ohw-item-toolbar-anchor], [data-ohw-link-popover-root], [data-ohw-floating-panel]')) {
|
|
16941
18292
|
return;
|
|
16942
18293
|
}
|
|
16943
18294
|
if (target.closest("[data-ohw-item-drag-surface]")) return;
|
|
@@ -17115,7 +18466,7 @@ function OhhwellsBridge() {
|
|
|
17115
18466
|
postToParent2({
|
|
17116
18467
|
type: "ow:ready",
|
|
17117
18468
|
version: "1",
|
|
17118
|
-
bridgeVersion: "0.1.
|
|
18469
|
+
bridgeVersion: "0.1.60",
|
|
17119
18470
|
path: pathname,
|
|
17120
18471
|
nodes: collectEditableNodes(editContentRef.current),
|
|
17121
18472
|
sections
|
|
@@ -17510,10 +18861,10 @@ function OhhwellsBridge() {
|
|
|
17510
18861
|
[postToParent2]
|
|
17511
18862
|
);
|
|
17512
18863
|
return bridgeRoot ? createPortal2(
|
|
17513
|
-
/* @__PURE__ */
|
|
17514
|
-
/* @__PURE__ */
|
|
17515
|
-
isEditMode && /* @__PURE__ */
|
|
17516
|
-
Object.entries(uploadingRects).map(([key, { rect, fadingOut }]) => /* @__PURE__ */
|
|
18864
|
+
/* @__PURE__ */ jsxs20(Fragment8, { children: [
|
|
18865
|
+
/* @__PURE__ */ jsx33("div", { ref: attachVisibleViewport, "data-ohw-visible-viewport": "", "aria-hidden": true }),
|
|
18866
|
+
isEditMode && /* @__PURE__ */ jsx33(AiSectionOverlay, { postToParent: postToParent2, apiRef: aiSectionApiRef }),
|
|
18867
|
+
Object.entries(uploadingRects).map(([key, { rect, fadingOut }]) => /* @__PURE__ */ jsx33(
|
|
17517
18868
|
MediaOverlay,
|
|
17518
18869
|
{
|
|
17519
18870
|
hover: { key, rect, elementType: "image", isDragOver: false, hasTextOverlap: false },
|
|
@@ -17524,7 +18875,7 @@ function OhhwellsBridge() {
|
|
|
17524
18875
|
},
|
|
17525
18876
|
`uploading-${key}`
|
|
17526
18877
|
)),
|
|
17527
|
-
mediaHover && !(mediaHover.key in uploadingRects) && /* @__PURE__ */
|
|
18878
|
+
mediaHover && !(mediaHover.key in uploadingRects) && /* @__PURE__ */ jsx33(
|
|
17528
18879
|
MediaOverlay,
|
|
17529
18880
|
{
|
|
17530
18881
|
hover: mediaHover,
|
|
@@ -17533,11 +18884,11 @@ function OhhwellsBridge() {
|
|
|
17533
18884
|
onVideoSettingsChange: handleVideoSettingsChange
|
|
17534
18885
|
}
|
|
17535
18886
|
),
|
|
17536
|
-
carouselHover && !linkPopover && !isItemDragging && /* @__PURE__ */
|
|
17537
|
-
siblingHintRect && !linkPopover && !isItemDragging && siblingHintRects.length === 0 && /* @__PURE__ */
|
|
17538
|
-
siblingHintRects.length > 0 && !linkPopover && !isItemDragging && siblingHintRects.map((rect, i) => /* @__PURE__ */
|
|
17539
|
-
isItemDragging && draggedItemRect && selectedElRef.current !== footerDragRef.current?.draggedEl && selectedElRef.current !== navDragRef.current?.draggedEl && /* @__PURE__ */
|
|
17540
|
-
isItemDragging && footerDropSlots.map((slot, i) => /* @__PURE__ */
|
|
18887
|
+
carouselHover && !linkPopover && !isItemDragging && /* @__PURE__ */ jsx33(CarouselOverlay, { hover: carouselHover, onEdit: handleEditCarousel }),
|
|
18888
|
+
siblingHintRect && !linkPopover && !isItemDragging && siblingHintRects.length === 0 && /* @__PURE__ */ jsx33(ItemInteractionLayer, { rect: siblingHintRect, state: "sibling-hint" }),
|
|
18889
|
+
siblingHintRects.length > 0 && !linkPopover && !isItemDragging && siblingHintRects.map((rect, i) => /* @__PURE__ */ jsx33(ItemInteractionLayer, { rect, state: "sibling-hint" }, `sibling-hint-${i}`)),
|
|
18890
|
+
isItemDragging && draggedItemRect && selectedElRef.current !== footerDragRef.current?.draggedEl && selectedElRef.current !== navDragRef.current?.draggedEl && /* @__PURE__ */ jsx33(ItemInteractionLayer, { rect: draggedItemRect, state: "dragging" }),
|
|
18891
|
+
isItemDragging && footerDropSlots.map((slot, i) => /* @__PURE__ */ jsx33(
|
|
17541
18892
|
"div",
|
|
17542
18893
|
{
|
|
17543
18894
|
className: "pointer-events-none fixed z-2147483646",
|
|
@@ -17547,7 +18898,7 @@ function OhhwellsBridge() {
|
|
|
17547
18898
|
width: slot.width,
|
|
17548
18899
|
height: slot.height
|
|
17549
18900
|
},
|
|
17550
|
-
children: /* @__PURE__ */
|
|
18901
|
+
children: /* @__PURE__ */ jsx33(
|
|
17551
18902
|
DropIndicator,
|
|
17552
18903
|
{
|
|
17553
18904
|
direction: slot.direction,
|
|
@@ -17558,7 +18909,7 @@ function OhhwellsBridge() {
|
|
|
17558
18909
|
},
|
|
17559
18910
|
`footer-drop-${slot.direction}-${slot.columnIndex}-${slot.insertIndex}-${i}`
|
|
17560
18911
|
)),
|
|
17561
|
-
isItemDragging && navDropSlots.map((slot, i) => /* @__PURE__ */
|
|
18912
|
+
isItemDragging && navDropSlots.map((slot, i) => /* @__PURE__ */ jsx33(
|
|
17562
18913
|
"div",
|
|
17563
18914
|
{
|
|
17564
18915
|
className: "pointer-events-none fixed z-2147483646",
|
|
@@ -17568,7 +18919,7 @@ function OhhwellsBridge() {
|
|
|
17568
18919
|
width: slot.width,
|
|
17569
18920
|
height: slot.height
|
|
17570
18921
|
},
|
|
17571
|
-
children: /* @__PURE__ */
|
|
18922
|
+
children: /* @__PURE__ */ jsx33(
|
|
17572
18923
|
DropIndicator,
|
|
17573
18924
|
{
|
|
17574
18925
|
direction: slot.direction,
|
|
@@ -17579,10 +18930,11 @@ function OhhwellsBridge() {
|
|
|
17579
18930
|
},
|
|
17580
18931
|
`nav-drop-${slot.direction}-${slot.parentId ?? "root"}-${slot.insertIndex}-${i}`
|
|
17581
18932
|
)),
|
|
17582
|
-
hoveredNavContainerRect && (toolbarVariant !== "select-frame" || isFooterFrameSelection) && !linkPopover && !isItemDragging && /* @__PURE__ */
|
|
17583
|
-
hoveredItemRect && !linkPopover && !hoveredNavContainerRect && !isItemDragging && hoveredItemElRef.current !== selectedElRef.current && /* @__PURE__ */
|
|
17584
|
-
|
|
17585
|
-
toolbarVariant === "select-frame" && toolbarRect && !linkPopover && !isItemDragging && !isFooterFrameSelection && selectedElRef.current &&
|
|
18933
|
+
hoveredNavContainerRect && (toolbarVariant !== "select-frame" || isFooterFrameSelection) && !linkPopover && !isItemDragging && /* @__PURE__ */ jsx33(ItemInteractionLayer, { rect: hoveredNavContainerRect, state: "hover" }),
|
|
18934
|
+
hoveredItemRect && !linkPopover && !hoveredNavContainerRect && !isItemDragging && hoveredItemElRef.current !== selectedElRef.current && /* @__PURE__ */ jsx33(ItemInteractionLayer, { rect: hoveredItemRect, state: "hover" }),
|
|
18935
|
+
hoveredTextRect && !isItemDragging && toolbarVariant !== "rich-text" && /* @__PURE__ */ jsx33(ItemInteractionLayer, { rect: hoveredTextRect, state: "hover" }),
|
|
18936
|
+
toolbarVariant === "select-frame" && toolbarRect && !linkPopover && !isItemDragging && !isFooterFrameSelection && selectedElRef.current && isNavbarLinksContainer2(selectedElRef.current) && /* @__PURE__ */ jsx33(NavbarContainerChrome, { rect: toolbarRect, onAdd: handleAddTopLevelNavItem }),
|
|
18937
|
+
toolbarVariant === "select-frame" && toolbarRect && !linkPopover && !isItemDragging && !isFooterFrameSelection && selectedElRef.current && isFooterLinksContainer(selectedElRef.current) && /* @__PURE__ */ jsx33(
|
|
17586
18938
|
FooterContainerChrome,
|
|
17587
18939
|
{
|
|
17588
18940
|
rect: toolbarRect,
|
|
@@ -17590,7 +18942,7 @@ function OhhwellsBridge() {
|
|
|
17590
18942
|
addDisabled: !canAddFooterColumn()
|
|
17591
18943
|
}
|
|
17592
18944
|
),
|
|
17593
|
-
toolbarRect && !linkPopover && (toolbarVariant === "link-action" || toolbarVariant === "select-frame") && /* @__PURE__ */
|
|
18945
|
+
toolbarRect && !linkPopover && (toolbarVariant === "link-action" || toolbarVariant === "select-frame" || toolbarVariant === "logo") && /* @__PURE__ */ jsx33(
|
|
17594
18946
|
ItemInteractionLayer,
|
|
17595
18947
|
{
|
|
17596
18948
|
rect: isItemDragging && draggedItemRect && (footerDragRef.current?.wasSelected || navDragRef.current?.wasSelected) ? draggedItemRect : toolbarRect,
|
|
@@ -17602,10 +18954,10 @@ function OhhwellsBridge() {
|
|
|
17602
18954
|
dragHandleLabel: reorderHrefKey ? `Reorder ${reorderHrefKey}` : "Reorder item",
|
|
17603
18955
|
onDragHandleDragStart: handleItemDragStart,
|
|
17604
18956
|
onDragHandleDragEnd: handleItemDragEnd,
|
|
17605
|
-
onItemPointerDown: handleItemChromePointerDown,
|
|
17606
|
-
onItemClick: handleItemChromeClick,
|
|
17607
|
-
itemDragSurface: !isFooterFrameSelection,
|
|
17608
|
-
toolbar: toolbarVariant === "link-action" && !isItemDragging || toolbarVariant === "select-frame" && (isFooterFrameSelection || selectedIsSocialsRow) && !isItemDragging ? /* @__PURE__ */
|
|
18957
|
+
onItemPointerDown: toolbarVariant === "logo" ? void 0 : handleItemChromePointerDown,
|
|
18958
|
+
onItemClick: toolbarVariant === "logo" ? void 0 : handleItemChromeClick,
|
|
18959
|
+
itemDragSurface: toolbarVariant !== "logo" && !isFooterFrameSelection,
|
|
18960
|
+
toolbar: toolbarVariant === "link-action" && !isItemDragging || toolbarVariant === "select-frame" && (isFooterFrameSelection || selectedIsSocialsRow) && !isItemDragging ? /* @__PURE__ */ jsx33(
|
|
17609
18961
|
ItemActionToolbar,
|
|
17610
18962
|
{
|
|
17611
18963
|
onEditLink: openLinkPopoverForSelected,
|
|
@@ -17621,7 +18973,10 @@ function OhhwellsBridge() {
|
|
|
17621
18973
|
onSelectParent: handleSelectParent,
|
|
17622
18974
|
onDuplicate: handleDuplicateSelected,
|
|
17623
18975
|
onDelete: handleDeleteSelected,
|
|
17624
|
-
addItemDisabled:
|
|
18976
|
+
addItemDisabled: isFooterFrameSelection && isFooterAddItemDisabled(selectedElRef.current) || selectedElRef.current !== null && (() => {
|
|
18977
|
+
const row = isSocialsRow(selectedElRef.current) ? selectedElRef.current : findSocialsRow(selectedElRef.current);
|
|
18978
|
+
return row ? !canAddSocialItem(row) : false;
|
|
18979
|
+
})(),
|
|
17625
18980
|
editLinkDisabled: false,
|
|
17626
18981
|
moreDisabled: false,
|
|
17627
18982
|
duplicateDisabled: isFooterFrameSelection || selectedIsSocialsRow,
|
|
@@ -17638,8 +18993,8 @@ function OhhwellsBridge() {
|
|
|
17638
18993
|
) : void 0
|
|
17639
18994
|
}
|
|
17640
18995
|
),
|
|
17641
|
-
toolbarRect && toolbarVariant === "rich-text" && !linkPopover && /* @__PURE__ */
|
|
17642
|
-
/* @__PURE__ */
|
|
18996
|
+
toolbarRect && toolbarVariant === "rich-text" && !linkPopover && /* @__PURE__ */ jsxs20(Fragment8, { children: [
|
|
18997
|
+
/* @__PURE__ */ jsx33(
|
|
17643
18998
|
EditGlowChrome,
|
|
17644
18999
|
{
|
|
17645
19000
|
rect: toolbarRect,
|
|
@@ -17649,7 +19004,7 @@ function OhhwellsBridge() {
|
|
|
17649
19004
|
hideHandle: isItemDragging
|
|
17650
19005
|
}
|
|
17651
19006
|
),
|
|
17652
|
-
/* @__PURE__ */
|
|
19007
|
+
/* @__PURE__ */ jsx33(
|
|
17653
19008
|
FloatingToolbar,
|
|
17654
19009
|
{
|
|
17655
19010
|
rect: toolbarRect,
|
|
@@ -17662,7 +19017,7 @@ function OhhwellsBridge() {
|
|
|
17662
19017
|
}
|
|
17663
19018
|
)
|
|
17664
19019
|
] }),
|
|
17665
|
-
maxBadge && /* @__PURE__ */
|
|
19020
|
+
maxBadge && /* @__PURE__ */ jsxs20(
|
|
17666
19021
|
"div",
|
|
17667
19022
|
{
|
|
17668
19023
|
"data-ohw-max-badge": "",
|
|
@@ -17688,7 +19043,7 @@ function OhhwellsBridge() {
|
|
|
17688
19043
|
]
|
|
17689
19044
|
}
|
|
17690
19045
|
),
|
|
17691
|
-
toggleState && !linkPopover && /* @__PURE__ */
|
|
19046
|
+
toggleState && !linkPopover && /* @__PURE__ */ jsx33(
|
|
17692
19047
|
StateToggle,
|
|
17693
19048
|
{
|
|
17694
19049
|
rect: toggleState.rect,
|
|
@@ -17697,15 +19052,15 @@ function OhhwellsBridge() {
|
|
|
17697
19052
|
onStateChange: handleStateChange
|
|
17698
19053
|
}
|
|
17699
19054
|
),
|
|
17700
|
-
sectionGap && !linkPopover && /* @__PURE__ */
|
|
19055
|
+
sectionGap && !linkPopover && /* @__PURE__ */ jsxs20(
|
|
17701
19056
|
"div",
|
|
17702
19057
|
{
|
|
17703
19058
|
"data-ohw-section-insert-line": "",
|
|
17704
19059
|
className: "fixed left-0 w-full z-2147483646 flex items-center pointer-events-none",
|
|
17705
19060
|
style: { top: sectionGap.y, transform: "translateY(-50%)" },
|
|
17706
19061
|
children: [
|
|
17707
|
-
/* @__PURE__ */
|
|
17708
|
-
/* @__PURE__ */
|
|
19062
|
+
/* @__PURE__ */ jsx33("div", { className: "flex-1 bg-primary", style: { height: 3 } }),
|
|
19063
|
+
/* @__PURE__ */ jsx33(
|
|
17709
19064
|
Badge,
|
|
17710
19065
|
{
|
|
17711
19066
|
className: "px-8 py-1 bg-primary hover:bg-primary text-primary-foreground text-xs font-medium shrink-0 rounded-full cursor-pointer pointer-events-auto",
|
|
@@ -17722,11 +19077,11 @@ function OhhwellsBridge() {
|
|
|
17722
19077
|
children: "Add Section"
|
|
17723
19078
|
}
|
|
17724
19079
|
),
|
|
17725
|
-
/* @__PURE__ */
|
|
19080
|
+
/* @__PURE__ */ jsx33("div", { className: "flex-1 bg-primary", style: { height: 3 } })
|
|
17726
19081
|
]
|
|
17727
19082
|
}
|
|
17728
19083
|
),
|
|
17729
|
-
linkPopover && dialogPortalContainer ? /* @__PURE__ */
|
|
19084
|
+
linkPopover && dialogPortalContainer ? /* @__PURE__ */ jsx33(
|
|
17730
19085
|
LinkPopover,
|
|
17731
19086
|
{
|
|
17732
19087
|
panelRef: linkPopoverPanelRef,
|
|
@@ -17743,7 +19098,7 @@ function OhhwellsBridge() {
|
|
|
17743
19098
|
},
|
|
17744
19099
|
linkPopover.key
|
|
17745
19100
|
) : null,
|
|
17746
|
-
floatingPanel && floatingPanel.kind === "socials-display" ? /* @__PURE__ */
|
|
19101
|
+
floatingPanel && floatingPanel.kind === "socials-display" ? /* @__PURE__ */ jsx33(
|
|
17747
19102
|
FloatingPanel,
|
|
17748
19103
|
{
|
|
17749
19104
|
open: true,
|
|
@@ -17753,7 +19108,7 @@ function OhhwellsBridge() {
|
|
|
17753
19108
|
onPositionChange: setFloatingPanelPos,
|
|
17754
19109
|
parentScroll: parentScrollSnap ?? parentScrollRef.current,
|
|
17755
19110
|
onClose: closeFloatingPanelOnly,
|
|
17756
|
-
children: /* @__PURE__ */
|
|
19111
|
+
children: /* @__PURE__ */ jsx33(
|
|
17757
19112
|
SocialsDisplayPanel,
|
|
17758
19113
|
{
|
|
17759
19114
|
display: socialsDisplayFor(floatingPanel.row, editContentRef.current),
|
|
@@ -17764,11 +19119,115 @@ function OhhwellsBridge() {
|
|
|
17764
19119
|
}
|
|
17765
19120
|
)
|
|
17766
19121
|
}
|
|
19122
|
+
) : null,
|
|
19123
|
+
floatingPanel && floatingPanel.kind === "logo-size" && logoSizeDraft ? /* @__PURE__ */ jsx33(
|
|
19124
|
+
FloatingPanel,
|
|
19125
|
+
{
|
|
19126
|
+
open: true,
|
|
19127
|
+
title: floatingPanel.title,
|
|
19128
|
+
context: floatingPanel.context,
|
|
19129
|
+
position: floatingPanelPos,
|
|
19130
|
+
onPositionChange: setFloatingPanelPos,
|
|
19131
|
+
parentScroll: parentScrollSnap ?? parentScrollRef.current,
|
|
19132
|
+
onClose: closeFloatingPanelAndDeselect,
|
|
19133
|
+
children: /* @__PURE__ */ jsx33(
|
|
19134
|
+
LogoSizePanel,
|
|
19135
|
+
{
|
|
19136
|
+
viewport: editorViewport,
|
|
19137
|
+
sizePx: editorViewport === "mobile" && !logoSizeDraft.mobileFollowing ? logoSizeDraft.mobilePx : logoSizeDraft.desktopPx,
|
|
19138
|
+
mobileFollowing: logoSizeDraft.mobileFollowing,
|
|
19139
|
+
onSizeChange: (px) => {
|
|
19140
|
+
const next = editorViewport === "mobile" ? { ...logoSizeDraft, mobilePx: px, mobileFollowing: false } : {
|
|
19141
|
+
...logoSizeDraft,
|
|
19142
|
+
desktopPx: px,
|
|
19143
|
+
mobilePx: logoSizeDraft.mobileFollowing ? px : logoSizeDraft.mobilePx
|
|
19144
|
+
};
|
|
19145
|
+
setLogoSizeDraft(next);
|
|
19146
|
+
persistLogoSizeDraft(floatingPanel.placement, next);
|
|
19147
|
+
},
|
|
19148
|
+
onCustomizeMobile: () => {
|
|
19149
|
+
const next = {
|
|
19150
|
+
...logoSizeDraft,
|
|
19151
|
+
mobileFollowing: false,
|
|
19152
|
+
mobilePx: logoSizeDraft.desktopPx
|
|
19153
|
+
};
|
|
19154
|
+
setLogoSizeDraft(next);
|
|
19155
|
+
persistLogoSizeDraft(floatingPanel.placement, next);
|
|
19156
|
+
},
|
|
19157
|
+
onResetMobile: () => {
|
|
19158
|
+
const next = {
|
|
19159
|
+
...logoSizeDraft,
|
|
19160
|
+
mobileFollowing: true,
|
|
19161
|
+
mobilePx: logoSizeDraft.desktopPx
|
|
19162
|
+
};
|
|
19163
|
+
setLogoSizeDraft(next);
|
|
19164
|
+
persistLogoSizeDraft(floatingPanel.placement, next);
|
|
19165
|
+
},
|
|
19166
|
+
onUpdateEverywhere: () => {
|
|
19167
|
+
const identity = readLogoIdentityFromDom();
|
|
19168
|
+
postToParent2({ type: "ow:open-logo-settings", ...identity });
|
|
19169
|
+
}
|
|
19170
|
+
}
|
|
19171
|
+
)
|
|
19172
|
+
}
|
|
17767
19173
|
) : null
|
|
17768
19174
|
] }),
|
|
17769
19175
|
bridgeRoot
|
|
17770
19176
|
) : null;
|
|
17771
19177
|
}
|
|
19178
|
+
|
|
19179
|
+
// src/ui/EmptySection.tsx
|
|
19180
|
+
import Link4 from "next/link";
|
|
19181
|
+
import { Fragment as Fragment9, jsx as jsx34, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
19182
|
+
function EmptySection({ title, homeHref = "/", eyebrowKey, titleKey, subtitleKey }) {
|
|
19183
|
+
return /* @__PURE__ */ jsxs21(Fragment9, { children: [
|
|
19184
|
+
/* @__PURE__ */ jsx34(
|
|
19185
|
+
"p",
|
|
19186
|
+
{
|
|
19187
|
+
style: {
|
|
19188
|
+
fontFamily: "var(--brand-font-body)",
|
|
19189
|
+
fontSize: "0.75rem",
|
|
19190
|
+
fontWeight: 500,
|
|
19191
|
+
letterSpacing: "0.15em",
|
|
19192
|
+
textTransform: "uppercase",
|
|
19193
|
+
color: "var(--brand-accent)",
|
|
19194
|
+
marginBottom: "1.5rem"
|
|
19195
|
+
},
|
|
19196
|
+
children: /* @__PURE__ */ jsx34(Link4, { href: homeHref, style: { color: "inherit" }, children: /* @__PURE__ */ jsx34("span", { ...eyebrowKey ? { "data-ohw-editable": "text", "data-ohw-key": eyebrowKey } : {}, children: "Home" }) })
|
|
19197
|
+
}
|
|
19198
|
+
),
|
|
19199
|
+
/* @__PURE__ */ jsx34(
|
|
19200
|
+
"h1",
|
|
19201
|
+
{
|
|
19202
|
+
style: {
|
|
19203
|
+
fontFamily: "var(--brand-font-heading)",
|
|
19204
|
+
fontSize: "clamp(2rem, 3.5vw, 2.75rem)",
|
|
19205
|
+
lineHeight: 1.1,
|
|
19206
|
+
letterSpacing: "-0.025em",
|
|
19207
|
+
color: "var(--brand-text)",
|
|
19208
|
+
marginBottom: "1rem"
|
|
19209
|
+
},
|
|
19210
|
+
...titleKey ? { "data-ohw-editable": "text", "data-ohw-key": titleKey, "data-ohw-max-length": 80 } : {},
|
|
19211
|
+
children: title
|
|
19212
|
+
}
|
|
19213
|
+
),
|
|
19214
|
+
/* @__PURE__ */ jsx34(
|
|
19215
|
+
"p",
|
|
19216
|
+
{
|
|
19217
|
+
style: {
|
|
19218
|
+
fontFamily: "var(--brand-font-body)",
|
|
19219
|
+
fontSize: "1rem",
|
|
19220
|
+
lineHeight: 1.7,
|
|
19221
|
+
fontWeight: 300,
|
|
19222
|
+
color: "var(--brand-text-muted)",
|
|
19223
|
+
maxWidth: "340px"
|
|
19224
|
+
},
|
|
19225
|
+
...subtitleKey ? { "data-ohw-editable": "text", "data-ohw-key": subtitleKey, "data-ohw-max-length": 160 } : {},
|
|
19226
|
+
children: "This page doesn't have any content yet."
|
|
19227
|
+
}
|
|
19228
|
+
)
|
|
19229
|
+
] });
|
|
19230
|
+
}
|
|
17772
19231
|
export {
|
|
17773
19232
|
AI_DEFAULT_BRAND,
|
|
17774
19233
|
AI_TREE_SCHEMA_VERSIONS,
|
|
@@ -17785,6 +19244,7 @@ export {
|
|
|
17785
19244
|
DropdownMenuItem,
|
|
17786
19245
|
DropdownMenuSeparator,
|
|
17787
19246
|
DropdownMenuTrigger,
|
|
19247
|
+
EmptySection,
|
|
17788
19248
|
ItemActionToolbar,
|
|
17789
19249
|
ItemInteractionLayer,
|
|
17790
19250
|
LinkEditorPanel,
|