@ohhwells/bridge 0.1.107 → 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 +469 -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 +468 -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; }`);
|
|
@@ -1353,6 +1418,22 @@ function accentBandContext(brand) {
|
|
|
1353
1418
|
function textAttrs(ctx, path) {
|
|
1354
1419
|
return ctx.keyFor ? { "data-ohw-key": ctx.keyFor(path), "data-ohw-editable": "text" } : {};
|
|
1355
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");
|
|
1356
1437
|
var TRANSPARENT_PX = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7";
|
|
1357
1438
|
function MediaBox({
|
|
1358
1439
|
refValue,
|
|
@@ -1365,13 +1446,17 @@ function MediaBox({
|
|
|
1365
1446
|
const url = refValue ? ctx.resolveMedia(refValue) : null;
|
|
1366
1447
|
const isIcon = /^(lucide|simple):/.test(refValue);
|
|
1367
1448
|
const aspectRatio = aspect && /^\d+:\d+$/.test(aspect) ? aspect.replace(":", " / ") : void 0;
|
|
1368
|
-
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
|
+
} : {};
|
|
1369
1453
|
if (isIcon) {
|
|
1370
1454
|
const Icon = refValue.startsWith("lucide:") ? lucideByName(refValue.slice(7)) : null;
|
|
1371
1455
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1372
1456
|
"span",
|
|
1373
1457
|
{
|
|
1374
1458
|
"data-ai-icon": refValue,
|
|
1459
|
+
...editAttrs,
|
|
1375
1460
|
style: {
|
|
1376
1461
|
display: "inline-flex",
|
|
1377
1462
|
width: 48,
|
|
@@ -2264,7 +2349,7 @@ function CollectionBlock({ node, ctx, path }) {
|
|
|
2264
2349
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
2265
2350
|
"div",
|
|
2266
2351
|
{
|
|
2267
|
-
"data-ai-grid":
|
|
2352
|
+
"data-ai-grid": String(itemsPerRow),
|
|
2268
2353
|
style: {
|
|
2269
2354
|
display: "grid",
|
|
2270
2355
|
gridTemplateColumns: `repeat(${itemsPerRow}, 1fr)`,
|
|
@@ -2617,6 +2702,7 @@ function AiTreeRenderer({
|
|
|
2617
2702
|
{
|
|
2618
2703
|
"data-ai-section": tree.tag ?? "",
|
|
2619
2704
|
...bgAttrs,
|
|
2705
|
+
"data-ai-responsive": "",
|
|
2620
2706
|
style: {
|
|
2621
2707
|
position: "relative",
|
|
2622
2708
|
padding: `${pad}px 0`,
|
|
@@ -2627,12 +2713,13 @@ function AiTreeRenderer({
|
|
|
2627
2713
|
color: settings.sectionBackground === "accent" ? blockBrand.palette.dark : void 0
|
|
2628
2714
|
},
|
|
2629
2715
|
children: [
|
|
2630
|
-
|
|
2716
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("style", { children: AI_RESPONSIVE_CSS }),
|
|
2631
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})` } }),
|
|
2632
2719
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
2633
2720
|
"div",
|
|
2634
2721
|
{
|
|
2635
|
-
"data-ai-
|
|
2722
|
+
"data-ai-section-inner": "",
|
|
2636
2723
|
style: {
|
|
2637
2724
|
position: "relative",
|
|
2638
2725
|
maxWidth: AI_TREE_TOKENS.sectionMaxWidth,
|
|
@@ -2643,7 +2730,7 @@ function AiTreeRenderer({
|
|
|
2643
2730
|
children: tree.rows.map((row, r2) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
2644
2731
|
"div",
|
|
2645
2732
|
{
|
|
2646
|
-
"data-ai-
|
|
2733
|
+
"data-ai-columns": "",
|
|
2647
2734
|
style: {
|
|
2648
2735
|
display: "grid",
|
|
2649
2736
|
gridTemplateColumns: "repeat(12, 1fr)",
|
|
@@ -2693,14 +2780,52 @@ function readRootVar(name) {
|
|
|
2693
2780
|
if (typeof document === "undefined") return "";
|
|
2694
2781
|
return getComputedStyle(document.documentElement).getPropertyValue(name).trim();
|
|
2695
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
|
+
}
|
|
2696
2821
|
function deriveBrandOverride() {
|
|
2697
2822
|
const dark = readRootVar("--ohw-brand-dark");
|
|
2698
2823
|
const primary = readRootVar("--ohw-brand-primary");
|
|
2699
2824
|
const light = readRootVar("--ohw-brand-light");
|
|
2700
2825
|
if (!dark || !primary || !light) return null;
|
|
2701
2826
|
const accent = readRootVar("--ohw-brand-accent");
|
|
2702
|
-
const heading =
|
|
2703
|
-
const body =
|
|
2827
|
+
const heading = readFontVar("--font-heading") || readFontVar("--font-display");
|
|
2828
|
+
const body = readFontVar("--font-body");
|
|
2704
2829
|
return {
|
|
2705
2830
|
palette: { dark, primary, accent: accent || dark, light },
|
|
2706
2831
|
fonts: {
|
|
@@ -2709,27 +2834,65 @@ function deriveBrandOverride() {
|
|
|
2709
2834
|
}
|
|
2710
2835
|
};
|
|
2711
2836
|
}
|
|
2712
|
-
function
|
|
2713
|
-
const
|
|
2714
|
-
const
|
|
2715
|
-
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");
|
|
2716
2841
|
if (!dark || !primary || !light) return null;
|
|
2717
|
-
const accent = readRootVar("--
|
|
2718
|
-
const heading =
|
|
2719
|
-
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");
|
|
2720
2845
|
return {
|
|
2721
|
-
palette: {
|
|
2846
|
+
palette: {
|
|
2847
|
+
dark: normalizeColorToHex(dark),
|
|
2848
|
+
primary: normalizeColorToHex(primary),
|
|
2849
|
+
accent: normalizeColorToHex(accent || dark),
|
|
2850
|
+
light: normalizeColorToHex(light)
|
|
2851
|
+
},
|
|
2722
2852
|
fonts: {
|
|
2723
2853
|
heading: heading || AI_DEFAULT_BRAND.fonts.heading,
|
|
2724
2854
|
body: body || AI_DEFAULT_BRAND.fonts.body
|
|
2725
2855
|
}
|
|
2726
2856
|
};
|
|
2727
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
|
+
}
|
|
2728
2886
|
function deriveTemplateButtonStyle() {
|
|
2729
2887
|
if (typeof document === "undefined") return null;
|
|
2730
2888
|
const candidates = Array.from(
|
|
2731
2889
|
document.querySelectorAll('[data-ohw-role="button"]')
|
|
2732
|
-
).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
|
+
);
|
|
2733
2896
|
const isFilled = (el) => {
|
|
2734
2897
|
const bg = getComputedStyle(el).backgroundColor;
|
|
2735
2898
|
if (!bg || bg === "transparent") return false;
|
|
@@ -7217,12 +7380,12 @@ var cva = (base, config) => (props) => {
|
|
|
7217
7380
|
var import_radix_ui2 = require("radix-ui");
|
|
7218
7381
|
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
7219
7382
|
var toggleVariants = cva(
|
|
7220
|
-
"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",
|
|
7221
7384
|
{
|
|
7222
7385
|
variants: {
|
|
7223
7386
|
variant: {
|
|
7224
7387
|
default: "bg-transparent border-0",
|
|
7225
|
-
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"
|
|
7226
7389
|
},
|
|
7227
7390
|
size: {
|
|
7228
7391
|
default: "px-2 py-1",
|
|
@@ -7315,10 +7478,10 @@ var DragHandle = React4.forwardRef(
|
|
|
7315
7478
|
type,
|
|
7316
7479
|
"data-slot": "drag-handle",
|
|
7317
7480
|
className: cn(
|
|
7318
|
-
"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",
|
|
7319
7482
|
"bg-white border border-transparent text-stone-500 shadow-md cursor-grab",
|
|
7320
7483
|
"enabled:hover:border enabled:hover:border-stone-200 enabled:hover:text-stone-950",
|
|
7321
|
-
"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",
|
|
7322
7485
|
"disabled:cursor-not-allowed disabled:opacity-40 disabled:text-stone-950 disabled:pointer-events-none",
|
|
7323
7486
|
className
|
|
7324
7487
|
),
|
|
@@ -7340,7 +7503,7 @@ var CustomToolbar = React5.forwardRef(({ className, onMouseDown, ...props }, ref
|
|
|
7340
7503
|
"data-ohw-toolbar": "",
|
|
7341
7504
|
className: cn(
|
|
7342
7505
|
// Figma: bg background, radius 8, gap-1, p-0.5, shadow-md — no border
|
|
7343
|
-
"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",
|
|
7344
7507
|
className
|
|
7345
7508
|
),
|
|
7346
7509
|
onMouseDown: (e) => {
|
|
@@ -7369,7 +7532,7 @@ var CustomToolbarButton = React5.forwardRef(
|
|
|
7369
7532
|
type,
|
|
7370
7533
|
className: cn(
|
|
7371
7534
|
"inline-flex size-7 shrink-0 items-center justify-center rounded-[calc(var(--radius,0.5rem)-2px)] text-foreground transition-colors",
|
|
7372
|
-
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",
|
|
7373
7536
|
className
|
|
7374
7537
|
),
|
|
7375
7538
|
...props
|
|
@@ -8571,13 +8734,13 @@ function FormFieldToolbar({
|
|
|
8571
8734
|
]
|
|
8572
8735
|
}
|
|
8573
8736
|
) }),
|
|
8574
|
-
/* @__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) => {
|
|
8575
8738
|
const Icon = TYPE_ICONS[entry.type];
|
|
8576
8739
|
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
8577
8740
|
DropdownMenuItem,
|
|
8578
8741
|
{
|
|
8579
8742
|
onSelect: () => onTypeChange(entry.type),
|
|
8580
|
-
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" : ""),
|
|
8581
8744
|
children: [
|
|
8582
8745
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Icon, { size: 14, strokeWidth: 1.75, className: "shrink-0", "aria-hidden": true }),
|
|
8583
8746
|
entry.label
|
|
@@ -8594,7 +8757,7 @@ function FormFieldToolbar({
|
|
|
8594
8757
|
type: "button",
|
|
8595
8758
|
"aria-pressed": required,
|
|
8596
8759
|
onClick: onRequiredToggle,
|
|
8597
|
-
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"),
|
|
8598
8761
|
"data-ohw-field-required-toggle": "",
|
|
8599
8762
|
children: [
|
|
8600
8763
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react4.Asterisk, { size: 14, strokeWidth: 2, "aria-hidden": true }),
|
|
@@ -8614,7 +8777,7 @@ function FormFieldToolbar({
|
|
|
8614
8777
|
children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react4.MoreHorizontal, { size: 15, "aria-hidden": true })
|
|
8615
8778
|
}
|
|
8616
8779
|
) }),
|
|
8617
|
-
/* @__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: [
|
|
8618
8781
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(DropdownMenuItem, { onSelect: onDuplicate, className: "rounded-md py-2 text-[13px]", children: [
|
|
8619
8782
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react4.Copy, { size: 14, strokeWidth: 1.75, className: "shrink-0", "aria-hidden": true }),
|
|
8620
8783
|
"Duplicate"
|
|
@@ -8634,7 +8797,7 @@ function FieldTypePicker({ onPick }) {
|
|
|
8634
8797
|
"div",
|
|
8635
8798
|
{
|
|
8636
8799
|
"data-ohw-field-type-picker": "",
|
|
8637
|
-
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",
|
|
8638
8801
|
children: FIELD_TYPES.map((entry) => {
|
|
8639
8802
|
const Icon = TYPE_ICONS[entry.type];
|
|
8640
8803
|
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
@@ -8642,7 +8805,7 @@ function FieldTypePicker({ onPick }) {
|
|
|
8642
8805
|
{
|
|
8643
8806
|
type: "button",
|
|
8644
8807
|
onClick: () => onPick(entry.type),
|
|
8645
|
-
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",
|
|
8646
8809
|
children: [
|
|
8647
8810
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Icon, { size: 26, strokeWidth: 1.5, "aria-hidden": true }),
|
|
8648
8811
|
entry.label
|
|
@@ -8668,7 +8831,7 @@ var buttonVariants = cva(
|
|
|
8668
8831
|
{
|
|
8669
8832
|
variants: {
|
|
8670
8833
|
variant: {
|
|
8671
|
-
default: "bg-primary text-primary-foreground hover:opacity-90",
|
|
8834
|
+
default: "bg-bridge-primary text-primary-foreground hover:opacity-90",
|
|
8672
8835
|
outline: "border border-border bg-background text-foreground shadow-sm hover:bg-muted/80",
|
|
8673
8836
|
ghost: "min-w-0 px-3 py-2 text-foreground hover:bg-muted/50"
|
|
8674
8837
|
},
|
|
@@ -8763,6 +8926,7 @@ function MediaOverlay({
|
|
|
8763
8926
|
(prev) => prev && prev.fullWidth === width && prev.height === height ? prev : { fullWidth: width, height }
|
|
8764
8927
|
);
|
|
8765
8928
|
}, [isVideo]);
|
|
8929
|
+
const replaceLabel = isVideo ? "Replace video" : hover.elementType === "bg-image" ? "Replace background" : "Replace image";
|
|
8766
8930
|
const replaceMode = buttonSize ? replaceButtonMode({ width: rect.width, height: rect.height }, buttonSize) : "none";
|
|
8767
8931
|
const box = {
|
|
8768
8932
|
position: "fixed",
|
|
@@ -8868,8 +9032,8 @@ function MediaOverlay({
|
|
|
8868
9032
|
pointerEvents: hover.hasTextOverlap ? "none" : "auto",
|
|
8869
9033
|
// Selected: a firm component ring with no wash, so the image reads as chosen rather
|
|
8870
9034
|
// than hovered. Hover keeps the existing tinted preview.
|
|
8871
|
-
boxShadow: selected ? "inset 0 0 0 2px var(--color-primary)" : "inset 0 0 0 1.5px var(--color-primary)",
|
|
8872
|
-
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)"
|
|
8873
9037
|
},
|
|
8874
9038
|
onClick: () => onSelect && !selected ? onSelect(hover.key) : onReplace(hover.key),
|
|
8875
9039
|
children: [
|
|
@@ -8892,17 +9056,17 @@ function MediaOverlay({
|
|
|
8892
9056
|
},
|
|
8893
9057
|
children: [
|
|
8894
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 }),
|
|
8895
|
-
|
|
9059
|
+
replaceLabel
|
|
8896
9060
|
]
|
|
8897
9061
|
}
|
|
8898
9062
|
),
|
|
8899
|
-
replaceMode
|
|
9063
|
+
showChrome && replaceMode !== "none" && /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
|
|
8900
9064
|
Button,
|
|
8901
9065
|
{
|
|
8902
9066
|
"data-ohw-media-overlay": "",
|
|
8903
9067
|
variant: "outline",
|
|
8904
9068
|
size: "sm",
|
|
8905
|
-
"aria-label":
|
|
9069
|
+
"aria-label": replaceLabel,
|
|
8906
9070
|
className: "gap-1.5 cursor-pointer hover:bg-background",
|
|
8907
9071
|
style: {
|
|
8908
9072
|
...OVERLAY_BUTTON_STYLE,
|
|
@@ -8925,7 +9089,7 @@ function MediaOverlay({
|
|
|
8925
9089
|
},
|
|
8926
9090
|
children: [
|
|
8927
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 }),
|
|
8928
|
-
replaceMode === "full" ?
|
|
9092
|
+
replaceMode === "full" ? replaceLabel : null
|
|
8929
9093
|
]
|
|
8930
9094
|
}
|
|
8931
9095
|
)
|
|
@@ -8963,8 +9127,8 @@ function CarouselOverlay({
|
|
|
8963
9127
|
height: rect.height,
|
|
8964
9128
|
zIndex: 2147483646,
|
|
8965
9129
|
pointerEvents: "auto",
|
|
8966
|
-
boxShadow: "inset 0 0 0 1.5px var(--color-primary)",
|
|
8967
|
-
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)"
|
|
8968
9132
|
},
|
|
8969
9133
|
onClick: () => onEdit(hover.key),
|
|
8970
9134
|
children: /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
|
|
@@ -9802,7 +9966,7 @@ function SectionTreeItem({
|
|
|
9802
9966
|
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
9803
9967
|
"div",
|
|
9804
9968
|
{
|
|
9805
|
-
className: "mr-
|
|
9969
|
+
className: "-mr-px h-9 w-2 shrink-0 rounded-bl-sm border-b border-l border-border mb-4",
|
|
9806
9970
|
"aria-hidden": true
|
|
9807
9971
|
}
|
|
9808
9972
|
),
|
|
@@ -9821,7 +9985,7 @@ function SectionTreeItem({
|
|
|
9821
9985
|
className: cn(
|
|
9822
9986
|
"flex h-9 min-w-0 flex-1 items-center gap-2 rounded-md border border-border bg-background p-3",
|
|
9823
9987
|
interactive && "cursor-pointer hover:bg-muted/30",
|
|
9824
|
-
interactive && selected && "border-primary"
|
|
9988
|
+
interactive && selected && "border-bridge-primary"
|
|
9825
9989
|
),
|
|
9826
9990
|
children: [
|
|
9827
9991
|
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
@@ -9951,7 +10115,7 @@ function UrlOrPageInput({
|
|
|
9951
10115
|
};
|
|
9952
10116
|
const fieldClassName = cn(
|
|
9953
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]",
|
|
9954
|
-
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"
|
|
9955
10119
|
);
|
|
9956
10120
|
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex w-full flex-col gap-2 p-0", children: [
|
|
9957
10121
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Label, { htmlFor: inputId, className: cn(urlError && "text-destructive"), children: "Destination" }),
|
|
@@ -13800,6 +13964,7 @@ function readLogoSizeState(content, placement) {
|
|
|
13800
13964
|
function getLogoElement(el) {
|
|
13801
13965
|
const marked = el.closest('[data-ohw-role="logo"], [data-ohw-logo]');
|
|
13802
13966
|
if (marked) return marked;
|
|
13967
|
+
if (el.closest('[data-ohw-editable="icon"]')) return null;
|
|
13803
13968
|
const root = el.closest("nav, [data-ohw-nav-root], footer");
|
|
13804
13969
|
if (!root) return null;
|
|
13805
13970
|
const anchor = el.closest("a");
|
|
@@ -14087,7 +14252,7 @@ function DisplaySwitch({
|
|
|
14087
14252
|
onClick: () => onChange(!checked),
|
|
14088
14253
|
className: cn(
|
|
14089
14254
|
"relative h-5 w-9 shrink-0 rounded-full transition-colors",
|
|
14090
|
-
checked ? "bg-primary" : "bg-primary-50",
|
|
14255
|
+
checked ? "bg-bridge-primary" : "bg-primary-50",
|
|
14091
14256
|
disabled ? "cursor-default opacity-50" : "cursor-pointer"
|
|
14092
14257
|
),
|
|
14093
14258
|
children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
@@ -14095,7 +14260,7 @@ function DisplaySwitch({
|
|
|
14095
14260
|
{
|
|
14096
14261
|
className: cn(
|
|
14097
14262
|
"absolute top-0.5 h-4 w-4 rounded-full bg-white transition-all",
|
|
14098
|
-
checked ? "left-
|
|
14263
|
+
checked ? "left-4.5" : "left-0.5"
|
|
14099
14264
|
)
|
|
14100
14265
|
}
|
|
14101
14266
|
)
|
|
@@ -15274,7 +15439,9 @@ function collectEditableNodes(extraContent, root = document) {
|
|
|
15274
15439
|
return {
|
|
15275
15440
|
key: el.dataset.ohwKey ?? "",
|
|
15276
15441
|
type: el.dataset.ohwEditable ?? "text",
|
|
15277
|
-
|
|
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
|
|
15278
15445
|
};
|
|
15279
15446
|
});
|
|
15280
15447
|
const hrefEls = Array.from(root.querySelectorAll("[data-ohw-href-key]"));
|
|
@@ -15711,7 +15878,7 @@ var badgeVariants = cva(
|
|
|
15711
15878
|
{
|
|
15712
15879
|
variants: {
|
|
15713
15880
|
variant: {
|
|
15714
|
-
default: "border-transparent bg-primary text-primary-foreground",
|
|
15881
|
+
default: "border-transparent bg-bridge-primary text-primary-foreground",
|
|
15715
15882
|
secondary: "border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80",
|
|
15716
15883
|
destructive: "border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80",
|
|
15717
15884
|
outline: "text-foreground"
|
|
@@ -15893,21 +16060,10 @@ function parseSchedulingInsertAfter(insertAfter) {
|
|
|
15893
16060
|
insertBefore: insertAfter.slice(idx + INSERT_BEFORE_MARKER.length)
|
|
15894
16061
|
};
|
|
15895
16062
|
}
|
|
15896
|
-
function
|
|
15897
|
-
|
|
15898
|
-
const
|
|
15899
|
-
|
|
15900
|
-
return { effectiveInsertAfter, insertBefore };
|
|
15901
|
-
}
|
|
15902
|
-
function getSchedulingMountPoint(insertAfter) {
|
|
15903
|
-
const { anchor } = parseSchedulingInsertAfter(insertAfter);
|
|
15904
|
-
let anchorEl = document.querySelector(`[data-ohw-section="${anchor}"]`);
|
|
15905
|
-
if (!anchorEl && anchor === "scheduling") {
|
|
15906
|
-
const widgets = Array.from(document.querySelectorAll('[data-ohw-section^="scheduling-"]'));
|
|
15907
|
-
anchorEl = widgets.at(-1) ?? null;
|
|
15908
|
-
}
|
|
15909
|
-
if (!anchorEl) return null;
|
|
15910
|
-
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 };
|
|
15911
16067
|
}
|
|
15912
16068
|
function schedulingMountDepth(insertAfter) {
|
|
15913
16069
|
if (!insertAfter.includes(INSERT_BEFORE_MARKER)) return 0;
|
|
@@ -15924,8 +16080,7 @@ function getPageSchedulingEntries(raw) {
|
|
|
15924
16080
|
}
|
|
15925
16081
|
}
|
|
15926
16082
|
function isSchedulingWidgetMissing(entry) {
|
|
15927
|
-
|
|
15928
|
-
return !document.querySelector(`[data-ohw-section="${schedulingSectionId(effectiveInsertAfter)}"]`);
|
|
16083
|
+
return !document.querySelector(`[data-ohw-section="${schedulingSectionId(entry.insertAfter)}"]`);
|
|
15929
16084
|
}
|
|
15930
16085
|
function hasMissingSchedulingWidgets(entries) {
|
|
15931
16086
|
return entries.some(isSchedulingWidgetMissing);
|
|
@@ -15963,17 +16118,18 @@ function initSectionsFromContent(content, removeExisting = false, currentPath =
|
|
|
15963
16118
|
} catch {
|
|
15964
16119
|
}
|
|
15965
16120
|
}
|
|
15966
|
-
function mountSchedulingWidget(
|
|
15967
|
-
const
|
|
15968
|
-
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);
|
|
15969
16124
|
if (document.querySelector(`[data-ohw-section="${sectionId}"]`)) return false;
|
|
15970
|
-
const
|
|
15971
|
-
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;
|
|
15972
16128
|
const container = document.createElement("div");
|
|
15973
16129
|
container.dataset.ohwSectionContainer = "scheduling";
|
|
15974
16130
|
container.dataset.ohwInstance = sectionId;
|
|
15975
|
-
if (
|
|
15976
|
-
const beforeAnchor = document.querySelector(`[data-ohw-section="${
|
|
16131
|
+
if (beforeId) {
|
|
16132
|
+
const beforeAnchor = document.querySelector(`[data-ohw-section="${beforeId}"]`);
|
|
15977
16133
|
const beforePoint = beforeAnchor?.closest('[data-ohw-section-container="scheduling"]') ?? beforeAnchor;
|
|
15978
16134
|
if (!beforePoint) return false;
|
|
15979
16135
|
beforePoint.insertAdjacentElement("beforebegin", container);
|
|
@@ -15984,20 +16140,26 @@ function mountSchedulingWidget(insertAfter, notifyOnConnect = false, scheduleId,
|
|
|
15984
16140
|
}
|
|
15985
16141
|
tail.insertAdjacentElement("afterend", container);
|
|
15986
16142
|
}
|
|
15987
|
-
|
|
15988
|
-
|
|
15989
|
-
|
|
15990
|
-
|
|
15991
|
-
|
|
15992
|
-
|
|
15993
|
-
|
|
15994
|
-
|
|
15995
|
-
|
|
15996
|
-
|
|
15997
|
-
|
|
15998
|
-
|
|
15999
|
-
|
|
16000
|
-
|
|
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
|
+
}
|
|
16001
16163
|
const tracker = getSectionsTracker();
|
|
16002
16164
|
let sections = [];
|
|
16003
16165
|
try {
|
|
@@ -16005,10 +16167,12 @@ function mountSchedulingWidget(insertAfter, notifyOnConnect = false, scheduleId,
|
|
|
16005
16167
|
} catch {
|
|
16006
16168
|
}
|
|
16007
16169
|
const inEditor = typeof window !== "undefined" && window.self !== window.top;
|
|
16008
|
-
if (inEditor && !sections.find((s) => s.type === "scheduling" && s.insertAfter ===
|
|
16170
|
+
if (inEditor && !sections.find((s) => s.type === "scheduling" && s.insertAfter === widgetId)) {
|
|
16009
16171
|
sections.push({
|
|
16010
16172
|
type: "scheduling",
|
|
16011
|
-
insertAfter:
|
|
16173
|
+
insertAfter: widgetId,
|
|
16174
|
+
anchorId,
|
|
16175
|
+
beforeId: beforeId ?? null,
|
|
16012
16176
|
pagePath: window.location.pathname,
|
|
16013
16177
|
...scheduleId ? { scheduleId } : {}
|
|
16014
16178
|
});
|
|
@@ -16022,7 +16186,8 @@ function mountSchedulingEntries(entries, notifyOnConnect = false) {
|
|
|
16022
16186
|
for (let i = pending.length - 1; i >= 0; i--) {
|
|
16023
16187
|
const entry = pending[i];
|
|
16024
16188
|
const shouldNotify = typeof notifyOnConnect === "function" ? notifyOnConnect(entry) : notifyOnConnect;
|
|
16025
|
-
|
|
16189
|
+
const { anchorId, beforeId } = resolveEntryAnchor(entry);
|
|
16190
|
+
if (mountSchedulingWidget(anchorId, shouldNotify, entry.scheduleId ?? null, beforeId, entry.insertAfter)) {
|
|
16026
16191
|
pending.splice(i, 1);
|
|
16027
16192
|
}
|
|
16028
16193
|
}
|
|
@@ -16186,6 +16351,11 @@ function applyLinkByKey(key, val) {
|
|
|
16186
16351
|
hrefAnchors.forEach((el) => applyLinkHref(el, val));
|
|
16187
16352
|
}
|
|
16188
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
|
+
}
|
|
16189
16359
|
function isInsideFloatingPanel(target) {
|
|
16190
16360
|
return Boolean(target.closest("[data-ohw-floating-panel]"));
|
|
16191
16361
|
}
|
|
@@ -16193,11 +16363,6 @@ function isPointOverFloatingPanel(clientX, clientY) {
|
|
|
16193
16363
|
const el = document.elementFromPoint(clientX, clientY);
|
|
16194
16364
|
return Boolean(el instanceof Element && el.closest("[data-ohw-floating-panel]"));
|
|
16195
16365
|
}
|
|
16196
|
-
function isInsideLinkEditor(target) {
|
|
16197
|
-
return Boolean(
|
|
16198
|
-
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"]')
|
|
16199
|
-
);
|
|
16200
|
-
}
|
|
16201
16366
|
function getHrefKeyFromElement(el) {
|
|
16202
16367
|
if (!el) return null;
|
|
16203
16368
|
const anchor = el.closest("[data-ohw-href-key]");
|
|
@@ -16462,7 +16627,7 @@ function getNavigationSelectionParent(el) {
|
|
|
16462
16627
|
if (!isFooterLinksContainer(el) && (el.hasAttribute("data-ohw-footer-col") || el.hasAttribute("data-ohw-footer-column") || isInferredFooterGroup2(el))) {
|
|
16463
16628
|
return getFooterLinksContainer();
|
|
16464
16629
|
}
|
|
16465
|
-
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)) {
|
|
16466
16631
|
return getNavigationRoot(el);
|
|
16467
16632
|
}
|
|
16468
16633
|
return null;
|
|
@@ -16678,7 +16843,6 @@ var ICONS = {
|
|
|
16678
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"/>',
|
|
16679
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"/>'
|
|
16680
16845
|
};
|
|
16681
|
-
var HEIGHT_SETTLE_DELAYS = [150, 400, 800];
|
|
16682
16846
|
var SELECTION_CHROME_GAP2 = 4;
|
|
16683
16847
|
var TOOLBAR_STROKE_GAP2 = 4;
|
|
16684
16848
|
var TOOLBAR_OFFSET_FROM_ELEMENT = SELECTION_CHROME_GAP2 + TOOLBAR_STROKE_GAP2;
|
|
@@ -16775,6 +16939,10 @@ function getIframeVisibleClip(parentScroll) {
|
|
|
16775
16939
|
);
|
|
16776
16940
|
return { top: clipTop, bottom: Math.max(clipTop, clipBottom) };
|
|
16777
16941
|
}
|
|
16942
|
+
function isRectOutsideClip(rect, clip) {
|
|
16943
|
+
if (!clip) return false;
|
|
16944
|
+
return rect.bottom < clip.top || rect.top > clip.bottom;
|
|
16945
|
+
}
|
|
16778
16946
|
function applyVisibleViewport(el, parentScroll) {
|
|
16779
16947
|
const clip = getIframeVisibleClip(parentScroll);
|
|
16780
16948
|
const top = clip?.top ?? 0;
|
|
@@ -17058,6 +17226,7 @@ function StateToggle({
|
|
|
17058
17226
|
);
|
|
17059
17227
|
}
|
|
17060
17228
|
var contentCache = /* @__PURE__ */ new Map();
|
|
17229
|
+
var fetchedContentPaths = /* @__PURE__ */ new Set();
|
|
17061
17230
|
var brandingCache = /* @__PURE__ */ new Map();
|
|
17062
17231
|
var OHW_LOADER_STYLE = {
|
|
17063
17232
|
position: "fixed",
|
|
@@ -17606,13 +17775,6 @@ function OhhwellsBridge() {
|
|
|
17606
17775
|
const [isItemDragging, setIsItemDragging] = (0, import_react17.useState)(false);
|
|
17607
17776
|
const [isFooterFrameSelection, setIsFooterFrameSelection] = (0, import_react17.useState)(false);
|
|
17608
17777
|
isFooterFrameSelectionRef.current = isFooterFrameSelection;
|
|
17609
|
-
const [floatingPanel, setFloatingPanel] = (0, import_react17.useState)(null);
|
|
17610
|
-
const floatingPanelOpenRef = (0, import_react17.useRef)(false);
|
|
17611
|
-
floatingPanelOpenRef.current = floatingPanel !== null;
|
|
17612
|
-
const [floatingPanelPos, setFloatingPanelPos] = (0, import_react17.useState)(null);
|
|
17613
|
-
const [logoSizeDraft, setLogoSizeDraft] = (0, import_react17.useState)(null);
|
|
17614
|
-
const [editorViewport, setEditorViewport] = (0, import_react17.useState)("desktop");
|
|
17615
|
-
const [parentScrollSnap, setParentScrollSnap] = (0, import_react17.useState)(null);
|
|
17616
17778
|
const [navDropdownPreviewOpen, setNavDropdownPreviewOpen] = (0, import_react17.useState)(null);
|
|
17617
17779
|
const [footerHeadingVisible, setFooterHeadingVisible] = (0, import_react17.useState)(null);
|
|
17618
17780
|
const footerDragRef = (0, import_react17.useRef)(null);
|
|
@@ -17630,6 +17792,13 @@ function OhhwellsBridge() {
|
|
|
17630
17792
|
const brandKitRef = (0, import_react17.useRef)("");
|
|
17631
17793
|
const stylesRef = (0, import_react17.useRef)("");
|
|
17632
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);
|
|
17633
17802
|
const [sitePages, setSitePages] = (0, import_react17.useState)([]);
|
|
17634
17803
|
const [sectionsByPath, setSectionsByPath] = (0, import_react17.useState)({});
|
|
17635
17804
|
const sectionsPrefetchGenRef = (0, import_react17.useRef)(0);
|
|
@@ -17638,7 +17807,18 @@ function OhhwellsBridge() {
|
|
|
17638
17807
|
const linkPopoverOpenRef = (0, import_react17.useRef)(false);
|
|
17639
17808
|
const linkPopoverGraceUntilRef = (0, import_react17.useRef)(0);
|
|
17640
17809
|
setLinkPopoverRef.current = setLinkPopover;
|
|
17810
|
+
setFloatingPanelRef.current = setFloatingPanel;
|
|
17641
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
|
+
}, []);
|
|
17642
17822
|
const {
|
|
17643
17823
|
navDragRef,
|
|
17644
17824
|
navPointerDragRef,
|
|
@@ -18979,6 +19159,7 @@ function OhhwellsBridge() {
|
|
|
18979
19159
|
}
|
|
18980
19160
|
if (typeof content[STYLE_STORE_KEY] === "string") {
|
|
18981
19161
|
stylesRef.current = content[STYLE_STORE_KEY];
|
|
19162
|
+
document.querySelectorAll('[data-ohw-editable="form"]').forEach((f) => markFormFields(f));
|
|
18982
19163
|
applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
|
|
18983
19164
|
}
|
|
18984
19165
|
applyBrandChrome(content);
|
|
@@ -18986,11 +19167,11 @@ function OhhwellsBridge() {
|
|
|
18986
19167
|
for (const [key, val] of Object.entries(content)) {
|
|
18987
19168
|
if (key === "__ohw_sections") continue;
|
|
18988
19169
|
if (key === AI_SECTIONS_KEY) continue;
|
|
19170
|
+
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
19171
|
+
if (LOGO_IMAGE_KEYS.includes(key)) continue;
|
|
18989
19172
|
if (key === BRAND_KIT_KEY) continue;
|
|
18990
19173
|
if (key === STYLE_STORE_KEY) continue;
|
|
18991
19174
|
if (BRAND_CHROME_KEYS.has(key)) continue;
|
|
18992
|
-
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
18993
|
-
if (LOGO_IMAGE_KEYS.includes(key)) continue;
|
|
18994
19175
|
if (applyVideoSettingNode(key, val)) continue;
|
|
18995
19176
|
if (applyCarouselNode(key, val)) continue;
|
|
18996
19177
|
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
@@ -19061,7 +19242,9 @@ function OhhwellsBridge() {
|
|
|
19061
19242
|
let cancelled = false;
|
|
19062
19243
|
setFetchState("loading");
|
|
19063
19244
|
const apiUrl = process.env.NEXT_PUBLIC_FLOWOPS_API_URL ?? "https://flowops-backend-staging-2yfdh7pwpq-as.a.run.app";
|
|
19064
|
-
|
|
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) => {
|
|
19065
19248
|
if (cancelled) return;
|
|
19066
19249
|
const content = data?.content ?? {};
|
|
19067
19250
|
const branding = Boolean(data?.showBranding);
|
|
@@ -19170,7 +19353,9 @@ function OhhwellsBridge() {
|
|
|
19170
19353
|
}, [isEditMode]);
|
|
19171
19354
|
(0, import_react17.useEffect)(() => {
|
|
19172
19355
|
if (isEditMode || fetchState !== "done") return;
|
|
19356
|
+
console.log("env", process.env.NEXT_PUBLIC_FLOWOPS_API_URL);
|
|
19173
19357
|
const apiUrl = process.env.NEXT_PUBLIC_FLOWOPS_API_URL ?? "https://flowops-backend-staging-2yfdh7pwpq-as.a.run.app";
|
|
19358
|
+
console.log({ apiUrl, subdomain });
|
|
19174
19359
|
bindPublishedForms(apiUrl, subdomain, contentCache.get(subdomain) ?? {});
|
|
19175
19360
|
}, [isEditMode, fetchState, subdomain]);
|
|
19176
19361
|
(0, import_react17.useEffect)(() => {
|
|
@@ -19195,16 +19380,17 @@ function OhhwellsBridge() {
|
|
|
19195
19380
|
applyAiSectionsToDom(parseAiSectionsState(content[AI_SECTIONS_KEY]));
|
|
19196
19381
|
}
|
|
19197
19382
|
if (typeof content[STYLE_STORE_KEY] === "string") {
|
|
19383
|
+
document.querySelectorAll('[data-ohw-editable="form"]').forEach((f) => markFormFields(f));
|
|
19198
19384
|
applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
|
|
19199
19385
|
}
|
|
19200
19386
|
for (const [key, val] of Object.entries(content)) {
|
|
19201
19387
|
if (key === "__ohw_sections") continue;
|
|
19202
19388
|
if (key === AI_SECTIONS_KEY) continue;
|
|
19389
|
+
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
19390
|
+
if (LOGO_IMAGE_KEYS.includes(key)) continue;
|
|
19203
19391
|
if (key === BRAND_KIT_KEY) continue;
|
|
19204
19392
|
if (key === STYLE_STORE_KEY) continue;
|
|
19205
19393
|
if (BRAND_CHROME_KEYS.has(key)) continue;
|
|
19206
|
-
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
19207
|
-
if (LOGO_IMAGE_KEYS.includes(key)) continue;
|
|
19208
19394
|
if (applyVideoSettingNode(key, val)) continue;
|
|
19209
19395
|
if (applyCarouselNode(key, val)) continue;
|
|
19210
19396
|
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
@@ -19255,6 +19441,17 @@ function OhhwellsBridge() {
|
|
|
19255
19441
|
debounceTimer = setTimeout(applyFromCache, 150);
|
|
19256
19442
|
};
|
|
19257
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
|
+
}
|
|
19258
19455
|
observer = new MutationObserver(scheduleApply);
|
|
19259
19456
|
observer.observe(document.body, { childList: true, subtree: true });
|
|
19260
19457
|
return () => {
|
|
@@ -19390,26 +19587,11 @@ function OhhwellsBridge() {
|
|
|
19390
19587
|
const t2 = setTimeout(measure, 500);
|
|
19391
19588
|
const ro = new ResizeObserver(schedule);
|
|
19392
19589
|
ro.observe(document.body);
|
|
19393
|
-
let lastWidth = window.innerWidth;
|
|
19394
|
-
let resizeTimers = [];
|
|
19395
|
-
const clearResizeTimers = () => {
|
|
19396
|
-
resizeTimers.forEach(clearTimeout);
|
|
19397
|
-
resizeTimers = [];
|
|
19398
|
-
};
|
|
19399
|
-
const handleResize = () => {
|
|
19400
|
-
if (window.innerWidth === lastWidth) return;
|
|
19401
|
-
lastWidth = window.innerWidth;
|
|
19402
|
-
clearResizeTimers();
|
|
19403
|
-
resizeTimers = HEIGHT_SETTLE_DELAYS.map((delay) => setTimeout(measure, delay));
|
|
19404
|
-
};
|
|
19405
|
-
window.addEventListener("resize", handleResize);
|
|
19406
19590
|
return () => {
|
|
19407
19591
|
clearTimeout(t1);
|
|
19408
19592
|
clearTimeout(t2);
|
|
19409
19593
|
if (raf != null) cancelAnimationFrame(raf);
|
|
19410
19594
|
ro.disconnect();
|
|
19411
|
-
clearResizeTimers();
|
|
19412
|
-
window.removeEventListener("resize", handleResize);
|
|
19413
19595
|
};
|
|
19414
19596
|
}, [pathname, isEditMode, postToParent2]);
|
|
19415
19597
|
(0, import_react17.useEffect)(() => {
|
|
@@ -19640,6 +19822,10 @@ function OhhwellsBridge() {
|
|
|
19640
19822
|
[data-ohw-editable-state], [data-ohw-editable-state] * { pointer-events: none !important; }
|
|
19641
19823
|
[data-ohw-editable-state][data-ohw-active-state] [data-ohw-editable] { pointer-events: auto !important; }
|
|
19642
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; }
|
|
19643
19829
|
`;
|
|
19644
19830
|
if (!existing) {
|
|
19645
19831
|
const base = document.createElement("style");
|
|
@@ -19678,9 +19864,6 @@ function OhhwellsBridge() {
|
|
|
19678
19864
|
if (target.closest("[data-ohw-state-toggle]")) return;
|
|
19679
19865
|
if (target.closest("[data-ohw-max-badge]")) return;
|
|
19680
19866
|
if (isInsideLinkEditor(target)) return;
|
|
19681
|
-
if (selectedMediaElRef.current && !selectedMediaElRef.current.contains(target) && !target.closest("[data-ohw-media-overlay], [data-ohw-edit-chrome], [data-ohw-item-interaction]")) {
|
|
19682
|
-
clearMediaSelectionRef.current();
|
|
19683
|
-
}
|
|
19684
19867
|
if (isInsideFloatingPanel(target)) return;
|
|
19685
19868
|
if (target.closest("[data-ohw-form-toolbar]")) return;
|
|
19686
19869
|
if (target.closest(
|
|
@@ -19688,6 +19871,9 @@ function OhhwellsBridge() {
|
|
|
19688
19871
|
)) {
|
|
19689
19872
|
return;
|
|
19690
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
|
+
}
|
|
19691
19877
|
{
|
|
19692
19878
|
const formEl = getFormElement(target);
|
|
19693
19879
|
const onSuccessText = target.closest(`[${SUCCESS_TEXT_ATTR}]`);
|
|
@@ -19810,7 +19996,19 @@ function OhhwellsBridge() {
|
|
|
19810
19996
|
openLogoSizePanelRef.current(logoEl);
|
|
19811
19997
|
return;
|
|
19812
19998
|
}
|
|
19813
|
-
|
|
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
|
+
}
|
|
19814
20012
|
if (editable) {
|
|
19815
20013
|
if (editable.dataset.ohwEditable === "link") {
|
|
19816
20014
|
e.preventDefault();
|
|
@@ -19839,14 +20037,6 @@ function OhhwellsBridge() {
|
|
|
19839
20037
|
}
|
|
19840
20038
|
const clickedButton = findClosestButtonLike(target);
|
|
19841
20039
|
const buttonOnMedia = Boolean(clickedButton && isMediaEditable(editable) && editable.contains(clickedButton));
|
|
19842
|
-
console.log("[click-debug]", {
|
|
19843
|
-
editableType: editable.dataset.ohwEditable,
|
|
19844
|
-
editableTag: editable.tagName,
|
|
19845
|
-
targetTag: target.tagName,
|
|
19846
|
-
clickedButtonTag: clickedButton?.tagName ?? null,
|
|
19847
|
-
buttonOnMedia,
|
|
19848
|
-
isMediaEditableEditable: isMediaEditable(editable)
|
|
19849
|
-
});
|
|
19850
20040
|
if (isMediaEditable(editable) && !buttonOnMedia) {
|
|
19851
20041
|
e.preventDefault();
|
|
19852
20042
|
e.stopPropagation();
|
|
@@ -19873,11 +20063,6 @@ function OhhwellsBridge() {
|
|
|
19873
20063
|
const hrefLookupTarget = buttonOnMedia ? clickedButton : editable;
|
|
19874
20064
|
const hrefCtx = getHrefKeyFromElement(hrefLookupTarget);
|
|
19875
20065
|
const navAnchor = hrefCtx ? getNavigationItemAnchor(hrefCtx.anchor) : null;
|
|
19876
|
-
console.log("[click-debug 2]", {
|
|
19877
|
-
hrefLookupTargetTag: hrefLookupTarget.tagName,
|
|
19878
|
-
hrefCtx: hrefCtx ? { key: hrefCtx.key } : null,
|
|
19879
|
-
navAnchorTag: navAnchor?.tagName ?? null
|
|
19880
|
-
});
|
|
19881
20066
|
if (navAnchor) {
|
|
19882
20067
|
e.preventDefault();
|
|
19883
20068
|
e.stopPropagation();
|
|
@@ -20047,6 +20232,9 @@ function OhhwellsBridge() {
|
|
|
20047
20232
|
setHoveredItemRect(null);
|
|
20048
20233
|
hoveredNavContainerRef.current = null;
|
|
20049
20234
|
setHoveredNavContainerRect(null);
|
|
20235
|
+
siblingHintElRef.current = null;
|
|
20236
|
+
setSiblingHintRect(null);
|
|
20237
|
+
setSiblingHintRects([]);
|
|
20050
20238
|
return;
|
|
20051
20239
|
}
|
|
20052
20240
|
{
|
|
@@ -20167,7 +20355,6 @@ function OhhwellsBridge() {
|
|
|
20167
20355
|
hoveredNavContainerRef.current = null;
|
|
20168
20356
|
setHoveredNavContainerRect(null);
|
|
20169
20357
|
hoveredItemElRef.current = editable;
|
|
20170
|
-
setHoveredItemRect(isSelectedForHoverRef.current(editable) ? null : editable.getBoundingClientRect());
|
|
20171
20358
|
}
|
|
20172
20359
|
}
|
|
20173
20360
|
}
|
|
@@ -20464,7 +20651,7 @@ function OhhwellsBridge() {
|
|
|
20464
20651
|
}
|
|
20465
20652
|
};
|
|
20466
20653
|
const probeImageAt = (clientX, clientY, isDragOver = false, fromParentViewport = false) => {
|
|
20467
|
-
if (linkPopoverOpenRef.current) {
|
|
20654
|
+
if (linkPopoverOpenRef.current || floatingPanelOpenRef.current && isPointOverFloatingPanel(clientX, clientY)) {
|
|
20468
20655
|
if (hoveredImageRef.current) {
|
|
20469
20656
|
hoveredImageRef.current = null;
|
|
20470
20657
|
hoveredImageHasTextOverlapRef.current = false;
|
|
@@ -20553,6 +20740,15 @@ function OhhwellsBridge() {
|
|
|
20553
20740
|
}
|
|
20554
20741
|
return;
|
|
20555
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
|
+
}
|
|
20556
20752
|
const topEl = document.elementFromPoint(x2, y2);
|
|
20557
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"]')) {
|
|
20558
20754
|
if (hoveredImageRef.current) {
|
|
@@ -20828,8 +21024,7 @@ function OhhwellsBridge() {
|
|
|
20828
21024
|
};
|
|
20829
21025
|
const handleMouseMove = (e) => {
|
|
20830
21026
|
const { clientX, clientY } = e;
|
|
20831
|
-
if (
|
|
20832
|
-
if (isOverEditorChrome(clientX, clientY)) {
|
|
21027
|
+
if (document.documentElement.hasAttribute("data-ohw-panel-dragging") || floatingPanelOpenRef.current && isPointOverFloatingPanel(clientX, clientY) || isOverEditorChrome(clientX, clientY)) {
|
|
20833
21028
|
document.querySelectorAll("[data-ohw-hovered]").forEach((el) => el.removeAttribute("data-ohw-hovered"));
|
|
20834
21029
|
formHoverElRef.current = null;
|
|
20835
21030
|
setFormHoverRect(null);
|
|
@@ -20837,6 +21032,12 @@ function OhhwellsBridge() {
|
|
|
20837
21032
|
setHoveredItemRect(null);
|
|
20838
21033
|
hoveredNavContainerRef.current = null;
|
|
20839
21034
|
setHoveredNavContainerRect(null);
|
|
21035
|
+
siblingHintElRef.current = null;
|
|
21036
|
+
setSiblingHintRect(null);
|
|
21037
|
+
setSiblingHintRects([]);
|
|
21038
|
+
dismissImageHover();
|
|
21039
|
+
clearImageHover();
|
|
21040
|
+
setSectionGap(null);
|
|
20840
21041
|
return;
|
|
20841
21042
|
}
|
|
20842
21043
|
if (probeSocialsRowAt(clientX, clientY)) return;
|
|
@@ -20848,7 +21049,11 @@ function OhhwellsBridge() {
|
|
|
20848
21049
|
if (e.data?.type !== "ow:pointer-sync") return;
|
|
20849
21050
|
const { clientX, clientY } = e.data;
|
|
20850
21051
|
if (typeof clientX !== "number" || typeof clientY !== "number") return;
|
|
20851
|
-
if (
|
|
21052
|
+
if (document.documentElement.hasAttribute("data-ohw-panel-dragging") || floatingPanelOpenRef.current && isPointOverFloatingPanel(clientX, clientY)) {
|
|
21053
|
+
dismissImageHover();
|
|
21054
|
+
clearImageHover();
|
|
21055
|
+
return;
|
|
21056
|
+
}
|
|
20852
21057
|
if (probeSocialsRowAt(clientX, clientY)) return;
|
|
20853
21058
|
probeSectionGapAt(clientX, clientY);
|
|
20854
21059
|
probeImageAt(clientX, clientY);
|
|
@@ -21187,6 +21392,7 @@ function OhhwellsBridge() {
|
|
|
21187
21392
|
}
|
|
21188
21393
|
if (typeof content[STYLE_STORE_KEY] === "string") {
|
|
21189
21394
|
stylesRef.current = content[STYLE_STORE_KEY];
|
|
21395
|
+
document.querySelectorAll('[data-ohw-editable="form"]').forEach((f) => markFormFields(f));
|
|
21190
21396
|
applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
|
|
21191
21397
|
}
|
|
21192
21398
|
applyBrandChrome(content);
|
|
@@ -21198,11 +21404,11 @@ function OhhwellsBridge() {
|
|
|
21198
21404
|
continue;
|
|
21199
21405
|
}
|
|
21200
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;
|
|
21201
21409
|
if (key === BRAND_KIT_KEY) continue;
|
|
21202
21410
|
if (key === STYLE_STORE_KEY) continue;
|
|
21203
21411
|
if (BRAND_CHROME_KEYS.has(key)) continue;
|
|
21204
|
-
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
21205
|
-
if (LOGO_IMAGE_KEYS.includes(key) && !String(val ?? "").trim()) continue;
|
|
21206
21412
|
if (applyVideoSettingNode(key, val)) continue;
|
|
21207
21413
|
if (applyCarouselNode(key, val)) continue;
|
|
21208
21414
|
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
@@ -21423,10 +21629,26 @@ function OhhwellsBridge() {
|
|
|
21423
21629
|
const handleGetBrand = (e) => {
|
|
21424
21630
|
if (e.data?.type !== "ow:get-brand") return;
|
|
21425
21631
|
const template = deriveTemplateBrand();
|
|
21426
|
-
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) : "");
|
|
21427
21637
|
postToParentRef.current({ type: "ow:brand-value", value });
|
|
21428
21638
|
};
|
|
21429
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);
|
|
21430
21652
|
const handleMoveSection = (e) => {
|
|
21431
21653
|
if (e.data?.type !== "ow:move-section") return;
|
|
21432
21654
|
const instanceId = typeof e.data.instanceId === "string" ? e.data.instanceId : "";
|
|
@@ -21619,6 +21841,12 @@ function OhhwellsBridge() {
|
|
|
21619
21841
|
closeLinkPopoverRef.current();
|
|
21620
21842
|
return;
|
|
21621
21843
|
}
|
|
21844
|
+
if (floatingPanelOpenRef.current) {
|
|
21845
|
+
setFloatingPanelRef.current(null);
|
|
21846
|
+
deselectRef.current();
|
|
21847
|
+
deactivateRef.current();
|
|
21848
|
+
return;
|
|
21849
|
+
}
|
|
21622
21850
|
deselectRef.current();
|
|
21623
21851
|
deactivateRef.current();
|
|
21624
21852
|
clearMediaSelectionRef.current();
|
|
@@ -21907,8 +22135,12 @@ function OhhwellsBridge() {
|
|
|
21907
22135
|
if (inserted) {
|
|
21908
22136
|
const tracker = getSectionsTracker();
|
|
21909
22137
|
postToParentRef.current({ type: "ow:change", nodes: [{ key: "__ohw_sections", text: tracker.textContent ?? "[]" }] });
|
|
21910
|
-
const
|
|
21911
|
-
|
|
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);
|
|
21912
22144
|
}
|
|
21913
22145
|
};
|
|
21914
22146
|
const handleSwitchSchedule = (e) => {
|
|
@@ -22085,14 +22317,20 @@ function OhhwellsBridge() {
|
|
|
22085
22317
|
};
|
|
22086
22318
|
const applyToolbarPos = (rect) => {
|
|
22087
22319
|
const ps = parentScrollRef.current;
|
|
22320
|
+
const hidden = isRectOutsideClip(rect, getIframeVisibleClip(ps));
|
|
22088
22321
|
const measuredW = toolbarElRef.current?.offsetWidth || 330;
|
|
22089
22322
|
if (toolbarElRef.current) {
|
|
22090
|
-
|
|
22091
|
-
|
|
22092
|
-
|
|
22093
|
-
|
|
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
|
+
}
|
|
22094
22330
|
}
|
|
22095
22331
|
if (glowElRef.current) {
|
|
22332
|
+
glowElRef.current.style.display = hidden ? "none" : "";
|
|
22333
|
+
if (hidden) return;
|
|
22096
22334
|
const GAP = SELECTION_CHROME_GAP2;
|
|
22097
22335
|
glowElRef.current.style.top = `${rect.top - GAP}px`;
|
|
22098
22336
|
glowElRef.current.style.left = `${rect.left - GAP}px`;
|
|
@@ -22323,15 +22561,17 @@ function OhhwellsBridge() {
|
|
|
22323
22561
|
window.removeEventListener("message", handleAiSetBrand);
|
|
22324
22562
|
window.removeEventListener("message", handleAiSetStyles);
|
|
22325
22563
|
window.removeEventListener("message", handleGetBrand);
|
|
22564
|
+
window.removeEventListener("message", handleGetTemplateFonts);
|
|
22565
|
+
window.removeEventListener("message", handleGetTemplateBrand);
|
|
22326
22566
|
window.removeEventListener("message", handleMoveSection);
|
|
22327
22567
|
window.removeEventListener("message", handlePanelDragging);
|
|
22328
22568
|
window.removeEventListener("message", handleDeleteSection);
|
|
22329
22569
|
window.removeEventListener("message", handleDuplicateSection);
|
|
22330
22570
|
window.removeEventListener("message", handleDeactivate);
|
|
22331
|
-
document.documentElement.removeAttribute("data-ohw-panel-dragging");
|
|
22332
22571
|
window.removeEventListener("message", handleToastAction);
|
|
22333
22572
|
window.removeEventListener("message", handleFormCount);
|
|
22334
22573
|
window.removeEventListener("message", handleUiEscape);
|
|
22574
|
+
document.documentElement.removeAttribute("data-ohw-panel-dragging");
|
|
22335
22575
|
autoSaveTimers.current.forEach(clearTimeout);
|
|
22336
22576
|
autoSaveTimers.current.clear();
|
|
22337
22577
|
if (imageUnhoverTimerRef.current) clearTimeout(imageUnhoverTimerRef.current);
|
|
@@ -22534,7 +22774,7 @@ function OhhwellsBridge() {
|
|
|
22534
22774
|
postToParent2({
|
|
22535
22775
|
type: "ow:ready",
|
|
22536
22776
|
version: "1",
|
|
22537
|
-
bridgeVersion: "0.1.
|
|
22777
|
+
bridgeVersion: "0.1.108",
|
|
22538
22778
|
path: pathname,
|
|
22539
22779
|
nodes: collectEditableNodes(editContentRef.current),
|
|
22540
22780
|
sections
|
|
@@ -23150,7 +23390,7 @@ function OhhwellsBridge() {
|
|
|
23150
23390
|
"span",
|
|
23151
23391
|
{
|
|
23152
23392
|
"data-ohw-form-count": "",
|
|
23153
|
-
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",
|
|
23154
23394
|
children: formPickCount
|
|
23155
23395
|
}
|
|
23156
23396
|
)
|
|
@@ -23321,7 +23561,7 @@ function OhhwellsBridge() {
|
|
|
23321
23561
|
) : void 0
|
|
23322
23562
|
}
|
|
23323
23563
|
),
|
|
23324
|
-
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: [
|
|
23325
23565
|
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
23326
23566
|
EditGlowChrome,
|
|
23327
23567
|
{
|
|
@@ -23387,11 +23627,11 @@ function OhhwellsBridge() {
|
|
|
23387
23627
|
className: "fixed left-0 w-full z-2147483646 flex items-center pointer-events-none",
|
|
23388
23628
|
style: { top: sectionGap.y, transform: "translateY(-50%)" },
|
|
23389
23629
|
children: [
|
|
23390
|
-
/* @__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 } }),
|
|
23391
23631
|
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
23392
23632
|
Badge,
|
|
23393
23633
|
{
|
|
23394
|
-
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",
|
|
23395
23635
|
onClick: () => {
|
|
23396
23636
|
window.parent.postMessage(
|
|
23397
23637
|
{
|
|
@@ -23405,7 +23645,7 @@ function OhhwellsBridge() {
|
|
|
23405
23645
|
children: "Add Section"
|
|
23406
23646
|
}
|
|
23407
23647
|
),
|
|
23408
|
-
/* @__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 } })
|
|
23409
23649
|
]
|
|
23410
23650
|
}
|
|
23411
23651
|
),
|
|
@@ -23453,6 +23693,59 @@ function OhhwellsBridge() {
|
|
|
23453
23693
|
) : null
|
|
23454
23694
|
] });
|
|
23455
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
|
+
}
|
|
23456
23749
|
// Annotate the CommonJS export names for ESM import in node:
|
|
23457
23750
|
0 && (module.exports = {
|
|
23458
23751
|
AI_DEFAULT_BRAND,
|
|
@@ -23470,6 +23763,7 @@ function OhhwellsBridge() {
|
|
|
23470
23763
|
DropdownMenuItem,
|
|
23471
23764
|
DropdownMenuSeparator,
|
|
23472
23765
|
DropdownMenuTrigger,
|
|
23766
|
+
EmptySection,
|
|
23473
23767
|
ItemActionToolbar,
|
|
23474
23768
|
ItemInteractionLayer,
|
|
23475
23769
|
LinkEditorPanel,
|