@ohhwells/bridge 0.1.115 → 0.1.117
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 +316 -69
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +22 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.js +316 -69
- package/dist/index.js.map +1 -1
- package/dist/styles.css +67 -65
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -352,16 +352,17 @@ var LEGACY_BRAND_VAR_NAMES = [
|
|
|
352
352
|
"text-muted",
|
|
353
353
|
"surface",
|
|
354
354
|
"border",
|
|
355
|
-
"on-primary"
|
|
356
|
-
"navbar-background"
|
|
355
|
+
"on-primary"
|
|
357
356
|
].map((role) => `--brand-${role}`);
|
|
358
357
|
var FONT_VARS = {
|
|
359
358
|
heading: ["--font-heading", "--font-display", "--brand-font-heading"],
|
|
360
359
|
body: ["--font-body", "--brand-font-body"]
|
|
361
360
|
};
|
|
362
361
|
var BRAND_FONT_LINK_ID = "ohw-brand-fonts";
|
|
363
|
-
|
|
364
|
-
|
|
362
|
+
var CUSTOM_FONT_STYLE_ID = "ohw-brand-custom-fonts";
|
|
363
|
+
var CUSTOM_FONT_FORMATS = /* @__PURE__ */ new Set(["woff2", "woff", "truetype", "opentype"]);
|
|
364
|
+
function brandColorVars(palette) {
|
|
365
|
+
const { dark, primary, accent, light } = palette;
|
|
365
366
|
const mix = (a, aPct, b) => `color-mix(in srgb, ${a} ${aPct}%, ${b})`;
|
|
366
367
|
const surface = mix(light, 95, dark);
|
|
367
368
|
const border = mix(light, 85, dark);
|
|
@@ -384,22 +385,42 @@ function brandColorVars(kit) {
|
|
|
384
385
|
"--brand-border": border,
|
|
385
386
|
// Buttons/bands painted in the primary colour assume it's dark/saturated enough to need
|
|
386
387
|
// 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
|
|
388
|
+
"--brand-on-primary": light
|
|
389
389
|
};
|
|
390
390
|
}
|
|
391
|
+
function parseCustomFontWeight(raw) {
|
|
392
|
+
if (typeof raw !== "object" || raw === null) return null;
|
|
393
|
+
const w = raw;
|
|
394
|
+
if (typeof w.weight !== "number" || !Number.isFinite(w.weight)) return null;
|
|
395
|
+
if (typeof w.url !== "string" || !w.url) return null;
|
|
396
|
+
if (typeof w.format !== "string" || !CUSTOM_FONT_FORMATS.has(w.format)) return null;
|
|
397
|
+
const weightEnd = typeof w.weightEnd === "number" && Number.isFinite(w.weightEnd) && w.weightEnd > w.weight ? w.weightEnd : void 0;
|
|
398
|
+
return { weight: w.weight, ...weightEnd !== void 0 ? { weightEnd } : {}, url: w.url, format: w.format };
|
|
399
|
+
}
|
|
400
|
+
function parseCustomFont(raw) {
|
|
401
|
+
if (typeof raw !== "object" || raw === null) return null;
|
|
402
|
+
const f = raw;
|
|
403
|
+
if (typeof f.family !== "string" || !f.family) return null;
|
|
404
|
+
if (typeof f.label !== "string" || !f.label) return null;
|
|
405
|
+
if (!Array.isArray(f.weights)) return null;
|
|
406
|
+
const weights = f.weights.map(parseCustomFontWeight).filter((w) => w !== null);
|
|
407
|
+
if (weights.length === 0) return null;
|
|
408
|
+
return { family: f.family, label: f.label, weights };
|
|
409
|
+
}
|
|
391
410
|
function parseBrandKit(raw) {
|
|
392
411
|
if (!raw) return null;
|
|
393
412
|
try {
|
|
394
413
|
const parsed = JSON.parse(raw);
|
|
395
414
|
const p = parsed?.palette;
|
|
396
415
|
const f = parsed?.fonts;
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
416
|
+
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;
|
|
417
|
+
const fonts = f && typeof f.heading === "string" && typeof f.body === "string" ? { heading: f.heading, body: f.body } : void 0;
|
|
418
|
+
const customFonts = Array.isArray(parsed?.customFonts) ? parsed.customFonts.map(parseCustomFont).filter((c) => c !== null) : void 0;
|
|
419
|
+
if (!palette && !fonts && !customFonts) return null;
|
|
400
420
|
return {
|
|
401
|
-
palette
|
|
402
|
-
fonts
|
|
421
|
+
...palette ? { palette } : {},
|
|
422
|
+
...fonts ? { fonts } : {},
|
|
423
|
+
...customFonts ? { customFonts } : {}
|
|
403
424
|
};
|
|
404
425
|
} catch {
|
|
405
426
|
return null;
|
|
@@ -409,11 +430,16 @@ function familyOf(stack) {
|
|
|
409
430
|
const first = stack.split(",")[0]?.trim() ?? "";
|
|
410
431
|
return first.replace(/^['"]|['"]$/g, "");
|
|
411
432
|
}
|
|
433
|
+
function quoteFamily(family) {
|
|
434
|
+
return `'${family.replace(/\\/g, "\\\\").replace(/'/g, "\\'")}'`;
|
|
435
|
+
}
|
|
436
|
+
var WEIGHT_SCALE = [100, 200, 300, 400, 500, 600, 700, 800, 900];
|
|
412
437
|
function loadBrandFonts(families) {
|
|
413
438
|
const unique = [...new Set(families.map((f) => f.trim()).filter(Boolean))];
|
|
414
439
|
if (unique.length === 0) return;
|
|
415
|
-
const
|
|
416
|
-
const
|
|
440
|
+
const weights = WEIGHT_SCALE.join(";");
|
|
441
|
+
const spec = unique.map((f) => `family=${f.replace(/ /g, "+")}:wght@${weights}`).join("&");
|
|
442
|
+
const href = `https://fonts.googleapis.com/css2?${spec}&display=swap`;
|
|
417
443
|
let link = document.getElementById(BRAND_FONT_LINK_ID);
|
|
418
444
|
if (!link) {
|
|
419
445
|
link = document.createElement("link");
|
|
@@ -423,18 +449,54 @@ function loadBrandFonts(families) {
|
|
|
423
449
|
}
|
|
424
450
|
if (link.href !== href) link.href = href;
|
|
425
451
|
}
|
|
452
|
+
function escapeCssString(value) {
|
|
453
|
+
return value.replace(/\\/g, "\\\\").replace(/'/g, "\\'");
|
|
454
|
+
}
|
|
455
|
+
function loadCustomFonts(fonts) {
|
|
456
|
+
const list = fonts ?? [];
|
|
457
|
+
let style = document.getElementById(CUSTOM_FONT_STYLE_ID);
|
|
458
|
+
if (list.length === 0) {
|
|
459
|
+
style?.remove();
|
|
460
|
+
return;
|
|
461
|
+
}
|
|
462
|
+
if (!style) {
|
|
463
|
+
style = document.createElement("style");
|
|
464
|
+
style.id = CUSTOM_FONT_STYLE_ID;
|
|
465
|
+
document.head.appendChild(style);
|
|
466
|
+
}
|
|
467
|
+
style.textContent = list.flatMap(
|
|
468
|
+
(font) => font.weights.map((w) => {
|
|
469
|
+
const weightDescriptor = w.weightEnd ? `${w.weight} ${w.weightEnd}` : `${w.weight}`;
|
|
470
|
+
return `@font-face { font-family: '${escapeCssString(font.family)}'; src: url('${escapeCssString(w.url)}') format('${w.format}'); font-weight: ${weightDescriptor}; font-display: swap; }`;
|
|
471
|
+
})
|
|
472
|
+
).join("\n");
|
|
473
|
+
}
|
|
426
474
|
function applyBrandToDom(kit) {
|
|
427
475
|
const root = document.documentElement;
|
|
428
476
|
if (!kit) {
|
|
429
477
|
for (const name of [...BRAND_VAR_NAMES, ...LEGACY_BRAND_VAR_NAMES]) root.style.removeProperty(name);
|
|
430
478
|
for (const name of [...FONT_VARS.heading, ...FONT_VARS.body]) root.style.removeProperty(name);
|
|
431
479
|
document.getElementById(BRAND_FONT_LINK_ID)?.remove();
|
|
480
|
+
document.getElementById(CUSTOM_FONT_STYLE_ID)?.remove();
|
|
432
481
|
return;
|
|
433
482
|
}
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
483
|
+
if (kit.palette) {
|
|
484
|
+
for (const [name, value] of Object.entries(brandColorVars(kit.palette))) root.style.setProperty(name, value);
|
|
485
|
+
}
|
|
486
|
+
if (kit.customFonts) {
|
|
487
|
+
loadCustomFonts(kit.customFonts);
|
|
488
|
+
}
|
|
489
|
+
if (kit.fonts) {
|
|
490
|
+
const heading = quoteFamily(kit.fonts.heading);
|
|
491
|
+
const body = quoteFamily(kit.fonts.body);
|
|
492
|
+
for (const name of FONT_VARS.heading) root.style.setProperty(name, heading);
|
|
493
|
+
for (const name of FONT_VARS.body) root.style.setProperty(name, body);
|
|
494
|
+
const customFamilies = new Set((kit.customFonts ?? []).map((f) => f.family));
|
|
495
|
+
const googleFamilies = [familyOf(kit.fonts.heading), familyOf(kit.fonts.body)].filter(
|
|
496
|
+
(f) => !customFamilies.has(f)
|
|
497
|
+
);
|
|
498
|
+
loadBrandFonts(googleFamilies);
|
|
499
|
+
}
|
|
438
500
|
}
|
|
439
501
|
|
|
440
502
|
// src/lib/section-styles.ts
|
|
@@ -2723,14 +2785,52 @@ function readRootVar(name) {
|
|
|
2723
2785
|
if (typeof document === "undefined") return "";
|
|
2724
2786
|
return getComputedStyle(document.documentElement).getPropertyValue(name).trim();
|
|
2725
2787
|
}
|
|
2788
|
+
function normalizeColorToHex(value) {
|
|
2789
|
+
if (!value || typeof document === "undefined") return value;
|
|
2790
|
+
const canvas = document.createElement("canvas");
|
|
2791
|
+
canvas.width = 1;
|
|
2792
|
+
canvas.height = 1;
|
|
2793
|
+
const ctx = canvas.getContext("2d");
|
|
2794
|
+
if (!ctx) return value;
|
|
2795
|
+
ctx.fillStyle = value;
|
|
2796
|
+
ctx.fillRect(0, 0, 1, 1);
|
|
2797
|
+
const [r2, g, b] = ctx.getImageData(0, 0, 1, 1).data;
|
|
2798
|
+
const toHex = (n) => n.toString(16).padStart(2, "0");
|
|
2799
|
+
return `#${toHex(r2)}${toHex(g)}${toHex(b)}`;
|
|
2800
|
+
}
|
|
2801
|
+
var GENERIC_FONT_KEYWORDS = /* @__PURE__ */ new Set([
|
|
2802
|
+
"serif",
|
|
2803
|
+
"sans-serif",
|
|
2804
|
+
"monospace",
|
|
2805
|
+
"cursive",
|
|
2806
|
+
"fantasy",
|
|
2807
|
+
"system-ui",
|
|
2808
|
+
"ui-serif",
|
|
2809
|
+
"ui-sans-serif",
|
|
2810
|
+
"ui-monospace",
|
|
2811
|
+
"ui-rounded",
|
|
2812
|
+
"math",
|
|
2813
|
+
"emoji",
|
|
2814
|
+
"fangsong"
|
|
2815
|
+
]);
|
|
2816
|
+
function primaryFontFamily(stack) {
|
|
2817
|
+
const first = stack.split(",").map((part) => part.trim().replace(/^["']|["']$/g, "")).find((part) => part && !GENERIC_FONT_KEYWORDS.has(part.toLowerCase()));
|
|
2818
|
+
return first ?? "";
|
|
2819
|
+
}
|
|
2820
|
+
function humanizeFontFamily(name) {
|
|
2821
|
+
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());
|
|
2822
|
+
}
|
|
2823
|
+
function readFontVar(name) {
|
|
2824
|
+
return humanizeFontFamily(primaryFontFamily(readRootVar(name)));
|
|
2825
|
+
}
|
|
2726
2826
|
function deriveBrandOverride() {
|
|
2727
2827
|
const dark = readRootVar("--ohw-brand-dark");
|
|
2728
2828
|
const primary = readRootVar("--ohw-brand-primary");
|
|
2729
2829
|
const light = readRootVar("--ohw-brand-light");
|
|
2730
2830
|
if (!dark || !primary || !light) return null;
|
|
2731
2831
|
const accent = readRootVar("--ohw-brand-accent");
|
|
2732
|
-
const heading =
|
|
2733
|
-
const body =
|
|
2832
|
+
const heading = readFontVar("--font-heading") || readFontVar("--font-display");
|
|
2833
|
+
const body = readFontVar("--font-body");
|
|
2734
2834
|
return {
|
|
2735
2835
|
palette: { dark, primary, accent: accent || dark, light },
|
|
2736
2836
|
fonts: {
|
|
@@ -2739,22 +2839,55 @@ function deriveBrandOverride() {
|
|
|
2739
2839
|
}
|
|
2740
2840
|
};
|
|
2741
2841
|
}
|
|
2742
|
-
function
|
|
2842
|
+
function deriveTemplateBrandLive() {
|
|
2743
2843
|
const primary = readRootVar("--brand-primary") || readRootVar("--color-primary");
|
|
2744
2844
|
const dark = readRootVar("--brand-text") || readRootVar("--color-dark");
|
|
2745
2845
|
const light = readRootVar("--brand-background") || readRootVar("--color-light");
|
|
2746
2846
|
if (!dark || !primary || !light) return null;
|
|
2747
2847
|
const accent = readRootVar("--brand-accent") || readRootVar("--color-accent");
|
|
2748
|
-
const heading =
|
|
2749
|
-
const body =
|
|
2848
|
+
const heading = readFontVar("--brand-font-heading") || readFontVar("--font-heading") || readFontVar("--font-display");
|
|
2849
|
+
const body = readFontVar("--brand-font-body") || readFontVar("--font-body");
|
|
2750
2850
|
return {
|
|
2751
|
-
palette: {
|
|
2851
|
+
palette: {
|
|
2852
|
+
dark: normalizeColorToHex(dark),
|
|
2853
|
+
primary: normalizeColorToHex(primary),
|
|
2854
|
+
accent: normalizeColorToHex(accent || dark),
|
|
2855
|
+
light: normalizeColorToHex(light)
|
|
2856
|
+
},
|
|
2752
2857
|
fonts: {
|
|
2753
2858
|
heading: heading || AI_DEFAULT_BRAND.fonts.heading,
|
|
2754
2859
|
body: body || AI_DEFAULT_BRAND.fonts.body
|
|
2755
2860
|
}
|
|
2756
2861
|
};
|
|
2757
2862
|
}
|
|
2863
|
+
function deriveTemplateFontsLive() {
|
|
2864
|
+
const heading = readFontVar("--brand-font-heading") || readFontVar("--font-heading") || readFontVar("--font-display");
|
|
2865
|
+
const body = readFontVar("--brand-font-body") || readFontVar("--font-body");
|
|
2866
|
+
if (!heading && !body) return null;
|
|
2867
|
+
return {
|
|
2868
|
+
heading: heading || AI_DEFAULT_BRAND.fonts.heading,
|
|
2869
|
+
body: body || AI_DEFAULT_BRAND.fonts.body
|
|
2870
|
+
};
|
|
2871
|
+
}
|
|
2872
|
+
var OVERRIDE_VAR_NAMES = [...BRAND_VAR_NAMES, ...LEGACY_BRAND_VAR_NAMES, ...FONT_VARS.heading, ...FONT_VARS.body];
|
|
2873
|
+
function withOverrideStripped(read) {
|
|
2874
|
+
const root = document.documentElement;
|
|
2875
|
+
const restore = OVERRIDE_VAR_NAMES.map((name) => [name, root.style.getPropertyValue(name)]);
|
|
2876
|
+
for (const name of OVERRIDE_VAR_NAMES) root.style.removeProperty(name);
|
|
2877
|
+
try {
|
|
2878
|
+
return read();
|
|
2879
|
+
} finally {
|
|
2880
|
+
for (const [name, value] of restore) if (value) root.style.setProperty(name, value);
|
|
2881
|
+
}
|
|
2882
|
+
}
|
|
2883
|
+
var TEMPLATE_BRAND_SNAPSHOT = typeof document === "undefined" ? null : withOverrideStripped(deriveTemplateBrandLive);
|
|
2884
|
+
var TEMPLATE_FONTS_SNAPSHOT = typeof document === "undefined" ? null : withOverrideStripped(deriveTemplateFontsLive);
|
|
2885
|
+
function deriveTemplateBrand() {
|
|
2886
|
+
return TEMPLATE_BRAND_SNAPSHOT;
|
|
2887
|
+
}
|
|
2888
|
+
function deriveTemplateFonts() {
|
|
2889
|
+
return TEMPLATE_FONTS_SNAPSHOT;
|
|
2890
|
+
}
|
|
2758
2891
|
function deriveTemplateButtonStyle() {
|
|
2759
2892
|
if (typeof document === "undefined") return null;
|
|
2760
2893
|
const candidates = Array.from(
|
|
@@ -7252,12 +7385,12 @@ var cva = (base, config) => (props) => {
|
|
|
7252
7385
|
var import_radix_ui2 = require("radix-ui");
|
|
7253
7386
|
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
7254
7387
|
var toggleVariants = cva(
|
|
7255
|
-
"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",
|
|
7388
|
+
"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",
|
|
7256
7389
|
{
|
|
7257
7390
|
variants: {
|
|
7258
7391
|
variant: {
|
|
7259
7392
|
default: "bg-transparent border-0",
|
|
7260
|
-
outline: "border border-input bg-transparent shadow-xs hover:bg-accent hover:text-accent-foreground"
|
|
7393
|
+
outline: "border border-input bg-transparent shadow-xs hover:bg-bridge-accent hover:text-accent-foreground"
|
|
7261
7394
|
},
|
|
7262
7395
|
size: {
|
|
7263
7396
|
default: "px-2 py-1",
|
|
@@ -7350,10 +7483,10 @@ var DragHandle = React4.forwardRef(
|
|
|
7350
7483
|
type,
|
|
7351
7484
|
"data-slot": "drag-handle",
|
|
7352
7485
|
className: cn(
|
|
7353
|
-
"inline-flex h-7 w-4 shrink-0 items-center justify-center rounded-md transition-all duration-200 max-h-
|
|
7486
|
+
"inline-flex h-7 w-4 shrink-0 items-center justify-center rounded-md transition-all duration-200 max-h-7.5",
|
|
7354
7487
|
"bg-white border border-transparent text-stone-500 shadow-md cursor-grab",
|
|
7355
7488
|
"enabled:hover:border enabled:hover:border-stone-200 enabled:hover:text-stone-950",
|
|
7356
|
-
"enabled:active:border enabled:active:border-primary enabled:active:bg-primary-50 enabled:active:text-stone-950 enabled:active:shadow enabled:active:cursor-grabbing",
|
|
7489
|
+
"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",
|
|
7357
7490
|
"disabled:cursor-not-allowed disabled:opacity-40 disabled:text-stone-950 disabled:pointer-events-none",
|
|
7358
7491
|
className
|
|
7359
7492
|
),
|
|
@@ -7375,7 +7508,7 @@ var CustomToolbar = React5.forwardRef(({ className, onMouseDown, ...props }, ref
|
|
|
7375
7508
|
"data-ohw-toolbar": "",
|
|
7376
7509
|
className: cn(
|
|
7377
7510
|
// Figma: bg background, radius 8, gap-1, p-0.5, shadow-md — no border
|
|
7378
|
-
"inline-flex h-8 items-center gap-1 rounded-
|
|
7511
|
+
"inline-flex h-8 items-center gap-1 rounded-(--radius,0.5rem) bg-background p-0.5 font-sans whitespace-nowrap shadow-md",
|
|
7379
7512
|
className
|
|
7380
7513
|
),
|
|
7381
7514
|
onMouseDown: (e) => {
|
|
@@ -7404,7 +7537,7 @@ var CustomToolbarButton = React5.forwardRef(
|
|
|
7404
7537
|
type,
|
|
7405
7538
|
className: cn(
|
|
7406
7539
|
"inline-flex size-7 shrink-0 items-center justify-center rounded-[calc(var(--radius,0.5rem)-2px)] text-foreground transition-colors",
|
|
7407
|
-
active ? "bg-primary text-primary-foreground" : "bg-transparent hover:bg-muted disabled:cursor-not-allowed disabled:text-muted-foreground disabled:opacity-60",
|
|
7540
|
+
active ? "bg-bridge-primary text-primary-foreground" : "bg-transparent hover:bg-muted disabled:cursor-not-allowed disabled:text-muted-foreground disabled:opacity-60",
|
|
7408
7541
|
className
|
|
7409
7542
|
),
|
|
7410
7543
|
...props
|
|
@@ -8668,13 +8801,13 @@ function FormFieldToolbar({
|
|
|
8668
8801
|
]
|
|
8669
8802
|
}
|
|
8670
8803
|
) }),
|
|
8671
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(DropdownMenuContent, { align: "start", sideOffset: 8, className: "min-w-
|
|
8804
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(DropdownMenuContent, { align: "start", sideOffset: 8, className: "min-w-47.5 p-1", children: FIELD_TYPES.map((entry) => {
|
|
8672
8805
|
const Icon = TYPE_ICONS[entry.type];
|
|
8673
8806
|
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
8674
8807
|
DropdownMenuItem,
|
|
8675
8808
|
{
|
|
8676
8809
|
onSelect: () => onTypeChange(entry.type),
|
|
8677
|
-
className: "rounded-md py-2 text-[13px] " + (entry.type === type ? "bg-primary/10" : ""),
|
|
8810
|
+
className: "rounded-md py-2 text-[13px] " + (entry.type === type ? "bg-bridge-primary/10" : ""),
|
|
8678
8811
|
children: [
|
|
8679
8812
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Icon, { size: 14, strokeWidth: 1.75, className: "shrink-0", "aria-hidden": true }),
|
|
8680
8813
|
entry.label
|
|
@@ -8691,7 +8824,7 @@ function FormFieldToolbar({
|
|
|
8691
8824
|
type: "button",
|
|
8692
8825
|
"aria-pressed": required,
|
|
8693
8826
|
onClick: onRequiredToggle,
|
|
8694
|
-
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"),
|
|
8827
|
+
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"),
|
|
8695
8828
|
"data-ohw-field-required-toggle": "",
|
|
8696
8829
|
children: [
|
|
8697
8830
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react4.Asterisk, { size: 14, strokeWidth: 2, "aria-hidden": true }),
|
|
@@ -8711,7 +8844,7 @@ function FormFieldToolbar({
|
|
|
8711
8844
|
children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react4.MoreHorizontal, { size: 15, "aria-hidden": true })
|
|
8712
8845
|
}
|
|
8713
8846
|
) }),
|
|
8714
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(DropdownMenuContent, { align: "start", sideOffset: 8, className: "min-w-
|
|
8847
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(DropdownMenuContent, { align: "start", sideOffset: 8, className: "min-w-42.5 p-1", children: [
|
|
8715
8848
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(DropdownMenuItem, { onSelect: onDuplicate, className: "rounded-md py-2 text-[13px]", children: [
|
|
8716
8849
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react4.Copy, { size: 14, strokeWidth: 1.75, className: "shrink-0", "aria-hidden": true }),
|
|
8717
8850
|
"Duplicate"
|
|
@@ -8739,7 +8872,7 @@ function FieldTypePicker({ onPick }) {
|
|
|
8739
8872
|
{
|
|
8740
8873
|
type: "button",
|
|
8741
8874
|
onClick: () => onPick(entry.type),
|
|
8742
|
-
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",
|
|
8875
|
+
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",
|
|
8743
8876
|
children: [
|
|
8744
8877
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Icon, { size: 26, strokeWidth: 1.5, "aria-hidden": true }),
|
|
8745
8878
|
entry.label
|
|
@@ -8765,7 +8898,7 @@ var buttonVariants = cva(
|
|
|
8765
8898
|
{
|
|
8766
8899
|
variants: {
|
|
8767
8900
|
variant: {
|
|
8768
|
-
default: "bg-primary text-primary-foreground hover:opacity-90",
|
|
8901
|
+
default: "bg-bridge-primary text-primary-foreground hover:opacity-90",
|
|
8769
8902
|
outline: "border border-border bg-background text-foreground shadow-sm hover:bg-muted/80",
|
|
8770
8903
|
ghost: "min-w-0 px-3 py-2 text-foreground hover:bg-muted/50"
|
|
8771
8904
|
},
|
|
@@ -8838,6 +8971,7 @@ function MediaOverlay({
|
|
|
8838
8971
|
fadingOut = false,
|
|
8839
8972
|
selected = false,
|
|
8840
8973
|
hovered = false,
|
|
8974
|
+
cueOnly = false,
|
|
8841
8975
|
onFadeOutComplete,
|
|
8842
8976
|
onReplace,
|
|
8843
8977
|
onSelect,
|
|
@@ -8846,7 +8980,7 @@ function MediaOverlay({
|
|
|
8846
8980
|
const { rect } = hover;
|
|
8847
8981
|
const skeletonRef = React8.useRef(null);
|
|
8848
8982
|
const isVideo = hover.elementType === "video";
|
|
8849
|
-
const showChrome = !selected || hovered;
|
|
8983
|
+
const showChrome = (!selected || hovered) && !cueOnly;
|
|
8850
8984
|
const autoplay = hover.videoAutoplay ?? true;
|
|
8851
8985
|
const muted = hover.videoMuted ?? true;
|
|
8852
8986
|
const probeRef = React8.useRef(null);
|
|
@@ -8962,11 +9096,11 @@ function MediaOverlay({
|
|
|
8962
9096
|
// parent this needed a whole `ow:click-at` round-trip to re-hit-test inside the iframe;
|
|
8963
9097
|
// in-document, pointer-events does it natively. The button below opts back in, so
|
|
8964
9098
|
// Replace still works.
|
|
8965
|
-
pointerEvents: hover.hasTextOverlap ? "none" : "auto",
|
|
9099
|
+
pointerEvents: hover.hasTextOverlap || cueOnly ? "none" : "auto",
|
|
8966
9100
|
// Selected: a firm component ring with no wash, so the image reads as chosen rather
|
|
8967
9101
|
// than hovered. Hover keeps the existing tinted preview.
|
|
8968
|
-
boxShadow: selected ? "inset 0 0 0 2px var(--color-primary)" : "inset 0 0 0 1.5px var(--color-primary)",
|
|
8969
|
-
background: selected ? "transparent" : "color-mix(in srgb, var(--color-primary) 20%, transparent)"
|
|
9102
|
+
boxShadow: selected ? "inset 0 0 0 2px var(--color-bridge-primary)" : "inset 0 0 0 1.5px var(--color-bridge-primary)",
|
|
9103
|
+
background: selected ? "transparent" : "color-mix(in srgb, var(--color-bridge-primary) 20%, transparent)"
|
|
8970
9104
|
},
|
|
8971
9105
|
onClick: () => onSelect && !selected ? onSelect(hover.key) : onReplace(hover.key),
|
|
8972
9106
|
children: [
|
|
@@ -8993,7 +9127,7 @@ function MediaOverlay({
|
|
|
8993
9127
|
]
|
|
8994
9128
|
}
|
|
8995
9129
|
),
|
|
8996
|
-
replaceMode === "none" ? null : /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
|
|
9130
|
+
replaceMode === "none" || cueOnly ? null : /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
|
|
8997
9131
|
Button,
|
|
8998
9132
|
{
|
|
8999
9133
|
"data-ohw-media-overlay": "",
|
|
@@ -9013,7 +9147,7 @@ function MediaOverlay({
|
|
|
9013
9147
|
justifyContent: "center"
|
|
9014
9148
|
} : null,
|
|
9015
9149
|
// Don't let Replace steal clicks when text (e.g. nav) sits on top of this media.
|
|
9016
|
-
pointerEvents: hover.hasTextOverlap ? "none" : "auto"
|
|
9150
|
+
pointerEvents: hover.hasTextOverlap || cueOnly ? "none" : "auto"
|
|
9017
9151
|
},
|
|
9018
9152
|
onMouseDown: (e) => e.preventDefault(),
|
|
9019
9153
|
onClick: (e) => {
|
|
@@ -9043,7 +9177,8 @@ var OVERLAY_BUTTON_STYLE2 = {
|
|
|
9043
9177
|
};
|
|
9044
9178
|
function CarouselOverlay({
|
|
9045
9179
|
hover,
|
|
9046
|
-
onEdit
|
|
9180
|
+
onEdit,
|
|
9181
|
+
cueOnly = false
|
|
9047
9182
|
}) {
|
|
9048
9183
|
const { rect } = hover;
|
|
9049
9184
|
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
@@ -9059,12 +9194,12 @@ function CarouselOverlay({
|
|
|
9059
9194
|
width: rect.width,
|
|
9060
9195
|
height: rect.height,
|
|
9061
9196
|
zIndex: 2147483646,
|
|
9062
|
-
pointerEvents: "auto",
|
|
9063
|
-
boxShadow: "inset 0 0 0 1.5px var(--color-primary)",
|
|
9064
|
-
background: "color-mix(in srgb, var(--color-primary) 20%, transparent)"
|
|
9197
|
+
pointerEvents: cueOnly ? "none" : "auto",
|
|
9198
|
+
boxShadow: "inset 0 0 0 1.5px var(--color-bridge-primary)",
|
|
9199
|
+
background: "color-mix(in srgb, var(--color-bridge-primary) 20%, transparent)"
|
|
9065
9200
|
},
|
|
9066
9201
|
onClick: () => onEdit(hover.key),
|
|
9067
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
|
|
9202
|
+
children: cueOnly ? null : /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
|
|
9068
9203
|
Button,
|
|
9069
9204
|
{
|
|
9070
9205
|
"data-ohw-carousel-overlay": "",
|
|
@@ -9255,7 +9390,8 @@ function ReviewButton({
|
|
|
9255
9390
|
}
|
|
9256
9391
|
function AiSectionOverlay({
|
|
9257
9392
|
postToParent: postToParent2,
|
|
9258
|
-
apiRef
|
|
9393
|
+
apiRef,
|
|
9394
|
+
onSelectionChange
|
|
9259
9395
|
}) {
|
|
9260
9396
|
const [selectedId, setSelectedId] = (0, import_react8.useState)(null);
|
|
9261
9397
|
const [reviewId, setReviewId] = (0, import_react8.useState)(null);
|
|
@@ -9264,6 +9400,9 @@ function AiSectionOverlay({
|
|
|
9264
9400
|
reviewIdRef.current = reviewId;
|
|
9265
9401
|
const selectedIdRef = (0, import_react8.useRef)(null);
|
|
9266
9402
|
selectedIdRef.current = selectedId;
|
|
9403
|
+
(0, import_react8.useEffect)(() => {
|
|
9404
|
+
onSelectionChange?.(selectedId);
|
|
9405
|
+
}, [selectedId, onSelectionChange]);
|
|
9267
9406
|
const report = (0, import_react8.useCallback)(
|
|
9268
9407
|
(el) => {
|
|
9269
9408
|
const labelSrc = el ? sectionElementOf(el) : null;
|
|
@@ -9281,6 +9420,7 @@ function AiSectionOverlay({
|
|
|
9281
9420
|
const sectionEl = inner ? movableUnit(inner) : null;
|
|
9282
9421
|
const id = sectionEl ? instanceIdOf(sectionEl) || null : null;
|
|
9283
9422
|
if (id === selectedIdRef.current) return;
|
|
9423
|
+
selectedIdRef.current = id;
|
|
9284
9424
|
setSelectedId(id);
|
|
9285
9425
|
if (options?.report !== false) report(sectionEl);
|
|
9286
9426
|
},
|
|
@@ -9301,9 +9441,11 @@ function AiSectionOverlay({
|
|
|
9301
9441
|
return sectionEl != null;
|
|
9302
9442
|
},
|
|
9303
9443
|
clear: () => {
|
|
9444
|
+
selectedIdRef.current = null;
|
|
9304
9445
|
setSelectedId(null);
|
|
9305
9446
|
report(null);
|
|
9306
|
-
}
|
|
9447
|
+
},
|
|
9448
|
+
getSelectedId: () => selectedIdRef.current
|
|
9307
9449
|
};
|
|
9308
9450
|
return () => {
|
|
9309
9451
|
apiRef.current = null;
|
|
@@ -9312,6 +9454,7 @@ function AiSectionOverlay({
|
|
|
9312
9454
|
(0, import_react8.useEffect)(() => {
|
|
9313
9455
|
const onMessage = (e) => {
|
|
9314
9456
|
if (e.data?.type === "ow:ai-select" && e.data.sectionId === null) {
|
|
9457
|
+
selectedIdRef.current = null;
|
|
9315
9458
|
setSelectedId(null);
|
|
9316
9459
|
return;
|
|
9317
9460
|
}
|
|
@@ -9362,6 +9505,7 @@ function AiSectionOverlay({
|
|
|
9362
9505
|
if (reviewIdRef.current) return;
|
|
9363
9506
|
if (document.querySelector("[data-ohw-editing]")) return;
|
|
9364
9507
|
if (selectedIdRef.current) {
|
|
9508
|
+
selectedIdRef.current = null;
|
|
9365
9509
|
setSelectedId(null);
|
|
9366
9510
|
report(null);
|
|
9367
9511
|
}
|
|
@@ -9983,7 +10127,7 @@ function SectionTreeItem({
|
|
|
9983
10127
|
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
9984
10128
|
"div",
|
|
9985
10129
|
{
|
|
9986
|
-
className: "mr-
|
|
10130
|
+
className: "-mr-px h-9 w-2 shrink-0 rounded-bl-sm border-b border-l border-border mb-4",
|
|
9987
10131
|
"aria-hidden": true
|
|
9988
10132
|
}
|
|
9989
10133
|
),
|
|
@@ -10002,7 +10146,7 @@ function SectionTreeItem({
|
|
|
10002
10146
|
className: cn(
|
|
10003
10147
|
"flex h-9 min-w-0 flex-1 items-center gap-2 rounded-md border border-border bg-background p-3",
|
|
10004
10148
|
interactive && "cursor-pointer hover:bg-muted/30",
|
|
10005
|
-
interactive && selected && "border-primary"
|
|
10149
|
+
interactive && selected && "border-bridge-primary"
|
|
10006
10150
|
),
|
|
10007
10151
|
children: [
|
|
10008
10152
|
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
@@ -10132,7 +10276,7 @@ function UrlOrPageInput({
|
|
|
10132
10276
|
};
|
|
10133
10277
|
const fieldClassName = cn(
|
|
10134
10278
|
"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]",
|
|
10135
|
-
urlError ? "border-destructive shadow-[0_0_0_1px_var(--ohw-destructive)]" : isFocused ? "border-primary shadow-[0_0_0_1px_var(--ohw-primary)]" : "border-input"
|
|
10279
|
+
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"
|
|
10136
10280
|
);
|
|
10137
10281
|
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex w-full flex-col gap-2 p-0", children: [
|
|
10138
10282
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Label, { htmlFor: inputId, className: cn(urlError && "text-destructive"), children: "Destination" }),
|
|
@@ -14335,7 +14479,7 @@ function DisplaySwitch({
|
|
|
14335
14479
|
onClick: () => onChange(!checked),
|
|
14336
14480
|
className: cn(
|
|
14337
14481
|
"relative h-5 w-9 shrink-0 rounded-full transition-colors",
|
|
14338
|
-
checked ? "bg-primary" : "bg-primary-50",
|
|
14482
|
+
checked ? "bg-bridge-primary" : "bg-primary-50",
|
|
14339
14483
|
disabled ? "cursor-default opacity-50" : "cursor-pointer"
|
|
14340
14484
|
),
|
|
14341
14485
|
children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
@@ -14343,7 +14487,7 @@ function DisplaySwitch({
|
|
|
14343
14487
|
{
|
|
14344
14488
|
className: cn(
|
|
14345
14489
|
"absolute top-0.5 h-4 w-4 rounded-full bg-white transition-all",
|
|
14346
|
-
checked ? "left-
|
|
14490
|
+
checked ? "left-4.5" : "left-0.5"
|
|
14347
14491
|
)
|
|
14348
14492
|
}
|
|
14349
14493
|
)
|
|
@@ -15978,7 +16122,7 @@ var badgeVariants = cva(
|
|
|
15978
16122
|
{
|
|
15979
16123
|
variants: {
|
|
15980
16124
|
variant: {
|
|
15981
|
-
default: "border-transparent bg-primary text-primary-foreground",
|
|
16125
|
+
default: "border-transparent bg-bridge-primary text-primary-foreground",
|
|
15982
16126
|
secondary: "border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80",
|
|
15983
16127
|
destructive: "border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80",
|
|
15984
16128
|
outline: "text-foreground"
|
|
@@ -16370,6 +16514,19 @@ function isMediaEditable(el) {
|
|
|
16370
16514
|
const t = el.dataset.ohwEditable;
|
|
16371
16515
|
return t === "image" || t === "bg-image" || t === "video";
|
|
16372
16516
|
}
|
|
16517
|
+
var FULL_BLEED_MIN_COVERAGE = 0.98;
|
|
16518
|
+
function fullBleedSectionIdOf(media) {
|
|
16519
|
+
const section = media.closest("[data-ohw-section]");
|
|
16520
|
+
if (!section) return null;
|
|
16521
|
+
const s = section.getBoundingClientRect();
|
|
16522
|
+
if (s.width <= 0 || s.height <= 0) return null;
|
|
16523
|
+
const m = media.getBoundingClientRect();
|
|
16524
|
+
const overlapX = Math.min(m.right, s.right) - Math.max(m.left, s.left);
|
|
16525
|
+
const overlapY = Math.min(m.bottom, s.bottom) - Math.max(m.top, s.top);
|
|
16526
|
+
if (overlapX <= 0 || overlapY <= 0) return null;
|
|
16527
|
+
if (overlapX * overlapY / (s.width * s.height) < FULL_BLEED_MIN_COVERAGE) return null;
|
|
16528
|
+
return instanceIdOf(movableUnit(section)) || null;
|
|
16529
|
+
}
|
|
16373
16530
|
function isIconMarkupValue(value) {
|
|
16374
16531
|
return /^\s*<(svg|img)\b/i.test(value);
|
|
16375
16532
|
}
|
|
@@ -17543,20 +17700,38 @@ function OhhwellsBridge() {
|
|
|
17543
17700
|
const hoveredImageHasTextOverlapRef = (0, import_react17.useRef)(false);
|
|
17544
17701
|
const dragOverElRef = (0, import_react17.useRef)(null);
|
|
17545
17702
|
const [mediaHover, setMediaHover] = (0, import_react17.useState)(null);
|
|
17703
|
+
const [selectedAiSectionId, setSelectedAiSectionId] = (0, import_react17.useState)(null);
|
|
17704
|
+
const selectedAiSectionIdRef = (0, import_react17.useRef)(null);
|
|
17705
|
+
const handleAiSectionSelectionChange = (0, import_react17.useCallback)((id) => {
|
|
17706
|
+
selectedAiSectionIdRef.current = id;
|
|
17707
|
+
setSelectedAiSectionId(id);
|
|
17708
|
+
}, []);
|
|
17546
17709
|
const [selectedMedia, setSelectedMedia] = (0, import_react17.useState)(null);
|
|
17547
17710
|
const selectedMediaElRef = (0, import_react17.useRef)(null);
|
|
17711
|
+
const mediaKeyDropTokenRef = (0, import_react17.useRef)(0);
|
|
17548
17712
|
const clearMediaSelection = (0, import_react17.useCallback)(() => {
|
|
17549
17713
|
const prev = selectedMediaElRef.current;
|
|
17550
17714
|
selectedMediaElRef.current = null;
|
|
17551
17715
|
setSelectedMedia(null);
|
|
17552
17716
|
const sectionEl = prev?.closest("[data-ohw-section]") ?? null;
|
|
17553
17717
|
if (sectionEl) {
|
|
17554
|
-
|
|
17555
|
-
|
|
17556
|
-
|
|
17557
|
-
|
|
17558
|
-
key
|
|
17559
|
-
|
|
17718
|
+
const sectionInstanceId = instanceIdOf(movableUnit(sectionEl)) || null;
|
|
17719
|
+
if (!sectionInstanceId) return;
|
|
17720
|
+
const token = ++mediaKeyDropTokenRef.current;
|
|
17721
|
+
const onQueueDrained = (e) => {
|
|
17722
|
+
if (e.source !== window || e.data?.type !== "ow:media-key-drop" || e.data.token !== token) return;
|
|
17723
|
+
window.removeEventListener("message", onQueueDrained);
|
|
17724
|
+
if (aiSectionApiRef.current?.getSelectedId() !== sectionInstanceId) return;
|
|
17725
|
+
if (selectedMediaElRef.current) return;
|
|
17726
|
+
postToParentRef.current({
|
|
17727
|
+
type: "ow:section-selected",
|
|
17728
|
+
sectionId: sectionEl.dataset.ohwSection ?? null,
|
|
17729
|
+
sectionLabel: sectionEl.dataset.ohwSectionLabel ?? titleCaseSectionId(sectionEl.dataset.ohwSection ?? ""),
|
|
17730
|
+
key: null
|
|
17731
|
+
});
|
|
17732
|
+
};
|
|
17733
|
+
window.addEventListener("message", onQueueDrained);
|
|
17734
|
+
window.postMessage({ type: "ow:media-key-drop", token }, "*");
|
|
17560
17735
|
}
|
|
17561
17736
|
}, []);
|
|
17562
17737
|
const clearMediaSelectionRef = (0, import_react17.useRef)(clearMediaSelection);
|
|
@@ -19448,7 +19623,9 @@ function OhhwellsBridge() {
|
|
|
19448
19623
|
}, [isEditMode]);
|
|
19449
19624
|
(0, import_react17.useEffect)(() => {
|
|
19450
19625
|
if (isEditMode || fetchState !== "done") return;
|
|
19626
|
+
console.log("env", process.env.NEXT_PUBLIC_FLOWOPS_API_URL);
|
|
19451
19627
|
const apiUrl = process.env.NEXT_PUBLIC_FLOWOPS_API_URL ?? "https://flowops-backend-staging-2yfdh7pwpq-as.a.run.app";
|
|
19628
|
+
console.log({ apiUrl, subdomain });
|
|
19452
19629
|
bindPublishedForms(apiUrl, subdomain, contentCache.get(subdomain) ?? {});
|
|
19453
19630
|
}, [isEditMode, fetchState, subdomain]);
|
|
19454
19631
|
(0, import_react17.useEffect)(() => {
|
|
@@ -19996,6 +20173,23 @@ function OhhwellsBridge() {
|
|
|
19996
20173
|
if (selectedMediaElRef.current && !selectedMediaElRef.current.contains(target) && !target.closest("[data-ohw-media-overlay], [data-ohw-edit-chrome], [data-ohw-item-interaction]")) {
|
|
19997
20174
|
clearMediaSelectionRef.current();
|
|
19998
20175
|
}
|
|
20176
|
+
if (selectedMediaElRef.current && target.closest("[data-ohw-media-overlay]") && !findClosestButtonLike(target)) {
|
|
20177
|
+
const hit = findImageAtPoint(e.clientX, e.clientY, false);
|
|
20178
|
+
if (hit && hit !== selectedMediaElRef.current) {
|
|
20179
|
+
e.preventDefault();
|
|
20180
|
+
e.stopPropagation();
|
|
20181
|
+
const fullBleedSectionId = fullBleedSectionIdOf(hit);
|
|
20182
|
+
if (fullBleedSectionId && fullBleedSectionId !== selectedAiSectionIdRef.current) {
|
|
20183
|
+
clearMediaSelectionRef.current();
|
|
20184
|
+
deselectRef.current();
|
|
20185
|
+
deactivateRef.current();
|
|
20186
|
+
aiSectionApiRef.current?.selectFromElement(hit);
|
|
20187
|
+
return;
|
|
20188
|
+
}
|
|
20189
|
+
selectMediaElementRef.current(hit);
|
|
20190
|
+
return;
|
|
20191
|
+
}
|
|
20192
|
+
}
|
|
19999
20193
|
if (isInsideFloatingPanel(target)) return;
|
|
20000
20194
|
if (target.closest("[data-ohw-form-toolbar]")) return;
|
|
20001
20195
|
if (target.closest(
|
|
@@ -20177,6 +20371,14 @@ function OhhwellsBridge() {
|
|
|
20177
20371
|
if (isMediaEditable(editable) && !buttonOnMedia) {
|
|
20178
20372
|
e.preventDefault();
|
|
20179
20373
|
e.stopPropagation();
|
|
20374
|
+
const fullBleedSectionId = fullBleedSectionIdOf(editable);
|
|
20375
|
+
if (fullBleedSectionId && fullBleedSectionId !== selectedAiSectionIdRef.current) {
|
|
20376
|
+
clearMediaSelectionRef.current();
|
|
20377
|
+
deselectRef.current();
|
|
20378
|
+
deactivateRef.current();
|
|
20379
|
+
aiSectionApiRef.current?.selectFromElement(editable);
|
|
20380
|
+
return;
|
|
20381
|
+
}
|
|
20180
20382
|
if (selectedMediaElRef.current === editable) {
|
|
20181
20383
|
postToParentRef.current({ type: "ow:image-pick", key: editable.dataset.ohwKey ?? "", elementType: editable.dataset.ohwEditable ?? "image" });
|
|
20182
20384
|
} else {
|
|
@@ -20631,6 +20833,7 @@ function OhhwellsBridge() {
|
|
|
20631
20833
|
elementType: imgEl.dataset.ohwEditable ?? "image",
|
|
20632
20834
|
hasTextOverlap,
|
|
20633
20835
|
isDragOver,
|
|
20836
|
+
fullBleedSectionId: fullBleedSectionIdOf(imgEl),
|
|
20634
20837
|
...video ? { videoAutoplay: video.autoplay, videoMuted: video.muted } : {}
|
|
20635
20838
|
});
|
|
20636
20839
|
const track = imgEl.closest("[data-ohw-hover-pause]");
|
|
@@ -20803,7 +21006,13 @@ function OhhwellsBridge() {
|
|
|
20803
21006
|
setHoveredItemRect(null);
|
|
20804
21007
|
}
|
|
20805
21008
|
};
|
|
21009
|
+
const syncSelectedMediaPointerRelease = (released) => {
|
|
21010
|
+
setSelectedMedia(
|
|
21011
|
+
(prev) => prev && prev.hasTextOverlap !== released ? { ...prev, hasTextOverlap: released } : prev
|
|
21012
|
+
);
|
|
21013
|
+
};
|
|
20806
21014
|
const probeImageAt = (clientX, clientY, isDragOver = false, fromParentViewport = false) => {
|
|
21015
|
+
syncSelectedMediaPointerRelease(true);
|
|
20807
21016
|
if (linkPopoverOpenRef.current) {
|
|
20808
21017
|
if (hoveredImageRef.current) {
|
|
20809
21018
|
hoveredImageRef.current = null;
|
|
@@ -20998,6 +21207,7 @@ function OhhwellsBridge() {
|
|
|
20998
21207
|
return;
|
|
20999
21208
|
}
|
|
21000
21209
|
document.querySelectorAll("[data-ohw-hovered]").forEach((el) => el.removeAttribute("data-ohw-hovered"));
|
|
21210
|
+
syncSelectedMediaPointerRelease(false);
|
|
21001
21211
|
if (imgEl !== hoveredImageRef.current || hoveredImageHasTextOverlapRef.current) {
|
|
21002
21212
|
hoveredImageRef.current = imgEl;
|
|
21003
21213
|
showImageHover(imgEl, isDragOver);
|
|
@@ -21798,10 +22008,26 @@ function OhhwellsBridge() {
|
|
|
21798
22008
|
const handleGetBrand = (e) => {
|
|
21799
22009
|
if (e.data?.type !== "ow:get-brand") return;
|
|
21800
22010
|
const template = deriveTemplateBrand();
|
|
21801
|
-
const
|
|
22011
|
+
const fallback = template ?? (() => {
|
|
22012
|
+
const fonts = deriveTemplateFonts();
|
|
22013
|
+
return fonts ? { palette: AI_DEFAULT_BRAND.palette, fonts } : null;
|
|
22014
|
+
})();
|
|
22015
|
+
const value = brandKitRef.current || (fallback ? JSON.stringify(fallback) : "");
|
|
21802
22016
|
postToParentRef.current({ type: "ow:brand-value", value });
|
|
21803
22017
|
};
|
|
21804
22018
|
window.addEventListener("message", handleGetBrand);
|
|
22019
|
+
const handleGetTemplateFonts = (e) => {
|
|
22020
|
+
if (e.data?.type !== "ow:get-template-fonts") return;
|
|
22021
|
+
const fonts = deriveTemplateFonts();
|
|
22022
|
+
postToParentRef.current({ type: "ow:template-fonts-value", value: fonts ? JSON.stringify(fonts) : "" });
|
|
22023
|
+
};
|
|
22024
|
+
window.addEventListener("message", handleGetTemplateFonts);
|
|
22025
|
+
const handleGetTemplateBrand = (e) => {
|
|
22026
|
+
if (e.data?.type !== "ow:get-template-brand") return;
|
|
22027
|
+
const brand = deriveTemplateBrand();
|
|
22028
|
+
postToParentRef.current({ type: "ow:template-brand-value", value: brand ? JSON.stringify(brand) : "" });
|
|
22029
|
+
};
|
|
22030
|
+
window.addEventListener("message", handleGetTemplateBrand);
|
|
21805
22031
|
const handleMoveSection = (e) => {
|
|
21806
22032
|
if (e.data?.type !== "ow:move-section") return;
|
|
21807
22033
|
const instanceId = typeof e.data.instanceId === "string" ? e.data.instanceId : "";
|
|
@@ -22455,7 +22681,11 @@ function OhhwellsBridge() {
|
|
|
22455
22681
|
if (!key) return;
|
|
22456
22682
|
const r2 = getVisibleRect(container);
|
|
22457
22683
|
setCarouselHover(
|
|
22458
|
-
(prev) => prev && prev.key === key && prev.rect.top === r2.top && prev.rect.left === r2.left && prev.rect.width === r2.width && prev.rect.height === r2.height ? prev : {
|
|
22684
|
+
(prev) => prev && prev.key === key && prev.rect.top === r2.top && prev.rect.left === r2.left && prev.rect.width === r2.width && prev.rect.height === r2.height ? prev : {
|
|
22685
|
+
key,
|
|
22686
|
+
rect: { top: r2.top, left: r2.left, width: r2.width, height: r2.height },
|
|
22687
|
+
fullBleedSectionId: fullBleedSectionIdOf(container)
|
|
22688
|
+
}
|
|
22459
22689
|
);
|
|
22460
22690
|
};
|
|
22461
22691
|
const applyToolbarPos = (rect) => {
|
|
@@ -22704,6 +22934,8 @@ function OhhwellsBridge() {
|
|
|
22704
22934
|
window.removeEventListener("message", handleAiSetBrand);
|
|
22705
22935
|
window.removeEventListener("message", handleAiSetStyles);
|
|
22706
22936
|
window.removeEventListener("message", handleGetBrand);
|
|
22937
|
+
window.removeEventListener("message", handleGetTemplateFonts);
|
|
22938
|
+
window.removeEventListener("message", handleGetTemplateBrand);
|
|
22707
22939
|
window.removeEventListener("message", handleMoveSection);
|
|
22708
22940
|
window.removeEventListener("message", handlePanelDragging);
|
|
22709
22941
|
window.removeEventListener("message", handleDeleteSection);
|
|
@@ -22915,7 +23147,7 @@ function OhhwellsBridge() {
|
|
|
22915
23147
|
postToParent2({
|
|
22916
23148
|
type: "ow:ready",
|
|
22917
23149
|
version: "1",
|
|
22918
|
-
bridgeVersion: "0.1.
|
|
23150
|
+
bridgeVersion: "0.1.116",
|
|
22919
23151
|
path: pathname,
|
|
22920
23152
|
nodes: collectEditableNodes(editContentRef.current),
|
|
22921
23153
|
sections
|
|
@@ -23382,7 +23614,14 @@ function OhhwellsBridge() {
|
|
|
23382
23614
|
bridgeRoot ? (0, import_react_dom5.createPortal)(
|
|
23383
23615
|
/* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(import_jsx_runtime33.Fragment, { children: [
|
|
23384
23616
|
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { ref: attachVisibleViewport, "data-ohw-visible-viewport": "", "aria-hidden": true }),
|
|
23385
|
-
isEditMode && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
23617
|
+
isEditMode && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
23618
|
+
AiSectionOverlay,
|
|
23619
|
+
{
|
|
23620
|
+
postToParent: postToParent2,
|
|
23621
|
+
apiRef: aiSectionApiRef,
|
|
23622
|
+
onSelectionChange: handleAiSectionSelectionChange
|
|
23623
|
+
}
|
|
23624
|
+
),
|
|
23386
23625
|
isSectionDragging && sectionDropSlots.map((slot, i) => /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
23387
23626
|
"div",
|
|
23388
23627
|
{
|
|
@@ -23415,6 +23654,7 @@ function OhhwellsBridge() {
|
|
|
23415
23654
|
{
|
|
23416
23655
|
hover: mediaHover,
|
|
23417
23656
|
isUploading: false,
|
|
23657
|
+
cueOnly: !mediaHover.isDragOver && !!mediaHover.fullBleedSectionId && mediaHover.fullBleedSectionId !== selectedAiSectionId,
|
|
23418
23658
|
onReplace: handleMediaReplace,
|
|
23419
23659
|
onSelect: handleMediaSelect,
|
|
23420
23660
|
onVideoSettingsChange: handleVideoSettingsChange
|
|
@@ -23432,7 +23672,14 @@ function OhhwellsBridge() {
|
|
|
23432
23672
|
onVideoSettingsChange: handleVideoSettingsChange
|
|
23433
23673
|
}
|
|
23434
23674
|
),
|
|
23435
|
-
carouselHover && !linkPopover && !isItemDragging && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
23675
|
+
carouselHover && !linkPopover && !isItemDragging && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
23676
|
+
CarouselOverlay,
|
|
23677
|
+
{
|
|
23678
|
+
hover: carouselHover,
|
|
23679
|
+
onEdit: handleEditCarousel,
|
|
23680
|
+
cueOnly: !!carouselHover.fullBleedSectionId && carouselHover.fullBleedSectionId !== selectedAiSectionId
|
|
23681
|
+
}
|
|
23682
|
+
),
|
|
23436
23683
|
siblingHintRect && !linkPopover && !isItemDragging && siblingHintRects.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(ItemInteractionLayer, { rect: siblingHintRect, state: "sibling-hint" }),
|
|
23437
23684
|
siblingHintRects.length > 0 && !linkPopover && !isItemDragging && siblingHintRects.map((rect, i) => /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(ItemInteractionLayer, { rect, state: "sibling-hint" }, `sibling-hint-${i}`)),
|
|
23438
23685
|
isItemDragging && draggedItemRect && selectedElRef.current !== footerDragRef.current?.draggedEl && selectedElRef.current !== navDragRef.current?.draggedEl && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(ItemInteractionLayer, { rect: draggedItemRect, state: "dragging" }),
|
|
@@ -23531,7 +23778,7 @@ function OhhwellsBridge() {
|
|
|
23531
23778
|
"span",
|
|
23532
23779
|
{
|
|
23533
23780
|
"data-ohw-form-count": "",
|
|
23534
|
-
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",
|
|
23781
|
+
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",
|
|
23535
23782
|
children: formPickCount
|
|
23536
23783
|
}
|
|
23537
23784
|
)
|
|
@@ -23769,11 +24016,11 @@ function OhhwellsBridge() {
|
|
|
23769
24016
|
className: "fixed left-0 w-full z-2147483646 flex items-center pointer-events-none",
|
|
23770
24017
|
style: { top: sectionGap.y, transform: "translateY(-50%)" },
|
|
23771
24018
|
children: [
|
|
23772
|
-
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } }),
|
|
24019
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "flex-1 bg-bridge-primary", style: { height: 3 } }),
|
|
23773
24020
|
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
23774
24021
|
Badge,
|
|
23775
24022
|
{
|
|
23776
|
-
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",
|
|
24023
|
+
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",
|
|
23777
24024
|
onClick: () => {
|
|
23778
24025
|
window.parent.postMessage(
|
|
23779
24026
|
{
|
|
@@ -23787,7 +24034,7 @@ function OhhwellsBridge() {
|
|
|
23787
24034
|
children: "Add Section"
|
|
23788
24035
|
}
|
|
23789
24036
|
),
|
|
23790
|
-
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "flex-1 bg-primary", style: { height: 3 } })
|
|
24037
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "flex-1 bg-bridge-primary", style: { height: 3 } })
|
|
23791
24038
|
]
|
|
23792
24039
|
}
|
|
23793
24040
|
),
|