@mulmocast/deck 0.1.2 → 0.2.0
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/lib/render.js +26 -5
- package/lib/schema.d.ts +44 -0
- package/lib/schema.js +8 -0
- package/lib/utils.d.ts +6 -0
- package/lib/utils.js +23 -5
- package/package.json +1 -1
package/lib/render.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { escapeHtml, buildTailwindConfig, sanitizeHex, detectBlockTypes } from "./utils.js";
|
|
1
|
+
import { escapeHtml, buildTailwindConfig, sanitizeHex, detectBlockTypes, isSafeCssBackground } from "./utils.js";
|
|
2
2
|
import { renderSlideContent } from "./layouts/index.js";
|
|
3
3
|
/** Determine if a hex color is dark (luminance < 128) */
|
|
4
4
|
const isDarkBg = (hex) => {
|
|
@@ -64,9 +64,30 @@ export const generateSlideHTML = (theme, slide, reference, branding) => {
|
|
|
64
64
|
const cdnScripts = buildCdnScripts(theme, slide);
|
|
65
65
|
const slideStyle = slide.style;
|
|
66
66
|
const hasBgOpacity = branding?.backgroundImage?.bgOpacity !== undefined;
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
67
|
+
// Background resolution priority (any new field is optional; when absent the output is byte-identical to pre-extension behavior):
|
|
68
|
+
// slide.style.bgGradient > theme.bgGradient > slide.style.bgColor > theme.colors.bg (via `bg-d-bg` class).
|
|
69
|
+
// hasBgOpacity (branding bg image with custom opacity) still suppresses background styling, as before.
|
|
70
|
+
let bgCls = "";
|
|
71
|
+
let inlineStyle = "";
|
|
72
|
+
if (!hasBgOpacity) {
|
|
73
|
+
const slideBgGradient = slideStyle?.bgGradient && isSafeCssBackground(slideStyle.bgGradient) ? slideStyle.bgGradient : undefined;
|
|
74
|
+
const themeBgGradient = !slideBgGradient && theme.bgGradient && isSafeCssBackground(theme.bgGradient) ? theme.bgGradient : undefined;
|
|
75
|
+
const bgGradient = slideBgGradient ?? themeBgGradient;
|
|
76
|
+
if (bgGradient) {
|
|
77
|
+
inlineStyle = ` style="background:${bgGradient}"`;
|
|
78
|
+
}
|
|
79
|
+
else if (slideStyle?.bgColor) {
|
|
80
|
+
inlineStyle = ` style="background-color:#${sanitizeHex(slideStyle.bgColor)}"`;
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
bgCls = "bg-d-bg";
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
// Optional `<style>` block: when theme.titleGradient is set (and safe), paint h1 titles with a background-clipped gradient.
|
|
87
|
+
// Prepend a newline so that when set the block appears on its own line; when empty, no extra blank line is emitted.
|
|
88
|
+
const titleGradientCss = theme.titleGradient && isSafeCssBackground(theme.titleGradient)
|
|
89
|
+
? `\n<style>h1.font-title.font-bold{background:${theme.titleGradient};-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent;color:transparent;}</style>`
|
|
90
|
+
: "";
|
|
70
91
|
const footer = slideStyle?.footer ? `<p class="absolute bottom-2 right-4 text-xs text-d-dim font-body">${escapeHtml(slideStyle.footer)}</p>` : "";
|
|
71
92
|
const referenceHtml = reference
|
|
72
93
|
? `<div class="mt-auto px-4 pb-2"><p class="text-sm text-d-muted font-body opacity-80">${escapeHtml(reference)}</p></div>`
|
|
@@ -84,7 +105,7 @@ export const generateSlideHTML = (theme, slide, reference, branding) => {
|
|
|
84
105
|
${cdnScripts}
|
|
85
106
|
<style>
|
|
86
107
|
html, body { height: 100%; margin: 0; padding: 0; overflow: hidden; }
|
|
87
|
-
</style
|
|
108
|
+
</style>${titleGradientCss}
|
|
88
109
|
</head>
|
|
89
110
|
<body class="h-full">
|
|
90
111
|
<div class="relative overflow-hidden ${bgCls} w-full h-full flex flex-col"${inlineStyle}>
|
package/lib/schema.d.ts
CHANGED
|
@@ -28,6 +28,7 @@ export declare const slideThemeFontsSchema: z.ZodObject<{
|
|
|
28
28
|
title: z.ZodString;
|
|
29
29
|
body: z.ZodString;
|
|
30
30
|
mono: z.ZodString;
|
|
31
|
+
accent: z.ZodOptional<z.ZodString>;
|
|
31
32
|
}, z.core.$strip>;
|
|
32
33
|
export declare const slideThemeSchema: z.ZodObject<{
|
|
33
34
|
colors: z.ZodObject<{
|
|
@@ -49,7 +50,10 @@ export declare const slideThemeSchema: z.ZodObject<{
|
|
|
49
50
|
title: z.ZodString;
|
|
50
51
|
body: z.ZodString;
|
|
51
52
|
mono: z.ZodString;
|
|
53
|
+
accent: z.ZodOptional<z.ZodString>;
|
|
52
54
|
}, z.core.$strip>;
|
|
55
|
+
bgGradient: z.ZodOptional<z.ZodString>;
|
|
56
|
+
titleGradient: z.ZodOptional<z.ZodString>;
|
|
53
57
|
}, z.core.$strip>;
|
|
54
58
|
export declare const textBlockSchema: z.ZodObject<{
|
|
55
59
|
type: z.ZodLiteral<"text">;
|
|
@@ -895,6 +899,7 @@ export declare const cardSchema: z.ZodObject<{
|
|
|
895
899
|
}, z.core.$strip>;
|
|
896
900
|
export declare const slideStyleSchema: z.ZodObject<{
|
|
897
901
|
bgColor: z.ZodOptional<z.ZodString>;
|
|
902
|
+
bgGradient: z.ZodOptional<z.ZodString>;
|
|
898
903
|
decorations: z.ZodOptional<z.ZodBoolean>;
|
|
899
904
|
bgOpacity: z.ZodOptional<z.ZodNumber>;
|
|
900
905
|
footer: z.ZodOptional<z.ZodString>;
|
|
@@ -915,6 +920,7 @@ export declare const titleSlideSchema: z.ZodObject<{
|
|
|
915
920
|
}>>;
|
|
916
921
|
style: z.ZodOptional<z.ZodObject<{
|
|
917
922
|
bgColor: z.ZodOptional<z.ZodString>;
|
|
923
|
+
bgGradient: z.ZodOptional<z.ZodString>;
|
|
918
924
|
decorations: z.ZodOptional<z.ZodBoolean>;
|
|
919
925
|
bgOpacity: z.ZodOptional<z.ZodNumber>;
|
|
920
926
|
footer: z.ZodOptional<z.ZodString>;
|
|
@@ -1230,6 +1236,7 @@ export declare const columnsSlideSchema: z.ZodObject<{
|
|
|
1230
1236
|
}>>;
|
|
1231
1237
|
style: z.ZodOptional<z.ZodObject<{
|
|
1232
1238
|
bgColor: z.ZodOptional<z.ZodString>;
|
|
1239
|
+
bgGradient: z.ZodOptional<z.ZodString>;
|
|
1233
1240
|
decorations: z.ZodOptional<z.ZodBoolean>;
|
|
1234
1241
|
bgOpacity: z.ZodOptional<z.ZodNumber>;
|
|
1235
1242
|
footer: z.ZodOptional<z.ZodString>;
|
|
@@ -2082,6 +2089,7 @@ export declare const comparisonSlideSchema: z.ZodObject<{
|
|
|
2082
2089
|
}>>;
|
|
2083
2090
|
style: z.ZodOptional<z.ZodObject<{
|
|
2084
2091
|
bgColor: z.ZodOptional<z.ZodString>;
|
|
2092
|
+
bgGradient: z.ZodOptional<z.ZodString>;
|
|
2085
2093
|
decorations: z.ZodOptional<z.ZodBoolean>;
|
|
2086
2094
|
bgOpacity: z.ZodOptional<z.ZodNumber>;
|
|
2087
2095
|
footer: z.ZodOptional<z.ZodString>;
|
|
@@ -2650,6 +2658,7 @@ export declare const gridSlideSchema: z.ZodObject<{
|
|
|
2650
2658
|
}>>;
|
|
2651
2659
|
style: z.ZodOptional<z.ZodObject<{
|
|
2652
2660
|
bgColor: z.ZodOptional<z.ZodString>;
|
|
2661
|
+
bgGradient: z.ZodOptional<z.ZodString>;
|
|
2653
2662
|
decorations: z.ZodOptional<z.ZodBoolean>;
|
|
2654
2663
|
bgOpacity: z.ZodOptional<z.ZodNumber>;
|
|
2655
2664
|
footer: z.ZodOptional<z.ZodString>;
|
|
@@ -2671,6 +2680,7 @@ export declare const bigQuoteSlideSchema: z.ZodObject<{
|
|
|
2671
2680
|
}>>;
|
|
2672
2681
|
style: z.ZodOptional<z.ZodObject<{
|
|
2673
2682
|
bgColor: z.ZodOptional<z.ZodString>;
|
|
2683
|
+
bgGradient: z.ZodOptional<z.ZodString>;
|
|
2674
2684
|
decorations: z.ZodOptional<z.ZodBoolean>;
|
|
2675
2685
|
bgOpacity: z.ZodOptional<z.ZodNumber>;
|
|
2676
2686
|
footer: z.ZodOptional<z.ZodString>;
|
|
@@ -2738,6 +2748,7 @@ export declare const statsSlideSchema: z.ZodObject<{
|
|
|
2738
2748
|
}>>;
|
|
2739
2749
|
style: z.ZodOptional<z.ZodObject<{
|
|
2740
2750
|
bgColor: z.ZodOptional<z.ZodString>;
|
|
2751
|
+
bgGradient: z.ZodOptional<z.ZodString>;
|
|
2741
2752
|
decorations: z.ZodOptional<z.ZodBoolean>;
|
|
2742
2753
|
bgOpacity: z.ZodOptional<z.ZodNumber>;
|
|
2743
2754
|
footer: z.ZodOptional<z.ZodString>;
|
|
@@ -2789,6 +2800,7 @@ export declare const timelineSlideSchema: z.ZodObject<{
|
|
|
2789
2800
|
}>>;
|
|
2790
2801
|
style: z.ZodOptional<z.ZodObject<{
|
|
2791
2802
|
bgColor: z.ZodOptional<z.ZodString>;
|
|
2803
|
+
bgGradient: z.ZodOptional<z.ZodString>;
|
|
2792
2804
|
decorations: z.ZodOptional<z.ZodBoolean>;
|
|
2793
2805
|
bgOpacity: z.ZodOptional<z.ZodNumber>;
|
|
2794
2806
|
footer: z.ZodOptional<z.ZodString>;
|
|
@@ -3647,6 +3659,7 @@ export declare const splitSlideSchema: z.ZodObject<{
|
|
|
3647
3659
|
}>>;
|
|
3648
3660
|
style: z.ZodOptional<z.ZodObject<{
|
|
3649
3661
|
bgColor: z.ZodOptional<z.ZodString>;
|
|
3662
|
+
bgGradient: z.ZodOptional<z.ZodString>;
|
|
3650
3663
|
decorations: z.ZodOptional<z.ZodBoolean>;
|
|
3651
3664
|
bgOpacity: z.ZodOptional<z.ZodNumber>;
|
|
3652
3665
|
footer: z.ZodOptional<z.ZodString>;
|
|
@@ -4222,6 +4235,7 @@ export declare const matrixSlideSchema: z.ZodObject<{
|
|
|
4222
4235
|
}>>;
|
|
4223
4236
|
style: z.ZodOptional<z.ZodObject<{
|
|
4224
4237
|
bgColor: z.ZodOptional<z.ZodString>;
|
|
4238
|
+
bgGradient: z.ZodOptional<z.ZodString>;
|
|
4225
4239
|
decorations: z.ZodOptional<z.ZodBoolean>;
|
|
4226
4240
|
bgOpacity: z.ZodOptional<z.ZodNumber>;
|
|
4227
4241
|
footer: z.ZodOptional<z.ZodString>;
|
|
@@ -4278,6 +4292,7 @@ export declare const tableSlideSchema: z.ZodObject<{
|
|
|
4278
4292
|
}>>;
|
|
4279
4293
|
style: z.ZodOptional<z.ZodObject<{
|
|
4280
4294
|
bgColor: z.ZodOptional<z.ZodString>;
|
|
4295
|
+
bgGradient: z.ZodOptional<z.ZodString>;
|
|
4281
4296
|
decorations: z.ZodOptional<z.ZodBoolean>;
|
|
4282
4297
|
bgOpacity: z.ZodOptional<z.ZodNumber>;
|
|
4283
4298
|
footer: z.ZodOptional<z.ZodString>;
|
|
@@ -4346,6 +4361,7 @@ export declare const waterfallSlideSchema: z.ZodObject<{
|
|
|
4346
4361
|
}>>;
|
|
4347
4362
|
style: z.ZodOptional<z.ZodObject<{
|
|
4348
4363
|
bgColor: z.ZodOptional<z.ZodString>;
|
|
4364
|
+
bgGradient: z.ZodOptional<z.ZodString>;
|
|
4349
4365
|
decorations: z.ZodOptional<z.ZodBoolean>;
|
|
4350
4366
|
bgOpacity: z.ZodOptional<z.ZodNumber>;
|
|
4351
4367
|
footer: z.ZodOptional<z.ZodString>;
|
|
@@ -4413,6 +4429,7 @@ export declare const funnelSlideSchema: z.ZodObject<{
|
|
|
4413
4429
|
}>>;
|
|
4414
4430
|
style: z.ZodOptional<z.ZodObject<{
|
|
4415
4431
|
bgColor: z.ZodOptional<z.ZodString>;
|
|
4432
|
+
bgGradient: z.ZodOptional<z.ZodString>;
|
|
4416
4433
|
decorations: z.ZodOptional<z.ZodBoolean>;
|
|
4417
4434
|
bgOpacity: z.ZodOptional<z.ZodNumber>;
|
|
4418
4435
|
footer: z.ZodOptional<z.ZodString>;
|
|
@@ -4495,6 +4512,7 @@ export declare const slideLayoutSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
4495
4512
|
}>>;
|
|
4496
4513
|
style: z.ZodOptional<z.ZodObject<{
|
|
4497
4514
|
bgColor: z.ZodOptional<z.ZodString>;
|
|
4515
|
+
bgGradient: z.ZodOptional<z.ZodString>;
|
|
4498
4516
|
decorations: z.ZodOptional<z.ZodBoolean>;
|
|
4499
4517
|
bgOpacity: z.ZodOptional<z.ZodNumber>;
|
|
4500
4518
|
footer: z.ZodOptional<z.ZodString>;
|
|
@@ -4809,6 +4827,7 @@ export declare const slideLayoutSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
4809
4827
|
}>>;
|
|
4810
4828
|
style: z.ZodOptional<z.ZodObject<{
|
|
4811
4829
|
bgColor: z.ZodOptional<z.ZodString>;
|
|
4830
|
+
bgGradient: z.ZodOptional<z.ZodString>;
|
|
4812
4831
|
decorations: z.ZodOptional<z.ZodBoolean>;
|
|
4813
4832
|
bgOpacity: z.ZodOptional<z.ZodNumber>;
|
|
4814
4833
|
footer: z.ZodOptional<z.ZodString>;
|
|
@@ -5389,6 +5408,7 @@ export declare const slideLayoutSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
5389
5408
|
}>>;
|
|
5390
5409
|
style: z.ZodOptional<z.ZodObject<{
|
|
5391
5410
|
bgColor: z.ZodOptional<z.ZodString>;
|
|
5411
|
+
bgGradient: z.ZodOptional<z.ZodString>;
|
|
5392
5412
|
decorations: z.ZodOptional<z.ZodBoolean>;
|
|
5393
5413
|
bgOpacity: z.ZodOptional<z.ZodNumber>;
|
|
5394
5414
|
footer: z.ZodOptional<z.ZodString>;
|
|
@@ -5683,6 +5703,7 @@ export declare const slideLayoutSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
5683
5703
|
}>>;
|
|
5684
5704
|
style: z.ZodOptional<z.ZodObject<{
|
|
5685
5705
|
bgColor: z.ZodOptional<z.ZodString>;
|
|
5706
|
+
bgGradient: z.ZodOptional<z.ZodString>;
|
|
5686
5707
|
decorations: z.ZodOptional<z.ZodBoolean>;
|
|
5687
5708
|
bgOpacity: z.ZodOptional<z.ZodNumber>;
|
|
5688
5709
|
footer: z.ZodOptional<z.ZodString>;
|
|
@@ -5703,6 +5724,7 @@ export declare const slideLayoutSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
5703
5724
|
}>>;
|
|
5704
5725
|
style: z.ZodOptional<z.ZodObject<{
|
|
5705
5726
|
bgColor: z.ZodOptional<z.ZodString>;
|
|
5727
|
+
bgGradient: z.ZodOptional<z.ZodString>;
|
|
5706
5728
|
decorations: z.ZodOptional<z.ZodBoolean>;
|
|
5707
5729
|
bgOpacity: z.ZodOptional<z.ZodNumber>;
|
|
5708
5730
|
footer: z.ZodOptional<z.ZodString>;
|
|
@@ -5755,6 +5777,7 @@ export declare const slideLayoutSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
5755
5777
|
}>>;
|
|
5756
5778
|
style: z.ZodOptional<z.ZodObject<{
|
|
5757
5779
|
bgColor: z.ZodOptional<z.ZodString>;
|
|
5780
|
+
bgGradient: z.ZodOptional<z.ZodString>;
|
|
5758
5781
|
decorations: z.ZodOptional<z.ZodBoolean>;
|
|
5759
5782
|
bgOpacity: z.ZodOptional<z.ZodNumber>;
|
|
5760
5783
|
footer: z.ZodOptional<z.ZodString>;
|
|
@@ -5790,6 +5813,7 @@ export declare const slideLayoutSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
5790
5813
|
}>>;
|
|
5791
5814
|
style: z.ZodOptional<z.ZodObject<{
|
|
5792
5815
|
bgColor: z.ZodOptional<z.ZodString>;
|
|
5816
|
+
bgGradient: z.ZodOptional<z.ZodString>;
|
|
5793
5817
|
decorations: z.ZodOptional<z.ZodBoolean>;
|
|
5794
5818
|
bgOpacity: z.ZodOptional<z.ZodNumber>;
|
|
5795
5819
|
footer: z.ZodOptional<z.ZodString>;
|
|
@@ -6367,6 +6391,7 @@ export declare const slideLayoutSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
6367
6391
|
}>>;
|
|
6368
6392
|
style: z.ZodOptional<z.ZodObject<{
|
|
6369
6393
|
bgColor: z.ZodOptional<z.ZodString>;
|
|
6394
|
+
bgGradient: z.ZodOptional<z.ZodString>;
|
|
6370
6395
|
decorations: z.ZodOptional<z.ZodBoolean>;
|
|
6371
6396
|
bgOpacity: z.ZodOptional<z.ZodNumber>;
|
|
6372
6397
|
footer: z.ZodOptional<z.ZodString>;
|
|
@@ -6670,6 +6695,7 @@ export declare const slideLayoutSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
6670
6695
|
}>>;
|
|
6671
6696
|
style: z.ZodOptional<z.ZodObject<{
|
|
6672
6697
|
bgColor: z.ZodOptional<z.ZodString>;
|
|
6698
|
+
bgGradient: z.ZodOptional<z.ZodString>;
|
|
6673
6699
|
decorations: z.ZodOptional<z.ZodBoolean>;
|
|
6674
6700
|
bgOpacity: z.ZodOptional<z.ZodNumber>;
|
|
6675
6701
|
footer: z.ZodOptional<z.ZodString>;
|
|
@@ -6725,6 +6751,7 @@ export declare const slideLayoutSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
6725
6751
|
}>>;
|
|
6726
6752
|
style: z.ZodOptional<z.ZodObject<{
|
|
6727
6753
|
bgColor: z.ZodOptional<z.ZodString>;
|
|
6754
|
+
bgGradient: z.ZodOptional<z.ZodString>;
|
|
6728
6755
|
decorations: z.ZodOptional<z.ZodBoolean>;
|
|
6729
6756
|
bgOpacity: z.ZodOptional<z.ZodNumber>;
|
|
6730
6757
|
footer: z.ZodOptional<z.ZodString>;
|
|
@@ -6777,6 +6804,7 @@ export declare const slideLayoutSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
6777
6804
|
}>>;
|
|
6778
6805
|
style: z.ZodOptional<z.ZodObject<{
|
|
6779
6806
|
bgColor: z.ZodOptional<z.ZodString>;
|
|
6807
|
+
bgGradient: z.ZodOptional<z.ZodString>;
|
|
6780
6808
|
decorations: z.ZodOptional<z.ZodBoolean>;
|
|
6781
6809
|
bgOpacity: z.ZodOptional<z.ZodNumber>;
|
|
6782
6810
|
footer: z.ZodOptional<z.ZodString>;
|
|
@@ -6830,6 +6858,7 @@ export declare const slideLayoutSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
6830
6858
|
}>>;
|
|
6831
6859
|
style: z.ZodOptional<z.ZodObject<{
|
|
6832
6860
|
bgColor: z.ZodOptional<z.ZodString>;
|
|
6861
|
+
bgGradient: z.ZodOptional<z.ZodString>;
|
|
6833
6862
|
decorations: z.ZodOptional<z.ZodBoolean>;
|
|
6834
6863
|
bgOpacity: z.ZodOptional<z.ZodNumber>;
|
|
6835
6864
|
footer: z.ZodOptional<z.ZodString>;
|
|
@@ -6859,7 +6888,10 @@ export declare const mulmoSlideMediaSchema: z.ZodObject<{
|
|
|
6859
6888
|
title: z.ZodString;
|
|
6860
6889
|
body: z.ZodString;
|
|
6861
6890
|
mono: z.ZodString;
|
|
6891
|
+
accent: z.ZodOptional<z.ZodString>;
|
|
6862
6892
|
}, z.core.$strip>;
|
|
6893
|
+
bgGradient: z.ZodOptional<z.ZodString>;
|
|
6894
|
+
titleGradient: z.ZodOptional<z.ZodString>;
|
|
6863
6895
|
}, z.core.$strip>>;
|
|
6864
6896
|
slide: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
6865
6897
|
title: z.ZodString;
|
|
@@ -6877,6 +6909,7 @@ export declare const mulmoSlideMediaSchema: z.ZodObject<{
|
|
|
6877
6909
|
}>>;
|
|
6878
6910
|
style: z.ZodOptional<z.ZodObject<{
|
|
6879
6911
|
bgColor: z.ZodOptional<z.ZodString>;
|
|
6912
|
+
bgGradient: z.ZodOptional<z.ZodString>;
|
|
6880
6913
|
decorations: z.ZodOptional<z.ZodBoolean>;
|
|
6881
6914
|
bgOpacity: z.ZodOptional<z.ZodNumber>;
|
|
6882
6915
|
footer: z.ZodOptional<z.ZodString>;
|
|
@@ -7191,6 +7224,7 @@ export declare const mulmoSlideMediaSchema: z.ZodObject<{
|
|
|
7191
7224
|
}>>;
|
|
7192
7225
|
style: z.ZodOptional<z.ZodObject<{
|
|
7193
7226
|
bgColor: z.ZodOptional<z.ZodString>;
|
|
7227
|
+
bgGradient: z.ZodOptional<z.ZodString>;
|
|
7194
7228
|
decorations: z.ZodOptional<z.ZodBoolean>;
|
|
7195
7229
|
bgOpacity: z.ZodOptional<z.ZodNumber>;
|
|
7196
7230
|
footer: z.ZodOptional<z.ZodString>;
|
|
@@ -7771,6 +7805,7 @@ export declare const mulmoSlideMediaSchema: z.ZodObject<{
|
|
|
7771
7805
|
}>>;
|
|
7772
7806
|
style: z.ZodOptional<z.ZodObject<{
|
|
7773
7807
|
bgColor: z.ZodOptional<z.ZodString>;
|
|
7808
|
+
bgGradient: z.ZodOptional<z.ZodString>;
|
|
7774
7809
|
decorations: z.ZodOptional<z.ZodBoolean>;
|
|
7775
7810
|
bgOpacity: z.ZodOptional<z.ZodNumber>;
|
|
7776
7811
|
footer: z.ZodOptional<z.ZodString>;
|
|
@@ -8065,6 +8100,7 @@ export declare const mulmoSlideMediaSchema: z.ZodObject<{
|
|
|
8065
8100
|
}>>;
|
|
8066
8101
|
style: z.ZodOptional<z.ZodObject<{
|
|
8067
8102
|
bgColor: z.ZodOptional<z.ZodString>;
|
|
8103
|
+
bgGradient: z.ZodOptional<z.ZodString>;
|
|
8068
8104
|
decorations: z.ZodOptional<z.ZodBoolean>;
|
|
8069
8105
|
bgOpacity: z.ZodOptional<z.ZodNumber>;
|
|
8070
8106
|
footer: z.ZodOptional<z.ZodString>;
|
|
@@ -8085,6 +8121,7 @@ export declare const mulmoSlideMediaSchema: z.ZodObject<{
|
|
|
8085
8121
|
}>>;
|
|
8086
8122
|
style: z.ZodOptional<z.ZodObject<{
|
|
8087
8123
|
bgColor: z.ZodOptional<z.ZodString>;
|
|
8124
|
+
bgGradient: z.ZodOptional<z.ZodString>;
|
|
8088
8125
|
decorations: z.ZodOptional<z.ZodBoolean>;
|
|
8089
8126
|
bgOpacity: z.ZodOptional<z.ZodNumber>;
|
|
8090
8127
|
footer: z.ZodOptional<z.ZodString>;
|
|
@@ -8137,6 +8174,7 @@ export declare const mulmoSlideMediaSchema: z.ZodObject<{
|
|
|
8137
8174
|
}>>;
|
|
8138
8175
|
style: z.ZodOptional<z.ZodObject<{
|
|
8139
8176
|
bgColor: z.ZodOptional<z.ZodString>;
|
|
8177
|
+
bgGradient: z.ZodOptional<z.ZodString>;
|
|
8140
8178
|
decorations: z.ZodOptional<z.ZodBoolean>;
|
|
8141
8179
|
bgOpacity: z.ZodOptional<z.ZodNumber>;
|
|
8142
8180
|
footer: z.ZodOptional<z.ZodString>;
|
|
@@ -8172,6 +8210,7 @@ export declare const mulmoSlideMediaSchema: z.ZodObject<{
|
|
|
8172
8210
|
}>>;
|
|
8173
8211
|
style: z.ZodOptional<z.ZodObject<{
|
|
8174
8212
|
bgColor: z.ZodOptional<z.ZodString>;
|
|
8213
|
+
bgGradient: z.ZodOptional<z.ZodString>;
|
|
8175
8214
|
decorations: z.ZodOptional<z.ZodBoolean>;
|
|
8176
8215
|
bgOpacity: z.ZodOptional<z.ZodNumber>;
|
|
8177
8216
|
footer: z.ZodOptional<z.ZodString>;
|
|
@@ -8749,6 +8788,7 @@ export declare const mulmoSlideMediaSchema: z.ZodObject<{
|
|
|
8749
8788
|
}>>;
|
|
8750
8789
|
style: z.ZodOptional<z.ZodObject<{
|
|
8751
8790
|
bgColor: z.ZodOptional<z.ZodString>;
|
|
8791
|
+
bgGradient: z.ZodOptional<z.ZodString>;
|
|
8752
8792
|
decorations: z.ZodOptional<z.ZodBoolean>;
|
|
8753
8793
|
bgOpacity: z.ZodOptional<z.ZodNumber>;
|
|
8754
8794
|
footer: z.ZodOptional<z.ZodString>;
|
|
@@ -9052,6 +9092,7 @@ export declare const mulmoSlideMediaSchema: z.ZodObject<{
|
|
|
9052
9092
|
}>>;
|
|
9053
9093
|
style: z.ZodOptional<z.ZodObject<{
|
|
9054
9094
|
bgColor: z.ZodOptional<z.ZodString>;
|
|
9095
|
+
bgGradient: z.ZodOptional<z.ZodString>;
|
|
9055
9096
|
decorations: z.ZodOptional<z.ZodBoolean>;
|
|
9056
9097
|
bgOpacity: z.ZodOptional<z.ZodNumber>;
|
|
9057
9098
|
footer: z.ZodOptional<z.ZodString>;
|
|
@@ -9107,6 +9148,7 @@ export declare const mulmoSlideMediaSchema: z.ZodObject<{
|
|
|
9107
9148
|
}>>;
|
|
9108
9149
|
style: z.ZodOptional<z.ZodObject<{
|
|
9109
9150
|
bgColor: z.ZodOptional<z.ZodString>;
|
|
9151
|
+
bgGradient: z.ZodOptional<z.ZodString>;
|
|
9110
9152
|
decorations: z.ZodOptional<z.ZodBoolean>;
|
|
9111
9153
|
bgOpacity: z.ZodOptional<z.ZodNumber>;
|
|
9112
9154
|
footer: z.ZodOptional<z.ZodString>;
|
|
@@ -9159,6 +9201,7 @@ export declare const mulmoSlideMediaSchema: z.ZodObject<{
|
|
|
9159
9201
|
}>>;
|
|
9160
9202
|
style: z.ZodOptional<z.ZodObject<{
|
|
9161
9203
|
bgColor: z.ZodOptional<z.ZodString>;
|
|
9204
|
+
bgGradient: z.ZodOptional<z.ZodString>;
|
|
9162
9205
|
decorations: z.ZodOptional<z.ZodBoolean>;
|
|
9163
9206
|
bgOpacity: z.ZodOptional<z.ZodNumber>;
|
|
9164
9207
|
footer: z.ZodOptional<z.ZodString>;
|
|
@@ -9212,6 +9255,7 @@ export declare const mulmoSlideMediaSchema: z.ZodObject<{
|
|
|
9212
9255
|
}>>;
|
|
9213
9256
|
style: z.ZodOptional<z.ZodObject<{
|
|
9214
9257
|
bgColor: z.ZodOptional<z.ZodString>;
|
|
9258
|
+
bgGradient: z.ZodOptional<z.ZodString>;
|
|
9215
9259
|
decorations: z.ZodOptional<z.ZodBoolean>;
|
|
9216
9260
|
bgOpacity: z.ZodOptional<z.ZodNumber>;
|
|
9217
9261
|
footer: z.ZodOptional<z.ZodString>;
|
package/lib/schema.js
CHANGED
|
@@ -25,10 +25,16 @@ export const slideThemeFontsSchema = z.object({
|
|
|
25
25
|
title: z.string(),
|
|
26
26
|
body: z.string(),
|
|
27
27
|
mono: z.string(),
|
|
28
|
+
/** Optional secondary font for numbers / English labels (e.g. "Outfit"). When set, registers a `font-accent` Tailwind utility. */
|
|
29
|
+
accent: z.string().optional(),
|
|
28
30
|
});
|
|
29
31
|
export const slideThemeSchema = z.object({
|
|
30
32
|
colors: slideThemeColorsSchema,
|
|
31
33
|
fonts: slideThemeFontsSchema,
|
|
34
|
+
/** Optional CSS background value applied to every slide (e.g. `linear-gradient(...)`). Per-slide `style.bgGradient` wins over this. */
|
|
35
|
+
bgGradient: z.string().optional(),
|
|
36
|
+
/** Optional CSS gradient injected as `<style>` to paint `h1.font-title.font-bold` with `background-clip: text`. */
|
|
37
|
+
titleGradient: z.string().optional(),
|
|
32
38
|
});
|
|
33
39
|
// ═══════════════════════════════════════════════════════════
|
|
34
40
|
// Content Blocks — the atoms of slide content
|
|
@@ -171,6 +177,8 @@ export const cardSchema = z.object({
|
|
|
171
177
|
// ═══════════════════════════════════════════════════════════
|
|
172
178
|
export const slideStyleSchema = z.object({
|
|
173
179
|
bgColor: z.string().optional(),
|
|
180
|
+
/** Optional per-slide CSS background value (e.g. `linear-gradient(...)`); wins over `theme.bgGradient` and `bgColor`. */
|
|
181
|
+
bgGradient: z.string().optional(),
|
|
174
182
|
decorations: z.boolean().optional(),
|
|
175
183
|
bgOpacity: z.number().optional(),
|
|
176
184
|
footer: z.string().optional(),
|
package/lib/utils.d.ts
CHANGED
|
@@ -27,6 +27,12 @@ export declare const resolveChangeColor: (change: string) => string;
|
|
|
27
27
|
export declare const renderOptionalCallout: (callout: CalloutBar | undefined) => string;
|
|
28
28
|
/** Build the Tailwind config JSON string for theme colors and fonts */
|
|
29
29
|
export declare const buildTailwindConfig: (theme: SlideTheme) => string;
|
|
30
|
+
/**
|
|
31
|
+
* Validate a user-supplied CSS background value before injecting it into an HTML attribute or `<style>` block.
|
|
32
|
+
* Accepts gradient / color syntax; rejects anything that could break out of the attribute context, inject script,
|
|
33
|
+
* or pull external resources. Returns true only when the string is safe to embed verbatim.
|
|
34
|
+
*/
|
|
35
|
+
export declare const isSafeCssBackground: (s: string) => boolean;
|
|
30
36
|
/** Render a numbered circle badge */
|
|
31
37
|
export declare const numBadge: (num: number, colorKey: string) => string;
|
|
32
38
|
/** Render an icon in a square container */
|
package/lib/utils.js
CHANGED
|
@@ -90,19 +90,37 @@ export const buildTailwindConfig = (theme) => {
|
|
|
90
90
|
colorMap[mapped] = `#${v}`;
|
|
91
91
|
}
|
|
92
92
|
});
|
|
93
|
+
const fontFamily = {
|
|
94
|
+
title: [theme.fonts.title, "serif"],
|
|
95
|
+
body: [theme.fonts.body, "Arial", "sans-serif"],
|
|
96
|
+
mono: [theme.fonts.mono, "monospace"],
|
|
97
|
+
};
|
|
98
|
+
if (theme.fonts.accent) {
|
|
99
|
+
fontFamily.accent = [theme.fonts.accent, "ui-sans-serif", "system-ui", "sans-serif"];
|
|
100
|
+
}
|
|
93
101
|
return JSON.stringify({
|
|
94
102
|
theme: {
|
|
95
103
|
extend: {
|
|
96
104
|
colors: { d: colorMap },
|
|
97
|
-
fontFamily
|
|
98
|
-
title: [theme.fonts.title, "serif"],
|
|
99
|
-
body: [theme.fonts.body, "Arial", "sans-serif"],
|
|
100
|
-
mono: [theme.fonts.mono, "monospace"],
|
|
101
|
-
},
|
|
105
|
+
fontFamily,
|
|
102
106
|
},
|
|
103
107
|
},
|
|
104
108
|
});
|
|
105
109
|
};
|
|
110
|
+
/**
|
|
111
|
+
* Validate a user-supplied CSS background value before injecting it into an HTML attribute or `<style>` block.
|
|
112
|
+
* Accepts gradient / color syntax; rejects anything that could break out of the attribute context, inject script,
|
|
113
|
+
* or pull external resources. Returns true only when the string is safe to embed verbatim.
|
|
114
|
+
*/
|
|
115
|
+
export const isSafeCssBackground = (s) => {
|
|
116
|
+
if (!s || typeof s !== "string" || s.length > 2000)
|
|
117
|
+
return false;
|
|
118
|
+
if (/[<>"'`{};:\\\r\n]/.test(s))
|
|
119
|
+
return false;
|
|
120
|
+
if (/(javascript|vbscript|data\s+|expression\s*\(|behavior|@import|url\s*\(|attr\s*\(|content\s*\()/i.test(s))
|
|
121
|
+
return false;
|
|
122
|
+
return true;
|
|
123
|
+
};
|
|
106
124
|
/** Render a numbered circle badge */
|
|
107
125
|
export const numBadge = (num, colorKey) => {
|
|
108
126
|
return `<div class="w-10 h-10 rounded-full bg-${c(colorKey)} flex items-center justify-center shrink-0">
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mulmocast/deck",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "MulmoCast deck DSL: JSON-described semantic slide layouts (stats, comparison, timeline, ...) rendered to Tailwind-based HTML",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"types": "lib/index.d.ts",
|