@marlinjai/email-editor-core 0.3.0 → 0.4.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.
@@ -0,0 +1,667 @@
1
+ interface GradientStop {
2
+ color: string;
3
+ position: number;
4
+ }
5
+ interface BackgroundGradient {
6
+ type: 'linear' | 'radial';
7
+ angle: number;
8
+ stops: GradientStop[];
9
+ }
10
+ /**
11
+ * Converts a BackgroundGradient to a CSS background-image value.
12
+ * Returns undefined when stops array is empty.
13
+ *
14
+ * Examples:
15
+ * buildGradientCSS({ type: 'linear', angle: 90, stops: [{color:'#f00',position:0},{color:'#00f',position:100}] })
16
+ * // => "linear-gradient(90deg, #f00 0%, #00f 100%)"
17
+ *
18
+ * buildGradientCSS({ type: 'radial', angle: 0, stops: [{color:'#f00',position:0},{color:'#00f',position:100}] })
19
+ * // => "radial-gradient(circle, #f00 0%, #00f 100%)"
20
+ */
21
+ declare function buildGradientCSS(gradient: BackgroundGradient): string | undefined;
22
+
23
+ /**
24
+ * Spacing configuration for padding/margin
25
+ */
26
+ interface Spacing {
27
+ top?: string;
28
+ right?: string;
29
+ bottom?: string;
30
+ left?: string;
31
+ }
32
+ /**
33
+ * Custom font definition
34
+ */
35
+ interface FontDefinition {
36
+ name: string;
37
+ href: string;
38
+ }
39
+ /**
40
+ * Theme color for reusable brand colors
41
+ */
42
+ interface ThemeColor {
43
+ name: string;
44
+ value: string;
45
+ }
46
+ /**
47
+ * MJML attributes the editor has no control for, kept as found (values as they
48
+ * stood in the source, XML entities included) and emitted again by the
49
+ * compiler after the attributes the editor sets. Written by the MJML import,
50
+ * so an imported document compiles the way its source did: a `css-class` the
51
+ * author's `mj-style` rules target, an `mj-class`, a button's `font-weight`.
52
+ */
53
+ type ExtraAttributes = Record<string, string>;
54
+ /**
55
+ * What an imported document's `<mj-head>` and `<mj-body>` carried beyond the
56
+ * fields the editor has (title, preview, fonts, breakpoint, styles). When
57
+ * present, the compiler emits `attributes` instead of its own default
58
+ * `<mj-attributes>` (so the source's `mj-all`, per-component defaults and
59
+ * `mj-class` definitions apply as they did), `bodyAttributes` on `<mj-body>`,
60
+ * and `headRaw` (for example `mj-html-attributes`) verbatim inside `<mj-head>`.
61
+ */
62
+ interface MjmlHead {
63
+ /** The inner markup of `<mj-attributes>`, verbatim. An empty string means "no defaults at all". */
64
+ attributes?: string;
65
+ /** Attributes of `<mj-body>`, e.g. `background-color`, `width`. */
66
+ bodyAttributes?: ExtraAttributes;
67
+ /** Other head elements, verbatim, in source order. */
68
+ headRaw?: string;
69
+ }
70
+ /**
71
+ * Email template metadata
72
+ */
73
+ interface TemplateMetadata {
74
+ subject?: string;
75
+ previewText?: string;
76
+ title?: string;
77
+ /** Epoch milliseconds (what the editor emits) or an ISO 8601 string */
78
+ createdAt?: string | number;
79
+ /** Epoch milliseconds (what the editor emits) or an ISO 8601 string */
80
+ updatedAt?: string | number;
81
+ fonts?: FontDefinition[];
82
+ themeColors?: ThemeColor[];
83
+ breakpoint?: string;
84
+ customCSS?: string;
85
+ inlineCSS?: string;
86
+ /** Set by the MJML import; see {@link MjmlHead}. */
87
+ mjmlHead?: MjmlHead;
88
+ }
89
+ /**
90
+ * Base block interface - all blocks extend this
91
+ */
92
+ interface BaseBlock {
93
+ id: string;
94
+ type: string;
95
+ hidden?: boolean;
96
+ /** See {@link ExtraAttributes}. */
97
+ extraAttributes?: ExtraAttributes;
98
+ }
99
+ /**
100
+ * Text block with rich content
101
+ */
102
+ interface TextBlock extends BaseBlock {
103
+ type: 'text';
104
+ content: string;
105
+ align?: 'left' | 'center' | 'right' | 'justify';
106
+ color?: string;
107
+ fontSize?: string;
108
+ fontFamily?: string;
109
+ padding?: Spacing;
110
+ lineHeight?: string;
111
+ }
112
+ /**
113
+ * Image block
114
+ */
115
+ interface ImageBlock extends BaseBlock {
116
+ type: 'image';
117
+ src: string;
118
+ alt?: string;
119
+ width?: string;
120
+ height?: string;
121
+ align?: 'left' | 'center' | 'right';
122
+ href?: string;
123
+ padding?: Spacing;
124
+ borderRadius?: string;
125
+ }
126
+ /**
127
+ * Button block
128
+ */
129
+ interface ButtonBlock extends BaseBlock {
130
+ type: 'button';
131
+ label: string;
132
+ href: string;
133
+ align?: 'left' | 'center' | 'right';
134
+ backgroundColor?: string;
135
+ color?: string;
136
+ borderRadius?: string;
137
+ border?: string;
138
+ padding?: Spacing;
139
+ innerPadding?: string;
140
+ }
141
+ /**
142
+ * Divider block
143
+ */
144
+ interface DividerBlock extends BaseBlock {
145
+ type: 'divider';
146
+ borderColor?: string;
147
+ borderWidth?: string;
148
+ borderStyle?: 'solid' | 'dashed' | 'dotted';
149
+ width?: string;
150
+ padding?: Spacing;
151
+ }
152
+ /**
153
+ * Spacer block for vertical spacing
154
+ */
155
+ interface SpacerBlock extends BaseBlock {
156
+ type: 'spacer';
157
+ height: string;
158
+ }
159
+ /**
160
+ * Custom branded header block (locked)
161
+ */
162
+ interface HeaderBlock extends BaseBlock {
163
+ type: 'header';
164
+ locked: true;
165
+ }
166
+ /**
167
+ * Custom branded footer block (locked)
168
+ */
169
+ interface FooterBlock extends BaseBlock {
170
+ type: 'footer';
171
+ locked: true;
172
+ }
173
+ /**
174
+ * Social link definition
175
+ */
176
+ interface SocialLink {
177
+ platform: string;
178
+ url: string;
179
+ color?: string;
180
+ }
181
+ /**
182
+ * Social block for social media icons
183
+ */
184
+ interface SocialBlock extends BaseBlock {
185
+ type: 'social';
186
+ links: SocialLink[];
187
+ iconSize?: string;
188
+ iconPadding?: string;
189
+ borderRadius?: string;
190
+ align?: 'left' | 'center' | 'right';
191
+ mode?: 'horizontal' | 'vertical';
192
+ }
193
+ /**
194
+ * Hero block with background image
195
+ */
196
+ interface HeroBlock extends BaseBlock {
197
+ type: 'hero';
198
+ backgroundImage: string;
199
+ backgroundHeight?: string;
200
+ backgroundWidth?: string;
201
+ backgroundColor?: string;
202
+ verticalAlign?: 'top' | 'middle' | 'bottom';
203
+ mode?: 'fixed-height' | 'fluid-height';
204
+ }
205
+ /**
206
+ * Accordion item
207
+ */
208
+ interface AccordionItem {
209
+ title: string;
210
+ content: string;
211
+ }
212
+ /**
213
+ * Accordion block for collapsible content
214
+ */
215
+ interface AccordionBlock extends BaseBlock {
216
+ type: 'accordion';
217
+ items: AccordionItem[];
218
+ iconPosition?: 'left' | 'right';
219
+ borderColor?: string;
220
+ fontFamily?: string;
221
+ }
222
+ /**
223
+ * Raw HTML block
224
+ */
225
+ interface RawBlock extends BaseBlock {
226
+ type: 'raw';
227
+ html: string;
228
+ }
229
+ /**
230
+ * Navbar link definition
231
+ */
232
+ interface NavbarLink {
233
+ href: string;
234
+ label: string;
235
+ color?: string;
236
+ }
237
+ /**
238
+ * Navbar block for navigation
239
+ */
240
+ interface NavbarBlock extends BaseBlock {
241
+ type: 'navbar';
242
+ links: NavbarLink[];
243
+ hamburger?: boolean;
244
+ baseUrl?: string;
245
+ align?: 'left' | 'center' | 'right';
246
+ icoColor?: string;
247
+ padding?: Spacing;
248
+ }
249
+ /**
250
+ * Carousel image definition
251
+ */
252
+ interface CarouselImage {
253
+ src: string;
254
+ alt?: string;
255
+ href?: string;
256
+ thumbnailSrc?: string;
257
+ }
258
+ /**
259
+ * Carousel block for image slideshows
260
+ */
261
+ interface CarouselBlock extends BaseBlock {
262
+ type: 'carousel';
263
+ images: CarouselImage[];
264
+ thumbnails?: 'visible' | 'hidden';
265
+ borderRadius?: string;
266
+ iconWidth?: string;
267
+ tbBorderRadius?: string;
268
+ padding?: Spacing;
269
+ }
270
+ /**
271
+ * Table block for tabular data
272
+ */
273
+ interface TableBlock extends BaseBlock {
274
+ type: 'table';
275
+ headers: string[];
276
+ rows: string[][];
277
+ align?: 'left' | 'center' | 'right';
278
+ color?: string;
279
+ fontFamily?: string;
280
+ fontSize?: string;
281
+ cellpadding?: string;
282
+ cellspacing?: string;
283
+ border?: string;
284
+ padding?: Spacing;
285
+ }
286
+ /**
287
+ * Union type of all possible blocks
288
+ */
289
+ type Block = TextBlock | ImageBlock | ButtonBlock | DividerBlock | SpacerBlock | HeaderBlock | FooterBlock | SocialBlock | HeroBlock | AccordionBlock | RawBlock | NavbarBlock | CarouselBlock | TableBlock;
290
+ /**
291
+ * Column within a section
292
+ */
293
+ interface Column {
294
+ id: string;
295
+ width?: number;
296
+ blocks: Block[];
297
+ hidden?: boolean;
298
+ backgroundColor?: string;
299
+ backgroundGradient?: BackgroundGradient;
300
+ verticalAlign?: 'top' | 'middle' | 'bottom';
301
+ padding?: Spacing;
302
+ /**
303
+ * Optional sub-columns. When non-empty, `blocks` MUST be empty
304
+ * (a column is either a leaf with blocks, or a group with sub-columns).
305
+ * See `docs/superpowers/specs/2026-04-26-nested-columns-design.md`.
306
+ */
307
+ subColumns?: SubColumn[];
308
+ /** See {@link ExtraAttributes}. */
309
+ extraAttributes?: ExtraAttributes;
310
+ }
311
+ /**
312
+ * Sub-column inside a "group"-kind Column. Holds only leaf blocks
313
+ * (text, image, button, divider, spacer, social). Cannot itself contain
314
+ * sub-columns (no nesting beyond depth 2).
315
+ */
316
+ interface SubColumn {
317
+ id: string;
318
+ width: number;
319
+ blocks: Block[];
320
+ backgroundColor?: string;
321
+ verticalAlign?: 'top' | 'middle' | 'bottom';
322
+ paddingTop?: string;
323
+ paddingRight?: string;
324
+ paddingBottom?: string;
325
+ paddingLeft?: string;
326
+ }
327
+ /**
328
+ * Section containing columns
329
+ */
330
+ interface Section {
331
+ id: string;
332
+ type: 'section';
333
+ backgroundColor?: string;
334
+ backgroundImage?: string;
335
+ backgroundGradient?: BackgroundGradient;
336
+ backgroundPosition?: string;
337
+ backgroundRepeat?: 'repeat' | 'no-repeat';
338
+ backgroundSize?: string;
339
+ /**
340
+ * Full width (`full-width` in MJML). Inside a full-width {@link Wrapper},
341
+ * MJML renders the section at standard width whatever this says.
342
+ */
343
+ fullWidth?: boolean;
344
+ noStack?: boolean;
345
+ hidden?: boolean;
346
+ padding?: Spacing;
347
+ columns: Column[];
348
+ /**
349
+ * Emit the section's raw blocks straight into the parent (`<mj-body>`, or
350
+ * the `<mj-wrapper>` the section sits in) instead of inside an
351
+ * `<mj-section>`: markup that sat there in an imported document. Ignored as
352
+ * soon as the section holds any block that is not raw.
353
+ */
354
+ bodyRaw?: boolean;
355
+ /** See {@link ExtraAttributes}. */
356
+ extraAttributes?: ExtraAttributes;
357
+ }
358
+ /**
359
+ * A container around several sections (`<mj-wrapper>`): one background,
360
+ * border, radius and padding shared by the sections inside, with an optional
361
+ * vertical `gap` between them. Sits at the top level of a document, next to
362
+ * sections; it never holds another wrapper and never sits inside a section.
363
+ * It may be empty (it keeps its styling, and sections can be moved back in).
364
+ * Added in schema version 1.1.
365
+ */
366
+ interface Wrapper {
367
+ id: string;
368
+ type: 'wrapper';
369
+ hidden?: boolean;
370
+ backgroundColor?: string;
371
+ /** `background-url` in MJML. */
372
+ backgroundImage?: string;
373
+ backgroundGradient?: BackgroundGradient;
374
+ backgroundPosition?: string;
375
+ backgroundRepeat?: 'repeat' | 'no-repeat';
376
+ backgroundSize?: string;
377
+ /** CSS border shorthand for all four sides, e.g. `1px solid #dddddd`. */
378
+ border?: string;
379
+ borderTop?: string;
380
+ borderRight?: string;
381
+ borderBottom?: string;
382
+ borderLeft?: string;
383
+ borderRadius?: string;
384
+ /** MJML's default when unset is `20px 0`. */
385
+ padding?: Spacing;
386
+ /** Full width (`full-width`): the background spans the whole mail width; the sections inside stay at standard width. */
387
+ fullWidth?: boolean;
388
+ /** Class names for `css-class`, space separated, for the document's own `mj-style` rules. */
389
+ cssClass?: string;
390
+ /** Vertical space between the sections inside, in px (`gap`, MJML 4.15 and later). */
391
+ gap?: string;
392
+ textAlign?: 'left' | 'center' | 'right';
393
+ /** See {@link ExtraAttributes}. */
394
+ extraAttributes?: ExtraAttributes;
395
+ sections: Section[];
396
+ }
397
+ /** What the top level of a document holds, in order: sections and wrappers. */
398
+ type TopLevelItem = Section | Wrapper;
399
+ /** The document schema versions: 1.1 added {@link Wrapper}. */
400
+ type TemplateVersion = '1.0' | '1.1';
401
+ /**
402
+ * Complete email template structure
403
+ */
404
+ interface EmailTemplate {
405
+ /**
406
+ * The document's id. Optional: a document without one is valid, and the
407
+ * editor store assigns one when it opens it (see `TemplateModel`).
408
+ * `migrateTemplate` never adds or changes it.
409
+ */
410
+ id?: string;
411
+ /**
412
+ * The schema version. `migrateTemplate` brings every document it accepts to
413
+ * the current one (1.1); a 1.0 document cannot hold a wrapper.
414
+ */
415
+ version: TemplateVersion;
416
+ metadata: TemplateMetadata;
417
+ /** The document's top level, in order: sections and wrappers (see {@link TopLevelItem}). */
418
+ sections: TopLevelItem[];
419
+ }
420
+ /** Whether a top-level item is a {@link Wrapper}. */
421
+ declare function isWrapper(item: TopLevelItem): item is Wrapper;
422
+ /** Every section of a document in order, the ones inside wrappers included. */
423
+ declare function allSections(items: readonly TopLevelItem[]): Section[];
424
+ /**
425
+ * Result of MJML compilation
426
+ */
427
+ interface CompileResult {
428
+ mjml: string;
429
+ html: string;
430
+ errors?: string[];
431
+ }
432
+
433
+ /** The `<mj-attributes>` a document gets unless it brings its own (`metadata.mjmlHead.attributes`). */
434
+ declare const DEFAULT_MJML_ATTRIBUTES = "\n <mj-all font-family=\"Georgia, serif\" />\n <mj-text font-size=\"14px\" line-height=\"1.6\" />\n ";
435
+ /** Marks the editor's own raw markup so the MJML import can read the block back exactly. */
436
+ declare const EDITOR_DATA_ATTRIBUTE: {
437
+ readonly social: "data-ee-social";
438
+ readonly subColumns: "data-ee-subcols";
439
+ };
440
+ /**
441
+ * Standard, padded base64 of a UTF-8 string, without Node's `Buffer`, so the
442
+ * builder runs in the browser too. Byte-identical to `Buffer.toString('base64')`.
443
+ */
444
+ declare function base64Utf8(text: string): string;
445
+ /**
446
+ * The comments that fence everything the editor's own compile adds to a
447
+ * document (`toMJML(template, { editor: true })`): ghosts for hidden nodes, a
448
+ * floor for empty columns, markers around a Raw block's verbatim markup. MJML
449
+ * keeps body comments in place, so the same fence survives into the HTML and
450
+ * {@link stripEditorMarkup} takes the additions out of either.
451
+ */
452
+ declare const EDITOR_MARKER: {
453
+ readonly begin: "<!--ee:begin-->";
454
+ readonly end: "<!--ee:end-->";
455
+ };
456
+ /** The editor's additions removed from MJML or HTML, leaving the plain document. */
457
+ declare function stripEditorMarkup(markup: string): string;
458
+ /**
459
+ * The inline styles a Text block's content is wrapped in (`<div style>` inside
460
+ * MJML's own div), so nested tags inherit them. When this is empty the content
461
+ * sits directly in MJML's div. The canvas's in-place editor uses the same
462
+ * function to find the element that holds exactly `block.content`, so there
463
+ * is one rule for where the content lives.
464
+ */
465
+ declare function textInlineStyles(block: Pick<TextBlock, 'align' | 'color' | 'fontSize' | 'fontFamily' | 'lineHeight'>): string[];
466
+ /** Options of {@link MjmlBuilder.toMJML}. */
467
+ interface BuildOptions {
468
+ /**
469
+ * Emit the editor's own affordances, fenced by {@link EDITOR_MARKER} so they
470
+ * strip back to the plain document: a ghost row for a hidden block, a ghost
471
+ * section or wrapper for a hidden one (never a ghost column: a column's
472
+ * width depends on its siblings' count, so a ghost would move the visible
473
+ * ones), a 48px floor in an empty column so it can be a drop target, and
474
+ * id markers around Raw blocks. Display only; never sent.
475
+ */
476
+ editor?: boolean;
477
+ }
478
+ /** A block's (or sub-columns') JSON, base64-encoded, for an {@link EDITOR_DATA_ATTRIBUTE}. */
479
+ declare function encodeEditorData(value: unknown): string;
480
+ /** `a + b` for two px lengths (`0` counts as px); undefined when either is something else. */
481
+ declare function addPx(a: string, b: string): string | undefined;
482
+ /**
483
+ * A section's padding with a wrapper's gap added on top. MJML's `mj-wrapper`
484
+ * has no gap of its own, so the editor's `gap` is compiled this way: every
485
+ * section after the first inside the wrapper gets the gap added to its top
486
+ * padding (MJML's default 20px when the section declares none). The MJML
487
+ * import takes it off again, so a document survives export and import.
488
+ * A top padding that is not a px length is left alone.
489
+ */
490
+ declare function paddingWithGap(spacing: Spacing | undefined, gap: string): Spacing;
491
+ /** Options for one {@link MJMLCompiler.compile} call. */
492
+ interface CompileOptions {
493
+ /**
494
+ * MJML adds a Google Fonts `<link>` and `@import` on its own whenever a font
495
+ * family it knows (Open Sans, Droid Sans, Lato, Roboto, Ubuntu) appears in
496
+ * the document. `false` leaves them out, so the font falls back to the rest
497
+ * of its stack and the mail loads nothing from Google. Fonts the document
498
+ * declares itself (`metadata.fonts`) are always emitted. Default `true`.
499
+ */
500
+ webFonts?: boolean;
501
+ }
502
+ /**
503
+ * The options both engines compile with, in one place: the server's `mjml`
504
+ * and the browser's `mjml-browser` must receive the same ones, or their
505
+ * output differs by configuration rather than by build, and the parity test
506
+ * between them means nothing.
507
+ */
508
+ declare function mjmlOptions(options?: CompileOptions): {
509
+ fonts?: {} | undefined;
510
+ ignoreIncludes: boolean;
511
+ validationLevel: "soft";
512
+ minify: boolean;
513
+ };
514
+ /**
515
+ * Turns an EmailTemplate into MJML markup. `MJMLCompiler` (server) and
516
+ * `compileInBrowser` (browser) both compile what this emits.
517
+ */
518
+ declare class MjmlBuilder {
519
+ /**
520
+ * Set true while emitting a column with sub-columns. Causes generateHead
521
+ * to inject the responsive media query exactly once per template.
522
+ */
523
+ protected needsSubColumnStyles: boolean;
524
+ /** Set for the duration of one build in editor mode; see {@link BuildOptions}. */
525
+ protected editor: boolean;
526
+ /** `fragment` fenced as an editor addition, or nothing outside editor mode. */
527
+ protected ee(fragment: string): string;
528
+ /** The label of a ghost: what the node is, so the person can find and unhide it. */
529
+ private ghostText;
530
+ /**
531
+ * The MJML markup for a document, without compiling it to HTML.
532
+ */
533
+ toMJML(template: EmailTemplate, options?: BuildOptions): string;
534
+ /**
535
+ * Convert template to MJML markup
536
+ */
537
+ protected templateToMJML(template: EmailTemplate): string;
538
+ /**
539
+ * Generate MJML head section with all head components
540
+ * Supports: mj-title, mj-preview, mj-font, mj-breakpoint, mj-style
541
+ */
542
+ private generateHead;
543
+ /**
544
+ * Collect background-image CSS rules for all wrappers, sections and columns that have gradients.
545
+ * Returns a string of CSS rules to inject as a single mj-style block.
546
+ */
547
+ private collectGradientStyles;
548
+ /**
549
+ * Convert a wrapper to an `<mj-wrapper>` around its sections. The wrapper's
550
+ * attributes are MJML's own for `mj-wrapper`; the sections inside follow
551
+ * MJML's rules there (a full-width section inside a full-width wrapper
552
+ * renders at standard width, which the inspector explains).
553
+ */
554
+ private wrapperToMJML;
555
+ /** Background attributes shared by sections and wrappers: a gradient (with its Outlook fallback colour), or colour and image. */
556
+ private pushBackground;
557
+ /**
558
+ * Convert section to MJML
559
+ * Supports background images, full-width, and mj-group for non-stacking columns
560
+ */
561
+ private sectionToMJML;
562
+ /**
563
+ * Convert column to MJML
564
+ */
565
+ private columnToMJML;
566
+ /**
567
+ * Emit a group column as an mj-column wrapping a hand-built nested
568
+ * table inside an mj-raw island. The parent mj-section structure
569
+ * stays standard MJML; only the nested area escapes MJML's parser.
570
+ *
571
+ * The responsive media query (table.ee-sub-cols td.ee-sub-col) is
572
+ * injected once at document head via generateHead when the
573
+ * needsSubColumnStyles flag is set.
574
+ */
575
+ private subColumnsToMJML;
576
+ /**
577
+ * Convert block to MJML based on type
578
+ */
579
+ private blockToMJML;
580
+ /**
581
+ * Convert text block to MJML
582
+ *
583
+ * Note: MJML applies styles to the container <td>, but TipTap content
584
+ * (wrapped in <p> tags) doesn't inherit these styles. We solve this by
585
+ * wrapping the content in a <div> with explicit inline styles.
586
+ */
587
+ private textBlockToMJML;
588
+ /**
589
+ * Convert image block to MJML
590
+ */
591
+ private imageBlockToMJML;
592
+ /**
593
+ * Convert button block to MJML
594
+ */
595
+ private buttonBlockToMJML;
596
+ /**
597
+ * Convert divider block to MJML
598
+ */
599
+ private dividerBlockToMJML;
600
+ /**
601
+ * Convert spacer block to MJML
602
+ */
603
+ private spacerBlockToMJML;
604
+ /**
605
+ * Platform brand colors for social icons
606
+ */
607
+ private readonly SOCIAL_COLORS;
608
+ /**
609
+ * Get white SVG icon as data URI for a platform
610
+ * Uses clean, minimal SVGs optimized for email
611
+ */
612
+ private getSocialIconDataUri;
613
+ /**
614
+ * Convert social block to MJML using raw HTML table for reliable horizontal layout
615
+ * Uses styled anchor tags with background colors for full width control
616
+ */
617
+ private socialBlockToMJML;
618
+ /**
619
+ * Convert hero block to MJML
620
+ */
621
+ private heroBlockToMJML;
622
+ /**
623
+ * Convert accordion block to MJML
624
+ */
625
+ private accordionBlockToMJML;
626
+ /**
627
+ * Convert raw HTML block to MJML
628
+ */
629
+ private rawBlockToMJML;
630
+ /**
631
+ * Convert navbar block to MJML
632
+ */
633
+ private navbarBlockToMJML;
634
+ /**
635
+ * Convert carousel block to MJML
636
+ */
637
+ private carouselBlockToMJML;
638
+ /**
639
+ * Convert table block to MJML
640
+ */
641
+ private tableBlockToMJML;
642
+ /**
643
+ * Generate the locked header block.
644
+ *
645
+ * It used to render one client's company name and a logo from an image host;
646
+ * both are gone. What is left is a placeholder image slot. Keep this in step
647
+ * with `headerBlockDefinition` in `packages/blocks/src/branded/index.ts`:
648
+ * which of the two runs depends on how the registry is configured.
649
+ *
650
+ * The placeholder is a `data:` URI rather than an address on an image host,
651
+ * so a workspace whose `asset_policy` is `service_only` can still send a mail
652
+ * that contains this block.
653
+ */
654
+ private headerBlockToMJML;
655
+ /**
656
+ * Generate the locked footer block: the unsubscribe link and nothing else.
657
+ *
658
+ * It used to carry a copyright line naming one client's company. A locked
659
+ * block carries no props, so whoever sends the mail cannot correct a name
660
+ * that is not theirs; the line is gone rather than replaced with a fake one.
661
+ * Keep this in step with `footerBlockDefinition` in
662
+ * `packages/blocks/src/branded/index.ts`.
663
+ */
664
+ private footerBlockToMJML;
665
+ }
666
+
667
+ export { type AccordionBlock as A, type BuildOptions as B, type CompileOptions as C, DEFAULT_MJML_ATTRIBUTES as D, type EmailTemplate as E, type FontDefinition as F, type GradientStop as G, type HeaderBlock as H, type ImageBlock as I, type TextBlock as J, type ThemeColor as K, type TopLevelItem as L, MjmlBuilder as M, type NavbarBlock as N, addPx as O, allSections as P, base64Utf8 as Q, type RawBlock as R, type Section as S, type TableBlock as T, buildGradientCSS as U, encodeEditorData as V, type Wrapper as W, isWrapper as X, paddingWithGap as Y, textInlineStyles as Z, type CompileResult as a, EDITOR_MARKER as b, type Block as c, type BackgroundGradient as d, type MjmlHead as e, type AccordionItem as f, type BaseBlock as g, type ButtonBlock as h, type CarouselBlock as i, type CarouselImage as j, type Column as k, type DividerBlock as l, mjmlOptions as m, EDITOR_DATA_ATTRIBUTE as n, type ExtraAttributes as o, type FooterBlock as p, type HeroBlock as q, type NavbarLink as r, stripEditorMarkup as s, type SocialBlock as t, type SocialLink as u, type SpacerBlock as v, type Spacing as w, type SubColumn as x, type TemplateMetadata as y, type TemplateVersion as z };