@ohhwells/bridge 0.1.106 → 0.1.108-next.282
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 +482 -175
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +52 -1
- package/dist/index.d.ts +52 -1
- package/dist/index.js +481 -175
- package/dist/index.js.map +1 -1
- package/dist/pages.cjs +141 -0
- package/dist/pages.cjs.map +1 -0
- package/dist/pages.d.cts +45 -0
- package/dist/pages.d.ts +45 -0
- package/dist/pages.js +107 -0
- package/dist/pages.js.map +1 -0
- package/dist/styles.css +127 -73
- package/package.json +8 -3
package/dist/index.cjs
CHANGED
|
@@ -46,6 +46,7 @@ __export(index_exports, {
|
|
|
46
46
|
DropdownMenuItem: () => DropdownMenuItem,
|
|
47
47
|
DropdownMenuSeparator: () => DropdownMenuSeparator,
|
|
48
48
|
DropdownMenuTrigger: () => DropdownMenuTrigger,
|
|
49
|
+
EmptySection: () => EmptySection,
|
|
49
50
|
ItemActionToolbar: () => ItemActionToolbar,
|
|
50
51
|
ItemInteractionLayer: () => ItemInteractionLayer,
|
|
51
52
|
LinkEditorPanel: () => LinkEditorPanel,
|
|
@@ -352,16 +353,17 @@ var LEGACY_BRAND_VAR_NAMES = [
|
|
|
352
353
|
"text-muted",
|
|
353
354
|
"surface",
|
|
354
355
|
"border",
|
|
355
|
-
"on-primary"
|
|
356
|
-
"navbar-background"
|
|
356
|
+
"on-primary"
|
|
357
357
|
].map((role) => `--brand-${role}`);
|
|
358
358
|
var FONT_VARS = {
|
|
359
359
|
heading: ["--font-heading", "--font-display", "--brand-font-heading"],
|
|
360
360
|
body: ["--font-body", "--brand-font-body"]
|
|
361
361
|
};
|
|
362
362
|
var BRAND_FONT_LINK_ID = "ohw-brand-fonts";
|
|
363
|
-
|
|
364
|
-
|
|
363
|
+
var CUSTOM_FONT_STYLE_ID = "ohw-brand-custom-fonts";
|
|
364
|
+
var CUSTOM_FONT_FORMATS = /* @__PURE__ */ new Set(["woff2", "woff", "truetype", "opentype"]);
|
|
365
|
+
function brandColorVars(palette) {
|
|
366
|
+
const { dark, primary, accent, light } = palette;
|
|
365
367
|
const mix = (a, aPct, b) => `color-mix(in srgb, ${a} ${aPct}%, ${b})`;
|
|
366
368
|
const surface = mix(light, 95, dark);
|
|
367
369
|
const border = mix(light, 85, dark);
|
|
@@ -384,22 +386,42 @@ function brandColorVars(kit) {
|
|
|
384
386
|
"--brand-border": border,
|
|
385
387
|
// Buttons/bands painted in the primary colour assume it's dark/saturated enough to need
|
|
386
388
|
// light text on top — the same assumption LOGO_IMAGE's light-on-dark navbar mark makes.
|
|
387
|
-
"--brand-on-primary": light
|
|
388
|
-
"--brand-navbar-background": dark
|
|
389
|
+
"--brand-on-primary": light
|
|
389
390
|
};
|
|
390
391
|
}
|
|
392
|
+
function parseCustomFontWeight(raw) {
|
|
393
|
+
if (typeof raw !== "object" || raw === null) return null;
|
|
394
|
+
const w = raw;
|
|
395
|
+
if (typeof w.weight !== "number" || !Number.isFinite(w.weight)) return null;
|
|
396
|
+
if (typeof w.url !== "string" || !w.url) return null;
|
|
397
|
+
if (typeof w.format !== "string" || !CUSTOM_FONT_FORMATS.has(w.format)) return null;
|
|
398
|
+
const weightEnd = typeof w.weightEnd === "number" && Number.isFinite(w.weightEnd) && w.weightEnd > w.weight ? w.weightEnd : void 0;
|
|
399
|
+
return { weight: w.weight, ...weightEnd !== void 0 ? { weightEnd } : {}, url: w.url, format: w.format };
|
|
400
|
+
}
|
|
401
|
+
function parseCustomFont(raw) {
|
|
402
|
+
if (typeof raw !== "object" || raw === null) return null;
|
|
403
|
+
const f = raw;
|
|
404
|
+
if (typeof f.family !== "string" || !f.family) return null;
|
|
405
|
+
if (typeof f.label !== "string" || !f.label) return null;
|
|
406
|
+
if (!Array.isArray(f.weights)) return null;
|
|
407
|
+
const weights = f.weights.map(parseCustomFontWeight).filter((w) => w !== null);
|
|
408
|
+
if (weights.length === 0) return null;
|
|
409
|
+
return { family: f.family, label: f.label, weights };
|
|
410
|
+
}
|
|
391
411
|
function parseBrandKit(raw) {
|
|
392
412
|
if (!raw) return null;
|
|
393
413
|
try {
|
|
394
414
|
const parsed = JSON.parse(raw);
|
|
395
415
|
const p = parsed?.palette;
|
|
396
416
|
const f = parsed?.fonts;
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
417
|
+
const palette = p && typeof p.dark === "string" && typeof p.primary === "string" && typeof p.accent === "string" && typeof p.light === "string" ? { dark: p.dark, primary: p.primary, accent: p.accent, light: p.light } : void 0;
|
|
418
|
+
const fonts = f && typeof f.heading === "string" && typeof f.body === "string" ? { heading: f.heading, body: f.body } : void 0;
|
|
419
|
+
const customFonts = Array.isArray(parsed?.customFonts) ? parsed.customFonts.map(parseCustomFont).filter((c) => c !== null) : void 0;
|
|
420
|
+
if (!palette && !fonts && !customFonts) return null;
|
|
400
421
|
return {
|
|
401
|
-
palette
|
|
402
|
-
fonts
|
|
422
|
+
...palette ? { palette } : {},
|
|
423
|
+
...fonts ? { fonts } : {},
|
|
424
|
+
...customFonts ? { customFonts } : {}
|
|
403
425
|
};
|
|
404
426
|
} catch {
|
|
405
427
|
return null;
|
|
@@ -409,11 +431,16 @@ function familyOf(stack) {
|
|
|
409
431
|
const first = stack.split(",")[0]?.trim() ?? "";
|
|
410
432
|
return first.replace(/^['"]|['"]$/g, "");
|
|
411
433
|
}
|
|
434
|
+
function quoteFamily(family) {
|
|
435
|
+
return `'${family.replace(/\\/g, "\\\\").replace(/'/g, "\\'")}'`;
|
|
436
|
+
}
|
|
437
|
+
var WEIGHT_SCALE = [100, 200, 300, 400, 500, 600, 700, 800, 900];
|
|
412
438
|
function loadBrandFonts(families) {
|
|
413
439
|
const unique = [...new Set(families.map((f) => f.trim()).filter(Boolean))];
|
|
414
440
|
if (unique.length === 0) return;
|
|
415
|
-
const
|
|
416
|
-
const
|
|
441
|
+
const weights = WEIGHT_SCALE.join(";");
|
|
442
|
+
const spec = unique.map((f) => `family=${f.replace(/ /g, "+")}:wght@${weights}`).join("&");
|
|
443
|
+
const href = `https://fonts.googleapis.com/css2?${spec}&display=swap`;
|
|
417
444
|
let link = document.getElementById(BRAND_FONT_LINK_ID);
|
|
418
445
|
if (!link) {
|
|
419
446
|
link = document.createElement("link");
|
|
@@ -423,18 +450,54 @@ function loadBrandFonts(families) {
|
|
|
423
450
|
}
|
|
424
451
|
if (link.href !== href) link.href = href;
|
|
425
452
|
}
|
|
453
|
+
function escapeCssString(value) {
|
|
454
|
+
return value.replace(/\\/g, "\\\\").replace(/'/g, "\\'");
|
|
455
|
+
}
|
|
456
|
+
function loadCustomFonts(fonts) {
|
|
457
|
+
const list = fonts ?? [];
|
|
458
|
+
let style = document.getElementById(CUSTOM_FONT_STYLE_ID);
|
|
459
|
+
if (list.length === 0) {
|
|
460
|
+
style?.remove();
|
|
461
|
+
return;
|
|
462
|
+
}
|
|
463
|
+
if (!style) {
|
|
464
|
+
style = document.createElement("style");
|
|
465
|
+
style.id = CUSTOM_FONT_STYLE_ID;
|
|
466
|
+
document.head.appendChild(style);
|
|
467
|
+
}
|
|
468
|
+
style.textContent = list.flatMap(
|
|
469
|
+
(font) => font.weights.map((w) => {
|
|
470
|
+
const weightDescriptor = w.weightEnd ? `${w.weight} ${w.weightEnd}` : `${w.weight}`;
|
|
471
|
+
return `@font-face { font-family: '${escapeCssString(font.family)}'; src: url('${escapeCssString(w.url)}') format('${w.format}'); font-weight: ${weightDescriptor}; font-display: swap; }`;
|
|
472
|
+
})
|
|
473
|
+
).join("\n");
|
|
474
|
+
}
|
|
426
475
|
function applyBrandToDom(kit) {
|
|
427
476
|
const root = document.documentElement;
|
|
428
477
|
if (!kit) {
|
|
429
478
|
for (const name of [...BRAND_VAR_NAMES, ...LEGACY_BRAND_VAR_NAMES]) root.style.removeProperty(name);
|
|
430
479
|
for (const name of [...FONT_VARS.heading, ...FONT_VARS.body]) root.style.removeProperty(name);
|
|
431
480
|
document.getElementById(BRAND_FONT_LINK_ID)?.remove();
|
|
481
|
+
document.getElementById(CUSTOM_FONT_STYLE_ID)?.remove();
|
|
432
482
|
return;
|
|
433
483
|
}
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
484
|
+
if (kit.palette) {
|
|
485
|
+
for (const [name, value] of Object.entries(brandColorVars(kit.palette))) root.style.setProperty(name, value);
|
|
486
|
+
}
|
|
487
|
+
if (kit.customFonts) {
|
|
488
|
+
loadCustomFonts(kit.customFonts);
|
|
489
|
+
}
|
|
490
|
+
if (kit.fonts) {
|
|
491
|
+
const heading = quoteFamily(kit.fonts.heading);
|
|
492
|
+
const body = quoteFamily(kit.fonts.body);
|
|
493
|
+
for (const name of FONT_VARS.heading) root.style.setProperty(name, heading);
|
|
494
|
+
for (const name of FONT_VARS.body) root.style.setProperty(name, body);
|
|
495
|
+
const customFamilies = new Set((kit.customFonts ?? []).map((f) => f.family));
|
|
496
|
+
const googleFamilies = [familyOf(kit.fonts.heading), familyOf(kit.fonts.body)].filter(
|
|
497
|
+
(f) => !customFamilies.has(f)
|
|
498
|
+
);
|
|
499
|
+
loadBrandFonts(googleFamilies);
|
|
500
|
+
}
|
|
438
501
|
}
|
|
439
502
|
|
|
440
503
|
// src/lib/section-styles.ts
|
|
@@ -493,7 +556,9 @@ function styleSheetCss() {
|
|
|
493
556
|
}
|
|
494
557
|
rules.push(
|
|
495
558
|
`[data-ohw-style-corners="sharp"] :is(.card, [data-ohw-card], img, picture, figure, [data-ohw-editable="bg-image"]) { border-radius: 0 !important; }`,
|
|
496
|
-
`[data-ohw-style-corners="sharp"] :has(> img) { border-radius: 0 !important; }
|
|
559
|
+
`[data-ohw-style-corners="sharp"] :has(> img) { border-radius: 0 !important; }`,
|
|
560
|
+
`[data-ohw-style-corners="rounded"] :is(.card, [data-ohw-card], img, picture, figure, [data-ohw-editable="bg-image"]) { border-radius: max(0.75rem, var(--radius, 0px)) !important; }`,
|
|
561
|
+
`[data-ohw-style-corners="rounded"] :has(> img) { border-radius: max(0.75rem, var(--radius, 0px)) !important; }`
|
|
497
562
|
);
|
|
498
563
|
for (const align of ["left", "center", "right"]) {
|
|
499
564
|
rules.push(`[data-ohw-style-align="${align}"] { text-align: ${align} !important; }`);
|
|
@@ -593,6 +658,19 @@ function alignSubjectOf(el) {
|
|
|
593
658
|
while (subject.parentElement && !subject.parentElement.hasAttribute("data-ohw-section") && /^inline/.test(getComputedStyle(subject).display)) {
|
|
594
659
|
subject = subject.parentElement;
|
|
595
660
|
}
|
|
661
|
+
const TEXT_ROW = /^(P|LI|H[1-6]|BLOCKQUOTE|FIGCAPTION|DT|DD)$/;
|
|
662
|
+
const parent = subject.parentElement;
|
|
663
|
+
if (parent && TEXT_ROW.test(parent.tagName) && /^(inline-)?flex$/.test(getComputedStyle(parent).display)) {
|
|
664
|
+
return parent;
|
|
665
|
+
}
|
|
666
|
+
if (parent && !parent.hasAttribute("data-ohw-section")) {
|
|
667
|
+
const pcs = getComputedStyle(parent);
|
|
668
|
+
const children = Array.from(parent.children);
|
|
669
|
+
const textRowChild = (c) => c.hasAttribute("data-ohw-editable") || (c.textContent ?? "").trim().length === 0 || c.getAttribute("aria-hidden") === "true";
|
|
670
|
+
if (/^(inline-)?flex$/.test(pcs.display) && pcs.flexDirection.startsWith("row") && children.length > 0 && children.some((c) => c.hasAttribute("data-ohw-editable")) && children.every(textRowChild)) {
|
|
671
|
+
return parent;
|
|
672
|
+
}
|
|
673
|
+
}
|
|
596
674
|
const row = subject.closest("li");
|
|
597
675
|
if (row && row !== subject && /^(inline-)?flex$/.test(getComputedStyle(row).display)) {
|
|
598
676
|
return row;
|
|
@@ -1340,6 +1418,22 @@ function accentBandContext(brand) {
|
|
|
1340
1418
|
function textAttrs(ctx, path) {
|
|
1341
1419
|
return ctx.keyFor ? { "data-ohw-key": ctx.keyFor(path), "data-ohw-editable": "text" } : {};
|
|
1342
1420
|
}
|
|
1421
|
+
var AI_RESPONSIVE_CSS = [
|
|
1422
|
+
"@media (max-width: 960px) {",
|
|
1423
|
+
" [data-ai-responsive] [data-ai-grid] { grid-template-columns: repeat(2, 1fr) !important; }",
|
|
1424
|
+
' [data-ai-responsive] [data-ai-grid="1"] { grid-template-columns: 1fr !important; }',
|
|
1425
|
+
"}",
|
|
1426
|
+
"@media (max-width: 640px) {",
|
|
1427
|
+
" [data-ai-responsive] [data-ai-grid] { grid-template-columns: 1fr !important; }",
|
|
1428
|
+
" [data-ai-responsive] [data-ai-columns] > * { grid-column: 1 / -1 !important; }",
|
|
1429
|
+
// Group containers flatten to a column on phones; span placements come along for free.
|
|
1430
|
+
" [data-ai-responsive] [data-ai-group] { display: flex !important; flex-direction: column !important; }",
|
|
1431
|
+
" [data-ai-responsive] [data-ai-group] > * { grid-column: auto !important; }",
|
|
1432
|
+
" [data-ai-responsive] [data-ai-section-inner] { padding-left: 20px !important; padding-right: 20px !important; }",
|
|
1433
|
+
" [data-ai-responsive] { overflow-x: hidden; }",
|
|
1434
|
+
" [data-ai-responsive] img { max-width: 100%; }",
|
|
1435
|
+
"}"
|
|
1436
|
+
].join("\n");
|
|
1343
1437
|
var TRANSPARENT_PX = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7";
|
|
1344
1438
|
function MediaBox({
|
|
1345
1439
|
refValue,
|
|
@@ -1352,13 +1446,17 @@ function MediaBox({
|
|
|
1352
1446
|
const url = refValue ? ctx.resolveMedia(refValue) : null;
|
|
1353
1447
|
const isIcon = /^(lucide|simple):/.test(refValue);
|
|
1354
1448
|
const aspectRatio = aspect && /^\d+:\d+$/.test(aspect) ? aspect.replace(":", " / ") : void 0;
|
|
1355
|
-
const editAttrs = ctx.keyFor && editPath
|
|
1449
|
+
const editAttrs = ctx.keyFor && editPath ? {
|
|
1450
|
+
"data-ohw-key": ctx.keyFor(editPath),
|
|
1451
|
+
"data-ohw-editable": isIcon ? "icon" : "image"
|
|
1452
|
+
} : {};
|
|
1356
1453
|
if (isIcon) {
|
|
1357
1454
|
const Icon = refValue.startsWith("lucide:") ? lucideByName(refValue.slice(7)) : null;
|
|
1358
1455
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1359
1456
|
"span",
|
|
1360
1457
|
{
|
|
1361
1458
|
"data-ai-icon": refValue,
|
|
1459
|
+
...editAttrs,
|
|
1362
1460
|
style: {
|
|
1363
1461
|
display: "inline-flex",
|
|
1364
1462
|
width: 48,
|
|
@@ -2251,7 +2349,7 @@ function CollectionBlock({ node, ctx, path }) {
|
|
|
2251
2349
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
2252
2350
|
"div",
|
|
2253
2351
|
{
|
|
2254
|
-
"data-ai-grid":
|
|
2352
|
+
"data-ai-grid": String(itemsPerRow),
|
|
2255
2353
|
style: {
|
|
2256
2354
|
display: "grid",
|
|
2257
2355
|
gridTemplateColumns: `repeat(${itemsPerRow}, 1fr)`,
|
|
@@ -2604,6 +2702,7 @@ function AiTreeRenderer({
|
|
|
2604
2702
|
{
|
|
2605
2703
|
"data-ai-section": tree.tag ?? "",
|
|
2606
2704
|
...bgAttrs,
|
|
2705
|
+
"data-ai-responsive": "",
|
|
2607
2706
|
style: {
|
|
2608
2707
|
position: "relative",
|
|
2609
2708
|
padding: `${pad}px 0`,
|
|
@@ -2614,12 +2713,13 @@ function AiTreeRenderer({
|
|
|
2614
2713
|
color: settings.sectionBackground === "accent" ? blockBrand.palette.dark : void 0
|
|
2615
2714
|
},
|
|
2616
2715
|
children: [
|
|
2617
|
-
|
|
2716
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("style", { children: AI_RESPONSIVE_CSS }),
|
|
2618
2717
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("style", { children: AI_MOBILE_CSS }),
|
|
2718
|
+
isOverlay && backgroundUrl && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { position: "absolute", inset: 0, background: `rgba(255,255,255,${overlayAlpha})` } }),
|
|
2619
2719
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
2620
2720
|
"div",
|
|
2621
2721
|
{
|
|
2622
|
-
"data-ai-
|
|
2722
|
+
"data-ai-section-inner": "",
|
|
2623
2723
|
style: {
|
|
2624
2724
|
position: "relative",
|
|
2625
2725
|
maxWidth: AI_TREE_TOKENS.sectionMaxWidth,
|
|
@@ -2630,7 +2730,7 @@ function AiTreeRenderer({
|
|
|
2630
2730
|
children: tree.rows.map((row, r2) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
2631
2731
|
"div",
|
|
2632
2732
|
{
|
|
2633
|
-
"data-ai-
|
|
2733
|
+
"data-ai-columns": "",
|
|
2634
2734
|
style: {
|
|
2635
2735
|
display: "grid",
|
|
2636
2736
|
gridTemplateColumns: "repeat(12, 1fr)",
|
|
@@ -2680,14 +2780,52 @@ function readRootVar(name) {
|
|
|
2680
2780
|
if (typeof document === "undefined") return "";
|
|
2681
2781
|
return getComputedStyle(document.documentElement).getPropertyValue(name).trim();
|
|
2682
2782
|
}
|
|
2783
|
+
function normalizeColorToHex(value) {
|
|
2784
|
+
if (!value || typeof document === "undefined") return value;
|
|
2785
|
+
const canvas = document.createElement("canvas");
|
|
2786
|
+
canvas.width = 1;
|
|
2787
|
+
canvas.height = 1;
|
|
2788
|
+
const ctx = canvas.getContext("2d");
|
|
2789
|
+
if (!ctx) return value;
|
|
2790
|
+
ctx.fillStyle = value;
|
|
2791
|
+
ctx.fillRect(0, 0, 1, 1);
|
|
2792
|
+
const [r2, g, b] = ctx.getImageData(0, 0, 1, 1).data;
|
|
2793
|
+
const toHex = (n) => n.toString(16).padStart(2, "0");
|
|
2794
|
+
return `#${toHex(r2)}${toHex(g)}${toHex(b)}`;
|
|
2795
|
+
}
|
|
2796
|
+
var GENERIC_FONT_KEYWORDS = /* @__PURE__ */ new Set([
|
|
2797
|
+
"serif",
|
|
2798
|
+
"sans-serif",
|
|
2799
|
+
"monospace",
|
|
2800
|
+
"cursive",
|
|
2801
|
+
"fantasy",
|
|
2802
|
+
"system-ui",
|
|
2803
|
+
"ui-serif",
|
|
2804
|
+
"ui-sans-serif",
|
|
2805
|
+
"ui-monospace",
|
|
2806
|
+
"ui-rounded",
|
|
2807
|
+
"math",
|
|
2808
|
+
"emoji",
|
|
2809
|
+
"fangsong"
|
|
2810
|
+
]);
|
|
2811
|
+
function primaryFontFamily(stack) {
|
|
2812
|
+
const first = stack.split(",").map((part) => part.trim().replace(/^["']|["']$/g, "")).find((part) => part && !GENERIC_FONT_KEYWORDS.has(part.toLowerCase()));
|
|
2813
|
+
return first ?? "";
|
|
2814
|
+
}
|
|
2815
|
+
function humanizeFontFamily(name) {
|
|
2816
|
+
return name.replace(/^__/, "").replace(/_[0-9a-f]{6}$/i, "").replace(/_/g, " ").replace(/([a-z0-9])([A-Z])/g, "$1 $2").trim().replace(/\s+/g, " ").replace(/(^|\s)([a-z])/g, (_, sep, c) => sep + c.toUpperCase());
|
|
2817
|
+
}
|
|
2818
|
+
function readFontVar(name) {
|
|
2819
|
+
return humanizeFontFamily(primaryFontFamily(readRootVar(name)));
|
|
2820
|
+
}
|
|
2683
2821
|
function deriveBrandOverride() {
|
|
2684
2822
|
const dark = readRootVar("--ohw-brand-dark");
|
|
2685
2823
|
const primary = readRootVar("--ohw-brand-primary");
|
|
2686
2824
|
const light = readRootVar("--ohw-brand-light");
|
|
2687
2825
|
if (!dark || !primary || !light) return null;
|
|
2688
2826
|
const accent = readRootVar("--ohw-brand-accent");
|
|
2689
|
-
const heading =
|
|
2690
|
-
const body =
|
|
2827
|
+
const heading = readFontVar("--font-heading") || readFontVar("--font-display");
|
|
2828
|
+
const body = readFontVar("--font-body");
|
|
2691
2829
|
return {
|
|
2692
2830
|
palette: { dark, primary, accent: accent || dark, light },
|
|
2693
2831
|
fonts: {
|
|
@@ -2696,27 +2834,65 @@ function deriveBrandOverride() {
|
|
|
2696
2834
|
}
|
|
2697
2835
|
};
|
|
2698
2836
|
}
|
|
2699
|
-
function
|
|
2700
|
-
const
|
|
2701
|
-
const
|
|
2702
|
-
const light = readRootVar("--
|
|
2837
|
+
function deriveTemplateBrandLive() {
|
|
2838
|
+
const dark = readRootVar("--color-dark") || readRootVar("--brand-text");
|
|
2839
|
+
const primary = readRootVar("--color-primary") || readRootVar("--brand-primary");
|
|
2840
|
+
const light = readRootVar("--color-light") || readRootVar("--brand-background");
|
|
2703
2841
|
if (!dark || !primary || !light) return null;
|
|
2704
|
-
const accent = readRootVar("--
|
|
2705
|
-
const heading =
|
|
2706
|
-
const body =
|
|
2842
|
+
const accent = readRootVar("--color-accent") || readRootVar("--brand-accent");
|
|
2843
|
+
const heading = readFontVar("--brand-font-heading") || readFontVar("--font-heading") || readFontVar("--font-display");
|
|
2844
|
+
const body = readFontVar("--brand-font-body") || readFontVar("--font-body");
|
|
2707
2845
|
return {
|
|
2708
|
-
palette: {
|
|
2846
|
+
palette: {
|
|
2847
|
+
dark: normalizeColorToHex(dark),
|
|
2848
|
+
primary: normalizeColorToHex(primary),
|
|
2849
|
+
accent: normalizeColorToHex(accent || dark),
|
|
2850
|
+
light: normalizeColorToHex(light)
|
|
2851
|
+
},
|
|
2709
2852
|
fonts: {
|
|
2710
2853
|
heading: heading || AI_DEFAULT_BRAND.fonts.heading,
|
|
2711
2854
|
body: body || AI_DEFAULT_BRAND.fonts.body
|
|
2712
2855
|
}
|
|
2713
2856
|
};
|
|
2714
2857
|
}
|
|
2858
|
+
function deriveTemplateFontsLive() {
|
|
2859
|
+
const heading = readFontVar("--brand-font-heading") || readFontVar("--font-heading") || readFontVar("--font-display");
|
|
2860
|
+
const body = readFontVar("--brand-font-body") || readFontVar("--font-body");
|
|
2861
|
+
if (!heading && !body) return null;
|
|
2862
|
+
return {
|
|
2863
|
+
heading: heading || AI_DEFAULT_BRAND.fonts.heading,
|
|
2864
|
+
body: body || AI_DEFAULT_BRAND.fonts.body
|
|
2865
|
+
};
|
|
2866
|
+
}
|
|
2867
|
+
var OVERRIDE_VAR_NAMES = [...BRAND_VAR_NAMES, ...LEGACY_BRAND_VAR_NAMES, ...FONT_VARS.heading, ...FONT_VARS.body];
|
|
2868
|
+
function withOverrideStripped(read) {
|
|
2869
|
+
const root = document.documentElement;
|
|
2870
|
+
const restore = OVERRIDE_VAR_NAMES.map((name) => [name, root.style.getPropertyValue(name)]);
|
|
2871
|
+
for (const name of OVERRIDE_VAR_NAMES) root.style.removeProperty(name);
|
|
2872
|
+
try {
|
|
2873
|
+
return read();
|
|
2874
|
+
} finally {
|
|
2875
|
+
for (const [name, value] of restore) if (value) root.style.setProperty(name, value);
|
|
2876
|
+
}
|
|
2877
|
+
}
|
|
2878
|
+
var TEMPLATE_BRAND_SNAPSHOT = typeof document === "undefined" ? null : withOverrideStripped(deriveTemplateBrandLive);
|
|
2879
|
+
var TEMPLATE_FONTS_SNAPSHOT = typeof document === "undefined" ? null : withOverrideStripped(deriveTemplateFontsLive);
|
|
2880
|
+
function deriveTemplateBrand() {
|
|
2881
|
+
return TEMPLATE_BRAND_SNAPSHOT;
|
|
2882
|
+
}
|
|
2883
|
+
function deriveTemplateFonts() {
|
|
2884
|
+
return TEMPLATE_FONTS_SNAPSHOT;
|
|
2885
|
+
}
|
|
2715
2886
|
function deriveTemplateButtonStyle() {
|
|
2716
2887
|
if (typeof document === "undefined") return null;
|
|
2717
2888
|
const candidates = Array.from(
|
|
2718
2889
|
document.querySelectorAll('[data-ohw-role="button"]')
|
|
2719
|
-
).filter(
|
|
2890
|
+
).filter(
|
|
2891
|
+
(el) => !el.closest(`[${CONTAINER_ATTR}]`) && // Whole-card links legitimately carry the button role (serene's clickable treatment
|
|
2892
|
+
// cards) but must never donate the "button look" — a real button holds at most its
|
|
2893
|
+
// one editable label, a card holds a headline, copy and prices.
|
|
2894
|
+
el.querySelectorAll("[data-ohw-editable]").length <= 1
|
|
2895
|
+
);
|
|
2720
2896
|
const isFilled = (el) => {
|
|
2721
2897
|
const bg = getComputedStyle(el).backgroundColor;
|
|
2722
2898
|
if (!bg || bg === "transparent") return false;
|
|
@@ -7204,12 +7380,12 @@ var cva = (base, config) => (props) => {
|
|
|
7204
7380
|
var import_radix_ui2 = require("radix-ui");
|
|
7205
7381
|
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
7206
7382
|
var toggleVariants = cva(
|
|
7207
|
-
"inline-flex items-center justify-center gap-2 rounded-md text-sm font-medium whitespace-nowrap transition-[color,box-shadow] outline-none hover:bg-muted hover:text-muted-foreground focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 data-[state=on]:bg-accent data-[state=on]:text-accent-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
7383
|
+
"inline-flex items-center justify-center gap-2 rounded-md text-sm font-medium whitespace-nowrap transition-[color,box-shadow] outline-none hover:bg-muted hover:text-muted-foreground focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 data-[state=on]:bg-bridge-accent data-[state=on]:text-accent-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
7208
7384
|
{
|
|
7209
7385
|
variants: {
|
|
7210
7386
|
variant: {
|
|
7211
7387
|
default: "bg-transparent border-0",
|
|
7212
|
-
outline: "border border-input bg-transparent shadow-xs hover:bg-accent hover:text-accent-foreground"
|
|
7388
|
+
outline: "border border-input bg-transparent shadow-xs hover:bg-bridge-accent hover:text-accent-foreground"
|
|
7213
7389
|
},
|
|
7214
7390
|
size: {
|
|
7215
7391
|
default: "px-2 py-1",
|
|
@@ -7302,10 +7478,10 @@ var DragHandle = React4.forwardRef(
|
|
|
7302
7478
|
type,
|
|
7303
7479
|
"data-slot": "drag-handle",
|
|
7304
7480
|
className: cn(
|
|
7305
|
-
"inline-flex h-7 w-4 shrink-0 items-center justify-center rounded-md transition-all duration-200 max-h-
|
|
7481
|
+
"inline-flex h-7 w-4 shrink-0 items-center justify-center rounded-md transition-all duration-200 max-h-7.5",
|
|
7306
7482
|
"bg-white border border-transparent text-stone-500 shadow-md cursor-grab",
|
|
7307
7483
|
"enabled:hover:border enabled:hover:border-stone-200 enabled:hover:text-stone-950",
|
|
7308
|
-
"enabled:active:border enabled:active:border-primary enabled:active:bg-primary-50 enabled:active:text-stone-950 enabled:active:shadow enabled:active:cursor-grabbing",
|
|
7484
|
+
"enabled:active:border enabled:active:border-bridge-primary enabled:active:bg-primary-50 enabled:active:text-stone-950 enabled:active:shadow enabled:active:cursor-grabbing",
|
|
7309
7485
|
"disabled:cursor-not-allowed disabled:opacity-40 disabled:text-stone-950 disabled:pointer-events-none",
|
|
7310
7486
|
className
|
|
7311
7487
|
),
|
|
@@ -7327,7 +7503,7 @@ var CustomToolbar = React5.forwardRef(({ className, onMouseDown, ...props }, ref
|
|
|
7327
7503
|
"data-ohw-toolbar": "",
|
|
7328
7504
|
className: cn(
|
|
7329
7505
|
// Figma: bg background, radius 8, gap-1, p-0.5, shadow-md — no border
|
|
7330
|
-
"inline-flex h-8 items-center gap-1 rounded-
|
|
7506
|
+
"inline-flex h-8 items-center gap-1 rounded-(--radius,0.5rem) bg-background p-0.5 font-sans whitespace-nowrap shadow-md",
|
|
7331
7507
|
className
|
|
7332
7508
|
),
|
|
7333
7509
|
onMouseDown: (e) => {
|
|
@@ -7356,7 +7532,7 @@ var CustomToolbarButton = React5.forwardRef(
|
|
|
7356
7532
|
type,
|
|
7357
7533
|
className: cn(
|
|
7358
7534
|
"inline-flex size-7 shrink-0 items-center justify-center rounded-[calc(var(--radius,0.5rem)-2px)] text-foreground transition-colors",
|
|
7359
|
-
active ? "bg-primary text-primary-foreground" : "bg-transparent hover:bg-muted disabled:cursor-not-allowed disabled:text-muted-foreground disabled:opacity-60",
|
|
7535
|
+
active ? "bg-bridge-primary text-primary-foreground" : "bg-transparent hover:bg-muted disabled:cursor-not-allowed disabled:text-muted-foreground disabled:opacity-60",
|
|
7360
7536
|
className
|
|
7361
7537
|
),
|
|
7362
7538
|
...props
|
|
@@ -8558,13 +8734,13 @@ function FormFieldToolbar({
|
|
|
8558
8734
|
]
|
|
8559
8735
|
}
|
|
8560
8736
|
) }),
|
|
8561
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(DropdownMenuContent, { align: "start", sideOffset: 8, className: "min-w-
|
|
8737
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(DropdownMenuContent, { align: "start", sideOffset: 8, className: "min-w-47.5 p-1", children: FIELD_TYPES.map((entry) => {
|
|
8562
8738
|
const Icon = TYPE_ICONS[entry.type];
|
|
8563
8739
|
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
8564
8740
|
DropdownMenuItem,
|
|
8565
8741
|
{
|
|
8566
8742
|
onSelect: () => onTypeChange(entry.type),
|
|
8567
|
-
className: "rounded-md py-2 text-[13px] " + (entry.type === type ? "bg-primary/10" : ""),
|
|
8743
|
+
className: "rounded-md py-2 text-[13px] " + (entry.type === type ? "bg-bridge-primary/10" : ""),
|
|
8568
8744
|
children: [
|
|
8569
8745
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Icon, { size: 14, strokeWidth: 1.75, className: "shrink-0", "aria-hidden": true }),
|
|
8570
8746
|
entry.label
|
|
@@ -8581,7 +8757,7 @@ function FormFieldToolbar({
|
|
|
8581
8757
|
type: "button",
|
|
8582
8758
|
"aria-pressed": required,
|
|
8583
8759
|
onClick: onRequiredToggle,
|
|
8584
|
-
className: "flex h-7 items-center gap-1.5 whitespace-nowrap rounded-md px-2 text-[13px] font-medium transition-colors " + (required ? "bg-primary/10 text-primary" : "text-foreground hover:bg-muted/70"),
|
|
8760
|
+
className: "flex h-7 items-center gap-1.5 whitespace-nowrap rounded-md px-2 text-[13px] font-medium transition-colors " + (required ? "bg-bridge-primary/10 text-bridge-primary" : "text-foreground hover:bg-muted/70"),
|
|
8585
8761
|
"data-ohw-field-required-toggle": "",
|
|
8586
8762
|
children: [
|
|
8587
8763
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react4.Asterisk, { size: 14, strokeWidth: 2, "aria-hidden": true }),
|
|
@@ -8601,7 +8777,7 @@ function FormFieldToolbar({
|
|
|
8601
8777
|
children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react4.MoreHorizontal, { size: 15, "aria-hidden": true })
|
|
8602
8778
|
}
|
|
8603
8779
|
) }),
|
|
8604
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(DropdownMenuContent, { align: "start", sideOffset: 8, className: "min-w-
|
|
8780
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(DropdownMenuContent, { align: "start", sideOffset: 8, className: "min-w-42.5 p-1", children: [
|
|
8605
8781
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(DropdownMenuItem, { onSelect: onDuplicate, className: "rounded-md py-2 text-[13px]", children: [
|
|
8606
8782
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react4.Copy, { size: 14, strokeWidth: 1.75, className: "shrink-0", "aria-hidden": true }),
|
|
8607
8783
|
"Duplicate"
|
|
@@ -8621,7 +8797,7 @@ function FieldTypePicker({ onPick }) {
|
|
|
8621
8797
|
"div",
|
|
8622
8798
|
{
|
|
8623
8799
|
"data-ohw-field-type-picker": "",
|
|
8624
|
-
className: "pointer-events-auto grid w-
|
|
8800
|
+
className: "pointer-events-auto grid w-105 grid-cols-3 gap-3 rounded-xl border border-border bg-background p-4 shadow-lg",
|
|
8625
8801
|
children: FIELD_TYPES.map((entry) => {
|
|
8626
8802
|
const Icon = TYPE_ICONS[entry.type];
|
|
8627
8803
|
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
@@ -8629,7 +8805,7 @@ function FieldTypePicker({ onPick }) {
|
|
|
8629
8805
|
{
|
|
8630
8806
|
type: "button",
|
|
8631
8807
|
onClick: () => onPick(entry.type),
|
|
8632
|
-
className: "flex h-
|
|
8808
|
+
className: "flex h-26 flex-col items-center justify-center gap-3 rounded-xl border border-border text-[15px] font-medium text-foreground transition-colors hover:border-bridge-primary hover:bg-bridge-primary/5",
|
|
8633
8809
|
children: [
|
|
8634
8810
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Icon, { size: 26, strokeWidth: 1.5, "aria-hidden": true }),
|
|
8635
8811
|
entry.label
|
|
@@ -8655,7 +8831,7 @@ var buttonVariants = cva(
|
|
|
8655
8831
|
{
|
|
8656
8832
|
variants: {
|
|
8657
8833
|
variant: {
|
|
8658
|
-
default: "bg-primary text-primary-foreground hover:opacity-90",
|
|
8834
|
+
default: "bg-bridge-primary text-primary-foreground hover:opacity-90",
|
|
8659
8835
|
outline: "border border-border bg-background text-foreground shadow-sm hover:bg-muted/80",
|
|
8660
8836
|
ghost: "min-w-0 px-3 py-2 text-foreground hover:bg-muted/50"
|
|
8661
8837
|
},
|
|
@@ -8750,6 +8926,7 @@ function MediaOverlay({
|
|
|
8750
8926
|
(prev) => prev && prev.fullWidth === width && prev.height === height ? prev : { fullWidth: width, height }
|
|
8751
8927
|
);
|
|
8752
8928
|
}, [isVideo]);
|
|
8929
|
+
const replaceLabel = isVideo ? "Replace video" : hover.elementType === "bg-image" ? "Replace background" : "Replace image";
|
|
8753
8930
|
const replaceMode = buttonSize ? replaceButtonMode({ width: rect.width, height: rect.height }, buttonSize) : "none";
|
|
8754
8931
|
const box = {
|
|
8755
8932
|
position: "fixed",
|
|
@@ -8855,8 +9032,8 @@ function MediaOverlay({
|
|
|
8855
9032
|
pointerEvents: hover.hasTextOverlap ? "none" : "auto",
|
|
8856
9033
|
// Selected: a firm component ring with no wash, so the image reads as chosen rather
|
|
8857
9034
|
// than hovered. Hover keeps the existing tinted preview.
|
|
8858
|
-
boxShadow: selected ? "inset 0 0 0 2px var(--color-primary)" : "inset 0 0 0 1.5px var(--color-primary)",
|
|
8859
|
-
background: selected ? "transparent" : "color-mix(in srgb, var(--color-primary) 20%, transparent)"
|
|
9035
|
+
boxShadow: selected ? "inset 0 0 0 2px var(--color-bridge-primary)" : "inset 0 0 0 1.5px var(--color-bridge-primary)",
|
|
9036
|
+
background: selected ? "transparent" : "color-mix(in srgb, var(--color-bridge-primary) 20%, transparent)"
|
|
8860
9037
|
},
|
|
8861
9038
|
onClick: () => onSelect && !selected ? onSelect(hover.key) : onReplace(hover.key),
|
|
8862
9039
|
children: [
|
|
@@ -8879,17 +9056,17 @@ function MediaOverlay({
|
|
|
8879
9056
|
},
|
|
8880
9057
|
children: [
|
|
8881
9058
|
isVideo ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_lucide_react5.Film, { size: 14 }) : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_lucide_react5.ImageIcon, { size: 14 }),
|
|
8882
|
-
|
|
9059
|
+
replaceLabel
|
|
8883
9060
|
]
|
|
8884
9061
|
}
|
|
8885
9062
|
),
|
|
8886
|
-
replaceMode
|
|
9063
|
+
showChrome && replaceMode !== "none" && /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
|
|
8887
9064
|
Button,
|
|
8888
9065
|
{
|
|
8889
9066
|
"data-ohw-media-overlay": "",
|
|
8890
9067
|
variant: "outline",
|
|
8891
9068
|
size: "sm",
|
|
8892
|
-
"aria-label":
|
|
9069
|
+
"aria-label": replaceLabel,
|
|
8893
9070
|
className: "gap-1.5 cursor-pointer hover:bg-background",
|
|
8894
9071
|
style: {
|
|
8895
9072
|
...OVERLAY_BUTTON_STYLE,
|
|
@@ -8912,7 +9089,7 @@ function MediaOverlay({
|
|
|
8912
9089
|
},
|
|
8913
9090
|
children: [
|
|
8914
9091
|
isVideo ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_lucide_react5.Film, { size: 14 }) : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_lucide_react5.ImageIcon, { size: 14 }),
|
|
8915
|
-
replaceMode === "full" ?
|
|
9092
|
+
replaceMode === "full" ? replaceLabel : null
|
|
8916
9093
|
]
|
|
8917
9094
|
}
|
|
8918
9095
|
)
|
|
@@ -8950,8 +9127,8 @@ function CarouselOverlay({
|
|
|
8950
9127
|
height: rect.height,
|
|
8951
9128
|
zIndex: 2147483646,
|
|
8952
9129
|
pointerEvents: "auto",
|
|
8953
|
-
boxShadow: "inset 0 0 0 1.5px var(--color-primary)",
|
|
8954
|
-
background: "color-mix(in srgb, var(--color-primary) 20%, transparent)"
|
|
9130
|
+
boxShadow: "inset 0 0 0 1.5px var(--color-bridge-primary)",
|
|
9131
|
+
background: "color-mix(in srgb, var(--color-bridge-primary) 20%, transparent)"
|
|
8955
9132
|
},
|
|
8956
9133
|
onClick: () => onEdit(hover.key),
|
|
8957
9134
|
children: /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
|
|
@@ -9789,7 +9966,7 @@ function SectionTreeItem({
|
|
|
9789
9966
|
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
9790
9967
|
"div",
|
|
9791
9968
|
{
|
|
9792
|
-
className: "mr-
|
|
9969
|
+
className: "-mr-px h-9 w-2 shrink-0 rounded-bl-sm border-b border-l border-border mb-4",
|
|
9793
9970
|
"aria-hidden": true
|
|
9794
9971
|
}
|
|
9795
9972
|
),
|
|
@@ -9808,7 +9985,7 @@ function SectionTreeItem({
|
|
|
9808
9985
|
className: cn(
|
|
9809
9986
|
"flex h-9 min-w-0 flex-1 items-center gap-2 rounded-md border border-border bg-background p-3",
|
|
9810
9987
|
interactive && "cursor-pointer hover:bg-muted/30",
|
|
9811
|
-
interactive && selected && "border-primary"
|
|
9988
|
+
interactive && selected && "border-bridge-primary"
|
|
9812
9989
|
),
|
|
9813
9990
|
children: [
|
|
9814
9991
|
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
@@ -9938,7 +10115,7 @@ function UrlOrPageInput({
|
|
|
9938
10115
|
};
|
|
9939
10116
|
const fieldClassName = cn(
|
|
9940
10117
|
"data-ohw-link-field flex h-[36px] w-full items-center overflow-hidden rounded-md border bg-background pl-3 pr-3 py-2 outline-none transition-[border-color,box-shadow]",
|
|
9941
|
-
urlError ? "border-destructive shadow-[0_0_0_1px_var(--ohw-destructive)]" : isFocused ? "border-primary shadow-[0_0_0_1px_var(--ohw-primary)]" : "border-input"
|
|
10118
|
+
urlError ? "border-destructive shadow-[0_0_0_1px_var(--ohw-destructive)]" : isFocused ? "border-bridge-primary shadow-[0_0_0_1px_var(--ohw-primary)]" : "border-input"
|
|
9942
10119
|
);
|
|
9943
10120
|
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex w-full flex-col gap-2 p-0", children: [
|
|
9944
10121
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Label, { htmlFor: inputId, className: cn(urlError && "text-destructive"), children: "Destination" }),
|
|
@@ -13787,6 +13964,7 @@ function readLogoSizeState(content, placement) {
|
|
|
13787
13964
|
function getLogoElement(el) {
|
|
13788
13965
|
const marked = el.closest('[data-ohw-role="logo"], [data-ohw-logo]');
|
|
13789
13966
|
if (marked) return marked;
|
|
13967
|
+
if (el.closest('[data-ohw-editable="icon"]')) return null;
|
|
13790
13968
|
const root = el.closest("nav, [data-ohw-nav-root], footer");
|
|
13791
13969
|
if (!root) return null;
|
|
13792
13970
|
const anchor = el.closest("a");
|
|
@@ -14074,7 +14252,7 @@ function DisplaySwitch({
|
|
|
14074
14252
|
onClick: () => onChange(!checked),
|
|
14075
14253
|
className: cn(
|
|
14076
14254
|
"relative h-5 w-9 shrink-0 rounded-full transition-colors",
|
|
14077
|
-
checked ? "bg-primary" : "bg-primary-50",
|
|
14255
|
+
checked ? "bg-bridge-primary" : "bg-primary-50",
|
|
14078
14256
|
disabled ? "cursor-default opacity-50" : "cursor-pointer"
|
|
14079
14257
|
),
|
|
14080
14258
|
children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
@@ -14082,7 +14260,7 @@ function DisplaySwitch({
|
|
|
14082
14260
|
{
|
|
14083
14261
|
className: cn(
|
|
14084
14262
|
"absolute top-0.5 h-4 w-4 rounded-full bg-white transition-all",
|
|
14085
|
-
checked ? "left-
|
|
14263
|
+
checked ? "left-4.5" : "left-0.5"
|
|
14086
14264
|
)
|
|
14087
14265
|
}
|
|
14088
14266
|
)
|
|
@@ -15261,7 +15439,9 @@ function collectEditableNodes(extraContent, root = document) {
|
|
|
15261
15439
|
return {
|
|
15262
15440
|
key: el.dataset.ohwKey ?? "",
|
|
15263
15441
|
type: el.dataset.ohwEditable ?? "text",
|
|
15264
|
-
|
|
15442
|
+
// innerText does not exist on SVG elements (a circular-badge <textPath> is a legitimate
|
|
15443
|
+
// plain editable) — textContent is the value there.
|
|
15444
|
+
text: el.dataset.ohwEditable === "plain" ? el.innerText ?? el.textContent ?? "" : el.innerHTML
|
|
15265
15445
|
};
|
|
15266
15446
|
});
|
|
15267
15447
|
const hrefEls = Array.from(root.querySelectorAll("[data-ohw-href-key]"));
|
|
@@ -15698,7 +15878,7 @@ var badgeVariants = cva(
|
|
|
15698
15878
|
{
|
|
15699
15879
|
variants: {
|
|
15700
15880
|
variant: {
|
|
15701
|
-
default: "border-transparent bg-primary text-primary-foreground",
|
|
15881
|
+
default: "border-transparent bg-bridge-primary text-primary-foreground",
|
|
15702
15882
|
secondary: "border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80",
|
|
15703
15883
|
destructive: "border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80",
|
|
15704
15884
|
outline: "text-foreground"
|
|
@@ -15880,21 +16060,10 @@ function parseSchedulingInsertAfter(insertAfter) {
|
|
|
15880
16060
|
insertBefore: insertAfter.slice(idx + INSERT_BEFORE_MARKER.length)
|
|
15881
16061
|
};
|
|
15882
16062
|
}
|
|
15883
|
-
function
|
|
15884
|
-
|
|
15885
|
-
const
|
|
15886
|
-
|
|
15887
|
-
return { effectiveInsertAfter, insertBefore };
|
|
15888
|
-
}
|
|
15889
|
-
function getSchedulingMountPoint(insertAfter) {
|
|
15890
|
-
const { anchor } = parseSchedulingInsertAfter(insertAfter);
|
|
15891
|
-
let anchorEl = document.querySelector(`[data-ohw-section="${anchor}"]`);
|
|
15892
|
-
if (!anchorEl && anchor === "scheduling") {
|
|
15893
|
-
const widgets = Array.from(document.querySelectorAll('[data-ohw-section^="scheduling-"]'));
|
|
15894
|
-
anchorEl = widgets.at(-1) ?? null;
|
|
15895
|
-
}
|
|
15896
|
-
if (!anchorEl) return null;
|
|
15897
|
-
return anchorEl.closest('[data-ohw-section-container="scheduling"]') ?? anchorEl;
|
|
16063
|
+
function resolveEntryAnchor(entry) {
|
|
16064
|
+
if (entry.anchorId !== void 0) return { anchorId: entry.anchorId, beforeId: entry.beforeId ?? null };
|
|
16065
|
+
const parsed = parseSchedulingInsertAfter(entry.insertAfter);
|
|
16066
|
+
return { anchorId: parsed.anchor, beforeId: parsed.insertBefore };
|
|
15898
16067
|
}
|
|
15899
16068
|
function schedulingMountDepth(insertAfter) {
|
|
15900
16069
|
if (!insertAfter.includes(INSERT_BEFORE_MARKER)) return 0;
|
|
@@ -15911,8 +16080,7 @@ function getPageSchedulingEntries(raw) {
|
|
|
15911
16080
|
}
|
|
15912
16081
|
}
|
|
15913
16082
|
function isSchedulingWidgetMissing(entry) {
|
|
15914
|
-
|
|
15915
|
-
return !document.querySelector(`[data-ohw-section="${schedulingSectionId(effectiveInsertAfter)}"]`);
|
|
16083
|
+
return !document.querySelector(`[data-ohw-section="${schedulingSectionId(entry.insertAfter)}"]`);
|
|
15916
16084
|
}
|
|
15917
16085
|
function hasMissingSchedulingWidgets(entries) {
|
|
15918
16086
|
return entries.some(isSchedulingWidgetMissing);
|
|
@@ -15950,17 +16118,18 @@ function initSectionsFromContent(content, removeExisting = false, currentPath =
|
|
|
15950
16118
|
} catch {
|
|
15951
16119
|
}
|
|
15952
16120
|
}
|
|
15953
|
-
function mountSchedulingWidget(
|
|
15954
|
-
const
|
|
15955
|
-
const sectionId = schedulingSectionId(
|
|
16121
|
+
function mountSchedulingWidget(anchorId, notifyOnConnect = false, scheduleId, beforeId, existingWidgetId) {
|
|
16122
|
+
const widgetId = existingWidgetId ?? (beforeId ? `${anchorId}${INSERT_BEFORE_MARKER}${beforeId}` : anchorId);
|
|
16123
|
+
const sectionId = schedulingSectionId(widgetId);
|
|
15956
16124
|
if (document.querySelector(`[data-ohw-section="${sectionId}"]`)) return false;
|
|
15957
|
-
const
|
|
15958
|
-
if (!
|
|
16125
|
+
const anchorEl = document.querySelector(`[data-ohw-section="${anchorId}"]`);
|
|
16126
|
+
if (!anchorEl) return false;
|
|
16127
|
+
const mountPoint = anchorEl.closest('[data-ohw-section-container="scheduling"]') ?? anchorEl;
|
|
15959
16128
|
const container = document.createElement("div");
|
|
15960
16129
|
container.dataset.ohwSectionContainer = "scheduling";
|
|
15961
16130
|
container.dataset.ohwInstance = sectionId;
|
|
15962
|
-
if (
|
|
15963
|
-
const beforeAnchor = document.querySelector(`[data-ohw-section="${
|
|
16131
|
+
if (beforeId) {
|
|
16132
|
+
const beforeAnchor = document.querySelector(`[data-ohw-section="${beforeId}"]`);
|
|
15964
16133
|
const beforePoint = beforeAnchor?.closest('[data-ohw-section-container="scheduling"]') ?? beforeAnchor;
|
|
15965
16134
|
if (!beforePoint) return false;
|
|
15966
16135
|
beforePoint.insertAdjacentElement("beforebegin", container);
|
|
@@ -15971,20 +16140,26 @@ function mountSchedulingWidget(insertAfter, notifyOnConnect = false, scheduleId,
|
|
|
15971
16140
|
}
|
|
15972
16141
|
tail.insertAdjacentElement("afterend", container);
|
|
15973
16142
|
}
|
|
15974
|
-
|
|
15975
|
-
|
|
15976
|
-
|
|
15977
|
-
|
|
15978
|
-
|
|
15979
|
-
|
|
15980
|
-
|
|
15981
|
-
|
|
15982
|
-
|
|
15983
|
-
|
|
15984
|
-
|
|
15985
|
-
|
|
15986
|
-
|
|
15987
|
-
|
|
16143
|
+
try {
|
|
16144
|
+
const root = (0, import_client2.createRoot)(container);
|
|
16145
|
+
schedulingRoots.set(container, root);
|
|
16146
|
+
(0, import_react_dom3.flushSync)(() => {
|
|
16147
|
+
root.render(
|
|
16148
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
16149
|
+
SchedulingWidget,
|
|
16150
|
+
{
|
|
16151
|
+
notifyOnConnect,
|
|
16152
|
+
initialScheduleId: scheduleId,
|
|
16153
|
+
insertAfter: widgetId
|
|
16154
|
+
}
|
|
16155
|
+
)
|
|
16156
|
+
);
|
|
16157
|
+
});
|
|
16158
|
+
} catch (err) {
|
|
16159
|
+
console.error("[ow:scheduling] render threw", err);
|
|
16160
|
+
container.remove();
|
|
16161
|
+
return false;
|
|
16162
|
+
}
|
|
15988
16163
|
const tracker = getSectionsTracker();
|
|
15989
16164
|
let sections = [];
|
|
15990
16165
|
try {
|
|
@@ -15992,10 +16167,12 @@ function mountSchedulingWidget(insertAfter, notifyOnConnect = false, scheduleId,
|
|
|
15992
16167
|
} catch {
|
|
15993
16168
|
}
|
|
15994
16169
|
const inEditor = typeof window !== "undefined" && window.self !== window.top;
|
|
15995
|
-
if (inEditor && !sections.find((s) => s.type === "scheduling" && s.insertAfter ===
|
|
16170
|
+
if (inEditor && !sections.find((s) => s.type === "scheduling" && s.insertAfter === widgetId)) {
|
|
15996
16171
|
sections.push({
|
|
15997
16172
|
type: "scheduling",
|
|
15998
|
-
insertAfter:
|
|
16173
|
+
insertAfter: widgetId,
|
|
16174
|
+
anchorId,
|
|
16175
|
+
beforeId: beforeId ?? null,
|
|
15999
16176
|
pagePath: window.location.pathname,
|
|
16000
16177
|
...scheduleId ? { scheduleId } : {}
|
|
16001
16178
|
});
|
|
@@ -16009,7 +16186,8 @@ function mountSchedulingEntries(entries, notifyOnConnect = false) {
|
|
|
16009
16186
|
for (let i = pending.length - 1; i >= 0; i--) {
|
|
16010
16187
|
const entry = pending[i];
|
|
16011
16188
|
const shouldNotify = typeof notifyOnConnect === "function" ? notifyOnConnect(entry) : notifyOnConnect;
|
|
16012
|
-
|
|
16189
|
+
const { anchorId, beforeId } = resolveEntryAnchor(entry);
|
|
16190
|
+
if (mountSchedulingWidget(anchorId, shouldNotify, entry.scheduleId ?? null, beforeId, entry.insertAfter)) {
|
|
16013
16191
|
pending.splice(i, 1);
|
|
16014
16192
|
}
|
|
16015
16193
|
}
|
|
@@ -16173,6 +16351,11 @@ function applyLinkByKey(key, val) {
|
|
|
16173
16351
|
hrefAnchors.forEach((el) => applyLinkHref(el, val));
|
|
16174
16352
|
}
|
|
16175
16353
|
}
|
|
16354
|
+
function isInsideLinkEditor(target) {
|
|
16355
|
+
return Boolean(
|
|
16356
|
+
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"]')
|
|
16357
|
+
);
|
|
16358
|
+
}
|
|
16176
16359
|
function isInsideFloatingPanel(target) {
|
|
16177
16360
|
return Boolean(target.closest("[data-ohw-floating-panel]"));
|
|
16178
16361
|
}
|
|
@@ -16180,11 +16363,6 @@ function isPointOverFloatingPanel(clientX, clientY) {
|
|
|
16180
16363
|
const el = document.elementFromPoint(clientX, clientY);
|
|
16181
16364
|
return Boolean(el instanceof Element && el.closest("[data-ohw-floating-panel]"));
|
|
16182
16365
|
}
|
|
16183
|
-
function isInsideLinkEditor(target) {
|
|
16184
|
-
return Boolean(
|
|
16185
|
-
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"]')
|
|
16186
|
-
);
|
|
16187
|
-
}
|
|
16188
16366
|
function getHrefKeyFromElement(el) {
|
|
16189
16367
|
if (!el) return null;
|
|
16190
16368
|
const anchor = el.closest("[data-ohw-href-key]");
|
|
@@ -16449,7 +16627,7 @@ function getNavigationSelectionParent(el) {
|
|
|
16449
16627
|
if (!isFooterLinksContainer(el) && (el.hasAttribute("data-ohw-footer-col") || el.hasAttribute("data-ohw-footer-column") || isInferredFooterGroup2(el))) {
|
|
16450
16628
|
return getFooterLinksContainer();
|
|
16451
16629
|
}
|
|
16452
|
-
if (el.hasAttribute("data-ohw-nav-container") || el.hasAttribute("data-ohw-nav-drawer") || isFooterLinksContainer(el)) {
|
|
16630
|
+
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)) {
|
|
16453
16631
|
return getNavigationRoot(el);
|
|
16454
16632
|
}
|
|
16455
16633
|
return null;
|
|
@@ -16665,7 +16843,6 @@ var ICONS = {
|
|
|
16665
16843
|
insertUnorderedList: '<line x1="8" y1="6" x2="21" y2="6"/><line x1="8" y1="12" x2="21" y2="12"/><line x1="8" y1="18" x2="21" y2="18"/><line x1="3" y1="6" x2="3.01" y2="6"/><line x1="3" y1="12" x2="3.01" y2="12"/><line x1="3" y1="18" x2="3.01" y2="18"/>',
|
|
16666
16844
|
insertOrderedList: '<line x1="10" y1="6" x2="21" y2="6"/><line x1="10" y1="12" x2="21" y2="12"/><line x1="10" y1="18" x2="21" y2="18"/><path d="M4 6h1v4"/><path d="M4 10h2"/><path d="M6 18H4c0-1 2-2 2-3s-1-1.5-2-1"/>'
|
|
16667
16845
|
};
|
|
16668
|
-
var HEIGHT_SETTLE_DELAYS = [150, 400, 800];
|
|
16669
16846
|
var SELECTION_CHROME_GAP2 = 4;
|
|
16670
16847
|
var TOOLBAR_STROKE_GAP2 = 4;
|
|
16671
16848
|
var TOOLBAR_OFFSET_FROM_ELEMENT = SELECTION_CHROME_GAP2 + TOOLBAR_STROKE_GAP2;
|
|
@@ -16762,6 +16939,10 @@ function getIframeVisibleClip(parentScroll) {
|
|
|
16762
16939
|
);
|
|
16763
16940
|
return { top: clipTop, bottom: Math.max(clipTop, clipBottom) };
|
|
16764
16941
|
}
|
|
16942
|
+
function isRectOutsideClip(rect, clip) {
|
|
16943
|
+
if (!clip) return false;
|
|
16944
|
+
return rect.bottom < clip.top || rect.top > clip.bottom;
|
|
16945
|
+
}
|
|
16765
16946
|
function applyVisibleViewport(el, parentScroll) {
|
|
16766
16947
|
const clip = getIframeVisibleClip(parentScroll);
|
|
16767
16948
|
const top = clip?.top ?? 0;
|
|
@@ -17045,6 +17226,7 @@ function StateToggle({
|
|
|
17045
17226
|
);
|
|
17046
17227
|
}
|
|
17047
17228
|
var contentCache = /* @__PURE__ */ new Map();
|
|
17229
|
+
var fetchedContentPaths = /* @__PURE__ */ new Set();
|
|
17048
17230
|
var brandingCache = /* @__PURE__ */ new Map();
|
|
17049
17231
|
var OHW_LOADER_STYLE = {
|
|
17050
17232
|
position: "fixed",
|
|
@@ -17593,13 +17775,6 @@ function OhhwellsBridge() {
|
|
|
17593
17775
|
const [isItemDragging, setIsItemDragging] = (0, import_react17.useState)(false);
|
|
17594
17776
|
const [isFooterFrameSelection, setIsFooterFrameSelection] = (0, import_react17.useState)(false);
|
|
17595
17777
|
isFooterFrameSelectionRef.current = isFooterFrameSelection;
|
|
17596
|
-
const [floatingPanel, setFloatingPanel] = (0, import_react17.useState)(null);
|
|
17597
|
-
const floatingPanelOpenRef = (0, import_react17.useRef)(false);
|
|
17598
|
-
floatingPanelOpenRef.current = floatingPanel !== null;
|
|
17599
|
-
const [floatingPanelPos, setFloatingPanelPos] = (0, import_react17.useState)(null);
|
|
17600
|
-
const [logoSizeDraft, setLogoSizeDraft] = (0, import_react17.useState)(null);
|
|
17601
|
-
const [editorViewport, setEditorViewport] = (0, import_react17.useState)("desktop");
|
|
17602
|
-
const [parentScrollSnap, setParentScrollSnap] = (0, import_react17.useState)(null);
|
|
17603
17778
|
const [navDropdownPreviewOpen, setNavDropdownPreviewOpen] = (0, import_react17.useState)(null);
|
|
17604
17779
|
const [footerHeadingVisible, setFooterHeadingVisible] = (0, import_react17.useState)(null);
|
|
17605
17780
|
const footerDragRef = (0, import_react17.useRef)(null);
|
|
@@ -17617,6 +17792,13 @@ function OhhwellsBridge() {
|
|
|
17617
17792
|
const brandKitRef = (0, import_react17.useRef)("");
|
|
17618
17793
|
const stylesRef = (0, import_react17.useRef)("");
|
|
17619
17794
|
const pendingDeleteUndoRef = (0, import_react17.useRef)(null);
|
|
17795
|
+
const [floatingPanel, setFloatingPanel] = (0, import_react17.useState)(null);
|
|
17796
|
+
const floatingPanelOpenRef = (0, import_react17.useRef)(false);
|
|
17797
|
+
const setFloatingPanelRef = (0, import_react17.useRef)(setFloatingPanel);
|
|
17798
|
+
const [floatingPanelPos, setFloatingPanelPos] = (0, import_react17.useState)(null);
|
|
17799
|
+
const [logoSizeDraft, setLogoSizeDraft] = (0, import_react17.useState)(null);
|
|
17800
|
+
const [editorViewport, setEditorViewport] = (0, import_react17.useState)("desktop");
|
|
17801
|
+
const [parentScrollSnap, setParentScrollSnap] = (0, import_react17.useState)(null);
|
|
17620
17802
|
const [sitePages, setSitePages] = (0, import_react17.useState)([]);
|
|
17621
17803
|
const [sectionsByPath, setSectionsByPath] = (0, import_react17.useState)({});
|
|
17622
17804
|
const sectionsPrefetchGenRef = (0, import_react17.useRef)(0);
|
|
@@ -17625,7 +17807,18 @@ function OhhwellsBridge() {
|
|
|
17625
17807
|
const linkPopoverOpenRef = (0, import_react17.useRef)(false);
|
|
17626
17808
|
const linkPopoverGraceUntilRef = (0, import_react17.useRef)(0);
|
|
17627
17809
|
setLinkPopoverRef.current = setLinkPopover;
|
|
17810
|
+
setFloatingPanelRef.current = setFloatingPanel;
|
|
17628
17811
|
linkPopoverSessionRef.current = linkPopover;
|
|
17812
|
+
floatingPanelOpenRef.current = Boolean(floatingPanel);
|
|
17813
|
+
(0, import_react17.useEffect)(() => {
|
|
17814
|
+
const syncViewport = () => {
|
|
17815
|
+
const next = window.innerWidth <= 480 ? "mobile" : "desktop";
|
|
17816
|
+
setEditorViewport((prev) => prev === next ? prev : next);
|
|
17817
|
+
};
|
|
17818
|
+
syncViewport();
|
|
17819
|
+
window.addEventListener("resize", syncViewport);
|
|
17820
|
+
return () => window.removeEventListener("resize", syncViewport);
|
|
17821
|
+
}, []);
|
|
17629
17822
|
const {
|
|
17630
17823
|
navDragRef,
|
|
17631
17824
|
navPointerDragRef,
|
|
@@ -18966,6 +19159,7 @@ function OhhwellsBridge() {
|
|
|
18966
19159
|
}
|
|
18967
19160
|
if (typeof content[STYLE_STORE_KEY] === "string") {
|
|
18968
19161
|
stylesRef.current = content[STYLE_STORE_KEY];
|
|
19162
|
+
document.querySelectorAll('[data-ohw-editable="form"]').forEach((f) => markFormFields(f));
|
|
18969
19163
|
applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
|
|
18970
19164
|
}
|
|
18971
19165
|
applyBrandChrome(content);
|
|
@@ -18973,11 +19167,11 @@ function OhhwellsBridge() {
|
|
|
18973
19167
|
for (const [key, val] of Object.entries(content)) {
|
|
18974
19168
|
if (key === "__ohw_sections") continue;
|
|
18975
19169
|
if (key === AI_SECTIONS_KEY) continue;
|
|
19170
|
+
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
19171
|
+
if (LOGO_IMAGE_KEYS.includes(key)) continue;
|
|
18976
19172
|
if (key === BRAND_KIT_KEY) continue;
|
|
18977
19173
|
if (key === STYLE_STORE_KEY) continue;
|
|
18978
19174
|
if (BRAND_CHROME_KEYS.has(key)) continue;
|
|
18979
|
-
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
18980
|
-
if (LOGO_IMAGE_KEYS.includes(key)) continue;
|
|
18981
19175
|
if (applyVideoSettingNode(key, val)) continue;
|
|
18982
19176
|
if (applyCarouselNode(key, val)) continue;
|
|
18983
19177
|
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
@@ -19048,7 +19242,9 @@ function OhhwellsBridge() {
|
|
|
19048
19242
|
let cancelled = false;
|
|
19049
19243
|
setFetchState("loading");
|
|
19050
19244
|
const apiUrl = process.env.NEXT_PUBLIC_FLOWOPS_API_URL ?? "https://flowops-backend-staging-2yfdh7pwpq-as.a.run.app";
|
|
19051
|
-
|
|
19245
|
+
const initialPath = pathname;
|
|
19246
|
+
fetchedContentPaths.add(`${subdomain}::${initialPath}`);
|
|
19247
|
+
fetch(`${apiUrl}/api/public/sites/${subdomain}/content?path=${encodeURIComponent(initialPath)}`, { cache: "no-store" }).then((r2) => r2.ok ? r2.json() : null).then((data) => {
|
|
19052
19248
|
if (cancelled) return;
|
|
19053
19249
|
const content = data?.content ?? {};
|
|
19054
19250
|
const branding = Boolean(data?.showBranding);
|
|
@@ -19157,7 +19353,9 @@ function OhhwellsBridge() {
|
|
|
19157
19353
|
}, [isEditMode]);
|
|
19158
19354
|
(0, import_react17.useEffect)(() => {
|
|
19159
19355
|
if (isEditMode || fetchState !== "done") return;
|
|
19356
|
+
console.log("env", process.env.NEXT_PUBLIC_FLOWOPS_API_URL);
|
|
19160
19357
|
const apiUrl = process.env.NEXT_PUBLIC_FLOWOPS_API_URL ?? "https://flowops-backend-staging-2yfdh7pwpq-as.a.run.app";
|
|
19358
|
+
console.log({ apiUrl, subdomain });
|
|
19161
19359
|
bindPublishedForms(apiUrl, subdomain, contentCache.get(subdomain) ?? {});
|
|
19162
19360
|
}, [isEditMode, fetchState, subdomain]);
|
|
19163
19361
|
(0, import_react17.useEffect)(() => {
|
|
@@ -19182,16 +19380,17 @@ function OhhwellsBridge() {
|
|
|
19182
19380
|
applyAiSectionsToDom(parseAiSectionsState(content[AI_SECTIONS_KEY]));
|
|
19183
19381
|
}
|
|
19184
19382
|
if (typeof content[STYLE_STORE_KEY] === "string") {
|
|
19383
|
+
document.querySelectorAll('[data-ohw-editable="form"]').forEach((f) => markFormFields(f));
|
|
19185
19384
|
applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
|
|
19186
19385
|
}
|
|
19187
19386
|
for (const [key, val] of Object.entries(content)) {
|
|
19188
19387
|
if (key === "__ohw_sections") continue;
|
|
19189
19388
|
if (key === AI_SECTIONS_KEY) continue;
|
|
19389
|
+
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
19390
|
+
if (LOGO_IMAGE_KEYS.includes(key)) continue;
|
|
19190
19391
|
if (key === BRAND_KIT_KEY) continue;
|
|
19191
19392
|
if (key === STYLE_STORE_KEY) continue;
|
|
19192
19393
|
if (BRAND_CHROME_KEYS.has(key)) continue;
|
|
19193
|
-
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
19194
|
-
if (LOGO_IMAGE_KEYS.includes(key)) continue;
|
|
19195
19394
|
if (applyVideoSettingNode(key, val)) continue;
|
|
19196
19395
|
if (applyCarouselNode(key, val)) continue;
|
|
19197
19396
|
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
@@ -19242,6 +19441,17 @@ function OhhwellsBridge() {
|
|
|
19242
19441
|
debounceTimer = setTimeout(applyFromCache, 150);
|
|
19243
19442
|
};
|
|
19244
19443
|
applyFromCache();
|
|
19444
|
+
const pathCacheKey = `${subdomain}::${pathname}`;
|
|
19445
|
+
if (!fetchedContentPaths.has(pathCacheKey)) {
|
|
19446
|
+
fetchedContentPaths.add(pathCacheKey);
|
|
19447
|
+
const apiUrl = process.env.NEXT_PUBLIC_FLOWOPS_API_URL ?? "https://flowops-backend-staging-2yfdh7pwpq-as.a.run.app";
|
|
19448
|
+
fetch(`${apiUrl}/api/public/sites/${subdomain}/content?path=${encodeURIComponent(pathname)}`, { cache: "no-store" }).then((r2) => r2.ok ? r2.json() : null).then((data) => {
|
|
19449
|
+
if (!data?.content) return;
|
|
19450
|
+
contentCache.set(subdomain, data.content);
|
|
19451
|
+
applyFromCache();
|
|
19452
|
+
}).catch(() => {
|
|
19453
|
+
});
|
|
19454
|
+
}
|
|
19245
19455
|
observer = new MutationObserver(scheduleApply);
|
|
19246
19456
|
observer.observe(document.body, { childList: true, subtree: true });
|
|
19247
19457
|
return () => {
|
|
@@ -19377,26 +19587,11 @@ function OhhwellsBridge() {
|
|
|
19377
19587
|
const t2 = setTimeout(measure, 500);
|
|
19378
19588
|
const ro = new ResizeObserver(schedule);
|
|
19379
19589
|
ro.observe(document.body);
|
|
19380
|
-
let lastWidth = window.innerWidth;
|
|
19381
|
-
let resizeTimers = [];
|
|
19382
|
-
const clearResizeTimers = () => {
|
|
19383
|
-
resizeTimers.forEach(clearTimeout);
|
|
19384
|
-
resizeTimers = [];
|
|
19385
|
-
};
|
|
19386
|
-
const handleResize = () => {
|
|
19387
|
-
if (window.innerWidth === lastWidth) return;
|
|
19388
|
-
lastWidth = window.innerWidth;
|
|
19389
|
-
clearResizeTimers();
|
|
19390
|
-
resizeTimers = HEIGHT_SETTLE_DELAYS.map((delay) => setTimeout(measure, delay));
|
|
19391
|
-
};
|
|
19392
|
-
window.addEventListener("resize", handleResize);
|
|
19393
19590
|
return () => {
|
|
19394
19591
|
clearTimeout(t1);
|
|
19395
19592
|
clearTimeout(t2);
|
|
19396
19593
|
if (raf != null) cancelAnimationFrame(raf);
|
|
19397
19594
|
ro.disconnect();
|
|
19398
|
-
clearResizeTimers();
|
|
19399
|
-
window.removeEventListener("resize", handleResize);
|
|
19400
19595
|
};
|
|
19401
19596
|
}, [pathname, isEditMode, postToParent2]);
|
|
19402
19597
|
(0, import_react17.useEffect)(() => {
|
|
@@ -19627,6 +19822,10 @@ function OhhwellsBridge() {
|
|
|
19627
19822
|
[data-ohw-editable-state], [data-ohw-editable-state] * { pointer-events: none !important; }
|
|
19628
19823
|
[data-ohw-editable-state][data-ohw-active-state] [data-ohw-editable] { pointer-events: auto !important; }
|
|
19629
19824
|
[data-ohw-editable-state][data-ohw-active-state][data-ohw-editable] { pointer-events: auto !important; }
|
|
19825
|
+
/* SVG hit-tests painted glyphs only, so an editable curved-text badge answered clicks
|
|
19826
|
+
on its letter strokes alone (and a spinning one barely at all). In edit mode the
|
|
19827
|
+
whole box takes the click; the handler resolves it to the editable inside. */
|
|
19828
|
+
svg:has([data-ohw-editable]) { pointer-events: bounding-box !important; }
|
|
19630
19829
|
`;
|
|
19631
19830
|
if (!existing) {
|
|
19632
19831
|
const base = document.createElement("style");
|
|
@@ -19665,9 +19864,6 @@ function OhhwellsBridge() {
|
|
|
19665
19864
|
if (target.closest("[data-ohw-state-toggle]")) return;
|
|
19666
19865
|
if (target.closest("[data-ohw-max-badge]")) return;
|
|
19667
19866
|
if (isInsideLinkEditor(target)) return;
|
|
19668
|
-
if (selectedMediaElRef.current && !selectedMediaElRef.current.contains(target) && !target.closest("[data-ohw-media-overlay], [data-ohw-edit-chrome], [data-ohw-item-interaction]")) {
|
|
19669
|
-
clearMediaSelectionRef.current();
|
|
19670
|
-
}
|
|
19671
19867
|
if (isInsideFloatingPanel(target)) return;
|
|
19672
19868
|
if (target.closest("[data-ohw-form-toolbar]")) return;
|
|
19673
19869
|
if (target.closest(
|
|
@@ -19675,6 +19871,9 @@ function OhhwellsBridge() {
|
|
|
19675
19871
|
)) {
|
|
19676
19872
|
return;
|
|
19677
19873
|
}
|
|
19874
|
+
if (selectedMediaElRef.current && !selectedMediaElRef.current.contains(target) && !target.closest("[data-ohw-media-overlay], [data-ohw-edit-chrome], [data-ohw-item-interaction]")) {
|
|
19875
|
+
clearMediaSelectionRef.current();
|
|
19876
|
+
}
|
|
19678
19877
|
{
|
|
19679
19878
|
const formEl = getFormElement(target);
|
|
19680
19879
|
const onSuccessText = target.closest(`[${SUCCESS_TEXT_ATTR}]`);
|
|
@@ -19797,7 +19996,19 @@ function OhhwellsBridge() {
|
|
|
19797
19996
|
openLogoSizePanelRef.current(logoEl);
|
|
19798
19997
|
return;
|
|
19799
19998
|
}
|
|
19800
|
-
|
|
19999
|
+
let editable = target.closest("[data-ohw-editable]");
|
|
20000
|
+
if (!editable && target instanceof SVGElement) {
|
|
20001
|
+
const inner = target.closest("svg")?.querySelectorAll("[data-ohw-editable]");
|
|
20002
|
+
if (inner && inner.length === 1) editable = inner[0];
|
|
20003
|
+
}
|
|
20004
|
+
if (editable && !(editable instanceof HTMLElement)) {
|
|
20005
|
+
e.preventDefault();
|
|
20006
|
+
e.stopPropagation();
|
|
20007
|
+
deselectRef.current();
|
|
20008
|
+
deactivateRef.current();
|
|
20009
|
+
aiSectionApiRef.current?.selectFromElement(editable);
|
|
20010
|
+
return;
|
|
20011
|
+
}
|
|
19801
20012
|
if (editable) {
|
|
19802
20013
|
if (editable.dataset.ohwEditable === "link") {
|
|
19803
20014
|
e.preventDefault();
|
|
@@ -19826,14 +20037,6 @@ function OhhwellsBridge() {
|
|
|
19826
20037
|
}
|
|
19827
20038
|
const clickedButton = findClosestButtonLike(target);
|
|
19828
20039
|
const buttonOnMedia = Boolean(clickedButton && isMediaEditable(editable) && editable.contains(clickedButton));
|
|
19829
|
-
console.log("[click-debug]", {
|
|
19830
|
-
editableType: editable.dataset.ohwEditable,
|
|
19831
|
-
editableTag: editable.tagName,
|
|
19832
|
-
targetTag: target.tagName,
|
|
19833
|
-
clickedButtonTag: clickedButton?.tagName ?? null,
|
|
19834
|
-
buttonOnMedia,
|
|
19835
|
-
isMediaEditableEditable: isMediaEditable(editable)
|
|
19836
|
-
});
|
|
19837
20040
|
if (isMediaEditable(editable) && !buttonOnMedia) {
|
|
19838
20041
|
e.preventDefault();
|
|
19839
20042
|
e.stopPropagation();
|
|
@@ -19860,11 +20063,6 @@ function OhhwellsBridge() {
|
|
|
19860
20063
|
const hrefLookupTarget = buttonOnMedia ? clickedButton : editable;
|
|
19861
20064
|
const hrefCtx = getHrefKeyFromElement(hrefLookupTarget);
|
|
19862
20065
|
const navAnchor = hrefCtx ? getNavigationItemAnchor(hrefCtx.anchor) : null;
|
|
19863
|
-
console.log("[click-debug 2]", {
|
|
19864
|
-
hrefLookupTargetTag: hrefLookupTarget.tagName,
|
|
19865
|
-
hrefCtx: hrefCtx ? { key: hrefCtx.key } : null,
|
|
19866
|
-
navAnchorTag: navAnchor?.tagName ?? null
|
|
19867
|
-
});
|
|
19868
20066
|
if (navAnchor) {
|
|
19869
20067
|
e.preventDefault();
|
|
19870
20068
|
e.stopPropagation();
|
|
@@ -20034,6 +20232,9 @@ function OhhwellsBridge() {
|
|
|
20034
20232
|
setHoveredItemRect(null);
|
|
20035
20233
|
hoveredNavContainerRef.current = null;
|
|
20036
20234
|
setHoveredNavContainerRect(null);
|
|
20235
|
+
siblingHintElRef.current = null;
|
|
20236
|
+
setSiblingHintRect(null);
|
|
20237
|
+
setSiblingHintRects([]);
|
|
20037
20238
|
return;
|
|
20038
20239
|
}
|
|
20039
20240
|
{
|
|
@@ -20154,7 +20355,6 @@ function OhhwellsBridge() {
|
|
|
20154
20355
|
hoveredNavContainerRef.current = null;
|
|
20155
20356
|
setHoveredNavContainerRect(null);
|
|
20156
20357
|
hoveredItemElRef.current = editable;
|
|
20157
|
-
setHoveredItemRect(isSelectedForHoverRef.current(editable) ? null : editable.getBoundingClientRect());
|
|
20158
20358
|
}
|
|
20159
20359
|
}
|
|
20160
20360
|
}
|
|
@@ -20451,7 +20651,7 @@ function OhhwellsBridge() {
|
|
|
20451
20651
|
}
|
|
20452
20652
|
};
|
|
20453
20653
|
const probeImageAt = (clientX, clientY, isDragOver = false, fromParentViewport = false) => {
|
|
20454
|
-
if (linkPopoverOpenRef.current) {
|
|
20654
|
+
if (linkPopoverOpenRef.current || floatingPanelOpenRef.current && isPointOverFloatingPanel(clientX, clientY)) {
|
|
20455
20655
|
if (hoveredImageRef.current) {
|
|
20456
20656
|
hoveredImageRef.current = null;
|
|
20457
20657
|
hoveredImageHasTextOverlapRef.current = false;
|
|
@@ -20540,6 +20740,15 @@ function OhhwellsBridge() {
|
|
|
20540
20740
|
}
|
|
20541
20741
|
return;
|
|
20542
20742
|
}
|
|
20743
|
+
const cardHit = !isDragOver && Array.from(document.querySelectorAll(".card, [data-ohw-card]")).some((card) => {
|
|
20744
|
+
if (card.contains(imgEl)) return false;
|
|
20745
|
+
const r2 = card.getBoundingClientRect();
|
|
20746
|
+
return x2 >= r2.left && x2 <= r2.right && y2 >= r2.top && y2 <= r2.bottom;
|
|
20747
|
+
});
|
|
20748
|
+
if (cardHit) {
|
|
20749
|
+
dismissImageHover();
|
|
20750
|
+
return;
|
|
20751
|
+
}
|
|
20543
20752
|
const topEl = document.elementFromPoint(x2, y2);
|
|
20544
20753
|
if (topEl?.closest('[data-ohw-toolbar], [data-ohw-edit-chrome], [data-ohw-item-interaction], [data-ohw-drag-handle-container], [data-slot="drag-handle"], [data-ohw-more-menu], [data-slot="dropdown-menu-content"], [data-slot="dropdown-menu-item"]')) {
|
|
20545
20754
|
if (hoveredImageRef.current) {
|
|
@@ -20815,8 +21024,7 @@ function OhhwellsBridge() {
|
|
|
20815
21024
|
};
|
|
20816
21025
|
const handleMouseMove = (e) => {
|
|
20817
21026
|
const { clientX, clientY } = e;
|
|
20818
|
-
if (
|
|
20819
|
-
if (isOverEditorChrome(clientX, clientY)) {
|
|
21027
|
+
if (document.documentElement.hasAttribute("data-ohw-panel-dragging") || floatingPanelOpenRef.current && isPointOverFloatingPanel(clientX, clientY) || isOverEditorChrome(clientX, clientY)) {
|
|
20820
21028
|
document.querySelectorAll("[data-ohw-hovered]").forEach((el) => el.removeAttribute("data-ohw-hovered"));
|
|
20821
21029
|
formHoverElRef.current = null;
|
|
20822
21030
|
setFormHoverRect(null);
|
|
@@ -20824,6 +21032,12 @@ function OhhwellsBridge() {
|
|
|
20824
21032
|
setHoveredItemRect(null);
|
|
20825
21033
|
hoveredNavContainerRef.current = null;
|
|
20826
21034
|
setHoveredNavContainerRect(null);
|
|
21035
|
+
siblingHintElRef.current = null;
|
|
21036
|
+
setSiblingHintRect(null);
|
|
21037
|
+
setSiblingHintRects([]);
|
|
21038
|
+
dismissImageHover();
|
|
21039
|
+
clearImageHover();
|
|
21040
|
+
setSectionGap(null);
|
|
20827
21041
|
return;
|
|
20828
21042
|
}
|
|
20829
21043
|
if (probeSocialsRowAt(clientX, clientY)) return;
|
|
@@ -20835,7 +21049,11 @@ function OhhwellsBridge() {
|
|
|
20835
21049
|
if (e.data?.type !== "ow:pointer-sync") return;
|
|
20836
21050
|
const { clientX, clientY } = e.data;
|
|
20837
21051
|
if (typeof clientX !== "number" || typeof clientY !== "number") return;
|
|
20838
|
-
if (
|
|
21052
|
+
if (document.documentElement.hasAttribute("data-ohw-panel-dragging") || floatingPanelOpenRef.current && isPointOverFloatingPanel(clientX, clientY)) {
|
|
21053
|
+
dismissImageHover();
|
|
21054
|
+
clearImageHover();
|
|
21055
|
+
return;
|
|
21056
|
+
}
|
|
20839
21057
|
if (probeSocialsRowAt(clientX, clientY)) return;
|
|
20840
21058
|
probeSectionGapAt(clientX, clientY);
|
|
20841
21059
|
probeImageAt(clientX, clientY);
|
|
@@ -21174,6 +21392,7 @@ function OhhwellsBridge() {
|
|
|
21174
21392
|
}
|
|
21175
21393
|
if (typeof content[STYLE_STORE_KEY] === "string") {
|
|
21176
21394
|
stylesRef.current = content[STYLE_STORE_KEY];
|
|
21395
|
+
document.querySelectorAll('[data-ohw-editable="form"]').forEach((f) => markFormFields(f));
|
|
21177
21396
|
applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
|
|
21178
21397
|
}
|
|
21179
21398
|
applyBrandChrome(content);
|
|
@@ -21185,11 +21404,11 @@ function OhhwellsBridge() {
|
|
|
21185
21404
|
continue;
|
|
21186
21405
|
}
|
|
21187
21406
|
if (key === AI_SECTIONS_KEY) continue;
|
|
21407
|
+
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
21408
|
+
if (LOGO_IMAGE_KEYS.includes(key) && !String(val ?? "").trim()) continue;
|
|
21188
21409
|
if (key === BRAND_KIT_KEY) continue;
|
|
21189
21410
|
if (key === STYLE_STORE_KEY) continue;
|
|
21190
21411
|
if (BRAND_CHROME_KEYS.has(key)) continue;
|
|
21191
|
-
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
21192
|
-
if (LOGO_IMAGE_KEYS.includes(key) && !String(val ?? "").trim()) continue;
|
|
21193
21412
|
if (applyVideoSettingNode(key, val)) continue;
|
|
21194
21413
|
if (applyCarouselNode(key, val)) continue;
|
|
21195
21414
|
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
@@ -21410,10 +21629,26 @@ function OhhwellsBridge() {
|
|
|
21410
21629
|
const handleGetBrand = (e) => {
|
|
21411
21630
|
if (e.data?.type !== "ow:get-brand") return;
|
|
21412
21631
|
const template = deriveTemplateBrand();
|
|
21413
|
-
const
|
|
21632
|
+
const fallback = template ?? (() => {
|
|
21633
|
+
const fonts = deriveTemplateFonts();
|
|
21634
|
+
return fonts ? { palette: AI_DEFAULT_BRAND.palette, fonts } : null;
|
|
21635
|
+
})();
|
|
21636
|
+
const value = brandKitRef.current || (fallback ? JSON.stringify(fallback) : "");
|
|
21414
21637
|
postToParentRef.current({ type: "ow:brand-value", value });
|
|
21415
21638
|
};
|
|
21416
21639
|
window.addEventListener("message", handleGetBrand);
|
|
21640
|
+
const handleGetTemplateFonts = (e) => {
|
|
21641
|
+
if (e.data?.type !== "ow:get-template-fonts") return;
|
|
21642
|
+
const fonts = deriveTemplateFonts();
|
|
21643
|
+
postToParentRef.current({ type: "ow:template-fonts-value", value: fonts ? JSON.stringify(fonts) : "" });
|
|
21644
|
+
};
|
|
21645
|
+
window.addEventListener("message", handleGetTemplateFonts);
|
|
21646
|
+
const handleGetTemplateBrand = (e) => {
|
|
21647
|
+
if (e.data?.type !== "ow:get-template-brand") return;
|
|
21648
|
+
const brand = deriveTemplateBrand();
|
|
21649
|
+
postToParentRef.current({ type: "ow:template-brand-value", value: brand ? JSON.stringify(brand) : "" });
|
|
21650
|
+
};
|
|
21651
|
+
window.addEventListener("message", handleGetTemplateBrand);
|
|
21417
21652
|
const handleMoveSection = (e) => {
|
|
21418
21653
|
if (e.data?.type !== "ow:move-section") return;
|
|
21419
21654
|
const instanceId = typeof e.data.instanceId === "string" ? e.data.instanceId : "";
|
|
@@ -21606,6 +21841,12 @@ function OhhwellsBridge() {
|
|
|
21606
21841
|
closeLinkPopoverRef.current();
|
|
21607
21842
|
return;
|
|
21608
21843
|
}
|
|
21844
|
+
if (floatingPanelOpenRef.current) {
|
|
21845
|
+
setFloatingPanelRef.current(null);
|
|
21846
|
+
deselectRef.current();
|
|
21847
|
+
deactivateRef.current();
|
|
21848
|
+
return;
|
|
21849
|
+
}
|
|
21609
21850
|
deselectRef.current();
|
|
21610
21851
|
deactivateRef.current();
|
|
21611
21852
|
clearMediaSelectionRef.current();
|
|
@@ -21894,8 +22135,12 @@ function OhhwellsBridge() {
|
|
|
21894
22135
|
if (inserted) {
|
|
21895
22136
|
const tracker = getSectionsTracker();
|
|
21896
22137
|
postToParentRef.current({ type: "ow:change", nodes: [{ key: "__ohw_sections", text: tracker.textContent ?? "[]" }] });
|
|
21897
|
-
const
|
|
21898
|
-
|
|
22138
|
+
const reportHeight = () => {
|
|
22139
|
+
const h = document.body.scrollHeight;
|
|
22140
|
+
if (h > 50) postToParentRef.current({ type: "ow:height", height: h });
|
|
22141
|
+
};
|
|
22142
|
+
reportHeight();
|
|
22143
|
+
setTimeout(reportHeight, 500);
|
|
21899
22144
|
}
|
|
21900
22145
|
};
|
|
21901
22146
|
const handleSwitchSchedule = (e) => {
|
|
@@ -22072,14 +22317,20 @@ function OhhwellsBridge() {
|
|
|
22072
22317
|
};
|
|
22073
22318
|
const applyToolbarPos = (rect) => {
|
|
22074
22319
|
const ps = parentScrollRef.current;
|
|
22320
|
+
const hidden = isRectOutsideClip(rect, getIframeVisibleClip(ps));
|
|
22075
22321
|
const measuredW = toolbarElRef.current?.offsetWidth || 330;
|
|
22076
22322
|
if (toolbarElRef.current) {
|
|
22077
|
-
|
|
22078
|
-
|
|
22079
|
-
|
|
22080
|
-
|
|
22323
|
+
toolbarElRef.current.style.display = hidden ? "none" : "";
|
|
22324
|
+
if (!hidden) {
|
|
22325
|
+
const { top, left, transform } = calcToolbarPos(rect, ps, measuredW);
|
|
22326
|
+
toolbarElRef.current.style.top = `${top}px`;
|
|
22327
|
+
toolbarElRef.current.style.left = `${left}px`;
|
|
22328
|
+
toolbarElRef.current.style.transform = transform;
|
|
22329
|
+
}
|
|
22081
22330
|
}
|
|
22082
22331
|
if (glowElRef.current) {
|
|
22332
|
+
glowElRef.current.style.display = hidden ? "none" : "";
|
|
22333
|
+
if (hidden) return;
|
|
22083
22334
|
const GAP = SELECTION_CHROME_GAP2;
|
|
22084
22335
|
glowElRef.current.style.top = `${rect.top - GAP}px`;
|
|
22085
22336
|
glowElRef.current.style.left = `${rect.left - GAP}px`;
|
|
@@ -22310,15 +22561,17 @@ function OhhwellsBridge() {
|
|
|
22310
22561
|
window.removeEventListener("message", handleAiSetBrand);
|
|
22311
22562
|
window.removeEventListener("message", handleAiSetStyles);
|
|
22312
22563
|
window.removeEventListener("message", handleGetBrand);
|
|
22564
|
+
window.removeEventListener("message", handleGetTemplateFonts);
|
|
22565
|
+
window.removeEventListener("message", handleGetTemplateBrand);
|
|
22313
22566
|
window.removeEventListener("message", handleMoveSection);
|
|
22314
22567
|
window.removeEventListener("message", handlePanelDragging);
|
|
22315
22568
|
window.removeEventListener("message", handleDeleteSection);
|
|
22316
22569
|
window.removeEventListener("message", handleDuplicateSection);
|
|
22317
22570
|
window.removeEventListener("message", handleDeactivate);
|
|
22318
|
-
document.documentElement.removeAttribute("data-ohw-panel-dragging");
|
|
22319
22571
|
window.removeEventListener("message", handleToastAction);
|
|
22320
22572
|
window.removeEventListener("message", handleFormCount);
|
|
22321
22573
|
window.removeEventListener("message", handleUiEscape);
|
|
22574
|
+
document.documentElement.removeAttribute("data-ohw-panel-dragging");
|
|
22322
22575
|
autoSaveTimers.current.forEach(clearTimeout);
|
|
22323
22576
|
autoSaveTimers.current.clear();
|
|
22324
22577
|
if (imageUnhoverTimerRef.current) clearTimeout(imageUnhoverTimerRef.current);
|
|
@@ -22521,7 +22774,7 @@ function OhhwellsBridge() {
|
|
|
22521
22774
|
postToParent2({
|
|
22522
22775
|
type: "ow:ready",
|
|
22523
22776
|
version: "1",
|
|
22524
|
-
bridgeVersion: "0.1.
|
|
22777
|
+
bridgeVersion: "0.1.108",
|
|
22525
22778
|
path: pathname,
|
|
22526
22779
|
nodes: collectEditableNodes(editContentRef.current),
|
|
22527
22780
|
sections
|
|
@@ -23137,7 +23390,7 @@ function OhhwellsBridge() {
|
|
|
23137
23390
|
"span",
|
|
23138
23391
|
{
|
|
23139
23392
|
"data-ohw-form-count": "",
|
|
23140
|
-
className: "ml-0.5 inline-flex h-[18px] min-w-[18px] items-center justify-center rounded-full bg-primary px-1.5 text-[11px] font-semibold text-primary-foreground",
|
|
23393
|
+
className: "ml-0.5 inline-flex h-[18px] min-w-[18px] items-center justify-center rounded-full bg-bridge-primary px-1.5 text-[11px] font-semibold text-primary-foreground",
|
|
23141
23394
|
children: formPickCount
|
|
23142
23395
|
}
|
|
23143
23396
|
)
|
|
@@ -23308,7 +23561,7 @@ function OhhwellsBridge() {
|
|
|
23308
23561
|
) : void 0
|
|
23309
23562
|
}
|
|
23310
23563
|
),
|
|
23311
|
-
toolbarRect && toolbarVariant === "rich-text" && !linkPopover && /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(import_jsx_runtime33.Fragment, { children: [
|
|
23564
|
+
toolbarRect && toolbarVariant === "rich-text" && !linkPopover && !isRectOutsideClip(toolbarRect, getIframeVisibleClip(parentScrollRef.current)) && /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(import_jsx_runtime33.Fragment, { children: [
|
|
23312
23565
|
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
23313
23566
|
EditGlowChrome,
|
|
23314
23567
|
{
|
|
@@ -23374,11 +23627,11 @@ function OhhwellsBridge() {
|
|
|
23374
23627
|
className: "fixed left-0 w-full z-2147483646 flex items-center pointer-events-none",
|
|
23375
23628
|
style: { top: sectionGap.y, transform: "translateY(-50%)" },
|
|
23376
23629
|
children: [
|
|
23377
|
-
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } }),
|
|
23630
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "flex-1 bg-bridge-primary", style: { height: 3 } }),
|
|
23378
23631
|
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
23379
23632
|
Badge,
|
|
23380
23633
|
{
|
|
23381
|
-
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",
|
|
23634
|
+
className: "px-8 py-1 bg-bridge-primary hover:bg-bridge-primary text-primary-foreground text-xs font-medium shrink-0 rounded-full cursor-pointer pointer-events-auto",
|
|
23382
23635
|
onClick: () => {
|
|
23383
23636
|
window.parent.postMessage(
|
|
23384
23637
|
{
|
|
@@ -23392,7 +23645,7 @@ function OhhwellsBridge() {
|
|
|
23392
23645
|
children: "Add Section"
|
|
23393
23646
|
}
|
|
23394
23647
|
),
|
|
23395
|
-
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } })
|
|
23648
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "flex-1 bg-bridge-primary", style: { height: 3 } })
|
|
23396
23649
|
]
|
|
23397
23650
|
}
|
|
23398
23651
|
),
|
|
@@ -23440,6 +23693,59 @@ function OhhwellsBridge() {
|
|
|
23440
23693
|
) : null
|
|
23441
23694
|
] });
|
|
23442
23695
|
}
|
|
23696
|
+
|
|
23697
|
+
// src/ui/EmptySection.tsx
|
|
23698
|
+
var import_link = __toESM(require("next/link"), 1);
|
|
23699
|
+
var import_jsx_runtime34 = require("react/jsx-runtime");
|
|
23700
|
+
function EmptySection({ title, homeHref = "/", eyebrowKey, titleKey, subtitleKey }) {
|
|
23701
|
+
return /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(import_jsx_runtime34.Fragment, { children: [
|
|
23702
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
23703
|
+
"p",
|
|
23704
|
+
{
|
|
23705
|
+
style: {
|
|
23706
|
+
fontFamily: "var(--brand-font-body)",
|
|
23707
|
+
fontSize: "0.75rem",
|
|
23708
|
+
fontWeight: 500,
|
|
23709
|
+
letterSpacing: "0.15em",
|
|
23710
|
+
textTransform: "uppercase",
|
|
23711
|
+
color: "var(--brand-accent)",
|
|
23712
|
+
marginBottom: "1.5rem"
|
|
23713
|
+
},
|
|
23714
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_link.default, { href: homeHref, style: { color: "inherit" }, children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { ...eyebrowKey ? { "data-ohw-editable": "text", "data-ohw-key": eyebrowKey } : {}, children: "Home" }) })
|
|
23715
|
+
}
|
|
23716
|
+
),
|
|
23717
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
23718
|
+
"h1",
|
|
23719
|
+
{
|
|
23720
|
+
style: {
|
|
23721
|
+
fontFamily: "var(--brand-font-heading)",
|
|
23722
|
+
fontSize: "clamp(2rem, 3.5vw, 2.75rem)",
|
|
23723
|
+
lineHeight: 1.1,
|
|
23724
|
+
letterSpacing: "-0.025em",
|
|
23725
|
+
color: "var(--brand-text)",
|
|
23726
|
+
marginBottom: "1rem"
|
|
23727
|
+
},
|
|
23728
|
+
...titleKey ? { "data-ohw-editable": "text", "data-ohw-key": titleKey, "data-ohw-max-length": 80 } : {},
|
|
23729
|
+
children: title
|
|
23730
|
+
}
|
|
23731
|
+
),
|
|
23732
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
23733
|
+
"p",
|
|
23734
|
+
{
|
|
23735
|
+
style: {
|
|
23736
|
+
fontFamily: "var(--brand-font-body)",
|
|
23737
|
+
fontSize: "1rem",
|
|
23738
|
+
lineHeight: 1.7,
|
|
23739
|
+
fontWeight: 300,
|
|
23740
|
+
color: "var(--brand-text-muted)",
|
|
23741
|
+
maxWidth: "340px"
|
|
23742
|
+
},
|
|
23743
|
+
...subtitleKey ? { "data-ohw-editable": "text", "data-ohw-key": subtitleKey, "data-ohw-max-length": 160 } : {},
|
|
23744
|
+
children: "This page doesn't have any content yet."
|
|
23745
|
+
}
|
|
23746
|
+
)
|
|
23747
|
+
] });
|
|
23748
|
+
}
|
|
23443
23749
|
// Annotate the CommonJS export names for ESM import in node:
|
|
23444
23750
|
0 && (module.exports = {
|
|
23445
23751
|
AI_DEFAULT_BRAND,
|
|
@@ -23457,6 +23763,7 @@ function OhhwellsBridge() {
|
|
|
23457
23763
|
DropdownMenuItem,
|
|
23458
23764
|
DropdownMenuSeparator,
|
|
23459
23765
|
DropdownMenuTrigger,
|
|
23766
|
+
EmptySection,
|
|
23460
23767
|
ItemActionToolbar,
|
|
23461
23768
|
ItemInteractionLayer,
|
|
23462
23769
|
LinkEditorPanel,
|