@templatical/template-tools 0.38.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/schema.json ADDED
@@ -0,0 +1,1504 @@
1
+ {
2
+ "$id": "https://templatical.com/schema/template-content.json",
3
+ "$schema": "http://json-schema.org/draft-07/schema#",
4
+ "$ref": "#/definitions/TemplateContent",
5
+ "definitions": {
6
+ "TemplateContent": {
7
+ "type": "object",
8
+ "properties": {
9
+ "blocks": {
10
+ "type": "array",
11
+ "items": {
12
+ "$ref": "#/definitions/Block"
13
+ }
14
+ },
15
+ "settings": {
16
+ "$ref": "#/definitions/TemplateSettings"
17
+ }
18
+ },
19
+ "required": [
20
+ "blocks",
21
+ "settings"
22
+ ],
23
+ "additionalProperties": false
24
+ },
25
+ "Block": {
26
+ "anyOf": [
27
+ {
28
+ "$ref": "#/definitions/SectionBlock"
29
+ },
30
+ {
31
+ "$ref": "#/definitions/TitleBlock"
32
+ },
33
+ {
34
+ "$ref": "#/definitions/ParagraphBlock"
35
+ },
36
+ {
37
+ "$ref": "#/definitions/ImageBlock"
38
+ },
39
+ {
40
+ "$ref": "#/definitions/ButtonBlock"
41
+ },
42
+ {
43
+ "$ref": "#/definitions/DividerBlock"
44
+ },
45
+ {
46
+ "$ref": "#/definitions/VideoBlock"
47
+ },
48
+ {
49
+ "$ref": "#/definitions/SocialIconsBlock"
50
+ },
51
+ {
52
+ "$ref": "#/definitions/SpacerBlock"
53
+ },
54
+ {
55
+ "$ref": "#/definitions/HtmlBlock"
56
+ },
57
+ {
58
+ "$ref": "#/definitions/MenuBlock"
59
+ },
60
+ {
61
+ "$ref": "#/definitions/TableBlock"
62
+ },
63
+ {
64
+ "$ref": "#/definitions/CountdownBlock"
65
+ },
66
+ {
67
+ "$ref": "#/definitions/CustomBlock"
68
+ }
69
+ ]
70
+ },
71
+ "SectionBlock": {
72
+ "type": "object",
73
+ "properties": {
74
+ "id": {
75
+ "type": "string"
76
+ },
77
+ "type": {
78
+ "type": "string",
79
+ "const": "section"
80
+ },
81
+ "styles": {
82
+ "$ref": "#/definitions/BlockStyles"
83
+ },
84
+ "visibility": {
85
+ "$ref": "#/definitions/BlockVisibility"
86
+ },
87
+ "displayCondition": {
88
+ "type": "object",
89
+ "properties": {
90
+ "label": {
91
+ "type": "string"
92
+ },
93
+ "before": {
94
+ "type": "string"
95
+ },
96
+ "after": {
97
+ "type": "string"
98
+ },
99
+ "group": {
100
+ "type": "string"
101
+ },
102
+ "description": {
103
+ "type": "string"
104
+ }
105
+ },
106
+ "required": [
107
+ "label",
108
+ "before",
109
+ "after"
110
+ ],
111
+ "additionalProperties": false
112
+ },
113
+ "columns": {
114
+ "$ref": "#/definitions/ColumnLayout"
115
+ },
116
+ "children": {
117
+ "type": "array",
118
+ "items": {
119
+ "type": "array",
120
+ "items": {
121
+ "$ref": "#/definitions/Block"
122
+ }
123
+ }
124
+ },
125
+ "stackOnMobile": {
126
+ "type": "boolean",
127
+ "description": "Whether columns stack vertically on mobile. Absent or `true` keeps MJML's default responsive behavior (columns stack below 480px). `false` renders the columns inside an `<mj-group>` so they stay side-by-side on mobile, proportionally shrunk to fit."
128
+ },
129
+ "borderRadius": {
130
+ "type": "number",
131
+ "description": "Corner radius in px. Omitted/0 = square corners."
132
+ },
133
+ "wrapper": {
134
+ "$ref": "#/definitions/SectionWrapper",
135
+ "description": "Optional outer frame (rendered as an `mj-wrapper` around the section)."
136
+ }
137
+ },
138
+ "required": [
139
+ "children",
140
+ "columns",
141
+ "id",
142
+ "styles",
143
+ "type"
144
+ ],
145
+ "additionalProperties": false
146
+ },
147
+ "BlockStyles": {
148
+ "type": "object",
149
+ "properties": {
150
+ "padding": {
151
+ "$ref": "#/definitions/SpacingValue"
152
+ },
153
+ "backgroundColor": {
154
+ "type": "string"
155
+ }
156
+ },
157
+ "required": [
158
+ "padding"
159
+ ],
160
+ "additionalProperties": false
161
+ },
162
+ "SpacingValue": {
163
+ "type": "object",
164
+ "properties": {
165
+ "top": {
166
+ "type": "number"
167
+ },
168
+ "right": {
169
+ "type": "number"
170
+ },
171
+ "bottom": {
172
+ "type": "number"
173
+ },
174
+ "left": {
175
+ "type": "number"
176
+ }
177
+ },
178
+ "required": [
179
+ "top",
180
+ "right",
181
+ "bottom",
182
+ "left"
183
+ ],
184
+ "additionalProperties": false
185
+ },
186
+ "BlockVisibility": {
187
+ "type": "object",
188
+ "properties": {
189
+ "desktop": {
190
+ "type": "boolean"
191
+ },
192
+ "mobile": {
193
+ "type": "boolean"
194
+ }
195
+ },
196
+ "required": [
197
+ "desktop",
198
+ "mobile"
199
+ ],
200
+ "additionalProperties": false
201
+ },
202
+ "ColumnLayout": {
203
+ "type": "string",
204
+ "enum": [
205
+ "1",
206
+ "2",
207
+ "3",
208
+ "2-1",
209
+ "1-2"
210
+ ]
211
+ },
212
+ "SectionWrapper": {
213
+ "type": "object",
214
+ "properties": {
215
+ "backgroundColor": {
216
+ "type": "string"
217
+ },
218
+ "padding": {
219
+ "$ref": "#/definitions/SpacingValue"
220
+ },
221
+ "borderRadius": {
222
+ "type": "number",
223
+ "description": "Corner radius in px for the outer frame. Omitted/0 = square corners."
224
+ }
225
+ },
226
+ "additionalProperties": false,
227
+ "description": "Optional outer frame for a section. When present, the section is rendered inside an `mj-wrapper` — a full-width band (its own background + padding) that frames the section, e.g. a white card sitting on a colored band."
228
+ },
229
+ "TitleBlock": {
230
+ "type": "object",
231
+ "properties": {
232
+ "id": {
233
+ "type": "string"
234
+ },
235
+ "type": {
236
+ "type": "string",
237
+ "const": "title"
238
+ },
239
+ "styles": {
240
+ "$ref": "#/definitions/BlockStyles"
241
+ },
242
+ "visibility": {
243
+ "$ref": "#/definitions/BlockVisibility"
244
+ },
245
+ "displayCondition": {
246
+ "type": "object",
247
+ "properties": {
248
+ "label": {
249
+ "type": "string"
250
+ },
251
+ "before": {
252
+ "type": "string"
253
+ },
254
+ "after": {
255
+ "type": "string"
256
+ },
257
+ "group": {
258
+ "type": "string"
259
+ },
260
+ "description": {
261
+ "type": "string"
262
+ }
263
+ },
264
+ "required": [
265
+ "label",
266
+ "before",
267
+ "after"
268
+ ],
269
+ "additionalProperties": false
270
+ },
271
+ "content": {
272
+ "type": "string"
273
+ },
274
+ "level": {
275
+ "$ref": "#/definitions/HeadingLevel"
276
+ },
277
+ "color": {
278
+ "type": "string",
279
+ "description": "Text color. Unset = inherit the document-level `textColor`."
280
+ },
281
+ "textAlign": {
282
+ "type": "string",
283
+ "enum": [
284
+ "left",
285
+ "center",
286
+ "right"
287
+ ]
288
+ },
289
+ "fontFamily": {
290
+ "type": "string"
291
+ }
292
+ },
293
+ "required": [
294
+ "content",
295
+ "id",
296
+ "level",
297
+ "styles",
298
+ "textAlign",
299
+ "type"
300
+ ],
301
+ "additionalProperties": false
302
+ },
303
+ "HeadingLevel": {
304
+ "type": "number",
305
+ "enum": [
306
+ 1,
307
+ 2,
308
+ 3,
309
+ 4
310
+ ]
311
+ },
312
+ "ParagraphBlock": {
313
+ "type": "object",
314
+ "properties": {
315
+ "id": {
316
+ "type": "string"
317
+ },
318
+ "type": {
319
+ "type": "string",
320
+ "const": "paragraph"
321
+ },
322
+ "styles": {
323
+ "$ref": "#/definitions/BlockStyles"
324
+ },
325
+ "visibility": {
326
+ "$ref": "#/definitions/BlockVisibility"
327
+ },
328
+ "displayCondition": {
329
+ "type": "object",
330
+ "properties": {
331
+ "label": {
332
+ "type": "string"
333
+ },
334
+ "before": {
335
+ "type": "string"
336
+ },
337
+ "after": {
338
+ "type": "string"
339
+ },
340
+ "group": {
341
+ "type": "string"
342
+ },
343
+ "description": {
344
+ "type": "string"
345
+ }
346
+ },
347
+ "required": [
348
+ "label",
349
+ "before",
350
+ "after"
351
+ ],
352
+ "additionalProperties": false
353
+ },
354
+ "content": {
355
+ "type": "string"
356
+ },
357
+ "paragraphSpacing": {
358
+ "type": "number",
359
+ "description": "Gap in px between this block's paragraphs — the space below every `<p>` except the last. Absent means `RICH_TEXT_SPACING.paragraphGap`.\n\nOnly affects a block holding more than one paragraph; a single `<p>` has no internal gap, and the space around the block is `styles.padding`.\n\n`0` is a valid choice (paragraphs butted together) and is distinct from the field being absent, so readers must test for `undefined` rather than falsiness."
360
+ }
361
+ },
362
+ "required": [
363
+ "content",
364
+ "id",
365
+ "styles",
366
+ "type"
367
+ ],
368
+ "additionalProperties": false
369
+ },
370
+ "ImageBlock": {
371
+ "type": "object",
372
+ "properties": {
373
+ "id": {
374
+ "type": "string"
375
+ },
376
+ "type": {
377
+ "type": "string",
378
+ "const": "image"
379
+ },
380
+ "styles": {
381
+ "$ref": "#/definitions/BlockStyles"
382
+ },
383
+ "visibility": {
384
+ "$ref": "#/definitions/BlockVisibility"
385
+ },
386
+ "displayCondition": {
387
+ "type": "object",
388
+ "properties": {
389
+ "label": {
390
+ "type": "string"
391
+ },
392
+ "before": {
393
+ "type": "string"
394
+ },
395
+ "after": {
396
+ "type": "string"
397
+ },
398
+ "group": {
399
+ "type": "string"
400
+ },
401
+ "description": {
402
+ "type": "string"
403
+ }
404
+ },
405
+ "required": [
406
+ "label",
407
+ "before",
408
+ "after"
409
+ ],
410
+ "additionalProperties": false
411
+ },
412
+ "src": {
413
+ "type": "string"
414
+ },
415
+ "alt": {
416
+ "type": "string"
417
+ },
418
+ "width": {
419
+ "anyOf": [
420
+ {
421
+ "type": "number"
422
+ },
423
+ {
424
+ "type": "string",
425
+ "const": "full"
426
+ }
427
+ ]
428
+ },
429
+ "height": {
430
+ "type": "number",
431
+ "description": "Height in pixels. Absent means the height is derived from the width, so the image keeps its aspect ratio — setting both stretches it, since email clients don't support `object-fit`."
432
+ },
433
+ "align": {
434
+ "type": "string",
435
+ "enum": [
436
+ "left",
437
+ "center",
438
+ "right"
439
+ ]
440
+ },
441
+ "borderRadius": {
442
+ "type": "number",
443
+ "description": "Corner radius in px. Omitted/0 = square corners. A radius of at least half the rendered size rounds a square image to a circle, which is how avatar and portrait layouts are built."
444
+ },
445
+ "linkUrl": {
446
+ "type": "string"
447
+ },
448
+ "linkOpenInNewTab": {
449
+ "type": "boolean"
450
+ },
451
+ "placeholderUrl": {
452
+ "type": "string"
453
+ },
454
+ "decorative": {
455
+ "type": "boolean"
456
+ }
457
+ },
458
+ "required": [
459
+ "align",
460
+ "alt",
461
+ "id",
462
+ "src",
463
+ "styles",
464
+ "type",
465
+ "width"
466
+ ],
467
+ "additionalProperties": false
468
+ },
469
+ "ButtonBlock": {
470
+ "type": "object",
471
+ "properties": {
472
+ "id": {
473
+ "type": "string"
474
+ },
475
+ "type": {
476
+ "type": "string",
477
+ "const": "button"
478
+ },
479
+ "styles": {
480
+ "$ref": "#/definitions/BlockStyles"
481
+ },
482
+ "visibility": {
483
+ "$ref": "#/definitions/BlockVisibility"
484
+ },
485
+ "displayCondition": {
486
+ "type": "object",
487
+ "properties": {
488
+ "label": {
489
+ "type": "string"
490
+ },
491
+ "before": {
492
+ "type": "string"
493
+ },
494
+ "after": {
495
+ "type": "string"
496
+ },
497
+ "group": {
498
+ "type": "string"
499
+ },
500
+ "description": {
501
+ "type": "string"
502
+ }
503
+ },
504
+ "required": [
505
+ "label",
506
+ "before",
507
+ "after"
508
+ ],
509
+ "additionalProperties": false
510
+ },
511
+ "text": {
512
+ "type": "string"
513
+ },
514
+ "url": {
515
+ "type": "string"
516
+ },
517
+ "openInNewTab": {
518
+ "type": "boolean"
519
+ },
520
+ "backgroundColor": {
521
+ "type": "string"
522
+ },
523
+ "textColor": {
524
+ "type": "string"
525
+ },
526
+ "borderRadius": {
527
+ "type": "number"
528
+ },
529
+ "fontSize": {
530
+ "type": "number"
531
+ },
532
+ "buttonPadding": {
533
+ "$ref": "#/definitions/SpacingValue"
534
+ },
535
+ "fontFamily": {
536
+ "type": "string"
537
+ },
538
+ "width": {
539
+ "anyOf": [
540
+ {
541
+ "type": "number"
542
+ },
543
+ {
544
+ "type": "string",
545
+ "const": "full"
546
+ }
547
+ ]
548
+ },
549
+ "align": {
550
+ "type": "string",
551
+ "enum": [
552
+ "left",
553
+ "center",
554
+ "right"
555
+ ],
556
+ "description": "Placement of the button within its column. No visible effect when `width` is `\"full\"`, since the button then spans the column."
557
+ }
558
+ },
559
+ "required": [
560
+ "align",
561
+ "backgroundColor",
562
+ "borderRadius",
563
+ "buttonPadding",
564
+ "fontSize",
565
+ "id",
566
+ "styles",
567
+ "text",
568
+ "textColor",
569
+ "type",
570
+ "url"
571
+ ],
572
+ "additionalProperties": false
573
+ },
574
+ "DividerBlock": {
575
+ "type": "object",
576
+ "properties": {
577
+ "id": {
578
+ "type": "string"
579
+ },
580
+ "type": {
581
+ "type": "string",
582
+ "const": "divider"
583
+ },
584
+ "styles": {
585
+ "$ref": "#/definitions/BlockStyles"
586
+ },
587
+ "visibility": {
588
+ "$ref": "#/definitions/BlockVisibility"
589
+ },
590
+ "displayCondition": {
591
+ "type": "object",
592
+ "properties": {
593
+ "label": {
594
+ "type": "string"
595
+ },
596
+ "before": {
597
+ "type": "string"
598
+ },
599
+ "after": {
600
+ "type": "string"
601
+ },
602
+ "group": {
603
+ "type": "string"
604
+ },
605
+ "description": {
606
+ "type": "string"
607
+ }
608
+ },
609
+ "required": [
610
+ "label",
611
+ "before",
612
+ "after"
613
+ ],
614
+ "additionalProperties": false
615
+ },
616
+ "lineStyle": {
617
+ "type": "string",
618
+ "enum": [
619
+ "solid",
620
+ "dashed",
621
+ "dotted"
622
+ ]
623
+ },
624
+ "color": {
625
+ "type": "string"
626
+ },
627
+ "thickness": {
628
+ "type": "number"
629
+ },
630
+ "width": {
631
+ "anyOf": [
632
+ {
633
+ "type": "number"
634
+ },
635
+ {
636
+ "type": "string",
637
+ "const": "full"
638
+ }
639
+ ]
640
+ }
641
+ },
642
+ "required": [
643
+ "color",
644
+ "id",
645
+ "lineStyle",
646
+ "styles",
647
+ "thickness",
648
+ "type",
649
+ "width"
650
+ ],
651
+ "additionalProperties": false
652
+ },
653
+ "VideoBlock": {
654
+ "type": "object",
655
+ "properties": {
656
+ "id": {
657
+ "type": "string"
658
+ },
659
+ "type": {
660
+ "type": "string",
661
+ "const": "video"
662
+ },
663
+ "styles": {
664
+ "$ref": "#/definitions/BlockStyles"
665
+ },
666
+ "visibility": {
667
+ "$ref": "#/definitions/BlockVisibility"
668
+ },
669
+ "displayCondition": {
670
+ "type": "object",
671
+ "properties": {
672
+ "label": {
673
+ "type": "string"
674
+ },
675
+ "before": {
676
+ "type": "string"
677
+ },
678
+ "after": {
679
+ "type": "string"
680
+ },
681
+ "group": {
682
+ "type": "string"
683
+ },
684
+ "description": {
685
+ "type": "string"
686
+ }
687
+ },
688
+ "required": [
689
+ "label",
690
+ "before",
691
+ "after"
692
+ ],
693
+ "additionalProperties": false
694
+ },
695
+ "url": {
696
+ "type": "string"
697
+ },
698
+ "openInNewTab": {
699
+ "type": "boolean"
700
+ },
701
+ "thumbnailUrl": {
702
+ "type": "string"
703
+ },
704
+ "alt": {
705
+ "type": "string"
706
+ },
707
+ "width": {
708
+ "anyOf": [
709
+ {
710
+ "type": "number"
711
+ },
712
+ {
713
+ "type": "string",
714
+ "const": "full"
715
+ }
716
+ ]
717
+ },
718
+ "height": {
719
+ "type": "number",
720
+ "description": "Height in pixels for the thumbnail. Absent means the height is derived from the width, so the thumbnail keeps its aspect ratio — setting both stretches it, since email clients don't support `object-fit`."
721
+ },
722
+ "align": {
723
+ "type": "string",
724
+ "enum": [
725
+ "left",
726
+ "center",
727
+ "right"
728
+ ]
729
+ },
730
+ "placeholderUrl": {
731
+ "type": "string"
732
+ }
733
+ },
734
+ "required": [
735
+ "align",
736
+ "alt",
737
+ "id",
738
+ "styles",
739
+ "thumbnailUrl",
740
+ "type",
741
+ "url",
742
+ "width"
743
+ ],
744
+ "additionalProperties": false
745
+ },
746
+ "SocialIconsBlock": {
747
+ "type": "object",
748
+ "properties": {
749
+ "id": {
750
+ "type": "string"
751
+ },
752
+ "type": {
753
+ "type": "string",
754
+ "const": "social"
755
+ },
756
+ "styles": {
757
+ "$ref": "#/definitions/BlockStyles"
758
+ },
759
+ "visibility": {
760
+ "$ref": "#/definitions/BlockVisibility"
761
+ },
762
+ "displayCondition": {
763
+ "type": "object",
764
+ "properties": {
765
+ "label": {
766
+ "type": "string"
767
+ },
768
+ "before": {
769
+ "type": "string"
770
+ },
771
+ "after": {
772
+ "type": "string"
773
+ },
774
+ "group": {
775
+ "type": "string"
776
+ },
777
+ "description": {
778
+ "type": "string"
779
+ }
780
+ },
781
+ "required": [
782
+ "label",
783
+ "before",
784
+ "after"
785
+ ],
786
+ "additionalProperties": false
787
+ },
788
+ "icons": {
789
+ "type": "array",
790
+ "items": {
791
+ "$ref": "#/definitions/SocialIcon"
792
+ }
793
+ },
794
+ "iconStyle": {
795
+ "$ref": "#/definitions/SocialIconStyle"
796
+ },
797
+ "iconSize": {
798
+ "$ref": "#/definitions/SocialIconSize"
799
+ },
800
+ "spacing": {
801
+ "type": "number"
802
+ },
803
+ "align": {
804
+ "type": "string",
805
+ "enum": [
806
+ "left",
807
+ "center",
808
+ "right"
809
+ ]
810
+ }
811
+ },
812
+ "required": [
813
+ "align",
814
+ "iconSize",
815
+ "iconStyle",
816
+ "icons",
817
+ "id",
818
+ "spacing",
819
+ "styles",
820
+ "type"
821
+ ],
822
+ "additionalProperties": false
823
+ },
824
+ "SocialIcon": {
825
+ "type": "object",
826
+ "properties": {
827
+ "id": {
828
+ "type": "string"
829
+ },
830
+ "platform": {
831
+ "$ref": "#/definitions/SocialPlatform"
832
+ },
833
+ "url": {
834
+ "type": "string"
835
+ }
836
+ },
837
+ "required": [
838
+ "id",
839
+ "platform",
840
+ "url"
841
+ ],
842
+ "additionalProperties": false
843
+ },
844
+ "SocialPlatform": {
845
+ "type": "string",
846
+ "enum": [
847
+ "facebook",
848
+ "twitter",
849
+ "instagram",
850
+ "linkedin",
851
+ "youtube",
852
+ "tiktok",
853
+ "pinterest",
854
+ "email",
855
+ "whatsapp",
856
+ "telegram",
857
+ "discord",
858
+ "snapchat",
859
+ "reddit",
860
+ "github",
861
+ "dribbble",
862
+ "behance",
863
+ "website"
864
+ ]
865
+ },
866
+ "SocialIconStyle": {
867
+ "type": "string",
868
+ "enum": [
869
+ "solid",
870
+ "outlined",
871
+ "rounded",
872
+ "square",
873
+ "circle"
874
+ ]
875
+ },
876
+ "SocialIconSize": {
877
+ "type": "string",
878
+ "enum": [
879
+ "small",
880
+ "medium",
881
+ "large"
882
+ ]
883
+ },
884
+ "SpacerBlock": {
885
+ "type": "object",
886
+ "properties": {
887
+ "id": {
888
+ "type": "string"
889
+ },
890
+ "type": {
891
+ "type": "string",
892
+ "const": "spacer"
893
+ },
894
+ "styles": {
895
+ "$ref": "#/definitions/BlockStyles"
896
+ },
897
+ "visibility": {
898
+ "$ref": "#/definitions/BlockVisibility"
899
+ },
900
+ "displayCondition": {
901
+ "type": "object",
902
+ "properties": {
903
+ "label": {
904
+ "type": "string"
905
+ },
906
+ "before": {
907
+ "type": "string"
908
+ },
909
+ "after": {
910
+ "type": "string"
911
+ },
912
+ "group": {
913
+ "type": "string"
914
+ },
915
+ "description": {
916
+ "type": "string"
917
+ }
918
+ },
919
+ "required": [
920
+ "label",
921
+ "before",
922
+ "after"
923
+ ],
924
+ "additionalProperties": false
925
+ },
926
+ "height": {
927
+ "type": "number"
928
+ }
929
+ },
930
+ "required": [
931
+ "height",
932
+ "id",
933
+ "styles",
934
+ "type"
935
+ ],
936
+ "additionalProperties": false
937
+ },
938
+ "HtmlBlock": {
939
+ "type": "object",
940
+ "properties": {
941
+ "id": {
942
+ "type": "string"
943
+ },
944
+ "type": {
945
+ "type": "string",
946
+ "const": "html"
947
+ },
948
+ "styles": {
949
+ "$ref": "#/definitions/BlockStyles"
950
+ },
951
+ "visibility": {
952
+ "$ref": "#/definitions/BlockVisibility"
953
+ },
954
+ "displayCondition": {
955
+ "type": "object",
956
+ "properties": {
957
+ "label": {
958
+ "type": "string"
959
+ },
960
+ "before": {
961
+ "type": "string"
962
+ },
963
+ "after": {
964
+ "type": "string"
965
+ },
966
+ "group": {
967
+ "type": "string"
968
+ },
969
+ "description": {
970
+ "type": "string"
971
+ }
972
+ },
973
+ "required": [
974
+ "label",
975
+ "before",
976
+ "after"
977
+ ],
978
+ "additionalProperties": false
979
+ },
980
+ "content": {
981
+ "type": "string"
982
+ }
983
+ },
984
+ "required": [
985
+ "content",
986
+ "id",
987
+ "styles",
988
+ "type"
989
+ ],
990
+ "additionalProperties": false
991
+ },
992
+ "MenuBlock": {
993
+ "type": "object",
994
+ "properties": {
995
+ "id": {
996
+ "type": "string"
997
+ },
998
+ "type": {
999
+ "type": "string",
1000
+ "const": "menu"
1001
+ },
1002
+ "styles": {
1003
+ "$ref": "#/definitions/BlockStyles"
1004
+ },
1005
+ "visibility": {
1006
+ "$ref": "#/definitions/BlockVisibility"
1007
+ },
1008
+ "displayCondition": {
1009
+ "type": "object",
1010
+ "properties": {
1011
+ "label": {
1012
+ "type": "string"
1013
+ },
1014
+ "before": {
1015
+ "type": "string"
1016
+ },
1017
+ "after": {
1018
+ "type": "string"
1019
+ },
1020
+ "group": {
1021
+ "type": "string"
1022
+ },
1023
+ "description": {
1024
+ "type": "string"
1025
+ }
1026
+ },
1027
+ "required": [
1028
+ "label",
1029
+ "before",
1030
+ "after"
1031
+ ],
1032
+ "additionalProperties": false
1033
+ },
1034
+ "items": {
1035
+ "type": "array",
1036
+ "items": {
1037
+ "$ref": "#/definitions/MenuItemData"
1038
+ }
1039
+ },
1040
+ "fontSize": {
1041
+ "type": "number"
1042
+ },
1043
+ "fontFamily": {
1044
+ "type": "string"
1045
+ },
1046
+ "color": {
1047
+ "type": "string",
1048
+ "description": "Base text/link color. Unset = inherit the document-level `textColor`."
1049
+ },
1050
+ "linkColor": {
1051
+ "type": "string"
1052
+ },
1053
+ "textAlign": {
1054
+ "type": "string",
1055
+ "enum": [
1056
+ "left",
1057
+ "center",
1058
+ "right"
1059
+ ]
1060
+ },
1061
+ "separator": {
1062
+ "type": "string"
1063
+ },
1064
+ "separatorColor": {
1065
+ "type": "string"
1066
+ },
1067
+ "spacing": {
1068
+ "type": "number"
1069
+ }
1070
+ },
1071
+ "required": [
1072
+ "fontSize",
1073
+ "id",
1074
+ "items",
1075
+ "separator",
1076
+ "separatorColor",
1077
+ "spacing",
1078
+ "styles",
1079
+ "textAlign",
1080
+ "type"
1081
+ ],
1082
+ "additionalProperties": false
1083
+ },
1084
+ "MenuItemData": {
1085
+ "type": "object",
1086
+ "properties": {
1087
+ "id": {
1088
+ "type": "string"
1089
+ },
1090
+ "text": {
1091
+ "type": "string"
1092
+ },
1093
+ "url": {
1094
+ "type": "string"
1095
+ },
1096
+ "openInNewTab": {
1097
+ "type": "boolean"
1098
+ },
1099
+ "bold": {
1100
+ "type": "boolean"
1101
+ },
1102
+ "underline": {
1103
+ "type": "boolean"
1104
+ },
1105
+ "color": {
1106
+ "type": "string"
1107
+ }
1108
+ },
1109
+ "required": [
1110
+ "id",
1111
+ "text",
1112
+ "url",
1113
+ "openInNewTab",
1114
+ "bold",
1115
+ "underline"
1116
+ ],
1117
+ "additionalProperties": false
1118
+ },
1119
+ "TableBlock": {
1120
+ "type": "object",
1121
+ "properties": {
1122
+ "id": {
1123
+ "type": "string"
1124
+ },
1125
+ "type": {
1126
+ "type": "string",
1127
+ "const": "table"
1128
+ },
1129
+ "styles": {
1130
+ "$ref": "#/definitions/BlockStyles"
1131
+ },
1132
+ "visibility": {
1133
+ "$ref": "#/definitions/BlockVisibility"
1134
+ },
1135
+ "displayCondition": {
1136
+ "type": "object",
1137
+ "properties": {
1138
+ "label": {
1139
+ "type": "string"
1140
+ },
1141
+ "before": {
1142
+ "type": "string"
1143
+ },
1144
+ "after": {
1145
+ "type": "string"
1146
+ },
1147
+ "group": {
1148
+ "type": "string"
1149
+ },
1150
+ "description": {
1151
+ "type": "string"
1152
+ }
1153
+ },
1154
+ "required": [
1155
+ "label",
1156
+ "before",
1157
+ "after"
1158
+ ],
1159
+ "additionalProperties": false
1160
+ },
1161
+ "rows": {
1162
+ "type": "array",
1163
+ "items": {
1164
+ "$ref": "#/definitions/TableRowData"
1165
+ }
1166
+ },
1167
+ "hasHeaderRow": {
1168
+ "type": "boolean"
1169
+ },
1170
+ "headerBackgroundColor": {
1171
+ "type": "string"
1172
+ },
1173
+ "borderColor": {
1174
+ "type": "string"
1175
+ },
1176
+ "borderWidth": {
1177
+ "type": "number"
1178
+ },
1179
+ "cellPadding": {
1180
+ "type": "number"
1181
+ },
1182
+ "fontSize": {
1183
+ "type": "number"
1184
+ },
1185
+ "fontFamily": {
1186
+ "type": "string"
1187
+ },
1188
+ "color": {
1189
+ "type": "string",
1190
+ "description": "Text color. Unset = inherit the document-level `textColor`."
1191
+ },
1192
+ "textAlign": {
1193
+ "type": "string",
1194
+ "enum": [
1195
+ "left",
1196
+ "center",
1197
+ "right"
1198
+ ]
1199
+ }
1200
+ },
1201
+ "required": [
1202
+ "borderColor",
1203
+ "borderWidth",
1204
+ "cellPadding",
1205
+ "fontSize",
1206
+ "hasHeaderRow",
1207
+ "id",
1208
+ "rows",
1209
+ "styles",
1210
+ "textAlign",
1211
+ "type"
1212
+ ],
1213
+ "additionalProperties": false
1214
+ },
1215
+ "TableRowData": {
1216
+ "type": "object",
1217
+ "properties": {
1218
+ "id": {
1219
+ "type": "string"
1220
+ },
1221
+ "cells": {
1222
+ "type": "array",
1223
+ "items": {
1224
+ "$ref": "#/definitions/TableCellData"
1225
+ }
1226
+ }
1227
+ },
1228
+ "required": [
1229
+ "id",
1230
+ "cells"
1231
+ ],
1232
+ "additionalProperties": false
1233
+ },
1234
+ "TableCellData": {
1235
+ "type": "object",
1236
+ "properties": {
1237
+ "id": {
1238
+ "type": "string"
1239
+ },
1240
+ "content": {
1241
+ "type": "string"
1242
+ }
1243
+ },
1244
+ "required": [
1245
+ "id",
1246
+ "content"
1247
+ ],
1248
+ "additionalProperties": false
1249
+ },
1250
+ "CountdownBlock": {
1251
+ "type": "object",
1252
+ "properties": {
1253
+ "id": {
1254
+ "type": "string"
1255
+ },
1256
+ "type": {
1257
+ "type": "string",
1258
+ "const": "countdown"
1259
+ },
1260
+ "styles": {
1261
+ "$ref": "#/definitions/BlockStyles"
1262
+ },
1263
+ "visibility": {
1264
+ "$ref": "#/definitions/BlockVisibility"
1265
+ },
1266
+ "displayCondition": {
1267
+ "type": "object",
1268
+ "properties": {
1269
+ "label": {
1270
+ "type": "string"
1271
+ },
1272
+ "before": {
1273
+ "type": "string"
1274
+ },
1275
+ "after": {
1276
+ "type": "string"
1277
+ },
1278
+ "group": {
1279
+ "type": "string"
1280
+ },
1281
+ "description": {
1282
+ "type": "string"
1283
+ }
1284
+ },
1285
+ "required": [
1286
+ "label",
1287
+ "before",
1288
+ "after"
1289
+ ],
1290
+ "additionalProperties": false
1291
+ },
1292
+ "targetDate": {
1293
+ "type": "string"
1294
+ },
1295
+ "timezone": {
1296
+ "type": "string"
1297
+ },
1298
+ "showDays": {
1299
+ "type": "boolean"
1300
+ },
1301
+ "showHours": {
1302
+ "type": "boolean"
1303
+ },
1304
+ "showMinutes": {
1305
+ "type": "boolean"
1306
+ },
1307
+ "showSeconds": {
1308
+ "type": "boolean"
1309
+ },
1310
+ "separator": {
1311
+ "type": "string",
1312
+ "enum": [
1313
+ ":",
1314
+ "-",
1315
+ " "
1316
+ ]
1317
+ },
1318
+ "digitFontSize": {
1319
+ "type": "number"
1320
+ },
1321
+ "digitColor": {
1322
+ "type": "string"
1323
+ },
1324
+ "labelColor": {
1325
+ "type": "string"
1326
+ },
1327
+ "labelFontSize": {
1328
+ "type": "number"
1329
+ },
1330
+ "backgroundColor": {
1331
+ "type": "string"
1332
+ },
1333
+ "fontFamily": {
1334
+ "type": "string"
1335
+ },
1336
+ "labelDays": {
1337
+ "type": "string"
1338
+ },
1339
+ "labelHours": {
1340
+ "type": "string"
1341
+ },
1342
+ "labelMinutes": {
1343
+ "type": "string"
1344
+ },
1345
+ "labelSeconds": {
1346
+ "type": "string"
1347
+ },
1348
+ "expiredMessage": {
1349
+ "type": "string"
1350
+ },
1351
+ "expiredImageUrl": {
1352
+ "type": "string"
1353
+ },
1354
+ "hideOnExpiry": {
1355
+ "type": "boolean"
1356
+ }
1357
+ },
1358
+ "required": [
1359
+ "backgroundColor",
1360
+ "digitColor",
1361
+ "digitFontSize",
1362
+ "expiredImageUrl",
1363
+ "expiredMessage",
1364
+ "hideOnExpiry",
1365
+ "id",
1366
+ "labelColor",
1367
+ "labelDays",
1368
+ "labelFontSize",
1369
+ "labelHours",
1370
+ "labelMinutes",
1371
+ "labelSeconds",
1372
+ "separator",
1373
+ "showDays",
1374
+ "showHours",
1375
+ "showMinutes",
1376
+ "showSeconds",
1377
+ "styles",
1378
+ "targetDate",
1379
+ "timezone",
1380
+ "type"
1381
+ ],
1382
+ "additionalProperties": false
1383
+ },
1384
+ "CustomBlock": {
1385
+ "type": "object",
1386
+ "properties": {
1387
+ "id": {
1388
+ "type": "string"
1389
+ },
1390
+ "type": {
1391
+ "type": "string",
1392
+ "const": "custom"
1393
+ },
1394
+ "styles": {
1395
+ "$ref": "#/definitions/BlockStyles"
1396
+ },
1397
+ "visibility": {
1398
+ "$ref": "#/definitions/BlockVisibility"
1399
+ },
1400
+ "displayCondition": {
1401
+ "type": "object",
1402
+ "properties": {
1403
+ "label": {
1404
+ "type": "string"
1405
+ },
1406
+ "before": {
1407
+ "type": "string"
1408
+ },
1409
+ "after": {
1410
+ "type": "string"
1411
+ },
1412
+ "group": {
1413
+ "type": "string"
1414
+ },
1415
+ "description": {
1416
+ "type": "string"
1417
+ }
1418
+ },
1419
+ "required": [
1420
+ "label",
1421
+ "before",
1422
+ "after"
1423
+ ],
1424
+ "additionalProperties": false
1425
+ },
1426
+ "customType": {
1427
+ "type": "string"
1428
+ },
1429
+ "fieldValues": {
1430
+ "type": "object",
1431
+ "additionalProperties": {}
1432
+ },
1433
+ "renderedHtml": {
1434
+ "type": "string"
1435
+ },
1436
+ "dataSourceFetched": {
1437
+ "type": "boolean"
1438
+ }
1439
+ },
1440
+ "required": [
1441
+ "customType",
1442
+ "fieldValues",
1443
+ "id",
1444
+ "styles",
1445
+ "type"
1446
+ ],
1447
+ "additionalProperties": false
1448
+ },
1449
+ "TemplateSettings": {
1450
+ "type": "object",
1451
+ "properties": {
1452
+ "width": {
1453
+ "type": "number"
1454
+ },
1455
+ "backgroundColor": {
1456
+ "type": "string"
1457
+ },
1458
+ "textColor": {
1459
+ "type": "string",
1460
+ "description": "Document-level default text color: the `<mj-text>` default in the rendered MJML, inherited by every text block (Title, Paragraph, Menu, Table) that doesn't set its own `color`. Required, defaulting to `#1a1a1a` (see `DEFAULT_TEMPLATE_DEFAULTS`); customize the default per-consumer via `templateDefaults`. A block's explicit `color` or an inline text-color mark overrides it."
1461
+ },
1462
+ "linkColor": {
1463
+ "type": "string",
1464
+ "description": "Document-level link color: emitted as the global `a { color }` rule in the rendered MJML, so it cascades to every link — rich-text and menu alike. Optional: when unset, links inherit the surrounding text color (`color: inherit`), preserving the pre-#352 default. A per-block or per-item color (a Menu item's `color`, `MenuBlock.linkColor`) still overrides it."
1465
+ },
1466
+ "linkUnderline": {
1467
+ "type": "boolean",
1468
+ "description": "Whether links are underlined document-wide: drives the global `a { text-decoration }` rule (`underline` when true, `none` when false). Required, defaulting to `true` (see `DEFAULT_TEMPLATE_DEFAULTS`) — the common, more accessible email default. Applies to body (rich-text) links; buttons and menu items carry their own inline `text-decoration` and are unaffected. Set `false` to render links without an underline."
1469
+ },
1470
+ "fontFamily": {
1471
+ "type": "string"
1472
+ },
1473
+ "preheaderText": {
1474
+ "type": "string"
1475
+ },
1476
+ "locale": {
1477
+ "type": "string",
1478
+ "description": "BCP-47 language code for the rendered email's `<html lang>`. Drives screen-reader pronunciation. Default `'en'` via `DEFAULT_TEMPLATE_DEFAULTS`."
1479
+ },
1480
+ "direction": {
1481
+ "$ref": "#/definitions/ContentDirection",
1482
+ "description": "Writing direction of the delivered email: the canvas `dir` and the rendered `<mjml dir>`. Independent of the editor chrome (`init({ locale })`). Optional: when unset, `resolveContentDirection` falls through to the content language (`ar` / `he` / `fa` / … → `\"rtl\"`, otherwise `\"ltr\"`). An explicit `\"ltr\"` on an Arabic template is a stated decision, not a missing value."
1483
+ }
1484
+ },
1485
+ "required": [
1486
+ "width",
1487
+ "backgroundColor",
1488
+ "textColor",
1489
+ "linkUnderline",
1490
+ "fontFamily",
1491
+ "locale"
1492
+ ],
1493
+ "additionalProperties": false
1494
+ },
1495
+ "ContentDirection": {
1496
+ "type": "string",
1497
+ "enum": [
1498
+ "ltr",
1499
+ "rtl"
1500
+ ],
1501
+ "description": "Writing direction of the delivered email — the canvas `dir` and the rendered `<mjml dir>`. Independent of the editor chrome language (`init({ locale })`)."
1502
+ }
1503
+ }
1504
+ }