@react-email/render 0.0.16-canary.0 → 0.0.17-canary.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/dist/index.js ADDED
@@ -0,0 +1,889 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
7
+ var __getProtoOf = Object.getPrototypeOf;
8
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
10
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
11
+ var __spreadValues = (a, b) => {
12
+ for (var prop in b || (b = {}))
13
+ if (__hasOwnProp.call(b, prop))
14
+ __defNormalProp(a, prop, b[prop]);
15
+ if (__getOwnPropSymbols)
16
+ for (var prop of __getOwnPropSymbols(b)) {
17
+ if (__propIsEnum.call(b, prop))
18
+ __defNormalProp(a, prop, b[prop]);
19
+ }
20
+ return a;
21
+ };
22
+ var __export = (target, all) => {
23
+ for (var name in all)
24
+ __defProp(target, name, { get: all[name], enumerable: true });
25
+ };
26
+ var __copyProps = (to, from, except, desc) => {
27
+ if (from && typeof from === "object" || typeof from === "function") {
28
+ for (let key of __getOwnPropNames(from))
29
+ if (!__hasOwnProp.call(to, key) && key !== except)
30
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
31
+ }
32
+ return to;
33
+ };
34
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
35
+ // If the importer is in node compatibility mode or this is not an ESM
36
+ // file that has been converted to a CommonJS file using a Babel-
37
+ // compatible transform (i.e. "__esModule" has not been set), then set
38
+ // "default" to the CommonJS "module.exports" for node compatibility.
39
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
40
+ mod
41
+ ));
42
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
43
+ var __async = (__this, __arguments, generator) => {
44
+ return new Promise((resolve, reject) => {
45
+ var fulfilled = (value) => {
46
+ try {
47
+ step(generator.next(value));
48
+ } catch (e) {
49
+ reject(e);
50
+ }
51
+ };
52
+ var rejected = (value) => {
53
+ try {
54
+ step(generator.throw(value));
55
+ } catch (e) {
56
+ reject(e);
57
+ }
58
+ };
59
+ var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
60
+ step((generator = generator.apply(__this, __arguments)).next());
61
+ });
62
+ };
63
+
64
+ // src/index.ts
65
+ var src_exports = {};
66
+ __export(src_exports, {
67
+ doctype: () => doctype,
68
+ plainTextSelectors: () => plainTextSelectors,
69
+ render: () => render
70
+ });
71
+ module.exports = __toCommonJS(src_exports);
72
+
73
+ // src/render.ts
74
+ var import_constants2 = require("react-reconciler/constants");
75
+ var import_html_to_text = require("html-to-text");
76
+
77
+ // src/renderer/index.ts
78
+ var import_react_reconciler = __toESM(require("react-reconciler"));
79
+ var import_constants = require("react-reconciler/constants.js");
80
+
81
+ // src/renderer/dom-property.ts
82
+ var RESERVED = 0;
83
+ var STRING = 1;
84
+ var BOOLEANISH_STRING = 2;
85
+ var BOOLEAN = 3;
86
+ var OVERLOADED_BOOLEAN = 4;
87
+ var NUMERIC = 5;
88
+ var POSITIVE_NUMERIC = 6;
89
+ var ATTRIBUTE_NAME_START_CHAR = ":A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD";
90
+ var ATTRIBUTE_NAME_CHAR = `${ATTRIBUTE_NAME_START_CHAR}\\-.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040`;
91
+ var VALID_ATTRIBUTE_NAME_REGEX = new RegExp(
92
+ `^[${ATTRIBUTE_NAME_START_CHAR}][${ATTRIBUTE_NAME_CHAR}]*$`
93
+ );
94
+ function shouldIgnoreAttribute(name, propertyInfo) {
95
+ if (propertyInfo !== null) {
96
+ return propertyInfo.type === RESERVED;
97
+ }
98
+ if (name.length > 2 && (name.startsWith("o") || name.startsWith("O")) && (name[1] === "n" || name[1] === "N")) {
99
+ return true;
100
+ }
101
+ return false;
102
+ }
103
+ function getPropertyInfo(name) {
104
+ return Object.hasOwn(properties, name) ? properties[name] : null;
105
+ }
106
+ var PropertyInfoRecord = class {
107
+ constructor(name, type, mustUseProperty, attributeName, attributeNamespace, sanitizeURL, removeEmptyString) {
108
+ this.acceptsBooleans = type === BOOLEANISH_STRING || type === BOOLEAN || type === OVERLOADED_BOOLEAN;
109
+ this.attributeName = attributeName;
110
+ this.attributeNamespace = attributeNamespace;
111
+ this.mustUseProperty = mustUseProperty;
112
+ this.propertyName = name;
113
+ this.type = type;
114
+ this.sanitizeURL = sanitizeURL;
115
+ this.removeEmptyString = removeEmptyString;
116
+ }
117
+ };
118
+ var properties = {};
119
+ var reservedProps = [
120
+ "children",
121
+ "dangerouslySetInnerHTML",
122
+ // TODO: This prevents the assignment of defaultValue to regular
123
+ // elements (not just inputs). Now that ReactDOMInput assigns to the
124
+ // defaultValue property -- do we need this?
125
+ "defaultValue",
126
+ "defaultChecked",
127
+ "innerHTML",
128
+ "suppressContentEditableWarning",
129
+ "suppressHydrationWarning"
130
+ ];
131
+ reservedProps.forEach((name) => {
132
+ properties[name] = new PropertyInfoRecord(
133
+ name,
134
+ RESERVED,
135
+ false,
136
+ // mustUseProperty
137
+ name,
138
+ // attributeName
139
+ null,
140
+ // attributeNamespace
141
+ false,
142
+ // sanitizeURL
143
+ false
144
+ // removeEmptyString
145
+ );
146
+ });
147
+ [
148
+ ["acceptCharset", "accept-charset"],
149
+ ["className", "class"],
150
+ ["htmlFor", "for"],
151
+ ["httpEquiv", "http-equiv"]
152
+ ].forEach(([name, attributeName]) => {
153
+ properties[name] = new PropertyInfoRecord(
154
+ name,
155
+ STRING,
156
+ false,
157
+ // mustUseProperty
158
+ attributeName,
159
+ // attributeName
160
+ null,
161
+ // attributeNamespace
162
+ false,
163
+ // sanitizeURL
164
+ false
165
+ // removeEmptyString
166
+ );
167
+ });
168
+ ["contentEditable", "draggable", "spellCheck", "value"].forEach((name) => {
169
+ properties[name] = new PropertyInfoRecord(
170
+ name,
171
+ BOOLEANISH_STRING,
172
+ false,
173
+ // mustUseProperty
174
+ name.toLowerCase(),
175
+ // attributeName
176
+ null,
177
+ // attributeNamespace
178
+ false,
179
+ // sanitizeURL
180
+ false
181
+ // removeEmptyString
182
+ );
183
+ });
184
+ [
185
+ "autoReverse",
186
+ "externalResourcesRequired",
187
+ "focusable",
188
+ "preserveAlpha"
189
+ ].forEach((name) => {
190
+ properties[name] = new PropertyInfoRecord(
191
+ name,
192
+ BOOLEANISH_STRING,
193
+ false,
194
+ // mustUseProperty
195
+ name,
196
+ // attributeName
197
+ null,
198
+ // attributeNamespace
199
+ false,
200
+ // sanitizeURL
201
+ false
202
+ // removeEmptyString
203
+ );
204
+ });
205
+ [
206
+ "allowFullScreen",
207
+ "async",
208
+ // Note: there is a special case that prevents it from being written to the DOM
209
+ // on the client side because the browsers are inconsistent. Instead we call focus().
210
+ "autoFocus",
211
+ "autoPlay",
212
+ "controls",
213
+ "default",
214
+ "defer",
215
+ "disabled",
216
+ "disablePictureInPicture",
217
+ "disableRemotePlayback",
218
+ "formNoValidate",
219
+ "hidden",
220
+ "loop",
221
+ "noModule",
222
+ "noValidate",
223
+ "open",
224
+ "playsInline",
225
+ "readOnly",
226
+ "required",
227
+ "reversed",
228
+ "scoped",
229
+ "seamless",
230
+ // Microdata
231
+ "itemScope"
232
+ ].forEach((name) => {
233
+ properties[name] = new PropertyInfoRecord(
234
+ name,
235
+ BOOLEAN,
236
+ false,
237
+ // mustUseProperty
238
+ name.toLowerCase(),
239
+ // attributeName
240
+ null,
241
+ // attributeNamespace
242
+ false,
243
+ // sanitizeURL
244
+ false
245
+ // removeEmptyString
246
+ );
247
+ });
248
+ [
249
+ "checked",
250
+ // Note: `option.selected` is not updated if `select.multiple` is
251
+ // disabled with `removeAttribute`. We have special logic for handling this.
252
+ "multiple",
253
+ "muted",
254
+ "selected"
255
+ // NOTE: if you add a camelCased prop to this list,
256
+ // you'll need to set attributeName to name.toLowerCase()
257
+ // instead in the assignment below.
258
+ ].forEach((name) => {
259
+ properties[name] = new PropertyInfoRecord(
260
+ name,
261
+ BOOLEAN,
262
+ true,
263
+ // mustUseProperty
264
+ name,
265
+ // attributeName
266
+ null,
267
+ // attributeNamespace
268
+ false,
269
+ // sanitizeURL
270
+ false
271
+ // removeEmptyString
272
+ );
273
+ });
274
+ [
275
+ "capture",
276
+ "download"
277
+ // NOTE: if you add a camelCased prop to this list,
278
+ // you'll need to set attributeName to name.toLowerCase()
279
+ // instead in the assignment below.
280
+ ].forEach((name) => {
281
+ properties[name] = new PropertyInfoRecord(
282
+ name,
283
+ OVERLOADED_BOOLEAN,
284
+ false,
285
+ // mustUseProperty
286
+ name,
287
+ // attributeName
288
+ null,
289
+ // attributeNamespace
290
+ false,
291
+ // sanitizeURL
292
+ false
293
+ // removeEmptyString
294
+ );
295
+ });
296
+ [
297
+ "cols",
298
+ "rows",
299
+ "size",
300
+ "span"
301
+ // NOTE: if you add a camelCased prop to this list,
302
+ // you'll need to set attributeName to name.toLowerCase()
303
+ // instead in the assignment below.
304
+ ].forEach((name) => {
305
+ properties[name] = new PropertyInfoRecord(
306
+ name,
307
+ POSITIVE_NUMERIC,
308
+ false,
309
+ // mustUseProperty
310
+ name,
311
+ // attributeName
312
+ null,
313
+ // attributeNamespace
314
+ false,
315
+ // sanitizeURL
316
+ false
317
+ // removeEmptyString
318
+ );
319
+ });
320
+ ["rowSpan", "start"].forEach((name) => {
321
+ properties[name] = new PropertyInfoRecord(
322
+ name,
323
+ NUMERIC,
324
+ false,
325
+ // mustUseProperty
326
+ name.toLowerCase(),
327
+ // attributeName
328
+ null,
329
+ // attributeNamespace
330
+ false,
331
+ // sanitizeURL
332
+ false
333
+ // removeEmptyString
334
+ );
335
+ });
336
+ var CAMELIZE = /[-:]([a-z])/g;
337
+ var capitalize = (token) => token[1].toUpperCase();
338
+ [
339
+ "accent-height",
340
+ "alignment-baseline",
341
+ "arabic-form",
342
+ "baseline-shift",
343
+ "cap-height",
344
+ "clip-path",
345
+ "clip-rule",
346
+ "color-interpolation",
347
+ "color-interpolation-filters",
348
+ "color-profile",
349
+ "color-rendering",
350
+ "dominant-baseline",
351
+ "enable-background",
352
+ "fill-opacity",
353
+ "fill-rule",
354
+ "flood-color",
355
+ "flood-opacity",
356
+ "font-family",
357
+ "font-size",
358
+ "font-size-adjust",
359
+ "font-stretch",
360
+ "font-style",
361
+ "font-variant",
362
+ "font-weight",
363
+ "glyph-name",
364
+ "glyph-orientation-horizontal",
365
+ "glyph-orientation-vertical",
366
+ "horiz-adv-x",
367
+ "horiz-origin-x",
368
+ "image-rendering",
369
+ "letter-spacing",
370
+ "lighting-color",
371
+ "marker-end",
372
+ "marker-mid",
373
+ "marker-start",
374
+ "overline-position",
375
+ "overline-thickness",
376
+ "paint-order",
377
+ "panose-1",
378
+ "pointer-events",
379
+ "rendering-intent",
380
+ "shape-rendering",
381
+ "stop-color",
382
+ "stop-opacity",
383
+ "strikethrough-position",
384
+ "strikethrough-thickness",
385
+ "stroke-dasharray",
386
+ "stroke-dashoffset",
387
+ "stroke-linecap",
388
+ "stroke-linejoin",
389
+ "stroke-miterlimit",
390
+ "stroke-opacity",
391
+ "stroke-width",
392
+ "text-anchor",
393
+ "text-decoration",
394
+ "text-rendering",
395
+ "underline-position",
396
+ "underline-thickness",
397
+ "unicode-bidi",
398
+ "unicode-range",
399
+ "units-per-em",
400
+ "v-alphabetic",
401
+ "v-hanging",
402
+ "v-ideographic",
403
+ "v-mathematical",
404
+ "vector-effect",
405
+ "vert-adv-y",
406
+ "vert-origin-x",
407
+ "vert-origin-y",
408
+ "word-spacing",
409
+ "writing-mode",
410
+ "xmlns:xlink",
411
+ "x-height"
412
+ // NOTE: if you add a camelCased prop to this list,
413
+ // you'll need to set attributeName to name.toLowerCase()
414
+ // instead in the assignment below.
415
+ ].forEach((attributeName) => {
416
+ const name = attributeName.replace(CAMELIZE, capitalize);
417
+ properties[name] = new PropertyInfoRecord(
418
+ name,
419
+ STRING,
420
+ false,
421
+ // mustUseProperty
422
+ attributeName,
423
+ null,
424
+ // attributeNamespace
425
+ false,
426
+ // sanitizeURL
427
+ false
428
+ // removeEmptyString
429
+ );
430
+ });
431
+ [
432
+ "xlink:actuate",
433
+ "xlink:arcrole",
434
+ "xlink:role",
435
+ "xlink:show",
436
+ "xlink:title",
437
+ "xlink:type"
438
+ // NOTE: if you add a camelCased prop to this list,
439
+ // you'll need to set attributeName to name.toLowerCase()
440
+ // instead in the assignment below.
441
+ ].forEach((attributeName) => {
442
+ const name = attributeName.replace(CAMELIZE, capitalize);
443
+ properties[name] = new PropertyInfoRecord(
444
+ name,
445
+ STRING,
446
+ false,
447
+ // mustUseProperty
448
+ attributeName,
449
+ "http://www.w3.org/1999/xlink",
450
+ false,
451
+ // sanitizeURL
452
+ false
453
+ // removeEmptyString
454
+ );
455
+ });
456
+ [
457
+ "xml:base",
458
+ "xml:lang",
459
+ "xml:space"
460
+ // NOTE: if you add a camelCased prop to this list,
461
+ // you'll need to set attributeName to name.toLowerCase()
462
+ // instead in the assignment below.
463
+ ].forEach((attributeName) => {
464
+ const name = attributeName.replace(CAMELIZE, capitalize);
465
+ properties[name] = new PropertyInfoRecord(
466
+ name,
467
+ STRING,
468
+ false,
469
+ // mustUseProperty
470
+ attributeName,
471
+ "http://www.w3.org/XML/1998/namespace",
472
+ false,
473
+ // sanitizeURL
474
+ false
475
+ // removeEmptyString
476
+ );
477
+ });
478
+ ["tabIndex", "crossOrigin"].forEach((attributeName) => {
479
+ properties[attributeName] = new PropertyInfoRecord(
480
+ attributeName,
481
+ STRING,
482
+ false,
483
+ // mustUseProperty
484
+ attributeName.toLowerCase(),
485
+ // attributeName
486
+ null,
487
+ // attributeNamespace
488
+ false,
489
+ // sanitizeURL
490
+ false
491
+ // removeEmptyString
492
+ );
493
+ });
494
+ var xlinkHref = "xlinkHref";
495
+ properties[xlinkHref] = new PropertyInfoRecord(
496
+ "xlinkHref",
497
+ STRING,
498
+ false,
499
+ // mustUseProperty
500
+ "xlink:href",
501
+ "http://www.w3.org/1999/xlink",
502
+ true,
503
+ // sanitizeURL
504
+ false
505
+ // removeEmptyString
506
+ );
507
+ ["src", "href", "action", "formAction"].forEach((attributeName) => {
508
+ properties[attributeName] = new PropertyInfoRecord(
509
+ attributeName,
510
+ STRING,
511
+ false,
512
+ // mustUseProperty
513
+ attributeName.toLowerCase(),
514
+ // attributeName
515
+ null,
516
+ // attributeNamespace
517
+ true,
518
+ // sanitizeURL
519
+ true
520
+ // removeEmptyString
521
+ );
522
+ });
523
+
524
+ // src/renderer/unitless-css-properties.ts
525
+ var isPropWithUnitlessNumber = {
526
+ animationIterationCount: true,
527
+ aspectRatio: true,
528
+ borderImageOutset: true,
529
+ borderImageSlice: true,
530
+ borderImageWidth: true,
531
+ boxFlex: true,
532
+ boxFlexGroup: true,
533
+ boxOrdinalGroup: true,
534
+ columnCount: true,
535
+ columns: true,
536
+ flex: true,
537
+ flexGrow: true,
538
+ flexPositive: true,
539
+ flexShrink: true,
540
+ flexNegative: true,
541
+ flexOrder: true,
542
+ gridArea: true,
543
+ gridRow: true,
544
+ gridRowEnd: true,
545
+ gridRowSpan: true,
546
+ gridRowStart: true,
547
+ gridColumn: true,
548
+ gridColumnEnd: true,
549
+ gridColumnSpan: true,
550
+ gridColumnStart: true,
551
+ fontWeight: true,
552
+ lineClamp: true,
553
+ lineHeight: true,
554
+ opacity: true,
555
+ order: true,
556
+ orphans: true,
557
+ tabSize: true,
558
+ widows: true,
559
+ zIndex: true,
560
+ zoom: true,
561
+ // SVG-related properties
562
+ fillOpacity: true,
563
+ floodOpacity: true,
564
+ stopOpacity: true,
565
+ strokeDasharray: true,
566
+ strokeDashoffset: true,
567
+ strokeMiterlimit: true,
568
+ strokeOpacity: true,
569
+ strokeWidth: true
570
+ };
571
+ function propWithPrefix(prefix, prop) {
572
+ return prefix + prop.charAt(0).toUpperCase() + prop.substring(1);
573
+ }
574
+ var prefixes = ["Webkit", "ms", "Moz", "O"];
575
+ for (const key in isPropWithUnitlessNumber) {
576
+ const prop = key;
577
+ for (const prefix of prefixes) {
578
+ isPropWithUnitlessNumber[propWithPrefix(prefix, prop)] = isPropWithUnitlessNumber[prop];
579
+ }
580
+ }
581
+
582
+ // src/renderer/property-mapping.ts
583
+ function convertPropsIntoAttributes(props) {
584
+ return Object.keys(props).filter((key) => !key.startsWith("on") && key !== "children").map((originalKey) => {
585
+ const propertyInfo = getPropertyInfo(originalKey);
586
+ if (shouldIgnoreAttribute(originalKey, propertyInfo)) {
587
+ return void 0;
588
+ }
589
+ const value = props[originalKey];
590
+ if (value === void 0 || value === null)
591
+ return "";
592
+ const propertyName = propertyInfo ? propertyInfo.attributeName : originalKey;
593
+ if (typeof value === "string") {
594
+ return `${propertyName}="${value}"`;
595
+ }
596
+ if (propertyName === "style" && typeof value === "object") {
597
+ return convertStyleIntoAttribute(value);
598
+ }
599
+ if (typeof value === "object") {
600
+ return `${propertyName}="${JSON.stringify(value)}"`;
601
+ }
602
+ return `${propertyName}="${value}"`;
603
+ }).filter(Boolean).join(" ");
604
+ }
605
+ function convertStyleIntoAttribute(style) {
606
+ const inlineStyles = Object.entries(style).map(([key, value]) => {
607
+ let valueToUse = `${value}`;
608
+ if (typeof value === "number" && value !== 0 && !isPropWithUnitlessNumber[key]) {
609
+ valueToUse = `${value}px`;
610
+ }
611
+ valueToUse = valueToUse.trim();
612
+ valueToUse = valueToUse.replaceAll('"', "'");
613
+ if (key.startsWith("ms")) {
614
+ return `${fromCamelCaseToSnakeCase(key)}:${valueToUse}`;
615
+ }
616
+ return `${fromCamelCaseToSnakeCase(key)}:${valueToUse}`;
617
+ }).join(";");
618
+ return `style="${inlineStyles}"`;
619
+ }
620
+ function fromCamelCaseToSnakeCase(camelCasedText) {
621
+ return camelCasedText.replaceAll(
622
+ /([a-z])([A-Z])/g,
623
+ (_match, lowerCaseLetter, upperCaseLetter) => {
624
+ return `${lowerCaseLetter}-${upperCaseLetter.toLowerCase()}`;
625
+ }
626
+ );
627
+ }
628
+
629
+ // src/renderer/nodes/node.ts
630
+ var ParentNode = class {
631
+ constructor(id, internalChildren) {
632
+ this.id = id;
633
+ this.internalChildren = internalChildren;
634
+ }
635
+ removeChild(child) {
636
+ child.parent = void 0;
637
+ this.internalChildren = this.internalChildren.filter(
638
+ (otherChild) => otherChild.id !== child.id
639
+ );
640
+ }
641
+ insertBefore(toInsert, nodeToInsertBeforeOf) {
642
+ const index = this.internalChildren.findIndex(
643
+ (node) => node.id === nodeToInsertBeforeOf.id
644
+ );
645
+ if (index > -1) {
646
+ toInsert.parent = this;
647
+ this.internalChildren.splice(index, 0, toInsert);
648
+ }
649
+ }
650
+ appendChild(child) {
651
+ child.parent = this;
652
+ this.internalChildren.push(child);
653
+ }
654
+ get children() {
655
+ return this.internalChildren;
656
+ }
657
+ };
658
+
659
+ // src/renderer/nodes/element-node.ts
660
+ var ElementNode = class extends ParentNode {
661
+ constructor(tag, props) {
662
+ super(Symbol("ElementNode"), []);
663
+ this.hidden = false;
664
+ this.internalTag = tag;
665
+ this.props = props;
666
+ }
667
+ get tag() {
668
+ return this.internalTag;
669
+ }
670
+ get html() {
671
+ if (this.hidden)
672
+ return "";
673
+ const attributes = convertPropsIntoAttributes(this.props);
674
+ const attributePortion = attributes.trim().length > 0 ? ` ${attributes}` : "";
675
+ if (/^(AREA|BASE|BR|COL|COMMAND|EMBED|HR|IMG|INPUT|KEYGEN|LINK|META|PARAM|SOURCE|TRACK|WBR)$/.test(
676
+ this.internalTag.toUpperCase()
677
+ )) {
678
+ return `<${this.internalTag}${attributePortion}/>`;
679
+ }
680
+ let childrenPortion;
681
+ if ("dangerouslySetInnerHTML" in this.props && typeof this.props.dangerouslySetInnerHTML === "object" && this.props.dangerouslySetInnerHTML !== null && "__html" in this.props.dangerouslySetInnerHTML && typeof this.props.dangerouslySetInnerHTML.__html === "string") {
682
+ childrenPortion = this.props.dangerouslySetInnerHTML.__html;
683
+ } else {
684
+ childrenPortion = this.internalChildren.map((child) => child.html).join("");
685
+ }
686
+ return `<${this.internalTag}${attributePortion}>${childrenPortion}</${this.internalTag}>`;
687
+ }
688
+ get children() {
689
+ return this.internalChildren;
690
+ }
691
+ };
692
+
693
+ // src/renderer/nodes/text-node.ts
694
+ var TextNode = class {
695
+ constructor(text) {
696
+ this.id = Symbol("TextNode");
697
+ this.hidden = false;
698
+ this.text = text;
699
+ }
700
+ get html() {
701
+ if (this.hidden)
702
+ return "";
703
+ return this.text;
704
+ }
705
+ };
706
+
707
+ // src/renderer/index.ts
708
+ var renderer = (0, import_react_reconciler.default)({
709
+ isPrimaryRenderer: true,
710
+ supportsMutation: true,
711
+ supportsPersistence: false,
712
+ supportsHydration: true,
713
+ supportsMicrotasks: true,
714
+ scheduleMicrotask: queueMicrotask,
715
+ scheduleTimeout: setTimeout,
716
+ cancelTimeout: clearTimeout,
717
+ noTimeout: -1,
718
+ appendChildToContainer(container, child) {
719
+ container.appendChild(child);
720
+ },
721
+ insertInContainerBefore(container, child, beforeChild) {
722
+ container.insertBefore(child, beforeChild);
723
+ },
724
+ appendInitialChild(parent, child) {
725
+ parent.appendChild(child);
726
+ },
727
+ insertBefore(parent, child, beforeChild) {
728
+ parent.insertBefore(child, beforeChild);
729
+ },
730
+ appendChild(parent, child) {
731
+ parent.appendChild(child);
732
+ },
733
+ removeChild(node, removeNode) {
734
+ node.removeChild(removeNode);
735
+ },
736
+ removeChildFromContainer(container, node) {
737
+ container.removeChild(node);
738
+ },
739
+ clearContainer: (container) => {
740
+ for (const child of container.children) {
741
+ container.removeChild(child);
742
+ }
743
+ },
744
+ getRootHostContext: () => ({}),
745
+ createInstance(type, props) {
746
+ return new ElementNode(type, props);
747
+ },
748
+ createTextInstance(text) {
749
+ return new TextNode(text);
750
+ },
751
+ prepareForCommit: () => null,
752
+ preparePortalMount: () => null,
753
+ commitTextUpdate(node, _oldText, newText) {
754
+ node.text = newText;
755
+ },
756
+ resetAfterCommit() {
757
+ },
758
+ getChildHostContext(parentHostContext) {
759
+ return parentHostContext;
760
+ },
761
+ shouldSetTextContent: () => false,
762
+ resetTextContent() {
763
+ },
764
+ hideTextInstance(node) {
765
+ node.hidden = true;
766
+ },
767
+ unhideTextInstance(node) {
768
+ node.hidden = false;
769
+ },
770
+ getPublicInstance: (instance) => instance,
771
+ hideInstance(node) {
772
+ node.hidden = true;
773
+ },
774
+ unhideInstance(node) {
775
+ node.hidden = false;
776
+ },
777
+ finalizeInitialChildren: () => false,
778
+ getCurrentEventPriority: () => import_constants.DefaultEventPriority,
779
+ beforeActiveInstanceBlur() {
780
+ },
781
+ afterActiveInstanceBlur() {
782
+ },
783
+ detachDeletedInstance() {
784
+ },
785
+ getInstanceFromNode: () => null,
786
+ prepareScopeUpdate() {
787
+ },
788
+ getInstanceFromScope: () => null,
789
+ prepareUpdate() {
790
+ return null;
791
+ },
792
+ commitUpdate() {
793
+ }
794
+ });
795
+
796
+ // src/renderer/nodes/root.ts
797
+ var Root = class extends ParentNode {
798
+ constructor() {
799
+ super(Symbol("RootNode"), []);
800
+ }
801
+ get html() {
802
+ return this.internalChildren.map((child) => child.html).join("");
803
+ }
804
+ };
805
+
806
+ // src/plain-text-selectors.ts
807
+ var plainTextSelectors = [
808
+ { selector: "img", format: "skip" },
809
+ { selector: "#__react-email-preview", format: "skip" },
810
+ {
811
+ selector: "a",
812
+ options: { linkBrackets: false }
813
+ }
814
+ ];
815
+
816
+ // src/utils/pretty.ts
817
+ var import_js_beautify = __toESM(require("js-beautify"));
818
+ var defaults = {
819
+ unformatted: ["code", "pre", "em", "strong", "span"],
820
+ indent_inner_html: true,
821
+ indent_char: " ",
822
+ indent_size: 2,
823
+ sep: "\n"
824
+ };
825
+ var pretty = (str, options = {}) => {
826
+ return import_js_beautify.default.html(str, __spreadValues(__spreadValues({}, defaults), options));
827
+ };
828
+
829
+ // src/render.ts
830
+ function checkIfAllSuspensesAreDone(fiber) {
831
+ if (fiber.tag === 13 && fiber.memoizedState !== null) {
832
+ return false;
833
+ }
834
+ let child = fiber.child;
835
+ while (child !== null) {
836
+ if (!checkIfAllSuspensesAreDone(child)) {
837
+ return false;
838
+ }
839
+ child = child.sibling;
840
+ }
841
+ return true;
842
+ }
843
+ var renderToMarkup = (element) => {
844
+ return new Promise((resolve, reject) => {
845
+ const root = new Root();
846
+ const container = renderer.createContainer(
847
+ root,
848
+ import_constants2.ConcurrentRoot,
849
+ {},
850
+ false,
851
+ true,
852
+ "",
853
+ (err) => {
854
+ reject(err);
855
+ },
856
+ {}
857
+ );
858
+ renderer.updateContainer(element, container, null, () => {
859
+ function checkCompletion() {
860
+ if (checkIfAllSuspensesAreDone(container.current)) {
861
+ resolve(root.html);
862
+ } else {
863
+ setTimeout(checkCompletion, 0);
864
+ }
865
+ }
866
+ checkCompletion();
867
+ });
868
+ });
869
+ };
870
+ var doctype = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">';
871
+ var render = (element, options) => __async(void 0, null, function* () {
872
+ const markup = yield renderToMarkup(element);
873
+ const document = `${doctype}${markup}`;
874
+ if (options == null ? void 0 : options.plainText) {
875
+ return (0, import_html_to_text.convert)(document, __spreadValues({
876
+ selectors: plainTextSelectors
877
+ }, options.htmlToTextOptions));
878
+ }
879
+ if (options == null ? void 0 : options.pretty) {
880
+ return pretty(document);
881
+ }
882
+ return document;
883
+ });
884
+ // Annotate the CommonJS export names for ESM import in node:
885
+ 0 && (module.exports = {
886
+ doctype,
887
+ plainTextSelectors,
888
+ render
889
+ });