@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.js
CHANGED
|
@@ -279,16 +279,17 @@ var LEGACY_BRAND_VAR_NAMES = [
|
|
|
279
279
|
"text-muted",
|
|
280
280
|
"surface",
|
|
281
281
|
"border",
|
|
282
|
-
"on-primary"
|
|
283
|
-
"navbar-background"
|
|
282
|
+
"on-primary"
|
|
284
283
|
].map((role) => `--brand-${role}`);
|
|
285
284
|
var FONT_VARS = {
|
|
286
285
|
heading: ["--font-heading", "--font-display", "--brand-font-heading"],
|
|
287
286
|
body: ["--font-body", "--brand-font-body"]
|
|
288
287
|
};
|
|
289
288
|
var BRAND_FONT_LINK_ID = "ohw-brand-fonts";
|
|
290
|
-
|
|
291
|
-
|
|
289
|
+
var CUSTOM_FONT_STYLE_ID = "ohw-brand-custom-fonts";
|
|
290
|
+
var CUSTOM_FONT_FORMATS = /* @__PURE__ */ new Set(["woff2", "woff", "truetype", "opentype"]);
|
|
291
|
+
function brandColorVars(palette) {
|
|
292
|
+
const { dark, primary, accent, light } = palette;
|
|
292
293
|
const mix = (a, aPct, b) => `color-mix(in srgb, ${a} ${aPct}%, ${b})`;
|
|
293
294
|
const surface = mix(light, 95, dark);
|
|
294
295
|
const border = mix(light, 85, dark);
|
|
@@ -311,22 +312,42 @@ function brandColorVars(kit) {
|
|
|
311
312
|
"--brand-border": border,
|
|
312
313
|
// Buttons/bands painted in the primary colour assume it's dark/saturated enough to need
|
|
313
314
|
// light text on top — the same assumption LOGO_IMAGE's light-on-dark navbar mark makes.
|
|
314
|
-
"--brand-on-primary": light
|
|
315
|
-
"--brand-navbar-background": dark
|
|
315
|
+
"--brand-on-primary": light
|
|
316
316
|
};
|
|
317
317
|
}
|
|
318
|
+
function parseCustomFontWeight(raw) {
|
|
319
|
+
if (typeof raw !== "object" || raw === null) return null;
|
|
320
|
+
const w = raw;
|
|
321
|
+
if (typeof w.weight !== "number" || !Number.isFinite(w.weight)) return null;
|
|
322
|
+
if (typeof w.url !== "string" || !w.url) return null;
|
|
323
|
+
if (typeof w.format !== "string" || !CUSTOM_FONT_FORMATS.has(w.format)) return null;
|
|
324
|
+
const weightEnd = typeof w.weightEnd === "number" && Number.isFinite(w.weightEnd) && w.weightEnd > w.weight ? w.weightEnd : void 0;
|
|
325
|
+
return { weight: w.weight, ...weightEnd !== void 0 ? { weightEnd } : {}, url: w.url, format: w.format };
|
|
326
|
+
}
|
|
327
|
+
function parseCustomFont(raw) {
|
|
328
|
+
if (typeof raw !== "object" || raw === null) return null;
|
|
329
|
+
const f = raw;
|
|
330
|
+
if (typeof f.family !== "string" || !f.family) return null;
|
|
331
|
+
if (typeof f.label !== "string" || !f.label) return null;
|
|
332
|
+
if (!Array.isArray(f.weights)) return null;
|
|
333
|
+
const weights = f.weights.map(parseCustomFontWeight).filter((w) => w !== null);
|
|
334
|
+
if (weights.length === 0) return null;
|
|
335
|
+
return { family: f.family, label: f.label, weights };
|
|
336
|
+
}
|
|
318
337
|
function parseBrandKit(raw) {
|
|
319
338
|
if (!raw) return null;
|
|
320
339
|
try {
|
|
321
340
|
const parsed = JSON.parse(raw);
|
|
322
341
|
const p = parsed?.palette;
|
|
323
342
|
const f = parsed?.fonts;
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
343
|
+
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;
|
|
344
|
+
const fonts = f && typeof f.heading === "string" && typeof f.body === "string" ? { heading: f.heading, body: f.body } : void 0;
|
|
345
|
+
const customFonts = Array.isArray(parsed?.customFonts) ? parsed.customFonts.map(parseCustomFont).filter((c) => c !== null) : void 0;
|
|
346
|
+
if (!palette && !fonts && !customFonts) return null;
|
|
327
347
|
return {
|
|
328
|
-
palette
|
|
329
|
-
fonts
|
|
348
|
+
...palette ? { palette } : {},
|
|
349
|
+
...fonts ? { fonts } : {},
|
|
350
|
+
...customFonts ? { customFonts } : {}
|
|
330
351
|
};
|
|
331
352
|
} catch {
|
|
332
353
|
return null;
|
|
@@ -336,11 +357,16 @@ function familyOf(stack) {
|
|
|
336
357
|
const first = stack.split(",")[0]?.trim() ?? "";
|
|
337
358
|
return first.replace(/^['"]|['"]$/g, "");
|
|
338
359
|
}
|
|
360
|
+
function quoteFamily(family) {
|
|
361
|
+
return `'${family.replace(/\\/g, "\\\\").replace(/'/g, "\\'")}'`;
|
|
362
|
+
}
|
|
363
|
+
var WEIGHT_SCALE = [100, 200, 300, 400, 500, 600, 700, 800, 900];
|
|
339
364
|
function loadBrandFonts(families) {
|
|
340
365
|
const unique = [...new Set(families.map((f) => f.trim()).filter(Boolean))];
|
|
341
366
|
if (unique.length === 0) return;
|
|
342
|
-
const
|
|
343
|
-
const
|
|
367
|
+
const weights = WEIGHT_SCALE.join(";");
|
|
368
|
+
const spec = unique.map((f) => `family=${f.replace(/ /g, "+")}:wght@${weights}`).join("&");
|
|
369
|
+
const href = `https://fonts.googleapis.com/css2?${spec}&display=swap`;
|
|
344
370
|
let link = document.getElementById(BRAND_FONT_LINK_ID);
|
|
345
371
|
if (!link) {
|
|
346
372
|
link = document.createElement("link");
|
|
@@ -350,18 +376,54 @@ function loadBrandFonts(families) {
|
|
|
350
376
|
}
|
|
351
377
|
if (link.href !== href) link.href = href;
|
|
352
378
|
}
|
|
379
|
+
function escapeCssString(value) {
|
|
380
|
+
return value.replace(/\\/g, "\\\\").replace(/'/g, "\\'");
|
|
381
|
+
}
|
|
382
|
+
function loadCustomFonts(fonts) {
|
|
383
|
+
const list = fonts ?? [];
|
|
384
|
+
let style = document.getElementById(CUSTOM_FONT_STYLE_ID);
|
|
385
|
+
if (list.length === 0) {
|
|
386
|
+
style?.remove();
|
|
387
|
+
return;
|
|
388
|
+
}
|
|
389
|
+
if (!style) {
|
|
390
|
+
style = document.createElement("style");
|
|
391
|
+
style.id = CUSTOM_FONT_STYLE_ID;
|
|
392
|
+
document.head.appendChild(style);
|
|
393
|
+
}
|
|
394
|
+
style.textContent = list.flatMap(
|
|
395
|
+
(font) => font.weights.map((w) => {
|
|
396
|
+
const weightDescriptor = w.weightEnd ? `${w.weight} ${w.weightEnd}` : `${w.weight}`;
|
|
397
|
+
return `@font-face { font-family: '${escapeCssString(font.family)}'; src: url('${escapeCssString(w.url)}') format('${w.format}'); font-weight: ${weightDescriptor}; font-display: swap; }`;
|
|
398
|
+
})
|
|
399
|
+
).join("\n");
|
|
400
|
+
}
|
|
353
401
|
function applyBrandToDom(kit) {
|
|
354
402
|
const root = document.documentElement;
|
|
355
403
|
if (!kit) {
|
|
356
404
|
for (const name of [...BRAND_VAR_NAMES, ...LEGACY_BRAND_VAR_NAMES]) root.style.removeProperty(name);
|
|
357
405
|
for (const name of [...FONT_VARS.heading, ...FONT_VARS.body]) root.style.removeProperty(name);
|
|
358
406
|
document.getElementById(BRAND_FONT_LINK_ID)?.remove();
|
|
407
|
+
document.getElementById(CUSTOM_FONT_STYLE_ID)?.remove();
|
|
359
408
|
return;
|
|
360
409
|
}
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
410
|
+
if (kit.palette) {
|
|
411
|
+
for (const [name, value] of Object.entries(brandColorVars(kit.palette))) root.style.setProperty(name, value);
|
|
412
|
+
}
|
|
413
|
+
if (kit.customFonts) {
|
|
414
|
+
loadCustomFonts(kit.customFonts);
|
|
415
|
+
}
|
|
416
|
+
if (kit.fonts) {
|
|
417
|
+
const heading = quoteFamily(kit.fonts.heading);
|
|
418
|
+
const body = quoteFamily(kit.fonts.body);
|
|
419
|
+
for (const name of FONT_VARS.heading) root.style.setProperty(name, heading);
|
|
420
|
+
for (const name of FONT_VARS.body) root.style.setProperty(name, body);
|
|
421
|
+
const customFamilies = new Set((kit.customFonts ?? []).map((f) => f.family));
|
|
422
|
+
const googleFamilies = [familyOf(kit.fonts.heading), familyOf(kit.fonts.body)].filter(
|
|
423
|
+
(f) => !customFamilies.has(f)
|
|
424
|
+
);
|
|
425
|
+
loadBrandFonts(googleFamilies);
|
|
426
|
+
}
|
|
365
427
|
}
|
|
366
428
|
|
|
367
429
|
// src/lib/section-styles.ts
|
|
@@ -2650,14 +2712,52 @@ function readRootVar(name) {
|
|
|
2650
2712
|
if (typeof document === "undefined") return "";
|
|
2651
2713
|
return getComputedStyle(document.documentElement).getPropertyValue(name).trim();
|
|
2652
2714
|
}
|
|
2715
|
+
function normalizeColorToHex(value) {
|
|
2716
|
+
if (!value || typeof document === "undefined") return value;
|
|
2717
|
+
const canvas = document.createElement("canvas");
|
|
2718
|
+
canvas.width = 1;
|
|
2719
|
+
canvas.height = 1;
|
|
2720
|
+
const ctx = canvas.getContext("2d");
|
|
2721
|
+
if (!ctx) return value;
|
|
2722
|
+
ctx.fillStyle = value;
|
|
2723
|
+
ctx.fillRect(0, 0, 1, 1);
|
|
2724
|
+
const [r2, g, b] = ctx.getImageData(0, 0, 1, 1).data;
|
|
2725
|
+
const toHex = (n) => n.toString(16).padStart(2, "0");
|
|
2726
|
+
return `#${toHex(r2)}${toHex(g)}${toHex(b)}`;
|
|
2727
|
+
}
|
|
2728
|
+
var GENERIC_FONT_KEYWORDS = /* @__PURE__ */ new Set([
|
|
2729
|
+
"serif",
|
|
2730
|
+
"sans-serif",
|
|
2731
|
+
"monospace",
|
|
2732
|
+
"cursive",
|
|
2733
|
+
"fantasy",
|
|
2734
|
+
"system-ui",
|
|
2735
|
+
"ui-serif",
|
|
2736
|
+
"ui-sans-serif",
|
|
2737
|
+
"ui-monospace",
|
|
2738
|
+
"ui-rounded",
|
|
2739
|
+
"math",
|
|
2740
|
+
"emoji",
|
|
2741
|
+
"fangsong"
|
|
2742
|
+
]);
|
|
2743
|
+
function primaryFontFamily(stack) {
|
|
2744
|
+
const first = stack.split(",").map((part) => part.trim().replace(/^["']|["']$/g, "")).find((part) => part && !GENERIC_FONT_KEYWORDS.has(part.toLowerCase()));
|
|
2745
|
+
return first ?? "";
|
|
2746
|
+
}
|
|
2747
|
+
function humanizeFontFamily(name) {
|
|
2748
|
+
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());
|
|
2749
|
+
}
|
|
2750
|
+
function readFontVar(name) {
|
|
2751
|
+
return humanizeFontFamily(primaryFontFamily(readRootVar(name)));
|
|
2752
|
+
}
|
|
2653
2753
|
function deriveBrandOverride() {
|
|
2654
2754
|
const dark = readRootVar("--ohw-brand-dark");
|
|
2655
2755
|
const primary = readRootVar("--ohw-brand-primary");
|
|
2656
2756
|
const light = readRootVar("--ohw-brand-light");
|
|
2657
2757
|
if (!dark || !primary || !light) return null;
|
|
2658
2758
|
const accent = readRootVar("--ohw-brand-accent");
|
|
2659
|
-
const heading =
|
|
2660
|
-
const body =
|
|
2759
|
+
const heading = readFontVar("--font-heading") || readFontVar("--font-display");
|
|
2760
|
+
const body = readFontVar("--font-body");
|
|
2661
2761
|
return {
|
|
2662
2762
|
palette: { dark, primary, accent: accent || dark, light },
|
|
2663
2763
|
fonts: {
|
|
@@ -2666,22 +2766,55 @@ function deriveBrandOverride() {
|
|
|
2666
2766
|
}
|
|
2667
2767
|
};
|
|
2668
2768
|
}
|
|
2669
|
-
function
|
|
2769
|
+
function deriveTemplateBrandLive() {
|
|
2670
2770
|
const primary = readRootVar("--brand-primary") || readRootVar("--color-primary");
|
|
2671
2771
|
const dark = readRootVar("--brand-text") || readRootVar("--color-dark");
|
|
2672
2772
|
const light = readRootVar("--brand-background") || readRootVar("--color-light");
|
|
2673
2773
|
if (!dark || !primary || !light) return null;
|
|
2674
2774
|
const accent = readRootVar("--brand-accent") || readRootVar("--color-accent");
|
|
2675
|
-
const heading =
|
|
2676
|
-
const body =
|
|
2775
|
+
const heading = readFontVar("--brand-font-heading") || readFontVar("--font-heading") || readFontVar("--font-display");
|
|
2776
|
+
const body = readFontVar("--brand-font-body") || readFontVar("--font-body");
|
|
2677
2777
|
return {
|
|
2678
|
-
palette: {
|
|
2778
|
+
palette: {
|
|
2779
|
+
dark: normalizeColorToHex(dark),
|
|
2780
|
+
primary: normalizeColorToHex(primary),
|
|
2781
|
+
accent: normalizeColorToHex(accent || dark),
|
|
2782
|
+
light: normalizeColorToHex(light)
|
|
2783
|
+
},
|
|
2679
2784
|
fonts: {
|
|
2680
2785
|
heading: heading || AI_DEFAULT_BRAND.fonts.heading,
|
|
2681
2786
|
body: body || AI_DEFAULT_BRAND.fonts.body
|
|
2682
2787
|
}
|
|
2683
2788
|
};
|
|
2684
2789
|
}
|
|
2790
|
+
function deriveTemplateFontsLive() {
|
|
2791
|
+
const heading = readFontVar("--brand-font-heading") || readFontVar("--font-heading") || readFontVar("--font-display");
|
|
2792
|
+
const body = readFontVar("--brand-font-body") || readFontVar("--font-body");
|
|
2793
|
+
if (!heading && !body) return null;
|
|
2794
|
+
return {
|
|
2795
|
+
heading: heading || AI_DEFAULT_BRAND.fonts.heading,
|
|
2796
|
+
body: body || AI_DEFAULT_BRAND.fonts.body
|
|
2797
|
+
};
|
|
2798
|
+
}
|
|
2799
|
+
var OVERRIDE_VAR_NAMES = [...BRAND_VAR_NAMES, ...LEGACY_BRAND_VAR_NAMES, ...FONT_VARS.heading, ...FONT_VARS.body];
|
|
2800
|
+
function withOverrideStripped(read) {
|
|
2801
|
+
const root = document.documentElement;
|
|
2802
|
+
const restore = OVERRIDE_VAR_NAMES.map((name) => [name, root.style.getPropertyValue(name)]);
|
|
2803
|
+
for (const name of OVERRIDE_VAR_NAMES) root.style.removeProperty(name);
|
|
2804
|
+
try {
|
|
2805
|
+
return read();
|
|
2806
|
+
} finally {
|
|
2807
|
+
for (const [name, value] of restore) if (value) root.style.setProperty(name, value);
|
|
2808
|
+
}
|
|
2809
|
+
}
|
|
2810
|
+
var TEMPLATE_BRAND_SNAPSHOT = typeof document === "undefined" ? null : withOverrideStripped(deriveTemplateBrandLive);
|
|
2811
|
+
var TEMPLATE_FONTS_SNAPSHOT = typeof document === "undefined" ? null : withOverrideStripped(deriveTemplateFontsLive);
|
|
2812
|
+
function deriveTemplateBrand() {
|
|
2813
|
+
return TEMPLATE_BRAND_SNAPSHOT;
|
|
2814
|
+
}
|
|
2815
|
+
function deriveTemplateFonts() {
|
|
2816
|
+
return TEMPLATE_FONTS_SNAPSHOT;
|
|
2817
|
+
}
|
|
2685
2818
|
function deriveTemplateButtonStyle() {
|
|
2686
2819
|
if (typeof document === "undefined") return null;
|
|
2687
2820
|
const candidates = Array.from(
|
|
@@ -7179,12 +7312,12 @@ var cva = (base, config) => (props) => {
|
|
|
7179
7312
|
import { Toggle as TogglePrimitive } from "radix-ui";
|
|
7180
7313
|
import { jsx as jsx5 } from "react/jsx-runtime";
|
|
7181
7314
|
var toggleVariants = cva(
|
|
7182
|
-
"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",
|
|
7315
|
+
"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",
|
|
7183
7316
|
{
|
|
7184
7317
|
variants: {
|
|
7185
7318
|
variant: {
|
|
7186
7319
|
default: "bg-transparent border-0",
|
|
7187
|
-
outline: "border border-input bg-transparent shadow-xs hover:bg-accent hover:text-accent-foreground"
|
|
7320
|
+
outline: "border border-input bg-transparent shadow-xs hover:bg-bridge-accent hover:text-accent-foreground"
|
|
7188
7321
|
},
|
|
7189
7322
|
size: {
|
|
7190
7323
|
default: "px-2 py-1",
|
|
@@ -7277,10 +7410,10 @@ var DragHandle = React4.forwardRef(
|
|
|
7277
7410
|
type,
|
|
7278
7411
|
"data-slot": "drag-handle",
|
|
7279
7412
|
className: cn(
|
|
7280
|
-
"inline-flex h-7 w-4 shrink-0 items-center justify-center rounded-md transition-all duration-200 max-h-
|
|
7413
|
+
"inline-flex h-7 w-4 shrink-0 items-center justify-center rounded-md transition-all duration-200 max-h-7.5",
|
|
7281
7414
|
"bg-white border border-transparent text-stone-500 shadow-md cursor-grab",
|
|
7282
7415
|
"enabled:hover:border enabled:hover:border-stone-200 enabled:hover:text-stone-950",
|
|
7283
|
-
"enabled:active:border enabled:active:border-primary enabled:active:bg-primary-50 enabled:active:text-stone-950 enabled:active:shadow enabled:active:cursor-grabbing",
|
|
7416
|
+
"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",
|
|
7284
7417
|
"disabled:cursor-not-allowed disabled:opacity-40 disabled:text-stone-950 disabled:pointer-events-none",
|
|
7285
7418
|
className
|
|
7286
7419
|
),
|
|
@@ -7302,7 +7435,7 @@ var CustomToolbar = React5.forwardRef(({ className, onMouseDown, ...props }, ref
|
|
|
7302
7435
|
"data-ohw-toolbar": "",
|
|
7303
7436
|
className: cn(
|
|
7304
7437
|
// Figma: bg background, radius 8, gap-1, p-0.5, shadow-md — no border
|
|
7305
|
-
"inline-flex h-8 items-center gap-1 rounded-
|
|
7438
|
+
"inline-flex h-8 items-center gap-1 rounded-(--radius,0.5rem) bg-background p-0.5 font-sans whitespace-nowrap shadow-md",
|
|
7306
7439
|
className
|
|
7307
7440
|
),
|
|
7308
7441
|
onMouseDown: (e) => {
|
|
@@ -7331,7 +7464,7 @@ var CustomToolbarButton = React5.forwardRef(
|
|
|
7331
7464
|
type,
|
|
7332
7465
|
className: cn(
|
|
7333
7466
|
"inline-flex size-7 shrink-0 items-center justify-center rounded-[calc(var(--radius,0.5rem)-2px)] text-foreground transition-colors",
|
|
7334
|
-
active ? "bg-primary text-primary-foreground" : "bg-transparent hover:bg-muted disabled:cursor-not-allowed disabled:text-muted-foreground disabled:opacity-60",
|
|
7467
|
+
active ? "bg-bridge-primary text-primary-foreground" : "bg-transparent hover:bg-muted disabled:cursor-not-allowed disabled:text-muted-foreground disabled:opacity-60",
|
|
7335
7468
|
className
|
|
7336
7469
|
),
|
|
7337
7470
|
...props
|
|
@@ -8595,13 +8728,13 @@ function FormFieldToolbar({
|
|
|
8595
8728
|
]
|
|
8596
8729
|
}
|
|
8597
8730
|
) }),
|
|
8598
|
-
/* @__PURE__ */ jsx13(DropdownMenuContent, { align: "start", sideOffset: 8, className: "min-w-
|
|
8731
|
+
/* @__PURE__ */ jsx13(DropdownMenuContent, { align: "start", sideOffset: 8, className: "min-w-47.5 p-1", children: FIELD_TYPES.map((entry) => {
|
|
8599
8732
|
const Icon = TYPE_ICONS[entry.type];
|
|
8600
8733
|
return /* @__PURE__ */ jsxs6(
|
|
8601
8734
|
DropdownMenuItem,
|
|
8602
8735
|
{
|
|
8603
8736
|
onSelect: () => onTypeChange(entry.type),
|
|
8604
|
-
className: "rounded-md py-2 text-[13px] " + (entry.type === type ? "bg-primary/10" : ""),
|
|
8737
|
+
className: "rounded-md py-2 text-[13px] " + (entry.type === type ? "bg-bridge-primary/10" : ""),
|
|
8605
8738
|
children: [
|
|
8606
8739
|
/* @__PURE__ */ jsx13(Icon, { size: 14, strokeWidth: 1.75, className: "shrink-0", "aria-hidden": true }),
|
|
8607
8740
|
entry.label
|
|
@@ -8618,7 +8751,7 @@ function FormFieldToolbar({
|
|
|
8618
8751
|
type: "button",
|
|
8619
8752
|
"aria-pressed": required,
|
|
8620
8753
|
onClick: onRequiredToggle,
|
|
8621
|
-
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"),
|
|
8754
|
+
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"),
|
|
8622
8755
|
"data-ohw-field-required-toggle": "",
|
|
8623
8756
|
children: [
|
|
8624
8757
|
/* @__PURE__ */ jsx13(Asterisk, { size: 14, strokeWidth: 2, "aria-hidden": true }),
|
|
@@ -8638,7 +8771,7 @@ function FormFieldToolbar({
|
|
|
8638
8771
|
children: /* @__PURE__ */ jsx13(MoreHorizontal2, { size: 15, "aria-hidden": true })
|
|
8639
8772
|
}
|
|
8640
8773
|
) }),
|
|
8641
|
-
/* @__PURE__ */ jsxs6(DropdownMenuContent, { align: "start", sideOffset: 8, className: "min-w-
|
|
8774
|
+
/* @__PURE__ */ jsxs6(DropdownMenuContent, { align: "start", sideOffset: 8, className: "min-w-42.5 p-1", children: [
|
|
8642
8775
|
/* @__PURE__ */ jsxs6(DropdownMenuItem, { onSelect: onDuplicate, className: "rounded-md py-2 text-[13px]", children: [
|
|
8643
8776
|
/* @__PURE__ */ jsx13(Copy2, { size: 14, strokeWidth: 1.75, className: "shrink-0", "aria-hidden": true }),
|
|
8644
8777
|
"Duplicate"
|
|
@@ -8666,7 +8799,7 @@ function FieldTypePicker({ onPick }) {
|
|
|
8666
8799
|
{
|
|
8667
8800
|
type: "button",
|
|
8668
8801
|
onClick: () => onPick(entry.type),
|
|
8669
|
-
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",
|
|
8802
|
+
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",
|
|
8670
8803
|
children: [
|
|
8671
8804
|
/* @__PURE__ */ jsx13(Icon, { size: 26, strokeWidth: 1.5, "aria-hidden": true }),
|
|
8672
8805
|
entry.label
|
|
@@ -8692,7 +8825,7 @@ var buttonVariants = cva(
|
|
|
8692
8825
|
{
|
|
8693
8826
|
variants: {
|
|
8694
8827
|
variant: {
|
|
8695
|
-
default: "bg-primary text-primary-foreground hover:opacity-90",
|
|
8828
|
+
default: "bg-bridge-primary text-primary-foreground hover:opacity-90",
|
|
8696
8829
|
outline: "border border-border bg-background text-foreground shadow-sm hover:bg-muted/80",
|
|
8697
8830
|
ghost: "min-w-0 px-3 py-2 text-foreground hover:bg-muted/50"
|
|
8698
8831
|
},
|
|
@@ -8765,6 +8898,7 @@ function MediaOverlay({
|
|
|
8765
8898
|
fadingOut = false,
|
|
8766
8899
|
selected = false,
|
|
8767
8900
|
hovered = false,
|
|
8901
|
+
cueOnly = false,
|
|
8768
8902
|
onFadeOutComplete,
|
|
8769
8903
|
onReplace,
|
|
8770
8904
|
onSelect,
|
|
@@ -8773,7 +8907,7 @@ function MediaOverlay({
|
|
|
8773
8907
|
const { rect } = hover;
|
|
8774
8908
|
const skeletonRef = React8.useRef(null);
|
|
8775
8909
|
const isVideo = hover.elementType === "video";
|
|
8776
|
-
const showChrome = !selected || hovered;
|
|
8910
|
+
const showChrome = (!selected || hovered) && !cueOnly;
|
|
8777
8911
|
const autoplay = hover.videoAutoplay ?? true;
|
|
8778
8912
|
const muted = hover.videoMuted ?? true;
|
|
8779
8913
|
const probeRef = React8.useRef(null);
|
|
@@ -8889,11 +9023,11 @@ function MediaOverlay({
|
|
|
8889
9023
|
// parent this needed a whole `ow:click-at` round-trip to re-hit-test inside the iframe;
|
|
8890
9024
|
// in-document, pointer-events does it natively. The button below opts back in, so
|
|
8891
9025
|
// Replace still works.
|
|
8892
|
-
pointerEvents: hover.hasTextOverlap ? "none" : "auto",
|
|
9026
|
+
pointerEvents: hover.hasTextOverlap || cueOnly ? "none" : "auto",
|
|
8893
9027
|
// Selected: a firm component ring with no wash, so the image reads as chosen rather
|
|
8894
9028
|
// than hovered. Hover keeps the existing tinted preview.
|
|
8895
|
-
boxShadow: selected ? "inset 0 0 0 2px var(--color-primary)" : "inset 0 0 0 1.5px var(--color-primary)",
|
|
8896
|
-
background: selected ? "transparent" : "color-mix(in srgb, var(--color-primary) 20%, transparent)"
|
|
9029
|
+
boxShadow: selected ? "inset 0 0 0 2px var(--color-bridge-primary)" : "inset 0 0 0 1.5px var(--color-bridge-primary)",
|
|
9030
|
+
background: selected ? "transparent" : "color-mix(in srgb, var(--color-bridge-primary) 20%, transparent)"
|
|
8897
9031
|
},
|
|
8898
9032
|
onClick: () => onSelect && !selected ? onSelect(hover.key) : onReplace(hover.key),
|
|
8899
9033
|
children: [
|
|
@@ -8920,7 +9054,7 @@ function MediaOverlay({
|
|
|
8920
9054
|
]
|
|
8921
9055
|
}
|
|
8922
9056
|
),
|
|
8923
|
-
replaceMode === "none" ? null : /* @__PURE__ */ jsxs7(
|
|
9057
|
+
replaceMode === "none" || cueOnly ? null : /* @__PURE__ */ jsxs7(
|
|
8924
9058
|
Button,
|
|
8925
9059
|
{
|
|
8926
9060
|
"data-ohw-media-overlay": "",
|
|
@@ -8940,7 +9074,7 @@ function MediaOverlay({
|
|
|
8940
9074
|
justifyContent: "center"
|
|
8941
9075
|
} : null,
|
|
8942
9076
|
// Don't let Replace steal clicks when text (e.g. nav) sits on top of this media.
|
|
8943
|
-
pointerEvents: hover.hasTextOverlap ? "none" : "auto"
|
|
9077
|
+
pointerEvents: hover.hasTextOverlap || cueOnly ? "none" : "auto"
|
|
8944
9078
|
},
|
|
8945
9079
|
onMouseDown: (e) => e.preventDefault(),
|
|
8946
9080
|
onClick: (e) => {
|
|
@@ -8970,7 +9104,8 @@ var OVERLAY_BUTTON_STYLE2 = {
|
|
|
8970
9104
|
};
|
|
8971
9105
|
function CarouselOverlay({
|
|
8972
9106
|
hover,
|
|
8973
|
-
onEdit
|
|
9107
|
+
onEdit,
|
|
9108
|
+
cueOnly = false
|
|
8974
9109
|
}) {
|
|
8975
9110
|
const { rect } = hover;
|
|
8976
9111
|
return /* @__PURE__ */ jsx16(
|
|
@@ -8986,12 +9121,12 @@ function CarouselOverlay({
|
|
|
8986
9121
|
width: rect.width,
|
|
8987
9122
|
height: rect.height,
|
|
8988
9123
|
zIndex: 2147483646,
|
|
8989
|
-
pointerEvents: "auto",
|
|
8990
|
-
boxShadow: "inset 0 0 0 1.5px var(--color-primary)",
|
|
8991
|
-
background: "color-mix(in srgb, var(--color-primary) 20%, transparent)"
|
|
9124
|
+
pointerEvents: cueOnly ? "none" : "auto",
|
|
9125
|
+
boxShadow: "inset 0 0 0 1.5px var(--color-bridge-primary)",
|
|
9126
|
+
background: "color-mix(in srgb, var(--color-bridge-primary) 20%, transparent)"
|
|
8992
9127
|
},
|
|
8993
9128
|
onClick: () => onEdit(hover.key),
|
|
8994
|
-
children: /* @__PURE__ */ jsxs8(
|
|
9129
|
+
children: cueOnly ? null : /* @__PURE__ */ jsxs8(
|
|
8995
9130
|
Button,
|
|
8996
9131
|
{
|
|
8997
9132
|
"data-ohw-carousel-overlay": "",
|
|
@@ -9182,7 +9317,8 @@ function ReviewButton({
|
|
|
9182
9317
|
}
|
|
9183
9318
|
function AiSectionOverlay({
|
|
9184
9319
|
postToParent: postToParent2,
|
|
9185
|
-
apiRef
|
|
9320
|
+
apiRef,
|
|
9321
|
+
onSelectionChange
|
|
9186
9322
|
}) {
|
|
9187
9323
|
const [selectedId, setSelectedId] = useState6(null);
|
|
9188
9324
|
const [reviewId, setReviewId] = useState6(null);
|
|
@@ -9191,6 +9327,9 @@ function AiSectionOverlay({
|
|
|
9191
9327
|
reviewIdRef.current = reviewId;
|
|
9192
9328
|
const selectedIdRef = useRef4(null);
|
|
9193
9329
|
selectedIdRef.current = selectedId;
|
|
9330
|
+
useEffect4(() => {
|
|
9331
|
+
onSelectionChange?.(selectedId);
|
|
9332
|
+
}, [selectedId, onSelectionChange]);
|
|
9194
9333
|
const report = useCallback2(
|
|
9195
9334
|
(el) => {
|
|
9196
9335
|
const labelSrc = el ? sectionElementOf(el) : null;
|
|
@@ -9208,6 +9347,7 @@ function AiSectionOverlay({
|
|
|
9208
9347
|
const sectionEl = inner ? movableUnit(inner) : null;
|
|
9209
9348
|
const id = sectionEl ? instanceIdOf(sectionEl) || null : null;
|
|
9210
9349
|
if (id === selectedIdRef.current) return;
|
|
9350
|
+
selectedIdRef.current = id;
|
|
9211
9351
|
setSelectedId(id);
|
|
9212
9352
|
if (options?.report !== false) report(sectionEl);
|
|
9213
9353
|
},
|
|
@@ -9228,9 +9368,11 @@ function AiSectionOverlay({
|
|
|
9228
9368
|
return sectionEl != null;
|
|
9229
9369
|
},
|
|
9230
9370
|
clear: () => {
|
|
9371
|
+
selectedIdRef.current = null;
|
|
9231
9372
|
setSelectedId(null);
|
|
9232
9373
|
report(null);
|
|
9233
|
-
}
|
|
9374
|
+
},
|
|
9375
|
+
getSelectedId: () => selectedIdRef.current
|
|
9234
9376
|
};
|
|
9235
9377
|
return () => {
|
|
9236
9378
|
apiRef.current = null;
|
|
@@ -9239,6 +9381,7 @@ function AiSectionOverlay({
|
|
|
9239
9381
|
useEffect4(() => {
|
|
9240
9382
|
const onMessage = (e) => {
|
|
9241
9383
|
if (e.data?.type === "ow:ai-select" && e.data.sectionId === null) {
|
|
9384
|
+
selectedIdRef.current = null;
|
|
9242
9385
|
setSelectedId(null);
|
|
9243
9386
|
return;
|
|
9244
9387
|
}
|
|
@@ -9289,6 +9432,7 @@ function AiSectionOverlay({
|
|
|
9289
9432
|
if (reviewIdRef.current) return;
|
|
9290
9433
|
if (document.querySelector("[data-ohw-editing]")) return;
|
|
9291
9434
|
if (selectedIdRef.current) {
|
|
9435
|
+
selectedIdRef.current = null;
|
|
9292
9436
|
setSelectedId(null);
|
|
9293
9437
|
report(null);
|
|
9294
9438
|
}
|
|
@@ -9910,7 +10054,7 @@ function SectionTreeItem({
|
|
|
9910
10054
|
/* @__PURE__ */ jsx20(
|
|
9911
10055
|
"div",
|
|
9912
10056
|
{
|
|
9913
|
-
className: "mr-
|
|
10057
|
+
className: "-mr-px h-9 w-2 shrink-0 rounded-bl-sm border-b border-l border-border mb-4",
|
|
9914
10058
|
"aria-hidden": true
|
|
9915
10059
|
}
|
|
9916
10060
|
),
|
|
@@ -9929,7 +10073,7 @@ function SectionTreeItem({
|
|
|
9929
10073
|
className: cn(
|
|
9930
10074
|
"flex h-9 min-w-0 flex-1 items-center gap-2 rounded-md border border-border bg-background p-3",
|
|
9931
10075
|
interactive && "cursor-pointer hover:bg-muted/30",
|
|
9932
|
-
interactive && selected && "border-primary"
|
|
10076
|
+
interactive && selected && "border-bridge-primary"
|
|
9933
10077
|
),
|
|
9934
10078
|
children: [
|
|
9935
10079
|
/* @__PURE__ */ jsx20(
|
|
@@ -10059,7 +10203,7 @@ function UrlOrPageInput({
|
|
|
10059
10203
|
};
|
|
10060
10204
|
const fieldClassName = cn(
|
|
10061
10205
|
"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]",
|
|
10062
|
-
urlError ? "border-destructive shadow-[0_0_0_1px_var(--ohw-destructive)]" : isFocused ? "border-primary shadow-[0_0_0_1px_var(--ohw-primary)]" : "border-input"
|
|
10206
|
+
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"
|
|
10063
10207
|
);
|
|
10064
10208
|
return /* @__PURE__ */ jsxs13("div", { className: "flex w-full flex-col gap-2 p-0", children: [
|
|
10065
10209
|
/* @__PURE__ */ jsx23(Label, { htmlFor: inputId, className: cn(urlError && "text-destructive"), children: "Destination" }),
|
|
@@ -14268,7 +14412,7 @@ function DisplaySwitch({
|
|
|
14268
14412
|
onClick: () => onChange(!checked),
|
|
14269
14413
|
className: cn(
|
|
14270
14414
|
"relative h-5 w-9 shrink-0 rounded-full transition-colors",
|
|
14271
|
-
checked ? "bg-primary" : "bg-primary-50",
|
|
14415
|
+
checked ? "bg-bridge-primary" : "bg-primary-50",
|
|
14272
14416
|
disabled ? "cursor-default opacity-50" : "cursor-pointer"
|
|
14273
14417
|
),
|
|
14274
14418
|
children: /* @__PURE__ */ jsx28(
|
|
@@ -14276,7 +14420,7 @@ function DisplaySwitch({
|
|
|
14276
14420
|
{
|
|
14277
14421
|
className: cn(
|
|
14278
14422
|
"absolute top-0.5 h-4 w-4 rounded-full bg-white transition-all",
|
|
14279
|
-
checked ? "left-
|
|
14423
|
+
checked ? "left-4.5" : "left-0.5"
|
|
14280
14424
|
)
|
|
14281
14425
|
}
|
|
14282
14426
|
)
|
|
@@ -15911,7 +16055,7 @@ var badgeVariants = cva(
|
|
|
15911
16055
|
{
|
|
15912
16056
|
variants: {
|
|
15913
16057
|
variant: {
|
|
15914
|
-
default: "border-transparent bg-primary text-primary-foreground",
|
|
16058
|
+
default: "border-transparent bg-bridge-primary text-primary-foreground",
|
|
15915
16059
|
secondary: "border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80",
|
|
15916
16060
|
destructive: "border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80",
|
|
15917
16061
|
outline: "text-foreground"
|
|
@@ -16303,6 +16447,19 @@ function isMediaEditable(el) {
|
|
|
16303
16447
|
const t = el.dataset.ohwEditable;
|
|
16304
16448
|
return t === "image" || t === "bg-image" || t === "video";
|
|
16305
16449
|
}
|
|
16450
|
+
var FULL_BLEED_MIN_COVERAGE = 0.98;
|
|
16451
|
+
function fullBleedSectionIdOf(media) {
|
|
16452
|
+
const section = media.closest("[data-ohw-section]");
|
|
16453
|
+
if (!section) return null;
|
|
16454
|
+
const s = section.getBoundingClientRect();
|
|
16455
|
+
if (s.width <= 0 || s.height <= 0) return null;
|
|
16456
|
+
const m = media.getBoundingClientRect();
|
|
16457
|
+
const overlapX = Math.min(m.right, s.right) - Math.max(m.left, s.left);
|
|
16458
|
+
const overlapY = Math.min(m.bottom, s.bottom) - Math.max(m.top, s.top);
|
|
16459
|
+
if (overlapX <= 0 || overlapY <= 0) return null;
|
|
16460
|
+
if (overlapX * overlapY / (s.width * s.height) < FULL_BLEED_MIN_COVERAGE) return null;
|
|
16461
|
+
return instanceIdOf(movableUnit(section)) || null;
|
|
16462
|
+
}
|
|
16306
16463
|
function isIconMarkupValue(value) {
|
|
16307
16464
|
return /^\s*<(svg|img)\b/i.test(value);
|
|
16308
16465
|
}
|
|
@@ -17476,20 +17633,38 @@ function OhhwellsBridge() {
|
|
|
17476
17633
|
const hoveredImageHasTextOverlapRef = useRef10(false);
|
|
17477
17634
|
const dragOverElRef = useRef10(null);
|
|
17478
17635
|
const [mediaHover, setMediaHover] = useState14(null);
|
|
17636
|
+
const [selectedAiSectionId, setSelectedAiSectionId] = useState14(null);
|
|
17637
|
+
const selectedAiSectionIdRef = useRef10(null);
|
|
17638
|
+
const handleAiSectionSelectionChange = useCallback8((id) => {
|
|
17639
|
+
selectedAiSectionIdRef.current = id;
|
|
17640
|
+
setSelectedAiSectionId(id);
|
|
17641
|
+
}, []);
|
|
17479
17642
|
const [selectedMedia, setSelectedMedia] = useState14(null);
|
|
17480
17643
|
const selectedMediaElRef = useRef10(null);
|
|
17644
|
+
const mediaKeyDropTokenRef = useRef10(0);
|
|
17481
17645
|
const clearMediaSelection = useCallback8(() => {
|
|
17482
17646
|
const prev = selectedMediaElRef.current;
|
|
17483
17647
|
selectedMediaElRef.current = null;
|
|
17484
17648
|
setSelectedMedia(null);
|
|
17485
17649
|
const sectionEl = prev?.closest("[data-ohw-section]") ?? null;
|
|
17486
17650
|
if (sectionEl) {
|
|
17487
|
-
|
|
17488
|
-
|
|
17489
|
-
|
|
17490
|
-
|
|
17491
|
-
key
|
|
17492
|
-
|
|
17651
|
+
const sectionInstanceId = instanceIdOf(movableUnit(sectionEl)) || null;
|
|
17652
|
+
if (!sectionInstanceId) return;
|
|
17653
|
+
const token = ++mediaKeyDropTokenRef.current;
|
|
17654
|
+
const onQueueDrained = (e) => {
|
|
17655
|
+
if (e.source !== window || e.data?.type !== "ow:media-key-drop" || e.data.token !== token) return;
|
|
17656
|
+
window.removeEventListener("message", onQueueDrained);
|
|
17657
|
+
if (aiSectionApiRef.current?.getSelectedId() !== sectionInstanceId) return;
|
|
17658
|
+
if (selectedMediaElRef.current) return;
|
|
17659
|
+
postToParentRef.current({
|
|
17660
|
+
type: "ow:section-selected",
|
|
17661
|
+
sectionId: sectionEl.dataset.ohwSection ?? null,
|
|
17662
|
+
sectionLabel: sectionEl.dataset.ohwSectionLabel ?? titleCaseSectionId(sectionEl.dataset.ohwSection ?? ""),
|
|
17663
|
+
key: null
|
|
17664
|
+
});
|
|
17665
|
+
};
|
|
17666
|
+
window.addEventListener("message", onQueueDrained);
|
|
17667
|
+
window.postMessage({ type: "ow:media-key-drop", token }, "*");
|
|
17493
17668
|
}
|
|
17494
17669
|
}, []);
|
|
17495
17670
|
const clearMediaSelectionRef = useRef10(clearMediaSelection);
|
|
@@ -19381,7 +19556,9 @@ function OhhwellsBridge() {
|
|
|
19381
19556
|
}, [isEditMode]);
|
|
19382
19557
|
useEffect13(() => {
|
|
19383
19558
|
if (isEditMode || fetchState !== "done") return;
|
|
19559
|
+
console.log("env", process.env.NEXT_PUBLIC_FLOWOPS_API_URL);
|
|
19384
19560
|
const apiUrl = process.env.NEXT_PUBLIC_FLOWOPS_API_URL ?? "https://flowops-backend-staging-2yfdh7pwpq-as.a.run.app";
|
|
19561
|
+
console.log({ apiUrl, subdomain });
|
|
19385
19562
|
bindPublishedForms(apiUrl, subdomain, contentCache.get(subdomain) ?? {});
|
|
19386
19563
|
}, [isEditMode, fetchState, subdomain]);
|
|
19387
19564
|
useEffect13(() => {
|
|
@@ -19929,6 +20106,23 @@ function OhhwellsBridge() {
|
|
|
19929
20106
|
if (selectedMediaElRef.current && !selectedMediaElRef.current.contains(target) && !target.closest("[data-ohw-media-overlay], [data-ohw-edit-chrome], [data-ohw-item-interaction]")) {
|
|
19930
20107
|
clearMediaSelectionRef.current();
|
|
19931
20108
|
}
|
|
20109
|
+
if (selectedMediaElRef.current && target.closest("[data-ohw-media-overlay]") && !findClosestButtonLike(target)) {
|
|
20110
|
+
const hit = findImageAtPoint(e.clientX, e.clientY, false);
|
|
20111
|
+
if (hit && hit !== selectedMediaElRef.current) {
|
|
20112
|
+
e.preventDefault();
|
|
20113
|
+
e.stopPropagation();
|
|
20114
|
+
const fullBleedSectionId = fullBleedSectionIdOf(hit);
|
|
20115
|
+
if (fullBleedSectionId && fullBleedSectionId !== selectedAiSectionIdRef.current) {
|
|
20116
|
+
clearMediaSelectionRef.current();
|
|
20117
|
+
deselectRef.current();
|
|
20118
|
+
deactivateRef.current();
|
|
20119
|
+
aiSectionApiRef.current?.selectFromElement(hit);
|
|
20120
|
+
return;
|
|
20121
|
+
}
|
|
20122
|
+
selectMediaElementRef.current(hit);
|
|
20123
|
+
return;
|
|
20124
|
+
}
|
|
20125
|
+
}
|
|
19932
20126
|
if (isInsideFloatingPanel(target)) return;
|
|
19933
20127
|
if (target.closest("[data-ohw-form-toolbar]")) return;
|
|
19934
20128
|
if (target.closest(
|
|
@@ -20110,6 +20304,14 @@ function OhhwellsBridge() {
|
|
|
20110
20304
|
if (isMediaEditable(editable) && !buttonOnMedia) {
|
|
20111
20305
|
e.preventDefault();
|
|
20112
20306
|
e.stopPropagation();
|
|
20307
|
+
const fullBleedSectionId = fullBleedSectionIdOf(editable);
|
|
20308
|
+
if (fullBleedSectionId && fullBleedSectionId !== selectedAiSectionIdRef.current) {
|
|
20309
|
+
clearMediaSelectionRef.current();
|
|
20310
|
+
deselectRef.current();
|
|
20311
|
+
deactivateRef.current();
|
|
20312
|
+
aiSectionApiRef.current?.selectFromElement(editable);
|
|
20313
|
+
return;
|
|
20314
|
+
}
|
|
20113
20315
|
if (selectedMediaElRef.current === editable) {
|
|
20114
20316
|
postToParentRef.current({ type: "ow:image-pick", key: editable.dataset.ohwKey ?? "", elementType: editable.dataset.ohwEditable ?? "image" });
|
|
20115
20317
|
} else {
|
|
@@ -20564,6 +20766,7 @@ function OhhwellsBridge() {
|
|
|
20564
20766
|
elementType: imgEl.dataset.ohwEditable ?? "image",
|
|
20565
20767
|
hasTextOverlap,
|
|
20566
20768
|
isDragOver,
|
|
20769
|
+
fullBleedSectionId: fullBleedSectionIdOf(imgEl),
|
|
20567
20770
|
...video ? { videoAutoplay: video.autoplay, videoMuted: video.muted } : {}
|
|
20568
20771
|
});
|
|
20569
20772
|
const track = imgEl.closest("[data-ohw-hover-pause]");
|
|
@@ -20736,7 +20939,13 @@ function OhhwellsBridge() {
|
|
|
20736
20939
|
setHoveredItemRect(null);
|
|
20737
20940
|
}
|
|
20738
20941
|
};
|
|
20942
|
+
const syncSelectedMediaPointerRelease = (released) => {
|
|
20943
|
+
setSelectedMedia(
|
|
20944
|
+
(prev) => prev && prev.hasTextOverlap !== released ? { ...prev, hasTextOverlap: released } : prev
|
|
20945
|
+
);
|
|
20946
|
+
};
|
|
20739
20947
|
const probeImageAt = (clientX, clientY, isDragOver = false, fromParentViewport = false) => {
|
|
20948
|
+
syncSelectedMediaPointerRelease(true);
|
|
20740
20949
|
if (linkPopoverOpenRef.current) {
|
|
20741
20950
|
if (hoveredImageRef.current) {
|
|
20742
20951
|
hoveredImageRef.current = null;
|
|
@@ -20931,6 +21140,7 @@ function OhhwellsBridge() {
|
|
|
20931
21140
|
return;
|
|
20932
21141
|
}
|
|
20933
21142
|
document.querySelectorAll("[data-ohw-hovered]").forEach((el) => el.removeAttribute("data-ohw-hovered"));
|
|
21143
|
+
syncSelectedMediaPointerRelease(false);
|
|
20934
21144
|
if (imgEl !== hoveredImageRef.current || hoveredImageHasTextOverlapRef.current) {
|
|
20935
21145
|
hoveredImageRef.current = imgEl;
|
|
20936
21146
|
showImageHover(imgEl, isDragOver);
|
|
@@ -21731,10 +21941,26 @@ function OhhwellsBridge() {
|
|
|
21731
21941
|
const handleGetBrand = (e) => {
|
|
21732
21942
|
if (e.data?.type !== "ow:get-brand") return;
|
|
21733
21943
|
const template = deriveTemplateBrand();
|
|
21734
|
-
const
|
|
21944
|
+
const fallback = template ?? (() => {
|
|
21945
|
+
const fonts = deriveTemplateFonts();
|
|
21946
|
+
return fonts ? { palette: AI_DEFAULT_BRAND.palette, fonts } : null;
|
|
21947
|
+
})();
|
|
21948
|
+
const value = brandKitRef.current || (fallback ? JSON.stringify(fallback) : "");
|
|
21735
21949
|
postToParentRef.current({ type: "ow:brand-value", value });
|
|
21736
21950
|
};
|
|
21737
21951
|
window.addEventListener("message", handleGetBrand);
|
|
21952
|
+
const handleGetTemplateFonts = (e) => {
|
|
21953
|
+
if (e.data?.type !== "ow:get-template-fonts") return;
|
|
21954
|
+
const fonts = deriveTemplateFonts();
|
|
21955
|
+
postToParentRef.current({ type: "ow:template-fonts-value", value: fonts ? JSON.stringify(fonts) : "" });
|
|
21956
|
+
};
|
|
21957
|
+
window.addEventListener("message", handleGetTemplateFonts);
|
|
21958
|
+
const handleGetTemplateBrand = (e) => {
|
|
21959
|
+
if (e.data?.type !== "ow:get-template-brand") return;
|
|
21960
|
+
const brand = deriveTemplateBrand();
|
|
21961
|
+
postToParentRef.current({ type: "ow:template-brand-value", value: brand ? JSON.stringify(brand) : "" });
|
|
21962
|
+
};
|
|
21963
|
+
window.addEventListener("message", handleGetTemplateBrand);
|
|
21738
21964
|
const handleMoveSection = (e) => {
|
|
21739
21965
|
if (e.data?.type !== "ow:move-section") return;
|
|
21740
21966
|
const instanceId = typeof e.data.instanceId === "string" ? e.data.instanceId : "";
|
|
@@ -22388,7 +22614,11 @@ function OhhwellsBridge() {
|
|
|
22388
22614
|
if (!key) return;
|
|
22389
22615
|
const r2 = getVisibleRect(container);
|
|
22390
22616
|
setCarouselHover(
|
|
22391
|
-
(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 : {
|
|
22617
|
+
(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 : {
|
|
22618
|
+
key,
|
|
22619
|
+
rect: { top: r2.top, left: r2.left, width: r2.width, height: r2.height },
|
|
22620
|
+
fullBleedSectionId: fullBleedSectionIdOf(container)
|
|
22621
|
+
}
|
|
22392
22622
|
);
|
|
22393
22623
|
};
|
|
22394
22624
|
const applyToolbarPos = (rect) => {
|
|
@@ -22637,6 +22867,8 @@ function OhhwellsBridge() {
|
|
|
22637
22867
|
window.removeEventListener("message", handleAiSetBrand);
|
|
22638
22868
|
window.removeEventListener("message", handleAiSetStyles);
|
|
22639
22869
|
window.removeEventListener("message", handleGetBrand);
|
|
22870
|
+
window.removeEventListener("message", handleGetTemplateFonts);
|
|
22871
|
+
window.removeEventListener("message", handleGetTemplateBrand);
|
|
22640
22872
|
window.removeEventListener("message", handleMoveSection);
|
|
22641
22873
|
window.removeEventListener("message", handlePanelDragging);
|
|
22642
22874
|
window.removeEventListener("message", handleDeleteSection);
|
|
@@ -22848,7 +23080,7 @@ function OhhwellsBridge() {
|
|
|
22848
23080
|
postToParent2({
|
|
22849
23081
|
type: "ow:ready",
|
|
22850
23082
|
version: "1",
|
|
22851
|
-
bridgeVersion: "0.1.
|
|
23083
|
+
bridgeVersion: "0.1.116",
|
|
22852
23084
|
path: pathname,
|
|
22853
23085
|
nodes: collectEditableNodes(editContentRef.current),
|
|
22854
23086
|
sections
|
|
@@ -23315,7 +23547,14 @@ function OhhwellsBridge() {
|
|
|
23315
23547
|
bridgeRoot ? createPortal3(
|
|
23316
23548
|
/* @__PURE__ */ jsxs20(Fragment8, { children: [
|
|
23317
23549
|
/* @__PURE__ */ jsx33("div", { ref: attachVisibleViewport, "data-ohw-visible-viewport": "", "aria-hidden": true }),
|
|
23318
|
-
isEditMode && /* @__PURE__ */ jsx33(
|
|
23550
|
+
isEditMode && /* @__PURE__ */ jsx33(
|
|
23551
|
+
AiSectionOverlay,
|
|
23552
|
+
{
|
|
23553
|
+
postToParent: postToParent2,
|
|
23554
|
+
apiRef: aiSectionApiRef,
|
|
23555
|
+
onSelectionChange: handleAiSectionSelectionChange
|
|
23556
|
+
}
|
|
23557
|
+
),
|
|
23319
23558
|
isSectionDragging && sectionDropSlots.map((slot, i) => /* @__PURE__ */ jsx33(
|
|
23320
23559
|
"div",
|
|
23321
23560
|
{
|
|
@@ -23348,6 +23587,7 @@ function OhhwellsBridge() {
|
|
|
23348
23587
|
{
|
|
23349
23588
|
hover: mediaHover,
|
|
23350
23589
|
isUploading: false,
|
|
23590
|
+
cueOnly: !mediaHover.isDragOver && !!mediaHover.fullBleedSectionId && mediaHover.fullBleedSectionId !== selectedAiSectionId,
|
|
23351
23591
|
onReplace: handleMediaReplace,
|
|
23352
23592
|
onSelect: handleMediaSelect,
|
|
23353
23593
|
onVideoSettingsChange: handleVideoSettingsChange
|
|
@@ -23365,7 +23605,14 @@ function OhhwellsBridge() {
|
|
|
23365
23605
|
onVideoSettingsChange: handleVideoSettingsChange
|
|
23366
23606
|
}
|
|
23367
23607
|
),
|
|
23368
|
-
carouselHover && !linkPopover && !isItemDragging && /* @__PURE__ */ jsx33(
|
|
23608
|
+
carouselHover && !linkPopover && !isItemDragging && /* @__PURE__ */ jsx33(
|
|
23609
|
+
CarouselOverlay,
|
|
23610
|
+
{
|
|
23611
|
+
hover: carouselHover,
|
|
23612
|
+
onEdit: handleEditCarousel,
|
|
23613
|
+
cueOnly: !!carouselHover.fullBleedSectionId && carouselHover.fullBleedSectionId !== selectedAiSectionId
|
|
23614
|
+
}
|
|
23615
|
+
),
|
|
23369
23616
|
siblingHintRect && !linkPopover && !isItemDragging && siblingHintRects.length === 0 && /* @__PURE__ */ jsx33(ItemInteractionLayer, { rect: siblingHintRect, state: "sibling-hint" }),
|
|
23370
23617
|
siblingHintRects.length > 0 && !linkPopover && !isItemDragging && siblingHintRects.map((rect, i) => /* @__PURE__ */ jsx33(ItemInteractionLayer, { rect, state: "sibling-hint" }, `sibling-hint-${i}`)),
|
|
23371
23618
|
isItemDragging && draggedItemRect && selectedElRef.current !== footerDragRef.current?.draggedEl && selectedElRef.current !== navDragRef.current?.draggedEl && /* @__PURE__ */ jsx33(ItemInteractionLayer, { rect: draggedItemRect, state: "dragging" }),
|
|
@@ -23464,7 +23711,7 @@ function OhhwellsBridge() {
|
|
|
23464
23711
|
"span",
|
|
23465
23712
|
{
|
|
23466
23713
|
"data-ohw-form-count": "",
|
|
23467
|
-
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",
|
|
23714
|
+
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",
|
|
23468
23715
|
children: formPickCount
|
|
23469
23716
|
}
|
|
23470
23717
|
)
|
|
@@ -23702,11 +23949,11 @@ function OhhwellsBridge() {
|
|
|
23702
23949
|
className: "fixed left-0 w-full z-2147483646 flex items-center pointer-events-none",
|
|
23703
23950
|
style: { top: sectionGap.y, transform: "translateY(-50%)" },
|
|
23704
23951
|
children: [
|
|
23705
|
-
/* @__PURE__ */ jsx33("div", { className: "flex-1 bg-primary", style: { height: 3 } }),
|
|
23952
|
+
/* @__PURE__ */ jsx33("div", { className: "flex-1 bg-bridge-primary", style: { height: 3 } }),
|
|
23706
23953
|
/* @__PURE__ */ jsx33(
|
|
23707
23954
|
Badge,
|
|
23708
23955
|
{
|
|
23709
|
-
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",
|
|
23956
|
+
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",
|
|
23710
23957
|
onClick: () => {
|
|
23711
23958
|
window.parent.postMessage(
|
|
23712
23959
|
{
|
|
@@ -23720,7 +23967,7 @@ function OhhwellsBridge() {
|
|
|
23720
23967
|
children: "Add Section"
|
|
23721
23968
|
}
|
|
23722
23969
|
),
|
|
23723
|
-
/* @__PURE__ */ jsx33("div", { className: "flex-1 bg-primary", style: { height: 3 } })
|
|
23970
|
+
/* @__PURE__ */ jsx33("div", { className: "flex-1 bg-bridge-primary", style: { height: 3 } })
|
|
23724
23971
|
]
|
|
23725
23972
|
}
|
|
23726
23973
|
),
|