@ohhwells/bridge 0.1.110 → 0.1.112-next.289
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 +492 -176
- 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 +491 -176
- 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 +555 -504
- 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
|
|
@@ -459,6 +522,20 @@ var BG_VALUES = {
|
|
|
459
522
|
accent: "var(--ohw-brand-primary, var(--color-primary, #0078E5))",
|
|
460
523
|
"accent-soft": "color-mix(in srgb, var(--ohw-brand-primary, var(--color-primary, #0078E5)) 12%, var(--ohw-brand-light, var(--color-light, #FFFFFF)))"
|
|
461
524
|
};
|
|
525
|
+
var NAVBAR_COLOR_TOKENS = ["dark", "primary", "accent", "light"];
|
|
526
|
+
function navbarColorVar(token) {
|
|
527
|
+
const fallback = {
|
|
528
|
+
dark: "#0C0A09",
|
|
529
|
+
primary: "#0078E5",
|
|
530
|
+
accent: "#0078E5",
|
|
531
|
+
light: "#FFFFFF"
|
|
532
|
+
};
|
|
533
|
+
return `var(--ohw-brand-${token}, var(--color-${token}, ${fallback[token]}))`;
|
|
534
|
+
}
|
|
535
|
+
function resolveNavbarValue(value) {
|
|
536
|
+
if (value === void 0) return void 0;
|
|
537
|
+
return NAVBAR_COLOR_TOKENS.includes(value) ? navbarColorVar(value) : value;
|
|
538
|
+
}
|
|
462
539
|
var HEADLINE_SIZES = { md: 24, lg: 32, xl: 40, display: 56 };
|
|
463
540
|
function styleSheetCss() {
|
|
464
541
|
const rules = [];
|
|
@@ -628,8 +705,16 @@ function applyStylesToDom(store) {
|
|
|
628
705
|
for (const [sectionId, override] of Object.entries(store.sections)) {
|
|
629
706
|
const escaped = CSS.escape(sectionId);
|
|
630
707
|
const byInstance = document.querySelectorAll(`[data-ohw-instance="${escaped}"]`);
|
|
631
|
-
const sections =
|
|
708
|
+
const sections = Array.from(
|
|
709
|
+
byInstance.length ? byInstance : document.querySelectorAll(`[data-ohw-section="${escaped}"]`)
|
|
710
|
+
);
|
|
711
|
+
const isNavbar = sectionId === "navbar";
|
|
712
|
+
if (isNavbar) {
|
|
713
|
+
const drawer = document.querySelector("[data-ohw-nav-drawer]");
|
|
714
|
+
if (drawer && !sections.includes(drawer)) sections.push(drawer);
|
|
715
|
+
}
|
|
632
716
|
for (const marker of Array.from(sections)) {
|
|
717
|
+
const isDrawerMarker = isNavbar && marker.hasAttribute("data-ohw-nav-drawer");
|
|
633
718
|
const section = marker.querySelector(":scope > [data-ai-section]") ?? marker;
|
|
634
719
|
for (const [prop, attr] of Object.entries(SECTION_ATTRS)) {
|
|
635
720
|
const value = override[prop];
|
|
@@ -637,19 +722,23 @@ function applyStylesToDom(store) {
|
|
|
637
722
|
if (prop === "sectionBackground" && override.sectionBackgroundColor !== void 0) continue;
|
|
638
723
|
section.setAttribute(attr, String(value).replace(":", "-"));
|
|
639
724
|
}
|
|
640
|
-
|
|
725
|
+
const bgOverride = isDrawerMarker ? override.navbarMobileBackground ?? override.sectionBackgroundColor : override.sectionBackgroundColor;
|
|
726
|
+
const textOverride = isDrawerMarker ? override.navbarMobileTextColor ?? override.textColor : override.textColor;
|
|
727
|
+
const bgValue = isNavbar ? resolveNavbarValue(bgOverride) : bgOverride;
|
|
728
|
+
const textValue = isNavbar ? resolveNavbarValue(textOverride) : textOverride;
|
|
729
|
+
if (bgValue !== void 0) {
|
|
641
730
|
saveInline(section, "background");
|
|
642
|
-
section.style.setProperty("background",
|
|
731
|
+
section.style.setProperty("background", bgValue, "important");
|
|
643
732
|
section.setAttribute("data-ohw-style-bgcolor", "");
|
|
644
733
|
}
|
|
645
|
-
if (
|
|
734
|
+
if (textValue !== void 0 || override.fontFamily !== void 0) {
|
|
646
735
|
const textEls = marker.querySelectorAll(
|
|
647
736
|
'[data-ohw-editable="text"], [data-ohw-editable="plain"], [data-ohw-field-label]'
|
|
648
737
|
);
|
|
649
738
|
for (const el of Array.from(textEls)) {
|
|
650
|
-
if (
|
|
739
|
+
if (textValue !== void 0) {
|
|
651
740
|
saveInline(el, "color");
|
|
652
|
-
el.style.setProperty("color",
|
|
741
|
+
el.style.setProperty("color", textValue, "important");
|
|
653
742
|
el.setAttribute(NODE_WROTE_ATTR, "");
|
|
654
743
|
}
|
|
655
744
|
if (override.fontFamily !== void 0) {
|
|
@@ -1355,6 +1444,22 @@ function accentBandContext(brand) {
|
|
|
1355
1444
|
function textAttrs(ctx, path) {
|
|
1356
1445
|
return ctx.keyFor ? { "data-ohw-key": ctx.keyFor(path), "data-ohw-editable": "text" } : {};
|
|
1357
1446
|
}
|
|
1447
|
+
var AI_RESPONSIVE_CSS = [
|
|
1448
|
+
"@media (max-width: 960px) {",
|
|
1449
|
+
" [data-ai-responsive] [data-ai-grid] { grid-template-columns: repeat(2, 1fr) !important; }",
|
|
1450
|
+
' [data-ai-responsive] [data-ai-grid="1"] { grid-template-columns: 1fr !important; }',
|
|
1451
|
+
"}",
|
|
1452
|
+
"@media (max-width: 640px) {",
|
|
1453
|
+
" [data-ai-responsive] [data-ai-grid] { grid-template-columns: 1fr !important; }",
|
|
1454
|
+
" [data-ai-responsive] [data-ai-columns] > * { grid-column: 1 / -1 !important; }",
|
|
1455
|
+
// Group containers flatten to a column on phones; span placements come along for free.
|
|
1456
|
+
" [data-ai-responsive] [data-ai-group] { display: flex !important; flex-direction: column !important; }",
|
|
1457
|
+
" [data-ai-responsive] [data-ai-group] > * { grid-column: auto !important; }",
|
|
1458
|
+
" [data-ai-responsive] [data-ai-section-inner] { padding-left: 20px !important; padding-right: 20px !important; }",
|
|
1459
|
+
" [data-ai-responsive] { overflow-x: hidden; }",
|
|
1460
|
+
" [data-ai-responsive] img { max-width: 100%; }",
|
|
1461
|
+
"}"
|
|
1462
|
+
].join("\n");
|
|
1358
1463
|
var TRANSPARENT_PX = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7";
|
|
1359
1464
|
function MediaBox({
|
|
1360
1465
|
refValue,
|
|
@@ -1367,13 +1472,17 @@ function MediaBox({
|
|
|
1367
1472
|
const url = refValue ? ctx.resolveMedia(refValue) : null;
|
|
1368
1473
|
const isIcon = /^(lucide|simple):/.test(refValue);
|
|
1369
1474
|
const aspectRatio = aspect && /^\d+:\d+$/.test(aspect) ? aspect.replace(":", " / ") : void 0;
|
|
1370
|
-
const editAttrs = ctx.keyFor && editPath
|
|
1475
|
+
const editAttrs = ctx.keyFor && editPath ? {
|
|
1476
|
+
"data-ohw-key": ctx.keyFor(editPath),
|
|
1477
|
+
"data-ohw-editable": isIcon ? "icon" : "image"
|
|
1478
|
+
} : {};
|
|
1371
1479
|
if (isIcon) {
|
|
1372
1480
|
const Icon = refValue.startsWith("lucide:") ? lucideByName(refValue.slice(7)) : null;
|
|
1373
1481
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1374
1482
|
"span",
|
|
1375
1483
|
{
|
|
1376
1484
|
"data-ai-icon": refValue,
|
|
1485
|
+
...editAttrs,
|
|
1377
1486
|
style: {
|
|
1378
1487
|
display: "inline-flex",
|
|
1379
1488
|
width: 48,
|
|
@@ -2266,7 +2375,7 @@ function CollectionBlock({ node, ctx, path }) {
|
|
|
2266
2375
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
2267
2376
|
"div",
|
|
2268
2377
|
{
|
|
2269
|
-
"data-ai-grid":
|
|
2378
|
+
"data-ai-grid": String(itemsPerRow),
|
|
2270
2379
|
style: {
|
|
2271
2380
|
display: "grid",
|
|
2272
2381
|
gridTemplateColumns: `repeat(${itemsPerRow}, 1fr)`,
|
|
@@ -2619,6 +2728,7 @@ function AiTreeRenderer({
|
|
|
2619
2728
|
{
|
|
2620
2729
|
"data-ai-section": tree.tag ?? "",
|
|
2621
2730
|
...bgAttrs,
|
|
2731
|
+
"data-ai-responsive": "",
|
|
2622
2732
|
style: {
|
|
2623
2733
|
position: "relative",
|
|
2624
2734
|
padding: `${pad}px 0`,
|
|
@@ -2629,12 +2739,13 @@ function AiTreeRenderer({
|
|
|
2629
2739
|
color: settings.sectionBackground === "accent" ? blockBrand.palette.dark : void 0
|
|
2630
2740
|
},
|
|
2631
2741
|
children: [
|
|
2632
|
-
|
|
2742
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("style", { children: AI_RESPONSIVE_CSS }),
|
|
2633
2743
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("style", { children: AI_MOBILE_CSS }),
|
|
2744
|
+
isOverlay && backgroundUrl && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { position: "absolute", inset: 0, background: `rgba(255,255,255,${overlayAlpha})` } }),
|
|
2634
2745
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
2635
2746
|
"div",
|
|
2636
2747
|
{
|
|
2637
|
-
"data-ai-
|
|
2748
|
+
"data-ai-section-inner": "",
|
|
2638
2749
|
style: {
|
|
2639
2750
|
position: "relative",
|
|
2640
2751
|
maxWidth: AI_TREE_TOKENS.sectionMaxWidth,
|
|
@@ -2645,7 +2756,7 @@ function AiTreeRenderer({
|
|
|
2645
2756
|
children: tree.rows.map((row, r2) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
2646
2757
|
"div",
|
|
2647
2758
|
{
|
|
2648
|
-
"data-ai-
|
|
2759
|
+
"data-ai-columns": "",
|
|
2649
2760
|
style: {
|
|
2650
2761
|
display: "grid",
|
|
2651
2762
|
gridTemplateColumns: "repeat(12, 1fr)",
|
|
@@ -2695,14 +2806,52 @@ function readRootVar(name) {
|
|
|
2695
2806
|
if (typeof document === "undefined") return "";
|
|
2696
2807
|
return getComputedStyle(document.documentElement).getPropertyValue(name).trim();
|
|
2697
2808
|
}
|
|
2809
|
+
function normalizeColorToHex(value) {
|
|
2810
|
+
if (!value || typeof document === "undefined") return value;
|
|
2811
|
+
const canvas = document.createElement("canvas");
|
|
2812
|
+
canvas.width = 1;
|
|
2813
|
+
canvas.height = 1;
|
|
2814
|
+
const ctx = canvas.getContext("2d");
|
|
2815
|
+
if (!ctx) return value;
|
|
2816
|
+
ctx.fillStyle = value;
|
|
2817
|
+
ctx.fillRect(0, 0, 1, 1);
|
|
2818
|
+
const [r2, g, b] = ctx.getImageData(0, 0, 1, 1).data;
|
|
2819
|
+
const toHex = (n) => n.toString(16).padStart(2, "0");
|
|
2820
|
+
return `#${toHex(r2)}${toHex(g)}${toHex(b)}`;
|
|
2821
|
+
}
|
|
2822
|
+
var GENERIC_FONT_KEYWORDS = /* @__PURE__ */ new Set([
|
|
2823
|
+
"serif",
|
|
2824
|
+
"sans-serif",
|
|
2825
|
+
"monospace",
|
|
2826
|
+
"cursive",
|
|
2827
|
+
"fantasy",
|
|
2828
|
+
"system-ui",
|
|
2829
|
+
"ui-serif",
|
|
2830
|
+
"ui-sans-serif",
|
|
2831
|
+
"ui-monospace",
|
|
2832
|
+
"ui-rounded",
|
|
2833
|
+
"math",
|
|
2834
|
+
"emoji",
|
|
2835
|
+
"fangsong"
|
|
2836
|
+
]);
|
|
2837
|
+
function primaryFontFamily(stack) {
|
|
2838
|
+
const first = stack.split(",").map((part) => part.trim().replace(/^["']|["']$/g, "")).find((part) => part && !GENERIC_FONT_KEYWORDS.has(part.toLowerCase()));
|
|
2839
|
+
return first ?? "";
|
|
2840
|
+
}
|
|
2841
|
+
function humanizeFontFamily(name) {
|
|
2842
|
+
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());
|
|
2843
|
+
}
|
|
2844
|
+
function readFontVar(name) {
|
|
2845
|
+
return humanizeFontFamily(primaryFontFamily(readRootVar(name)));
|
|
2846
|
+
}
|
|
2698
2847
|
function deriveBrandOverride() {
|
|
2699
2848
|
const dark = readRootVar("--ohw-brand-dark");
|
|
2700
2849
|
const primary = readRootVar("--ohw-brand-primary");
|
|
2701
2850
|
const light = readRootVar("--ohw-brand-light");
|
|
2702
2851
|
if (!dark || !primary || !light) return null;
|
|
2703
2852
|
const accent = readRootVar("--ohw-brand-accent");
|
|
2704
|
-
const heading =
|
|
2705
|
-
const body =
|
|
2853
|
+
const heading = readFontVar("--font-heading") || readFontVar("--font-display");
|
|
2854
|
+
const body = readFontVar("--font-body");
|
|
2706
2855
|
return {
|
|
2707
2856
|
palette: { dark, primary, accent: accent || dark, light },
|
|
2708
2857
|
fonts: {
|
|
@@ -2711,22 +2860,55 @@ function deriveBrandOverride() {
|
|
|
2711
2860
|
}
|
|
2712
2861
|
};
|
|
2713
2862
|
}
|
|
2714
|
-
function
|
|
2863
|
+
function deriveTemplateBrandLive() {
|
|
2715
2864
|
const primary = readRootVar("--brand-primary") || readRootVar("--color-primary");
|
|
2716
2865
|
const dark = readRootVar("--brand-text") || readRootVar("--color-dark");
|
|
2717
2866
|
const light = readRootVar("--brand-background") || readRootVar("--color-light");
|
|
2718
2867
|
if (!dark || !primary || !light) return null;
|
|
2719
2868
|
const accent = readRootVar("--brand-accent") || readRootVar("--color-accent");
|
|
2720
|
-
const heading =
|
|
2721
|
-
const body =
|
|
2869
|
+
const heading = readFontVar("--brand-font-heading") || readFontVar("--font-heading") || readFontVar("--font-display");
|
|
2870
|
+
const body = readFontVar("--brand-font-body") || readFontVar("--font-body");
|
|
2722
2871
|
return {
|
|
2723
|
-
palette: {
|
|
2872
|
+
palette: {
|
|
2873
|
+
dark: normalizeColorToHex(dark),
|
|
2874
|
+
primary: normalizeColorToHex(primary),
|
|
2875
|
+
accent: normalizeColorToHex(accent || dark),
|
|
2876
|
+
light: normalizeColorToHex(light)
|
|
2877
|
+
},
|
|
2724
2878
|
fonts: {
|
|
2725
2879
|
heading: heading || AI_DEFAULT_BRAND.fonts.heading,
|
|
2726
2880
|
body: body || AI_DEFAULT_BRAND.fonts.body
|
|
2727
2881
|
}
|
|
2728
2882
|
};
|
|
2729
2883
|
}
|
|
2884
|
+
function deriveTemplateFontsLive() {
|
|
2885
|
+
const heading = readFontVar("--brand-font-heading") || readFontVar("--font-heading") || readFontVar("--font-display");
|
|
2886
|
+
const body = readFontVar("--brand-font-body") || readFontVar("--font-body");
|
|
2887
|
+
if (!heading && !body) return null;
|
|
2888
|
+
return {
|
|
2889
|
+
heading: heading || AI_DEFAULT_BRAND.fonts.heading,
|
|
2890
|
+
body: body || AI_DEFAULT_BRAND.fonts.body
|
|
2891
|
+
};
|
|
2892
|
+
}
|
|
2893
|
+
var OVERRIDE_VAR_NAMES = [...BRAND_VAR_NAMES, ...LEGACY_BRAND_VAR_NAMES, ...FONT_VARS.heading, ...FONT_VARS.body];
|
|
2894
|
+
function withOverrideStripped(read) {
|
|
2895
|
+
const root = document.documentElement;
|
|
2896
|
+
const restore = OVERRIDE_VAR_NAMES.map((name) => [name, root.style.getPropertyValue(name)]);
|
|
2897
|
+
for (const name of OVERRIDE_VAR_NAMES) root.style.removeProperty(name);
|
|
2898
|
+
try {
|
|
2899
|
+
return read();
|
|
2900
|
+
} finally {
|
|
2901
|
+
for (const [name, value] of restore) if (value) root.style.setProperty(name, value);
|
|
2902
|
+
}
|
|
2903
|
+
}
|
|
2904
|
+
var TEMPLATE_BRAND_SNAPSHOT = typeof document === "undefined" ? null : withOverrideStripped(deriveTemplateBrandLive);
|
|
2905
|
+
var TEMPLATE_FONTS_SNAPSHOT = typeof document === "undefined" ? null : withOverrideStripped(deriveTemplateFontsLive);
|
|
2906
|
+
function deriveTemplateBrand() {
|
|
2907
|
+
return TEMPLATE_BRAND_SNAPSHOT;
|
|
2908
|
+
}
|
|
2909
|
+
function deriveTemplateFonts() {
|
|
2910
|
+
return TEMPLATE_FONTS_SNAPSHOT;
|
|
2911
|
+
}
|
|
2730
2912
|
function deriveTemplateButtonStyle() {
|
|
2731
2913
|
if (typeof document === "undefined") return null;
|
|
2732
2914
|
const candidates = Array.from(
|
|
@@ -7224,12 +7406,12 @@ var cva = (base, config) => (props) => {
|
|
|
7224
7406
|
var import_radix_ui2 = require("radix-ui");
|
|
7225
7407
|
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
7226
7408
|
var toggleVariants = cva(
|
|
7227
|
-
"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",
|
|
7409
|
+
"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",
|
|
7228
7410
|
{
|
|
7229
7411
|
variants: {
|
|
7230
7412
|
variant: {
|
|
7231
7413
|
default: "bg-transparent border-0",
|
|
7232
|
-
outline: "border border-input bg-transparent shadow-xs hover:bg-accent hover:text-accent-foreground"
|
|
7414
|
+
outline: "border border-input bg-transparent shadow-xs hover:bg-bridge-accent hover:text-accent-foreground"
|
|
7233
7415
|
},
|
|
7234
7416
|
size: {
|
|
7235
7417
|
default: "px-2 py-1",
|
|
@@ -7322,10 +7504,10 @@ var DragHandle = React4.forwardRef(
|
|
|
7322
7504
|
type,
|
|
7323
7505
|
"data-slot": "drag-handle",
|
|
7324
7506
|
className: cn(
|
|
7325
|
-
"inline-flex h-7 w-4 shrink-0 items-center justify-center rounded-md transition-all duration-200 max-h-
|
|
7507
|
+
"inline-flex h-7 w-4 shrink-0 items-center justify-center rounded-md transition-all duration-200 max-h-7.5",
|
|
7326
7508
|
"bg-white border border-transparent text-stone-500 shadow-md cursor-grab",
|
|
7327
7509
|
"enabled:hover:border enabled:hover:border-stone-200 enabled:hover:text-stone-950",
|
|
7328
|
-
"enabled:active:border enabled:active:border-primary enabled:active:bg-primary-50 enabled:active:text-stone-950 enabled:active:shadow enabled:active:cursor-grabbing",
|
|
7510
|
+
"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",
|
|
7329
7511
|
"disabled:cursor-not-allowed disabled:opacity-40 disabled:text-stone-950 disabled:pointer-events-none",
|
|
7330
7512
|
className
|
|
7331
7513
|
),
|
|
@@ -7347,7 +7529,7 @@ var CustomToolbar = React5.forwardRef(({ className, onMouseDown, ...props }, ref
|
|
|
7347
7529
|
"data-ohw-toolbar": "",
|
|
7348
7530
|
className: cn(
|
|
7349
7531
|
// Figma: bg background, radius 8, gap-1, p-0.5, shadow-md — no border
|
|
7350
|
-
"inline-flex h-8 items-center gap-1 rounded-
|
|
7532
|
+
"inline-flex h-8 items-center gap-1 rounded-(--radius,0.5rem) bg-background p-0.5 font-sans whitespace-nowrap shadow-md",
|
|
7351
7533
|
className
|
|
7352
7534
|
),
|
|
7353
7535
|
onMouseDown: (e) => {
|
|
@@ -7376,7 +7558,7 @@ var CustomToolbarButton = React5.forwardRef(
|
|
|
7376
7558
|
type,
|
|
7377
7559
|
className: cn(
|
|
7378
7560
|
"inline-flex size-7 shrink-0 items-center justify-center rounded-[calc(var(--radius,0.5rem)-2px)] text-foreground transition-colors",
|
|
7379
|
-
active ? "bg-primary text-primary-foreground" : "bg-transparent hover:bg-muted disabled:cursor-not-allowed disabled:text-muted-foreground disabled:opacity-60",
|
|
7561
|
+
active ? "bg-bridge-primary text-primary-foreground" : "bg-transparent hover:bg-muted disabled:cursor-not-allowed disabled:text-muted-foreground disabled:opacity-60",
|
|
7380
7562
|
className
|
|
7381
7563
|
),
|
|
7382
7564
|
...props
|
|
@@ -8251,6 +8433,7 @@ var FIELD_TYPES = [
|
|
|
8251
8433
|
var FIELD_ATTR = "data-ohw-form-field";
|
|
8252
8434
|
var FIELD_TYPE_ATTR = "data-ohw-field-type";
|
|
8253
8435
|
var PLACEHOLDER_EDIT_ATTR = "data-ohw-placeholder-edit";
|
|
8436
|
+
var seedFieldByForm = /* @__PURE__ */ new WeakMap();
|
|
8254
8437
|
function fieldsKey(formKey) {
|
|
8255
8438
|
return `${formKey}-fields`;
|
|
8256
8439
|
}
|
|
@@ -8336,7 +8519,11 @@ function markFormFields(form) {
|
|
|
8336
8519
|
ensureFieldLabel(wrapper, key);
|
|
8337
8520
|
syncRequiredMark(wrapper);
|
|
8338
8521
|
});
|
|
8339
|
-
|
|
8522
|
+
const wrappers = listFieldWrappers(form);
|
|
8523
|
+
if (wrappers.length > 0 && !seedFieldByForm.has(form)) {
|
|
8524
|
+
seedFieldByForm.set(form, wrappers[0].cloneNode(true));
|
|
8525
|
+
}
|
|
8526
|
+
return wrappers;
|
|
8340
8527
|
}
|
|
8341
8528
|
function readFieldsFromDom(form) {
|
|
8342
8529
|
return listFieldWrappers(form).map((wrapper) => {
|
|
@@ -8480,12 +8667,27 @@ function insertField(form, type) {
|
|
|
8480
8667
|
wrapper = source.cloneNode(true);
|
|
8481
8668
|
source.after(wrapper);
|
|
8482
8669
|
} else {
|
|
8483
|
-
|
|
8484
|
-
|
|
8485
|
-
|
|
8486
|
-
|
|
8670
|
+
const seed = seedFieldByForm.get(form);
|
|
8671
|
+
if (seed) {
|
|
8672
|
+
wrapper = seed.cloneNode(true);
|
|
8673
|
+
} else {
|
|
8674
|
+
wrapper = document.createElement("div");
|
|
8675
|
+
const input2 = document.createElement("input");
|
|
8676
|
+
input2.style.width = "100%";
|
|
8677
|
+
input2.style.boxSizing = "border-box";
|
|
8678
|
+
input2.style.padding = "12px";
|
|
8679
|
+
input2.style.border = "1px solid color-mix(in srgb, currentColor 35%, transparent)";
|
|
8680
|
+
input2.style.borderRadius = "8px";
|
|
8681
|
+
input2.style.background = "#fff";
|
|
8682
|
+
input2.style.fontFamily = "inherit";
|
|
8683
|
+
input2.style.fontSize = "inherit";
|
|
8684
|
+
input2.style.color = "inherit";
|
|
8685
|
+
wrapper.append(input2);
|
|
8686
|
+
}
|
|
8487
8687
|
const submit = form.querySelector('button, input[type="submit"]');
|
|
8488
|
-
|
|
8688
|
+
let anchor = submit;
|
|
8689
|
+
while (anchor && anchor.parentElement !== form) anchor = anchor.parentElement;
|
|
8690
|
+
if (anchor) anchor.before(wrapper);
|
|
8489
8691
|
else form.appendChild(wrapper);
|
|
8490
8692
|
}
|
|
8491
8693
|
wrapper.setAttribute(FIELD_ATTR, key);
|
|
@@ -8620,13 +8822,13 @@ function FormFieldToolbar({
|
|
|
8620
8822
|
]
|
|
8621
8823
|
}
|
|
8622
8824
|
) }),
|
|
8623
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(DropdownMenuContent, { align: "start", sideOffset: 8, className: "min-w-
|
|
8825
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(DropdownMenuContent, { align: "start", sideOffset: 8, className: "min-w-47.5 p-1", children: FIELD_TYPES.map((entry) => {
|
|
8624
8826
|
const Icon = TYPE_ICONS[entry.type];
|
|
8625
8827
|
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
8626
8828
|
DropdownMenuItem,
|
|
8627
8829
|
{
|
|
8628
8830
|
onSelect: () => onTypeChange(entry.type),
|
|
8629
|
-
className: "rounded-md py-2 text-[13px] " + (entry.type === type ? "bg-primary/10" : ""),
|
|
8831
|
+
className: "rounded-md py-2 text-[13px] " + (entry.type === type ? "bg-bridge-primary/10" : ""),
|
|
8630
8832
|
children: [
|
|
8631
8833
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Icon, { size: 14, strokeWidth: 1.75, className: "shrink-0", "aria-hidden": true }),
|
|
8632
8834
|
entry.label
|
|
@@ -8643,7 +8845,7 @@ function FormFieldToolbar({
|
|
|
8643
8845
|
type: "button",
|
|
8644
8846
|
"aria-pressed": required,
|
|
8645
8847
|
onClick: onRequiredToggle,
|
|
8646
|
-
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"),
|
|
8848
|
+
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"),
|
|
8647
8849
|
"data-ohw-field-required-toggle": "",
|
|
8648
8850
|
children: [
|
|
8649
8851
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react4.Asterisk, { size: 14, strokeWidth: 2, "aria-hidden": true }),
|
|
@@ -8663,7 +8865,7 @@ function FormFieldToolbar({
|
|
|
8663
8865
|
children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react4.MoreHorizontal, { size: 15, "aria-hidden": true })
|
|
8664
8866
|
}
|
|
8665
8867
|
) }),
|
|
8666
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(DropdownMenuContent, { align: "start", sideOffset: 8, className: "min-w-
|
|
8868
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(DropdownMenuContent, { align: "start", sideOffset: 8, className: "min-w-42.5 p-1", children: [
|
|
8667
8869
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(DropdownMenuItem, { onSelect: onDuplicate, className: "rounded-md py-2 text-[13px]", children: [
|
|
8668
8870
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react4.Copy, { size: 14, strokeWidth: 1.75, className: "shrink-0", "aria-hidden": true }),
|
|
8669
8871
|
"Duplicate"
|
|
@@ -8691,7 +8893,7 @@ function FieldTypePicker({ onPick }) {
|
|
|
8691
8893
|
{
|
|
8692
8894
|
type: "button",
|
|
8693
8895
|
onClick: () => onPick(entry.type),
|
|
8694
|
-
className: "flex h-[76px] flex-col items-center justify-center gap-2 rounded-xl border border-border text-[15px] font-medium text-foreground transition-colors hover:border-primary hover:bg-primary/5",
|
|
8896
|
+
className: "flex h-[76px] flex-col items-center justify-center gap-2 rounded-xl border border-border text-[15px] font-medium text-foreground transition-colors hover:border-bridge-primary hover:bg-bridge-primary/5",
|
|
8695
8897
|
children: [
|
|
8696
8898
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Icon, { size: 26, strokeWidth: 1.5, "aria-hidden": true }),
|
|
8697
8899
|
entry.label
|
|
@@ -8717,7 +8919,7 @@ var buttonVariants = cva(
|
|
|
8717
8919
|
{
|
|
8718
8920
|
variants: {
|
|
8719
8921
|
variant: {
|
|
8720
|
-
default: "bg-primary text-primary-foreground hover:opacity-90",
|
|
8922
|
+
default: "bg-bridge-primary text-primary-foreground hover:opacity-90",
|
|
8721
8923
|
outline: "border border-border bg-background text-foreground shadow-sm hover:bg-muted/80",
|
|
8722
8924
|
ghost: "min-w-0 px-3 py-2 text-foreground hover:bg-muted/50"
|
|
8723
8925
|
},
|
|
@@ -8812,6 +9014,7 @@ function MediaOverlay({
|
|
|
8812
9014
|
(prev) => prev && prev.fullWidth === width && prev.height === height ? prev : { fullWidth: width, height }
|
|
8813
9015
|
);
|
|
8814
9016
|
}, [isVideo]);
|
|
9017
|
+
const replaceLabel = isVideo ? "Replace video" : hover.elementType === "bg-image" ? "Replace background" : "Replace image";
|
|
8815
9018
|
const replaceMode = buttonSize ? replaceButtonMode({ width: rect.width, height: rect.height }, buttonSize) : "none";
|
|
8816
9019
|
const box = {
|
|
8817
9020
|
position: "fixed",
|
|
@@ -8917,8 +9120,8 @@ function MediaOverlay({
|
|
|
8917
9120
|
pointerEvents: hover.hasTextOverlap ? "none" : "auto",
|
|
8918
9121
|
// Selected: a firm component ring with no wash, so the image reads as chosen rather
|
|
8919
9122
|
// than hovered. Hover keeps the existing tinted preview.
|
|
8920
|
-
boxShadow: selected ? "inset 0 0 0 2px var(--color-primary)" : "inset 0 0 0 1.5px var(--color-primary)",
|
|
8921
|
-
background: selected ? "transparent" : "color-mix(in srgb, var(--color-primary) 20%, transparent)"
|
|
9123
|
+
boxShadow: selected ? "inset 0 0 0 2px var(--color-bridge-primary)" : "inset 0 0 0 1.5px var(--color-bridge-primary)",
|
|
9124
|
+
background: selected ? "transparent" : "color-mix(in srgb, var(--color-bridge-primary) 20%, transparent)"
|
|
8922
9125
|
},
|
|
8923
9126
|
onClick: () => onSelect && !selected ? onSelect(hover.key) : onReplace(hover.key),
|
|
8924
9127
|
children: [
|
|
@@ -8941,17 +9144,17 @@ function MediaOverlay({
|
|
|
8941
9144
|
},
|
|
8942
9145
|
children: [
|
|
8943
9146
|
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 }),
|
|
8944
|
-
|
|
9147
|
+
replaceLabel
|
|
8945
9148
|
]
|
|
8946
9149
|
}
|
|
8947
9150
|
),
|
|
8948
|
-
replaceMode
|
|
9151
|
+
showChrome && replaceMode !== "none" && /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
|
|
8949
9152
|
Button,
|
|
8950
9153
|
{
|
|
8951
9154
|
"data-ohw-media-overlay": "",
|
|
8952
9155
|
variant: "outline",
|
|
8953
9156
|
size: "sm",
|
|
8954
|
-
"aria-label":
|
|
9157
|
+
"aria-label": replaceLabel,
|
|
8955
9158
|
className: "gap-1.5 cursor-pointer hover:bg-background",
|
|
8956
9159
|
style: {
|
|
8957
9160
|
...OVERLAY_BUTTON_STYLE,
|
|
@@ -8974,7 +9177,7 @@ function MediaOverlay({
|
|
|
8974
9177
|
},
|
|
8975
9178
|
children: [
|
|
8976
9179
|
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 }),
|
|
8977
|
-
replaceMode === "full" ?
|
|
9180
|
+
replaceMode === "full" ? replaceLabel : null
|
|
8978
9181
|
]
|
|
8979
9182
|
}
|
|
8980
9183
|
)
|
|
@@ -9012,8 +9215,8 @@ function CarouselOverlay({
|
|
|
9012
9215
|
height: rect.height,
|
|
9013
9216
|
zIndex: 2147483646,
|
|
9014
9217
|
pointerEvents: "auto",
|
|
9015
|
-
boxShadow: "inset 0 0 0 1.5px var(--color-primary)",
|
|
9016
|
-
background: "color-mix(in srgb, var(--color-primary) 20%, transparent)"
|
|
9218
|
+
boxShadow: "inset 0 0 0 1.5px var(--color-bridge-primary)",
|
|
9219
|
+
background: "color-mix(in srgb, var(--color-bridge-primary) 20%, transparent)"
|
|
9017
9220
|
},
|
|
9018
9221
|
onClick: () => onEdit(hover.key),
|
|
9019
9222
|
children: /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
|
|
@@ -9866,7 +10069,7 @@ function SectionTreeItem({
|
|
|
9866
10069
|
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
9867
10070
|
"div",
|
|
9868
10071
|
{
|
|
9869
|
-
className: "mr-
|
|
10072
|
+
className: "-mr-px h-9 w-2 shrink-0 rounded-bl-sm border-b border-l border-border mb-4",
|
|
9870
10073
|
"aria-hidden": true
|
|
9871
10074
|
}
|
|
9872
10075
|
),
|
|
@@ -9885,7 +10088,7 @@ function SectionTreeItem({
|
|
|
9885
10088
|
className: cn(
|
|
9886
10089
|
"flex h-9 min-w-0 flex-1 items-center gap-2 rounded-md border border-border bg-background p-3",
|
|
9887
10090
|
interactive && "cursor-pointer hover:bg-muted/30",
|
|
9888
|
-
interactive && selected && "border-primary"
|
|
10091
|
+
interactive && selected && "border-bridge-primary"
|
|
9889
10092
|
),
|
|
9890
10093
|
children: [
|
|
9891
10094
|
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
@@ -10015,7 +10218,7 @@ function UrlOrPageInput({
|
|
|
10015
10218
|
};
|
|
10016
10219
|
const fieldClassName = cn(
|
|
10017
10220
|
"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]",
|
|
10018
|
-
urlError ? "border-destructive shadow-[0_0_0_1px_var(--ohw-destructive)]" : isFocused ? "border-primary shadow-[0_0_0_1px_var(--ohw-primary)]" : "border-input"
|
|
10221
|
+
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"
|
|
10019
10222
|
);
|
|
10020
10223
|
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex w-full flex-col gap-2 p-0", children: [
|
|
10021
10224
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Label, { htmlFor: inputId, className: cn(urlError && "text-destructive"), children: "Destination" }),
|
|
@@ -13922,6 +14125,7 @@ function readLogoSizeState(content, placement) {
|
|
|
13922
14125
|
function getLogoElement(el) {
|
|
13923
14126
|
const marked = el.closest('[data-ohw-role="logo"], [data-ohw-logo]');
|
|
13924
14127
|
if (marked) return marked;
|
|
14128
|
+
if (el.closest('[data-ohw-editable="icon"]')) return null;
|
|
13925
14129
|
const root = el.closest("nav, [data-ohw-nav-root], footer");
|
|
13926
14130
|
if (!root) return null;
|
|
13927
14131
|
const anchor = el.closest("a");
|
|
@@ -14209,7 +14413,7 @@ function DisplaySwitch({
|
|
|
14209
14413
|
onClick: () => onChange(!checked),
|
|
14210
14414
|
className: cn(
|
|
14211
14415
|
"relative h-5 w-9 shrink-0 rounded-full transition-colors",
|
|
14212
|
-
checked ? "bg-primary" : "bg-primary-50",
|
|
14416
|
+
checked ? "bg-bridge-primary" : "bg-primary-50",
|
|
14213
14417
|
disabled ? "cursor-default opacity-50" : "cursor-pointer"
|
|
14214
14418
|
),
|
|
14215
14419
|
children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
@@ -14217,7 +14421,7 @@ function DisplaySwitch({
|
|
|
14217
14421
|
{
|
|
14218
14422
|
className: cn(
|
|
14219
14423
|
"absolute top-0.5 h-4 w-4 rounded-full bg-white transition-all",
|
|
14220
|
-
checked ? "left-
|
|
14424
|
+
checked ? "left-4.5" : "left-0.5"
|
|
14221
14425
|
)
|
|
14222
14426
|
}
|
|
14223
14427
|
)
|
|
@@ -15852,7 +16056,7 @@ var badgeVariants = cva(
|
|
|
15852
16056
|
{
|
|
15853
16057
|
variants: {
|
|
15854
16058
|
variant: {
|
|
15855
|
-
default: "border-transparent bg-primary text-primary-foreground",
|
|
16059
|
+
default: "border-transparent bg-bridge-primary text-primary-foreground",
|
|
15856
16060
|
secondary: "border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80",
|
|
15857
16061
|
destructive: "border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80",
|
|
15858
16062
|
outline: "text-foreground"
|
|
@@ -16034,21 +16238,10 @@ function parseSchedulingInsertAfter(insertAfter) {
|
|
|
16034
16238
|
insertBefore: insertAfter.slice(idx + INSERT_BEFORE_MARKER.length)
|
|
16035
16239
|
};
|
|
16036
16240
|
}
|
|
16037
|
-
function
|
|
16038
|
-
|
|
16039
|
-
const
|
|
16040
|
-
|
|
16041
|
-
return { effectiveInsertAfter, insertBefore };
|
|
16042
|
-
}
|
|
16043
|
-
function getSchedulingMountPoint(insertAfter) {
|
|
16044
|
-
const { anchor } = parseSchedulingInsertAfter(insertAfter);
|
|
16045
|
-
let anchorEl = document.querySelector(`[data-ohw-section="${anchor}"]`);
|
|
16046
|
-
if (!anchorEl && anchor === "scheduling") {
|
|
16047
|
-
const widgets = Array.from(document.querySelectorAll('[data-ohw-section^="scheduling-"]'));
|
|
16048
|
-
anchorEl = widgets.at(-1) ?? null;
|
|
16049
|
-
}
|
|
16050
|
-
if (!anchorEl) return null;
|
|
16051
|
-
return anchorEl.closest('[data-ohw-section-container="scheduling"]') ?? anchorEl;
|
|
16241
|
+
function resolveEntryAnchor(entry) {
|
|
16242
|
+
if (entry.anchorId !== void 0) return { anchorId: entry.anchorId, beforeId: entry.beforeId ?? null };
|
|
16243
|
+
const parsed = parseSchedulingInsertAfter(entry.insertAfter);
|
|
16244
|
+
return { anchorId: parsed.anchor, beforeId: parsed.insertBefore };
|
|
16052
16245
|
}
|
|
16053
16246
|
function schedulingMountDepth(insertAfter) {
|
|
16054
16247
|
if (!insertAfter.includes(INSERT_BEFORE_MARKER)) return 0;
|
|
@@ -16065,8 +16258,7 @@ function getPageSchedulingEntries(raw) {
|
|
|
16065
16258
|
}
|
|
16066
16259
|
}
|
|
16067
16260
|
function isSchedulingWidgetMissing(entry) {
|
|
16068
|
-
|
|
16069
|
-
return !document.querySelector(`[data-ohw-section="${schedulingSectionId(effectiveInsertAfter)}"]`);
|
|
16261
|
+
return !document.querySelector(`[data-ohw-section="${schedulingSectionId(entry.insertAfter)}"]`);
|
|
16070
16262
|
}
|
|
16071
16263
|
function hasMissingSchedulingWidgets(entries) {
|
|
16072
16264
|
return entries.some(isSchedulingWidgetMissing);
|
|
@@ -16104,17 +16296,18 @@ function initSectionsFromContent(content, removeExisting = false, currentPath =
|
|
|
16104
16296
|
} catch {
|
|
16105
16297
|
}
|
|
16106
16298
|
}
|
|
16107
|
-
function mountSchedulingWidget(
|
|
16108
|
-
const
|
|
16109
|
-
const sectionId = schedulingSectionId(
|
|
16299
|
+
function mountSchedulingWidget(anchorId, notifyOnConnect = false, scheduleId, beforeId, existingWidgetId) {
|
|
16300
|
+
const widgetId = existingWidgetId ?? (beforeId ? `${anchorId}${INSERT_BEFORE_MARKER}${beforeId}` : anchorId);
|
|
16301
|
+
const sectionId = schedulingSectionId(widgetId);
|
|
16110
16302
|
if (document.querySelector(`[data-ohw-section="${sectionId}"]`)) return false;
|
|
16111
|
-
const
|
|
16112
|
-
if (!
|
|
16303
|
+
const anchorEl = document.querySelector(`[data-ohw-section="${anchorId}"]`);
|
|
16304
|
+
if (!anchorEl) return false;
|
|
16305
|
+
const mountPoint = anchorEl.closest('[data-ohw-section-container="scheduling"]') ?? anchorEl;
|
|
16113
16306
|
const container = document.createElement("div");
|
|
16114
16307
|
container.dataset.ohwSectionContainer = "scheduling";
|
|
16115
16308
|
container.dataset.ohwInstance = sectionId;
|
|
16116
|
-
if (
|
|
16117
|
-
const beforeAnchor = document.querySelector(`[data-ohw-section="${
|
|
16309
|
+
if (beforeId) {
|
|
16310
|
+
const beforeAnchor = document.querySelector(`[data-ohw-section="${beforeId}"]`);
|
|
16118
16311
|
const beforePoint = beforeAnchor?.closest('[data-ohw-section-container="scheduling"]') ?? beforeAnchor;
|
|
16119
16312
|
if (!beforePoint) return false;
|
|
16120
16313
|
beforePoint.insertAdjacentElement("beforebegin", container);
|
|
@@ -16125,20 +16318,26 @@ function mountSchedulingWidget(insertAfter, notifyOnConnect = false, scheduleId,
|
|
|
16125
16318
|
}
|
|
16126
16319
|
tail.insertAdjacentElement("afterend", container);
|
|
16127
16320
|
}
|
|
16128
|
-
|
|
16129
|
-
|
|
16130
|
-
|
|
16131
|
-
|
|
16132
|
-
|
|
16133
|
-
|
|
16134
|
-
|
|
16135
|
-
|
|
16136
|
-
|
|
16137
|
-
|
|
16138
|
-
|
|
16139
|
-
|
|
16140
|
-
|
|
16141
|
-
|
|
16321
|
+
try {
|
|
16322
|
+
const root = (0, import_client2.createRoot)(container);
|
|
16323
|
+
schedulingRoots.set(container, root);
|
|
16324
|
+
(0, import_react_dom4.flushSync)(() => {
|
|
16325
|
+
root.render(
|
|
16326
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
16327
|
+
SchedulingWidget,
|
|
16328
|
+
{
|
|
16329
|
+
notifyOnConnect,
|
|
16330
|
+
initialScheduleId: scheduleId,
|
|
16331
|
+
insertAfter: widgetId
|
|
16332
|
+
}
|
|
16333
|
+
)
|
|
16334
|
+
);
|
|
16335
|
+
});
|
|
16336
|
+
} catch (err) {
|
|
16337
|
+
console.error("[ow:scheduling] render threw", err);
|
|
16338
|
+
container.remove();
|
|
16339
|
+
return false;
|
|
16340
|
+
}
|
|
16142
16341
|
const tracker = getSectionsTracker();
|
|
16143
16342
|
let sections = [];
|
|
16144
16343
|
try {
|
|
@@ -16146,10 +16345,12 @@ function mountSchedulingWidget(insertAfter, notifyOnConnect = false, scheduleId,
|
|
|
16146
16345
|
} catch {
|
|
16147
16346
|
}
|
|
16148
16347
|
const inEditor = typeof window !== "undefined" && window.self !== window.top;
|
|
16149
|
-
if (inEditor && !sections.find((s) => s.type === "scheduling" && s.insertAfter ===
|
|
16348
|
+
if (inEditor && !sections.find((s) => s.type === "scheduling" && s.insertAfter === widgetId)) {
|
|
16150
16349
|
sections.push({
|
|
16151
16350
|
type: "scheduling",
|
|
16152
|
-
insertAfter:
|
|
16351
|
+
insertAfter: widgetId,
|
|
16352
|
+
anchorId,
|
|
16353
|
+
beforeId: beforeId ?? null,
|
|
16153
16354
|
pagePath: window.location.pathname,
|
|
16154
16355
|
...scheduleId ? { scheduleId } : {}
|
|
16155
16356
|
});
|
|
@@ -16163,7 +16364,8 @@ function mountSchedulingEntries(entries, notifyOnConnect = false) {
|
|
|
16163
16364
|
for (let i = pending.length - 1; i >= 0; i--) {
|
|
16164
16365
|
const entry = pending[i];
|
|
16165
16366
|
const shouldNotify = typeof notifyOnConnect === "function" ? notifyOnConnect(entry) : notifyOnConnect;
|
|
16166
|
-
|
|
16367
|
+
const { anchorId, beforeId } = resolveEntryAnchor(entry);
|
|
16368
|
+
if (mountSchedulingWidget(anchorId, shouldNotify, entry.scheduleId ?? null, beforeId, entry.insertAfter)) {
|
|
16167
16369
|
pending.splice(i, 1);
|
|
16168
16370
|
}
|
|
16169
16371
|
}
|
|
@@ -16327,6 +16529,11 @@ function applyLinkByKey(key, val) {
|
|
|
16327
16529
|
hrefAnchors.forEach((el) => applyLinkHref(el, val));
|
|
16328
16530
|
}
|
|
16329
16531
|
}
|
|
16532
|
+
function isInsideLinkEditor(target) {
|
|
16533
|
+
return Boolean(
|
|
16534
|
+
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"]')
|
|
16535
|
+
);
|
|
16536
|
+
}
|
|
16330
16537
|
function isInsideFloatingPanel(target) {
|
|
16331
16538
|
return Boolean(target.closest("[data-ohw-floating-panel]"));
|
|
16332
16539
|
}
|
|
@@ -16334,11 +16541,6 @@ function isPointOverFloatingPanel(clientX, clientY) {
|
|
|
16334
16541
|
const el = document.elementFromPoint(clientX, clientY);
|
|
16335
16542
|
return Boolean(el instanceof Element && el.closest("[data-ohw-floating-panel]"));
|
|
16336
16543
|
}
|
|
16337
|
-
function isInsideLinkEditor(target) {
|
|
16338
|
-
return Boolean(
|
|
16339
|
-
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"]')
|
|
16340
|
-
);
|
|
16341
|
-
}
|
|
16342
16544
|
function getHrefKeyFromElement(el) {
|
|
16343
16545
|
if (!el) return null;
|
|
16344
16546
|
const anchor = el.closest("[data-ohw-href-key]");
|
|
@@ -16607,7 +16809,7 @@ function getNavigationSelectionParent(el) {
|
|
|
16607
16809
|
if (!isFooterLinksContainer(el) && (el.hasAttribute("data-ohw-footer-col") || el.hasAttribute("data-ohw-footer-column") || isInferredFooterGroup2(el))) {
|
|
16608
16810
|
return getFooterLinksContainer();
|
|
16609
16811
|
}
|
|
16610
|
-
if (el.hasAttribute("data-ohw-nav-container") || el.hasAttribute("data-ohw-nav-drawer") || isFooterLinksContainer(el)) {
|
|
16812
|
+
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)) {
|
|
16611
16813
|
return getNavigationRoot(el);
|
|
16612
16814
|
}
|
|
16613
16815
|
return null;
|
|
@@ -16823,7 +17025,6 @@ var ICONS = {
|
|
|
16823
17025
|
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"/>',
|
|
16824
17026
|
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"/>'
|
|
16825
17027
|
};
|
|
16826
|
-
var HEIGHT_SETTLE_DELAYS = [150, 400, 800];
|
|
16827
17028
|
var SELECTION_CHROME_GAP2 = 4;
|
|
16828
17029
|
var TOOLBAR_STROKE_GAP2 = 4;
|
|
16829
17030
|
var TOOLBAR_OFFSET_FROM_ELEMENT = SELECTION_CHROME_GAP2 + TOOLBAR_STROKE_GAP2;
|
|
@@ -17207,6 +17408,7 @@ function StateToggle({
|
|
|
17207
17408
|
);
|
|
17208
17409
|
}
|
|
17209
17410
|
var contentCache = /* @__PURE__ */ new Map();
|
|
17411
|
+
var fetchedContentPaths = /* @__PURE__ */ new Set();
|
|
17210
17412
|
var brandingCache = /* @__PURE__ */ new Map();
|
|
17211
17413
|
var OHW_LOADER_STYLE = {
|
|
17212
17414
|
position: "fixed",
|
|
@@ -17755,13 +17957,6 @@ function OhhwellsBridge() {
|
|
|
17755
17957
|
const [isItemDragging, setIsItemDragging] = (0, import_react17.useState)(false);
|
|
17756
17958
|
const [isFooterFrameSelection, setIsFooterFrameSelection] = (0, import_react17.useState)(false);
|
|
17757
17959
|
isFooterFrameSelectionRef.current = isFooterFrameSelection;
|
|
17758
|
-
const [floatingPanel, setFloatingPanel] = (0, import_react17.useState)(null);
|
|
17759
|
-
const floatingPanelOpenRef = (0, import_react17.useRef)(false);
|
|
17760
|
-
floatingPanelOpenRef.current = floatingPanel !== null;
|
|
17761
|
-
const [floatingPanelPos, setFloatingPanelPos] = (0, import_react17.useState)(null);
|
|
17762
|
-
const [logoSizeDraft, setLogoSizeDraft] = (0, import_react17.useState)(null);
|
|
17763
|
-
const [editorViewport, setEditorViewport] = (0, import_react17.useState)("desktop");
|
|
17764
|
-
const [parentScrollSnap, setParentScrollSnap] = (0, import_react17.useState)(null);
|
|
17765
17960
|
const [navDropdownPreviewOpen, setNavDropdownPreviewOpen] = (0, import_react17.useState)(null);
|
|
17766
17961
|
const [footerHeadingVisible, setFooterHeadingVisible] = (0, import_react17.useState)(null);
|
|
17767
17962
|
const footerDragRef = (0, import_react17.useRef)(null);
|
|
@@ -17778,7 +17973,15 @@ function OhhwellsBridge() {
|
|
|
17778
17973
|
const aiSectionsRef = (0, import_react17.useRef)("");
|
|
17779
17974
|
const brandKitRef = (0, import_react17.useRef)("");
|
|
17780
17975
|
const stylesRef = (0, import_react17.useRef)("");
|
|
17976
|
+
const appliedDrawerRef = (0, import_react17.useRef)(null);
|
|
17781
17977
|
const pendingDeleteUndoRef = (0, import_react17.useRef)(null);
|
|
17978
|
+
const [floatingPanel, setFloatingPanel] = (0, import_react17.useState)(null);
|
|
17979
|
+
const floatingPanelOpenRef = (0, import_react17.useRef)(false);
|
|
17980
|
+
const setFloatingPanelRef = (0, import_react17.useRef)(setFloatingPanel);
|
|
17981
|
+
const [floatingPanelPos, setFloatingPanelPos] = (0, import_react17.useState)(null);
|
|
17982
|
+
const [logoSizeDraft, setLogoSizeDraft] = (0, import_react17.useState)(null);
|
|
17983
|
+
const [editorViewport, setEditorViewport] = (0, import_react17.useState)("desktop");
|
|
17984
|
+
const [parentScrollSnap, setParentScrollSnap] = (0, import_react17.useState)(null);
|
|
17782
17985
|
const [sitePages, setSitePages] = (0, import_react17.useState)([]);
|
|
17783
17986
|
const [sectionsByPath, setSectionsByPath] = (0, import_react17.useState)({});
|
|
17784
17987
|
const sectionsPrefetchGenRef = (0, import_react17.useRef)(0);
|
|
@@ -17787,7 +17990,18 @@ function OhhwellsBridge() {
|
|
|
17787
17990
|
const linkPopoverOpenRef = (0, import_react17.useRef)(false);
|
|
17788
17991
|
const linkPopoverGraceUntilRef = (0, import_react17.useRef)(0);
|
|
17789
17992
|
setLinkPopoverRef.current = setLinkPopover;
|
|
17993
|
+
setFloatingPanelRef.current = setFloatingPanel;
|
|
17790
17994
|
linkPopoverSessionRef.current = linkPopover;
|
|
17995
|
+
floatingPanelOpenRef.current = Boolean(floatingPanel);
|
|
17996
|
+
(0, import_react17.useEffect)(() => {
|
|
17997
|
+
const syncViewport = () => {
|
|
17998
|
+
const next = window.innerWidth <= 480 ? "mobile" : "desktop";
|
|
17999
|
+
setEditorViewport((prev) => prev === next ? prev : next);
|
|
18000
|
+
};
|
|
18001
|
+
syncViewport();
|
|
18002
|
+
window.addEventListener("resize", syncViewport);
|
|
18003
|
+
return () => window.removeEventListener("resize", syncViewport);
|
|
18004
|
+
}, []);
|
|
17791
18005
|
const {
|
|
17792
18006
|
navDragRef,
|
|
17793
18007
|
navPointerDragRef,
|
|
@@ -19123,6 +19337,7 @@ function OhhwellsBridge() {
|
|
|
19123
19337
|
}
|
|
19124
19338
|
if (typeof content[STYLE_STORE_KEY] === "string") {
|
|
19125
19339
|
stylesRef.current = content[STYLE_STORE_KEY];
|
|
19340
|
+
document.querySelectorAll('[data-ohw-editable="form"]').forEach((f) => markFormFields(f));
|
|
19126
19341
|
applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
|
|
19127
19342
|
}
|
|
19128
19343
|
applyBrandChrome(content);
|
|
@@ -19130,11 +19345,11 @@ function OhhwellsBridge() {
|
|
|
19130
19345
|
for (const [key, val] of Object.entries(content)) {
|
|
19131
19346
|
if (key === "__ohw_sections") continue;
|
|
19132
19347
|
if (key === AI_SECTIONS_KEY) continue;
|
|
19348
|
+
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
19349
|
+
if (LOGO_IMAGE_KEYS.includes(key)) continue;
|
|
19133
19350
|
if (key === BRAND_KIT_KEY) continue;
|
|
19134
19351
|
if (key === STYLE_STORE_KEY) continue;
|
|
19135
19352
|
if (BRAND_CHROME_KEYS.has(key)) continue;
|
|
19136
|
-
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
19137
|
-
if (LOGO_IMAGE_KEYS.includes(key)) continue;
|
|
19138
19353
|
if (applyVideoSettingNode(key, val)) continue;
|
|
19139
19354
|
if (applyCarouselNode(key, val)) continue;
|
|
19140
19355
|
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
@@ -19205,7 +19420,9 @@ function OhhwellsBridge() {
|
|
|
19205
19420
|
let cancelled = false;
|
|
19206
19421
|
setFetchState("loading");
|
|
19207
19422
|
const apiUrl = process.env.NEXT_PUBLIC_FLOWOPS_API_URL ?? "https://flowops-backend-staging-2yfdh7pwpq-as.a.run.app";
|
|
19208
|
-
|
|
19423
|
+
const initialPath = pathname;
|
|
19424
|
+
fetchedContentPaths.add(`${subdomain}::${initialPath}`);
|
|
19425
|
+
fetch(`${apiUrl}/api/public/sites/${subdomain}/content?path=${encodeURIComponent(initialPath)}`, { cache: "no-store" }).then((r2) => r2.ok ? r2.json() : null).then((data) => {
|
|
19209
19426
|
if (cancelled) return;
|
|
19210
19427
|
const content = data?.content ?? {};
|
|
19211
19428
|
const branding = Boolean(data?.showBranding);
|
|
@@ -19314,7 +19531,9 @@ function OhhwellsBridge() {
|
|
|
19314
19531
|
}, [isEditMode]);
|
|
19315
19532
|
(0, import_react17.useEffect)(() => {
|
|
19316
19533
|
if (isEditMode || fetchState !== "done") return;
|
|
19534
|
+
console.log("env", process.env.NEXT_PUBLIC_FLOWOPS_API_URL);
|
|
19317
19535
|
const apiUrl = process.env.NEXT_PUBLIC_FLOWOPS_API_URL ?? "https://flowops-backend-staging-2yfdh7pwpq-as.a.run.app";
|
|
19536
|
+
console.log({ apiUrl, subdomain });
|
|
19318
19537
|
bindPublishedForms(apiUrl, subdomain, contentCache.get(subdomain) ?? {});
|
|
19319
19538
|
}, [isEditMode, fetchState, subdomain]);
|
|
19320
19539
|
(0, import_react17.useEffect)(() => {
|
|
@@ -19339,16 +19558,17 @@ function OhhwellsBridge() {
|
|
|
19339
19558
|
applyAiSectionsToDom(parseAiSectionsState(content[AI_SECTIONS_KEY]));
|
|
19340
19559
|
}
|
|
19341
19560
|
if (typeof content[STYLE_STORE_KEY] === "string") {
|
|
19561
|
+
document.querySelectorAll('[data-ohw-editable="form"]').forEach((f) => markFormFields(f));
|
|
19342
19562
|
applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
|
|
19343
19563
|
}
|
|
19344
19564
|
for (const [key, val] of Object.entries(content)) {
|
|
19345
19565
|
if (key === "__ohw_sections") continue;
|
|
19346
19566
|
if (key === AI_SECTIONS_KEY) continue;
|
|
19567
|
+
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
19568
|
+
if (LOGO_IMAGE_KEYS.includes(key)) continue;
|
|
19347
19569
|
if (key === BRAND_KIT_KEY) continue;
|
|
19348
19570
|
if (key === STYLE_STORE_KEY) continue;
|
|
19349
19571
|
if (BRAND_CHROME_KEYS.has(key)) continue;
|
|
19350
|
-
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
19351
|
-
if (LOGO_IMAGE_KEYS.includes(key)) continue;
|
|
19352
19572
|
if (applyVideoSettingNode(key, val)) continue;
|
|
19353
19573
|
if (applyCarouselNode(key, val)) continue;
|
|
19354
19574
|
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
@@ -19399,6 +19619,17 @@ function OhhwellsBridge() {
|
|
|
19399
19619
|
debounceTimer = setTimeout(applyFromCache, 150);
|
|
19400
19620
|
};
|
|
19401
19621
|
applyFromCache();
|
|
19622
|
+
const pathCacheKey = `${subdomain}::${pathname}`;
|
|
19623
|
+
if (!fetchedContentPaths.has(pathCacheKey)) {
|
|
19624
|
+
fetchedContentPaths.add(pathCacheKey);
|
|
19625
|
+
const apiUrl = process.env.NEXT_PUBLIC_FLOWOPS_API_URL ?? "https://flowops-backend-staging-2yfdh7pwpq-as.a.run.app";
|
|
19626
|
+
fetch(`${apiUrl}/api/public/sites/${subdomain}/content?path=${encodeURIComponent(pathname)}`, { cache: "no-store" }).then((r2) => r2.ok ? r2.json() : null).then((data) => {
|
|
19627
|
+
if (!data?.content) return;
|
|
19628
|
+
contentCache.set(subdomain, data.content);
|
|
19629
|
+
applyFromCache();
|
|
19630
|
+
}).catch(() => {
|
|
19631
|
+
});
|
|
19632
|
+
}
|
|
19402
19633
|
observer = new MutationObserver(scheduleApply);
|
|
19403
19634
|
observer.observe(document.body, { childList: true, subtree: true });
|
|
19404
19635
|
return () => {
|
|
@@ -19443,6 +19674,17 @@ function OhhwellsBridge() {
|
|
|
19443
19674
|
if (!isEditMode) return;
|
|
19444
19675
|
initSectionInstancesFromContent(editContentRef.current, pathname);
|
|
19445
19676
|
}, [pathname, isEditMode]);
|
|
19677
|
+
(0, import_react17.useEffect)(() => {
|
|
19678
|
+
if (!isEditMode) return;
|
|
19679
|
+
const observer = new MutationObserver(() => {
|
|
19680
|
+
const drawer = document.querySelector("[data-ohw-nav-drawer]");
|
|
19681
|
+
if (!drawer || drawer === appliedDrawerRef.current) return;
|
|
19682
|
+
appliedDrawerRef.current = drawer;
|
|
19683
|
+
applyStylesToDom(parseStyleStore(stylesRef.current));
|
|
19684
|
+
});
|
|
19685
|
+
observer.observe(document.body, { childList: true, subtree: true });
|
|
19686
|
+
return () => observer.disconnect();
|
|
19687
|
+
}, [isEditMode, pathname]);
|
|
19446
19688
|
(0, import_react17.useEffect)(() => {
|
|
19447
19689
|
const contentForNav = () => {
|
|
19448
19690
|
if (isEditMode) return editContentRef.current;
|
|
@@ -19534,26 +19776,11 @@ function OhhwellsBridge() {
|
|
|
19534
19776
|
const t2 = setTimeout(measure, 500);
|
|
19535
19777
|
const ro = new ResizeObserver(schedule);
|
|
19536
19778
|
ro.observe(document.body);
|
|
19537
|
-
let lastWidth = window.innerWidth;
|
|
19538
|
-
let resizeTimers = [];
|
|
19539
|
-
const clearResizeTimers = () => {
|
|
19540
|
-
resizeTimers.forEach(clearTimeout);
|
|
19541
|
-
resizeTimers = [];
|
|
19542
|
-
};
|
|
19543
|
-
const handleResize = () => {
|
|
19544
|
-
if (window.innerWidth === lastWidth) return;
|
|
19545
|
-
lastWidth = window.innerWidth;
|
|
19546
|
-
clearResizeTimers();
|
|
19547
|
-
resizeTimers = HEIGHT_SETTLE_DELAYS.map((delay) => setTimeout(measure, delay));
|
|
19548
|
-
};
|
|
19549
|
-
window.addEventListener("resize", handleResize);
|
|
19550
19779
|
return () => {
|
|
19551
19780
|
clearTimeout(t1);
|
|
19552
19781
|
clearTimeout(t2);
|
|
19553
19782
|
if (raf != null) cancelAnimationFrame(raf);
|
|
19554
19783
|
ro.disconnect();
|
|
19555
|
-
clearResizeTimers();
|
|
19556
|
-
window.removeEventListener("resize", handleResize);
|
|
19557
19784
|
};
|
|
19558
19785
|
}, [pathname, isEditMode, postToParent2]);
|
|
19559
19786
|
(0, import_react17.useEffect)(() => {
|
|
@@ -19663,8 +19890,10 @@ function OhhwellsBridge() {
|
|
|
19663
19890
|
crushed its fields together (OHH-490). Not media (image/bg-image/video/icon/map)
|
|
19664
19891
|
either: those can be their own flex containers centering fallback content (a
|
|
19665
19892
|
placeholder label, a mascot emoji) \u2014 forcing block broke that centering while the
|
|
19666
|
-
image was unset (OHH-758-ish).
|
|
19667
|
-
|
|
19893
|
+
image was unset (OHH-758-ish). Not inside a container that declares its editables
|
|
19894
|
+
inline (data-ohw-inline-editables): a row of inline links \u2014 a footer's legal line \u2014
|
|
19895
|
+
keeps its line; blockified labels put each link on its own row in the editor only. */
|
|
19896
|
+
[data-ohw-editable]:not([data-ohw-editable="form"]):not([data-ohw-editable="image"]):not([data-ohw-editable="bg-image"]):not([data-ohw-editable="video"]):not([data-ohw-editable="icon"]):not([data-ohw-editable="map"]):not([data-ohw-inline-editables] *) {
|
|
19668
19897
|
display: block;
|
|
19669
19898
|
}
|
|
19670
19899
|
/* The block-force above is an author rule, so it beats the browser's own
|
|
@@ -19734,7 +19963,10 @@ function OhhwellsBridge() {
|
|
|
19734
19963
|
flex-wrap: wrap !important;
|
|
19735
19964
|
align-items: flex-end !important;
|
|
19736
19965
|
}
|
|
19737
|
-
|
|
19966
|
+
/* Generated forms are excluded: they are always a single column, so the 12rem
|
|
19967
|
+
flex BASIS \u2014 a minimum width in a horizontal row \u2014 reads as a 12rem HEIGHT
|
|
19968
|
+
there and inflates every field to the tallest one's size. */
|
|
19969
|
+
[data-ohw-editable="form"]:not([data-ai-form]) [data-ohw-form-field] {
|
|
19738
19970
|
flex: 1 1 12rem !important;
|
|
19739
19971
|
min-width: min(12rem, 100%) !important;
|
|
19740
19972
|
max-width: 100% !important;
|
|
@@ -19843,9 +20075,6 @@ function OhhwellsBridge() {
|
|
|
19843
20075
|
if (target.closest("[data-ohw-state-toggle]")) return;
|
|
19844
20076
|
if (target.closest("[data-ohw-max-badge]")) return;
|
|
19845
20077
|
if (isInsideLinkEditor(target)) return;
|
|
19846
|
-
if (selectedMediaElRef.current && !selectedMediaElRef.current.contains(target) && !target.closest("[data-ohw-media-overlay], [data-ohw-edit-chrome], [data-ohw-item-interaction]")) {
|
|
19847
|
-
clearMediaSelectionRef.current();
|
|
19848
|
-
}
|
|
19849
20078
|
if (isInsideFloatingPanel(target)) return;
|
|
19850
20079
|
if (target.closest("[data-ohw-form-toolbar]")) return;
|
|
19851
20080
|
if (target.closest(
|
|
@@ -19853,6 +20082,9 @@ function OhhwellsBridge() {
|
|
|
19853
20082
|
)) {
|
|
19854
20083
|
return;
|
|
19855
20084
|
}
|
|
20085
|
+
if (selectedMediaElRef.current && !selectedMediaElRef.current.contains(target) && !target.closest("[data-ohw-media-overlay], [data-ohw-edit-chrome], [data-ohw-item-interaction]")) {
|
|
20086
|
+
clearMediaSelectionRef.current();
|
|
20087
|
+
}
|
|
19856
20088
|
{
|
|
19857
20089
|
const formEl = getFormElement(target);
|
|
19858
20090
|
const onSuccessText = target.closest(`[${SUCCESS_TEXT_ATTR}]`);
|
|
@@ -20016,14 +20248,6 @@ function OhhwellsBridge() {
|
|
|
20016
20248
|
}
|
|
20017
20249
|
const clickedButton = findClosestButtonLike(target);
|
|
20018
20250
|
const buttonOnMedia = Boolean(clickedButton && isMediaEditable(editable) && editable.contains(clickedButton));
|
|
20019
|
-
console.log("[click-debug]", {
|
|
20020
|
-
editableType: editable.dataset.ohwEditable,
|
|
20021
|
-
editableTag: editable.tagName,
|
|
20022
|
-
targetTag: target.tagName,
|
|
20023
|
-
clickedButtonTag: clickedButton?.tagName ?? null,
|
|
20024
|
-
buttonOnMedia,
|
|
20025
|
-
isMediaEditableEditable: isMediaEditable(editable)
|
|
20026
|
-
});
|
|
20027
20251
|
if (isMediaEditable(editable) && !buttonOnMedia) {
|
|
20028
20252
|
e.preventDefault();
|
|
20029
20253
|
e.stopPropagation();
|
|
@@ -20050,11 +20274,6 @@ function OhhwellsBridge() {
|
|
|
20050
20274
|
const hrefLookupTarget = buttonOnMedia ? clickedButton : editable;
|
|
20051
20275
|
const hrefCtx = getHrefKeyFromElement(hrefLookupTarget);
|
|
20052
20276
|
const navAnchor = hrefCtx ? getNavigationItemAnchor(hrefCtx.anchor) : null;
|
|
20053
|
-
console.log("[click-debug 2]", {
|
|
20054
|
-
hrefLookupTargetTag: hrefLookupTarget.tagName,
|
|
20055
|
-
hrefCtx: hrefCtx ? { key: hrefCtx.key } : null,
|
|
20056
|
-
navAnchorTag: navAnchor?.tagName ?? null
|
|
20057
|
-
});
|
|
20058
20277
|
if (navAnchor) {
|
|
20059
20278
|
e.preventDefault();
|
|
20060
20279
|
e.stopPropagation();
|
|
@@ -20224,6 +20443,9 @@ function OhhwellsBridge() {
|
|
|
20224
20443
|
setHoveredItemRect(null);
|
|
20225
20444
|
hoveredNavContainerRef.current = null;
|
|
20226
20445
|
setHoveredNavContainerRect(null);
|
|
20446
|
+
siblingHintElRef.current = null;
|
|
20447
|
+
setSiblingHintRect(null);
|
|
20448
|
+
setSiblingHintRects([]);
|
|
20227
20449
|
return;
|
|
20228
20450
|
}
|
|
20229
20451
|
{
|
|
@@ -20344,7 +20566,6 @@ function OhhwellsBridge() {
|
|
|
20344
20566
|
hoveredNavContainerRef.current = null;
|
|
20345
20567
|
setHoveredNavContainerRect(null);
|
|
20346
20568
|
hoveredItemElRef.current = editable;
|
|
20347
|
-
setHoveredItemRect(isSelectedForHoverRef.current(editable) ? null : editable.getBoundingClientRect());
|
|
20348
20569
|
}
|
|
20349
20570
|
}
|
|
20350
20571
|
}
|
|
@@ -20641,7 +20862,7 @@ function OhhwellsBridge() {
|
|
|
20641
20862
|
}
|
|
20642
20863
|
};
|
|
20643
20864
|
const probeImageAt = (clientX, clientY, isDragOver = false, fromParentViewport = false) => {
|
|
20644
|
-
if (linkPopoverOpenRef.current) {
|
|
20865
|
+
if (linkPopoverOpenRef.current || floatingPanelOpenRef.current && isPointOverFloatingPanel(clientX, clientY)) {
|
|
20645
20866
|
if (hoveredImageRef.current) {
|
|
20646
20867
|
hoveredImageRef.current = null;
|
|
20647
20868
|
hoveredImageHasTextOverlapRef.current = false;
|
|
@@ -21014,8 +21235,7 @@ function OhhwellsBridge() {
|
|
|
21014
21235
|
};
|
|
21015
21236
|
const handleMouseMove = (e) => {
|
|
21016
21237
|
const { clientX, clientY } = e;
|
|
21017
|
-
if (
|
|
21018
|
-
if (isOverEditorChrome(clientX, clientY)) {
|
|
21238
|
+
if (document.documentElement.hasAttribute("data-ohw-panel-dragging") || floatingPanelOpenRef.current && isPointOverFloatingPanel(clientX, clientY) || isOverEditorChrome(clientX, clientY)) {
|
|
21019
21239
|
document.querySelectorAll("[data-ohw-hovered]").forEach((el) => el.removeAttribute("data-ohw-hovered"));
|
|
21020
21240
|
formHoverElRef.current = null;
|
|
21021
21241
|
setFormHoverRect(null);
|
|
@@ -21023,7 +21243,12 @@ function OhhwellsBridge() {
|
|
|
21023
21243
|
setHoveredItemRect(null);
|
|
21024
21244
|
hoveredNavContainerRef.current = null;
|
|
21025
21245
|
setHoveredNavContainerRect(null);
|
|
21246
|
+
siblingHintElRef.current = null;
|
|
21247
|
+
setSiblingHintRect(null);
|
|
21248
|
+
setSiblingHintRects([]);
|
|
21026
21249
|
dismissImageHover();
|
|
21250
|
+
clearImageHover();
|
|
21251
|
+
setSectionGap(null);
|
|
21027
21252
|
return;
|
|
21028
21253
|
}
|
|
21029
21254
|
if (probeSocialsRowAt(clientX, clientY)) return;
|
|
@@ -21035,7 +21260,11 @@ function OhhwellsBridge() {
|
|
|
21035
21260
|
if (e.data?.type !== "ow:pointer-sync") return;
|
|
21036
21261
|
const { clientX, clientY } = e.data;
|
|
21037
21262
|
if (typeof clientX !== "number" || typeof clientY !== "number") return;
|
|
21038
|
-
if (
|
|
21263
|
+
if (document.documentElement.hasAttribute("data-ohw-panel-dragging") || floatingPanelOpenRef.current && isPointOverFloatingPanel(clientX, clientY)) {
|
|
21264
|
+
dismissImageHover();
|
|
21265
|
+
clearImageHover();
|
|
21266
|
+
return;
|
|
21267
|
+
}
|
|
21039
21268
|
if (probeSocialsRowAt(clientX, clientY)) return;
|
|
21040
21269
|
probeSectionGapAt(clientX, clientY);
|
|
21041
21270
|
probeImageAt(clientX, clientY);
|
|
@@ -21374,6 +21603,7 @@ function OhhwellsBridge() {
|
|
|
21374
21603
|
}
|
|
21375
21604
|
if (typeof content[STYLE_STORE_KEY] === "string") {
|
|
21376
21605
|
stylesRef.current = content[STYLE_STORE_KEY];
|
|
21606
|
+
document.querySelectorAll('[data-ohw-editable="form"]').forEach((f) => markFormFields(f));
|
|
21377
21607
|
applyStylesToDom(parseStyleStore(content[STYLE_STORE_KEY]));
|
|
21378
21608
|
}
|
|
21379
21609
|
applyBrandChrome(content);
|
|
@@ -21385,11 +21615,11 @@ function OhhwellsBridge() {
|
|
|
21385
21615
|
continue;
|
|
21386
21616
|
}
|
|
21387
21617
|
if (key === AI_SECTIONS_KEY) continue;
|
|
21618
|
+
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
21619
|
+
if (LOGO_IMAGE_KEYS.includes(key) && !String(val ?? "").trim()) continue;
|
|
21388
21620
|
if (key === BRAND_KIT_KEY) continue;
|
|
21389
21621
|
if (key === STYLE_STORE_KEY) continue;
|
|
21390
21622
|
if (BRAND_CHROME_KEYS.has(key)) continue;
|
|
21391
|
-
if (key === LOGO_PLACEHOLDER_KEY) continue;
|
|
21392
|
-
if (LOGO_IMAGE_KEYS.includes(key) && !String(val ?? "").trim()) continue;
|
|
21393
21623
|
if (applyVideoSettingNode(key, val)) continue;
|
|
21394
21624
|
if (applyCarouselNode(key, val)) continue;
|
|
21395
21625
|
document.querySelectorAll(`[data-ohw-key="${key}"]`).forEach((el) => {
|
|
@@ -21407,6 +21637,7 @@ function OhhwellsBridge() {
|
|
|
21407
21637
|
applyMapQuery(el, val);
|
|
21408
21638
|
} else if (el.dataset.ohwEditable === "icon") {
|
|
21409
21639
|
applyIconMarkup(el, val);
|
|
21640
|
+
} else if (el.dataset.ohwEditable === "form") {
|
|
21410
21641
|
} else if (isIconMarkupValue(val)) {
|
|
21411
21642
|
} else {
|
|
21412
21643
|
el.innerHTML = val;
|
|
@@ -21416,6 +21647,9 @@ function OhhwellsBridge() {
|
|
|
21416
21647
|
}
|
|
21417
21648
|
applyLogoFromContent(content);
|
|
21418
21649
|
applyLogoSizes(content);
|
|
21650
|
+
document.querySelectorAll('[data-ohw-editable="form"]').forEach((form) => {
|
|
21651
|
+
reconcileFieldsFromContent(form, content);
|
|
21652
|
+
});
|
|
21419
21653
|
if (sectionsJson) {
|
|
21420
21654
|
initSectionsFromContent({ __ohw_sections: sectionsJson }, true);
|
|
21421
21655
|
sectionsLoadedRef.current = true;
|
|
@@ -21610,10 +21844,26 @@ function OhhwellsBridge() {
|
|
|
21610
21844
|
const handleGetBrand = (e) => {
|
|
21611
21845
|
if (e.data?.type !== "ow:get-brand") return;
|
|
21612
21846
|
const template = deriveTemplateBrand();
|
|
21613
|
-
const
|
|
21847
|
+
const fallback = template ?? (() => {
|
|
21848
|
+
const fonts = deriveTemplateFonts();
|
|
21849
|
+
return fonts ? { palette: AI_DEFAULT_BRAND.palette, fonts } : null;
|
|
21850
|
+
})();
|
|
21851
|
+
const value = brandKitRef.current || (fallback ? JSON.stringify(fallback) : "");
|
|
21614
21852
|
postToParentRef.current({ type: "ow:brand-value", value });
|
|
21615
21853
|
};
|
|
21616
21854
|
window.addEventListener("message", handleGetBrand);
|
|
21855
|
+
const handleGetTemplateFonts = (e) => {
|
|
21856
|
+
if (e.data?.type !== "ow:get-template-fonts") return;
|
|
21857
|
+
const fonts = deriveTemplateFonts();
|
|
21858
|
+
postToParentRef.current({ type: "ow:template-fonts-value", value: fonts ? JSON.stringify(fonts) : "" });
|
|
21859
|
+
};
|
|
21860
|
+
window.addEventListener("message", handleGetTemplateFonts);
|
|
21861
|
+
const handleGetTemplateBrand = (e) => {
|
|
21862
|
+
if (e.data?.type !== "ow:get-template-brand") return;
|
|
21863
|
+
const brand = deriveTemplateBrand();
|
|
21864
|
+
postToParentRef.current({ type: "ow:template-brand-value", value: brand ? JSON.stringify(brand) : "" });
|
|
21865
|
+
};
|
|
21866
|
+
window.addEventListener("message", handleGetTemplateBrand);
|
|
21617
21867
|
const handleMoveSection = (e) => {
|
|
21618
21868
|
if (e.data?.type !== "ow:move-section") return;
|
|
21619
21869
|
const instanceId = typeof e.data.instanceId === "string" ? e.data.instanceId : "";
|
|
@@ -21806,6 +22056,12 @@ function OhhwellsBridge() {
|
|
|
21806
22056
|
closeLinkPopoverRef.current();
|
|
21807
22057
|
return;
|
|
21808
22058
|
}
|
|
22059
|
+
if (floatingPanelOpenRef.current) {
|
|
22060
|
+
setFloatingPanelRef.current(null);
|
|
22061
|
+
deselectRef.current();
|
|
22062
|
+
deactivateRef.current();
|
|
22063
|
+
return;
|
|
22064
|
+
}
|
|
21809
22065
|
deselectRef.current();
|
|
21810
22066
|
deactivateRef.current();
|
|
21811
22067
|
clearMediaSelectionRef.current();
|
|
@@ -22094,8 +22350,12 @@ function OhhwellsBridge() {
|
|
|
22094
22350
|
if (inserted) {
|
|
22095
22351
|
const tracker = getSectionsTracker();
|
|
22096
22352
|
postToParentRef.current({ type: "ow:change", nodes: [{ key: "__ohw_sections", text: tracker.textContent ?? "[]" }] });
|
|
22097
|
-
const
|
|
22098
|
-
|
|
22353
|
+
const reportHeight = () => {
|
|
22354
|
+
const h = document.body.scrollHeight;
|
|
22355
|
+
if (h > 50) postToParentRef.current({ type: "ow:height", height: h });
|
|
22356
|
+
};
|
|
22357
|
+
reportHeight();
|
|
22358
|
+
setTimeout(reportHeight, 500);
|
|
22099
22359
|
}
|
|
22100
22360
|
};
|
|
22101
22361
|
const handleSwitchSchedule = (e) => {
|
|
@@ -22516,15 +22776,17 @@ function OhhwellsBridge() {
|
|
|
22516
22776
|
window.removeEventListener("message", handleAiSetBrand);
|
|
22517
22777
|
window.removeEventListener("message", handleAiSetStyles);
|
|
22518
22778
|
window.removeEventListener("message", handleGetBrand);
|
|
22779
|
+
window.removeEventListener("message", handleGetTemplateFonts);
|
|
22780
|
+
window.removeEventListener("message", handleGetTemplateBrand);
|
|
22519
22781
|
window.removeEventListener("message", handleMoveSection);
|
|
22520
22782
|
window.removeEventListener("message", handlePanelDragging);
|
|
22521
22783
|
window.removeEventListener("message", handleDeleteSection);
|
|
22522
22784
|
window.removeEventListener("message", handleDuplicateSection);
|
|
22523
22785
|
window.removeEventListener("message", handleDeactivate);
|
|
22524
|
-
document.documentElement.removeAttribute("data-ohw-panel-dragging");
|
|
22525
22786
|
window.removeEventListener("message", handleToastAction);
|
|
22526
22787
|
window.removeEventListener("message", handleFormCount);
|
|
22527
22788
|
window.removeEventListener("message", handleUiEscape);
|
|
22789
|
+
document.documentElement.removeAttribute("data-ohw-panel-dragging");
|
|
22528
22790
|
autoSaveTimers.current.forEach(clearTimeout);
|
|
22529
22791
|
autoSaveTimers.current.clear();
|
|
22530
22792
|
if (imageUnhoverTimerRef.current) clearTimeout(imageUnhoverTimerRef.current);
|
|
@@ -22727,7 +22989,7 @@ function OhhwellsBridge() {
|
|
|
22727
22989
|
postToParent2({
|
|
22728
22990
|
type: "ow:ready",
|
|
22729
22991
|
version: "1",
|
|
22730
|
-
bridgeVersion: "0.1.
|
|
22992
|
+
bridgeVersion: "0.1.112",
|
|
22731
22993
|
path: pathname,
|
|
22732
22994
|
nodes: collectEditableNodes(editContentRef.current),
|
|
22733
22995
|
sections
|
|
@@ -23343,7 +23605,7 @@ function OhhwellsBridge() {
|
|
|
23343
23605
|
"span",
|
|
23344
23606
|
{
|
|
23345
23607
|
"data-ohw-form-count": "",
|
|
23346
|
-
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",
|
|
23608
|
+
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",
|
|
23347
23609
|
children: formPickCount
|
|
23348
23610
|
}
|
|
23349
23611
|
)
|
|
@@ -23581,11 +23843,11 @@ function OhhwellsBridge() {
|
|
|
23581
23843
|
className: "fixed left-0 w-full z-2147483646 flex items-center pointer-events-none",
|
|
23582
23844
|
style: { top: sectionGap.y, transform: "translateY(-50%)" },
|
|
23583
23845
|
children: [
|
|
23584
|
-
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } }),
|
|
23846
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "flex-1 bg-bridge-primary", style: { height: 3 } }),
|
|
23585
23847
|
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
23586
23848
|
Badge,
|
|
23587
23849
|
{
|
|
23588
|
-
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",
|
|
23850
|
+
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",
|
|
23589
23851
|
onClick: () => {
|
|
23590
23852
|
window.parent.postMessage(
|
|
23591
23853
|
{
|
|
@@ -23599,7 +23861,7 @@ function OhhwellsBridge() {
|
|
|
23599
23861
|
children: "Add Section"
|
|
23600
23862
|
}
|
|
23601
23863
|
),
|
|
23602
|
-
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } })
|
|
23864
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "flex-1 bg-bridge-primary", style: { height: 3 } })
|
|
23603
23865
|
]
|
|
23604
23866
|
}
|
|
23605
23867
|
),
|
|
@@ -23647,6 +23909,59 @@ function OhhwellsBridge() {
|
|
|
23647
23909
|
) : null
|
|
23648
23910
|
] });
|
|
23649
23911
|
}
|
|
23912
|
+
|
|
23913
|
+
// src/ui/EmptySection.tsx
|
|
23914
|
+
var import_link = __toESM(require("next/link"), 1);
|
|
23915
|
+
var import_jsx_runtime34 = require("react/jsx-runtime");
|
|
23916
|
+
function EmptySection({ title, homeHref = "/", eyebrowKey, titleKey, subtitleKey }) {
|
|
23917
|
+
return /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(import_jsx_runtime34.Fragment, { children: [
|
|
23918
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
23919
|
+
"p",
|
|
23920
|
+
{
|
|
23921
|
+
style: {
|
|
23922
|
+
fontFamily: "var(--brand-font-body)",
|
|
23923
|
+
fontSize: "0.75rem",
|
|
23924
|
+
fontWeight: 500,
|
|
23925
|
+
letterSpacing: "0.15em",
|
|
23926
|
+
textTransform: "uppercase",
|
|
23927
|
+
color: "var(--brand-accent)",
|
|
23928
|
+
marginBottom: "1.5rem"
|
|
23929
|
+
},
|
|
23930
|
+
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" }) })
|
|
23931
|
+
}
|
|
23932
|
+
),
|
|
23933
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
23934
|
+
"h1",
|
|
23935
|
+
{
|
|
23936
|
+
style: {
|
|
23937
|
+
fontFamily: "var(--brand-font-heading)",
|
|
23938
|
+
fontSize: "clamp(2rem, 3.5vw, 2.75rem)",
|
|
23939
|
+
lineHeight: 1.1,
|
|
23940
|
+
letterSpacing: "-0.025em",
|
|
23941
|
+
color: "var(--brand-text)",
|
|
23942
|
+
marginBottom: "1rem"
|
|
23943
|
+
},
|
|
23944
|
+
...titleKey ? { "data-ohw-editable": "text", "data-ohw-key": titleKey, "data-ohw-max-length": 80 } : {},
|
|
23945
|
+
children: title
|
|
23946
|
+
}
|
|
23947
|
+
),
|
|
23948
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
23949
|
+
"p",
|
|
23950
|
+
{
|
|
23951
|
+
style: {
|
|
23952
|
+
fontFamily: "var(--brand-font-body)",
|
|
23953
|
+
fontSize: "1rem",
|
|
23954
|
+
lineHeight: 1.7,
|
|
23955
|
+
fontWeight: 300,
|
|
23956
|
+
color: "var(--brand-text-muted)",
|
|
23957
|
+
maxWidth: "340px"
|
|
23958
|
+
},
|
|
23959
|
+
...subtitleKey ? { "data-ohw-editable": "text", "data-ohw-key": subtitleKey, "data-ohw-max-length": 160 } : {},
|
|
23960
|
+
children: "This page doesn't have any content yet."
|
|
23961
|
+
}
|
|
23962
|
+
)
|
|
23963
|
+
] });
|
|
23964
|
+
}
|
|
23650
23965
|
// Annotate the CommonJS export names for ESM import in node:
|
|
23651
23966
|
0 && (module.exports = {
|
|
23652
23967
|
AI_DEFAULT_BRAND,
|
|
@@ -23664,6 +23979,7 @@ function OhhwellsBridge() {
|
|
|
23664
23979
|
DropdownMenuItem,
|
|
23665
23980
|
DropdownMenuSeparator,
|
|
23666
23981
|
DropdownMenuTrigger,
|
|
23982
|
+
EmptySection,
|
|
23667
23983
|
ItemActionToolbar,
|
|
23668
23984
|
ItemInteractionLayer,
|
|
23669
23985
|
LinkEditorPanel,
|