@ohhwells/bridge 0.1.115 → 0.1.116
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 +204 -51
- 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 +204 -51
- package/dist/index.js.map +1 -1
- package/dist/styles.css +67 -65
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -63,6 +63,27 @@ interface AiLayoutTree {
|
|
|
63
63
|
align?: 'top' | 'center' | 'bottom' | 'stretch';
|
|
64
64
|
}>;
|
|
65
65
|
}
|
|
66
|
+
/** One uploaded weight file for a custom font family. */
|
|
67
|
+
interface AiCustomFontWeight {
|
|
68
|
+
weight: number;
|
|
69
|
+
/** Present when the file is a variable font with a `wght` axis — `weight` is the axis min,
|
|
70
|
+
* `weightEnd` the axis max, together spanning every weight the one file actually covers. */
|
|
71
|
+
weightEnd?: number;
|
|
72
|
+
url: string;
|
|
73
|
+
format: 'woff2' | 'woff' | 'truetype' | 'opentype';
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* A custom (non-Google) font family, grouped by its uploaded weight files so a bold heading
|
|
77
|
+
* actually resolves to a real bold file instead of the browser synthesizing fake bold from
|
|
78
|
+
* whichever single weight happens to be present.
|
|
79
|
+
*/
|
|
80
|
+
interface AiCustomFont {
|
|
81
|
+
/** Collision-proof internal family name — what `fonts.heading`/`fonts.body` actually reference. */
|
|
82
|
+
family: string;
|
|
83
|
+
/** Human-readable name shown in the picker; hidden everywhere the internal `family` is used. */
|
|
84
|
+
label: string;
|
|
85
|
+
weights: AiCustomFontWeight[];
|
|
86
|
+
}
|
|
66
87
|
/** The site brand kit the renderer styles from (editor Brand settings). */
|
|
67
88
|
interface AiBrandKit {
|
|
68
89
|
palette: {
|
|
@@ -75,6 +96,7 @@ interface AiBrandKit {
|
|
|
75
96
|
heading: string;
|
|
76
97
|
body: string;
|
|
77
98
|
};
|
|
99
|
+
customFonts?: AiCustomFont[];
|
|
78
100
|
}
|
|
79
101
|
/**
|
|
80
102
|
* Shape, padding and typography measured off a host-template CTA, so generated buttons read as the
|
package/dist/index.d.ts
CHANGED
|
@@ -63,6 +63,27 @@ interface AiLayoutTree {
|
|
|
63
63
|
align?: 'top' | 'center' | 'bottom' | 'stretch';
|
|
64
64
|
}>;
|
|
65
65
|
}
|
|
66
|
+
/** One uploaded weight file for a custom font family. */
|
|
67
|
+
interface AiCustomFontWeight {
|
|
68
|
+
weight: number;
|
|
69
|
+
/** Present when the file is a variable font with a `wght` axis — `weight` is the axis min,
|
|
70
|
+
* `weightEnd` the axis max, together spanning every weight the one file actually covers. */
|
|
71
|
+
weightEnd?: number;
|
|
72
|
+
url: string;
|
|
73
|
+
format: 'woff2' | 'woff' | 'truetype' | 'opentype';
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* A custom (non-Google) font family, grouped by its uploaded weight files so a bold heading
|
|
77
|
+
* actually resolves to a real bold file instead of the browser synthesizing fake bold from
|
|
78
|
+
* whichever single weight happens to be present.
|
|
79
|
+
*/
|
|
80
|
+
interface AiCustomFont {
|
|
81
|
+
/** Collision-proof internal family name — what `fonts.heading`/`fonts.body` actually reference. */
|
|
82
|
+
family: string;
|
|
83
|
+
/** Human-readable name shown in the picker; hidden everywhere the internal `family` is used. */
|
|
84
|
+
label: string;
|
|
85
|
+
weights: AiCustomFontWeight[];
|
|
86
|
+
}
|
|
66
87
|
/** The site brand kit the renderer styles from (editor Brand settings). */
|
|
67
88
|
interface AiBrandKit {
|
|
68
89
|
palette: {
|
|
@@ -75,6 +96,7 @@ interface AiBrandKit {
|
|
|
75
96
|
heading: string;
|
|
76
97
|
body: string;
|
|
77
98
|
};
|
|
99
|
+
customFonts?: AiCustomFont[];
|
|
78
100
|
}
|
|
79
101
|
/**
|
|
80
102
|
* Shape, padding and typography measured off a host-template CTA, so generated buttons read as the
|
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
|
},
|
|
@@ -8892,8 +9025,8 @@ function MediaOverlay({
|
|
|
8892
9025
|
pointerEvents: hover.hasTextOverlap ? "none" : "auto",
|
|
8893
9026
|
// Selected: a firm component ring with no wash, so the image reads as chosen rather
|
|
8894
9027
|
// 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)"
|
|
9028
|
+
boxShadow: selected ? "inset 0 0 0 2px var(--color-bridge-primary)" : "inset 0 0 0 1.5px var(--color-bridge-primary)",
|
|
9029
|
+
background: selected ? "transparent" : "color-mix(in srgb, var(--color-bridge-primary) 20%, transparent)"
|
|
8897
9030
|
},
|
|
8898
9031
|
onClick: () => onSelect && !selected ? onSelect(hover.key) : onReplace(hover.key),
|
|
8899
9032
|
children: [
|
|
@@ -8987,8 +9120,8 @@ function CarouselOverlay({
|
|
|
8987
9120
|
height: rect.height,
|
|
8988
9121
|
zIndex: 2147483646,
|
|
8989
9122
|
pointerEvents: "auto",
|
|
8990
|
-
boxShadow: "inset 0 0 0 1.5px var(--color-primary)",
|
|
8991
|
-
background: "color-mix(in srgb, var(--color-primary) 20%, transparent)"
|
|
9123
|
+
boxShadow: "inset 0 0 0 1.5px var(--color-bridge-primary)",
|
|
9124
|
+
background: "color-mix(in srgb, var(--color-bridge-primary) 20%, transparent)"
|
|
8992
9125
|
},
|
|
8993
9126
|
onClick: () => onEdit(hover.key),
|
|
8994
9127
|
children: /* @__PURE__ */ jsxs8(
|
|
@@ -9910,7 +10043,7 @@ function SectionTreeItem({
|
|
|
9910
10043
|
/* @__PURE__ */ jsx20(
|
|
9911
10044
|
"div",
|
|
9912
10045
|
{
|
|
9913
|
-
className: "mr-
|
|
10046
|
+
className: "-mr-px h-9 w-2 shrink-0 rounded-bl-sm border-b border-l border-border mb-4",
|
|
9914
10047
|
"aria-hidden": true
|
|
9915
10048
|
}
|
|
9916
10049
|
),
|
|
@@ -9929,7 +10062,7 @@ function SectionTreeItem({
|
|
|
9929
10062
|
className: cn(
|
|
9930
10063
|
"flex h-9 min-w-0 flex-1 items-center gap-2 rounded-md border border-border bg-background p-3",
|
|
9931
10064
|
interactive && "cursor-pointer hover:bg-muted/30",
|
|
9932
|
-
interactive && selected && "border-primary"
|
|
10065
|
+
interactive && selected && "border-bridge-primary"
|
|
9933
10066
|
),
|
|
9934
10067
|
children: [
|
|
9935
10068
|
/* @__PURE__ */ jsx20(
|
|
@@ -10059,7 +10192,7 @@ function UrlOrPageInput({
|
|
|
10059
10192
|
};
|
|
10060
10193
|
const fieldClassName = cn(
|
|
10061
10194
|
"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"
|
|
10195
|
+
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
10196
|
);
|
|
10064
10197
|
return /* @__PURE__ */ jsxs13("div", { className: "flex w-full flex-col gap-2 p-0", children: [
|
|
10065
10198
|
/* @__PURE__ */ jsx23(Label, { htmlFor: inputId, className: cn(urlError && "text-destructive"), children: "Destination" }),
|
|
@@ -14268,7 +14401,7 @@ function DisplaySwitch({
|
|
|
14268
14401
|
onClick: () => onChange(!checked),
|
|
14269
14402
|
className: cn(
|
|
14270
14403
|
"relative h-5 w-9 shrink-0 rounded-full transition-colors",
|
|
14271
|
-
checked ? "bg-primary" : "bg-primary-50",
|
|
14404
|
+
checked ? "bg-bridge-primary" : "bg-primary-50",
|
|
14272
14405
|
disabled ? "cursor-default opacity-50" : "cursor-pointer"
|
|
14273
14406
|
),
|
|
14274
14407
|
children: /* @__PURE__ */ jsx28(
|
|
@@ -14276,7 +14409,7 @@ function DisplaySwitch({
|
|
|
14276
14409
|
{
|
|
14277
14410
|
className: cn(
|
|
14278
14411
|
"absolute top-0.5 h-4 w-4 rounded-full bg-white transition-all",
|
|
14279
|
-
checked ? "left-
|
|
14412
|
+
checked ? "left-4.5" : "left-0.5"
|
|
14280
14413
|
)
|
|
14281
14414
|
}
|
|
14282
14415
|
)
|
|
@@ -15911,7 +16044,7 @@ var badgeVariants = cva(
|
|
|
15911
16044
|
{
|
|
15912
16045
|
variants: {
|
|
15913
16046
|
variant: {
|
|
15914
|
-
default: "border-transparent bg-primary text-primary-foreground",
|
|
16047
|
+
default: "border-transparent bg-bridge-primary text-primary-foreground",
|
|
15915
16048
|
secondary: "border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80",
|
|
15916
16049
|
destructive: "border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80",
|
|
15917
16050
|
outline: "text-foreground"
|
|
@@ -19381,7 +19514,9 @@ function OhhwellsBridge() {
|
|
|
19381
19514
|
}, [isEditMode]);
|
|
19382
19515
|
useEffect13(() => {
|
|
19383
19516
|
if (isEditMode || fetchState !== "done") return;
|
|
19517
|
+
console.log("env", process.env.NEXT_PUBLIC_FLOWOPS_API_URL);
|
|
19384
19518
|
const apiUrl = process.env.NEXT_PUBLIC_FLOWOPS_API_URL ?? "https://flowops-backend-staging-2yfdh7pwpq-as.a.run.app";
|
|
19519
|
+
console.log({ apiUrl, subdomain });
|
|
19385
19520
|
bindPublishedForms(apiUrl, subdomain, contentCache.get(subdomain) ?? {});
|
|
19386
19521
|
}, [isEditMode, fetchState, subdomain]);
|
|
19387
19522
|
useEffect13(() => {
|
|
@@ -21731,10 +21866,26 @@ function OhhwellsBridge() {
|
|
|
21731
21866
|
const handleGetBrand = (e) => {
|
|
21732
21867
|
if (e.data?.type !== "ow:get-brand") return;
|
|
21733
21868
|
const template = deriveTemplateBrand();
|
|
21734
|
-
const
|
|
21869
|
+
const fallback = template ?? (() => {
|
|
21870
|
+
const fonts = deriveTemplateFonts();
|
|
21871
|
+
return fonts ? { palette: AI_DEFAULT_BRAND.palette, fonts } : null;
|
|
21872
|
+
})();
|
|
21873
|
+
const value = brandKitRef.current || (fallback ? JSON.stringify(fallback) : "");
|
|
21735
21874
|
postToParentRef.current({ type: "ow:brand-value", value });
|
|
21736
21875
|
};
|
|
21737
21876
|
window.addEventListener("message", handleGetBrand);
|
|
21877
|
+
const handleGetTemplateFonts = (e) => {
|
|
21878
|
+
if (e.data?.type !== "ow:get-template-fonts") return;
|
|
21879
|
+
const fonts = deriveTemplateFonts();
|
|
21880
|
+
postToParentRef.current({ type: "ow:template-fonts-value", value: fonts ? JSON.stringify(fonts) : "" });
|
|
21881
|
+
};
|
|
21882
|
+
window.addEventListener("message", handleGetTemplateFonts);
|
|
21883
|
+
const handleGetTemplateBrand = (e) => {
|
|
21884
|
+
if (e.data?.type !== "ow:get-template-brand") return;
|
|
21885
|
+
const brand = deriveTemplateBrand();
|
|
21886
|
+
postToParentRef.current({ type: "ow:template-brand-value", value: brand ? JSON.stringify(brand) : "" });
|
|
21887
|
+
};
|
|
21888
|
+
window.addEventListener("message", handleGetTemplateBrand);
|
|
21738
21889
|
const handleMoveSection = (e) => {
|
|
21739
21890
|
if (e.data?.type !== "ow:move-section") return;
|
|
21740
21891
|
const instanceId = typeof e.data.instanceId === "string" ? e.data.instanceId : "";
|
|
@@ -22637,6 +22788,8 @@ function OhhwellsBridge() {
|
|
|
22637
22788
|
window.removeEventListener("message", handleAiSetBrand);
|
|
22638
22789
|
window.removeEventListener("message", handleAiSetStyles);
|
|
22639
22790
|
window.removeEventListener("message", handleGetBrand);
|
|
22791
|
+
window.removeEventListener("message", handleGetTemplateFonts);
|
|
22792
|
+
window.removeEventListener("message", handleGetTemplateBrand);
|
|
22640
22793
|
window.removeEventListener("message", handleMoveSection);
|
|
22641
22794
|
window.removeEventListener("message", handlePanelDragging);
|
|
22642
22795
|
window.removeEventListener("message", handleDeleteSection);
|
|
@@ -22848,7 +23001,7 @@ function OhhwellsBridge() {
|
|
|
22848
23001
|
postToParent2({
|
|
22849
23002
|
type: "ow:ready",
|
|
22850
23003
|
version: "1",
|
|
22851
|
-
bridgeVersion: "0.1.
|
|
23004
|
+
bridgeVersion: "0.1.115",
|
|
22852
23005
|
path: pathname,
|
|
22853
23006
|
nodes: collectEditableNodes(editContentRef.current),
|
|
22854
23007
|
sections
|
|
@@ -23464,7 +23617,7 @@ function OhhwellsBridge() {
|
|
|
23464
23617
|
"span",
|
|
23465
23618
|
{
|
|
23466
23619
|
"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",
|
|
23620
|
+
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
23621
|
children: formPickCount
|
|
23469
23622
|
}
|
|
23470
23623
|
)
|
|
@@ -23702,11 +23855,11 @@ function OhhwellsBridge() {
|
|
|
23702
23855
|
className: "fixed left-0 w-full z-2147483646 flex items-center pointer-events-none",
|
|
23703
23856
|
style: { top: sectionGap.y, transform: "translateY(-50%)" },
|
|
23704
23857
|
children: [
|
|
23705
|
-
/* @__PURE__ */ jsx33("div", { className: "flex-1 bg-primary", style: { height: 3 } }),
|
|
23858
|
+
/* @__PURE__ */ jsx33("div", { className: "flex-1 bg-bridge-primary", style: { height: 3 } }),
|
|
23706
23859
|
/* @__PURE__ */ jsx33(
|
|
23707
23860
|
Badge,
|
|
23708
23861
|
{
|
|
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",
|
|
23862
|
+
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
23863
|
onClick: () => {
|
|
23711
23864
|
window.parent.postMessage(
|
|
23712
23865
|
{
|
|
@@ -23720,7 +23873,7 @@ function OhhwellsBridge() {
|
|
|
23720
23873
|
children: "Add Section"
|
|
23721
23874
|
}
|
|
23722
23875
|
),
|
|
23723
|
-
/* @__PURE__ */ jsx33("div", { className: "flex-1 bg-primary", style: { height: 3 } })
|
|
23876
|
+
/* @__PURE__ */ jsx33("div", { className: "flex-1 bg-bridge-primary", style: { height: 3 } })
|
|
23724
23877
|
]
|
|
23725
23878
|
}
|
|
23726
23879
|
),
|