@react-email/editor 0.0.0-experimental.4 → 0.0.0-experimental.40

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.
Files changed (74) hide show
  1. package/dist/core/index.cjs +9 -0
  2. package/dist/core/index.d.cts +2 -0
  3. package/dist/core/index.d.mts +3 -0
  4. package/dist/core/index.mjs +4 -0
  5. package/dist/create-paste-handler-B8BtjBk3.d.cts +14 -0
  6. package/dist/create-paste-handler-B8BtjBk3.d.cts.map +1 -0
  7. package/dist/create-paste-handler-CGR738bC.d.mts +14 -0
  8. package/dist/create-paste-handler-CGR738bC.d.mts.map +1 -0
  9. package/dist/event-bus-CHEzOS_O.mjs +329 -0
  10. package/dist/event-bus-CHEzOS_O.mjs.map +1 -0
  11. package/dist/event-bus-fb8U7hrl.cjs +450 -0
  12. package/dist/extension-DyY8_bh4.mjs +1110 -0
  13. package/dist/extension-DyY8_bh4.mjs.map +1 -0
  14. package/dist/extension-w5VaUeSw.cjs +1235 -0
  15. package/dist/extensions/index.cjs +51 -0
  16. package/dist/extensions/index.d.cts +399 -0
  17. package/dist/extensions/index.d.cts.map +1 -0
  18. package/dist/extensions/index.d.mts +400 -0
  19. package/dist/extensions/index.d.mts.map +1 -0
  20. package/dist/extensions/index.mjs +5 -0
  21. package/dist/extensions-BvfmaKCn.mjs +2088 -0
  22. package/dist/extensions-BvfmaKCn.mjs.map +1 -0
  23. package/dist/extensions-CkjPj2JO.cjs +2369 -0
  24. package/dist/global-content-D_WYaFgX.mjs +78 -0
  25. package/dist/global-content-D_WYaFgX.mjs.map +1 -0
  26. package/dist/global-content-bJgotqmA.cjs +89 -0
  27. package/dist/index-C4KcMQ0R.d.cts +161 -0
  28. package/dist/index-C4KcMQ0R.d.cts.map +1 -0
  29. package/dist/index-CxX7W63O.d.mts +161 -0
  30. package/dist/index-CxX7W63O.d.mts.map +1 -0
  31. package/dist/index.cjs +74 -0
  32. package/dist/index.css +832 -0
  33. package/dist/index.css.map +1 -0
  34. package/dist/index.d.cts +33 -0
  35. package/dist/index.d.cts.map +1 -0
  36. package/dist/index.d.mts +31 -277
  37. package/dist/index.d.mts.map +1 -1
  38. package/dist/index.mjs +64 -1377
  39. package/dist/index.mjs.map +1 -1
  40. package/dist/plugins/index.cjs +23 -0
  41. package/dist/plugins/index.d.cts +191 -0
  42. package/dist/plugins/index.d.cts.map +1 -0
  43. package/dist/plugins/index.d.mts +191 -0
  44. package/dist/plugins/index.d.mts.map +1 -0
  45. package/dist/plugins/index.mjs +3 -0
  46. package/dist/root-CkYaJZpj.mjs +2316 -0
  47. package/dist/root-CkYaJZpj.mjs.map +1 -0
  48. package/dist/root-Gu08xybW.cjs +2832 -0
  49. package/dist/set-text-alignment-Cv72txmv.cjs +24 -0
  50. package/dist/set-text-alignment-OA8IMWmO.mjs +19 -0
  51. package/dist/set-text-alignment-OA8IMWmO.mjs.map +1 -0
  52. package/dist/styles-C-cCyJCn.cjs +211 -0
  53. package/dist/styles-_TMw3YxC.mjs +194 -0
  54. package/dist/styles-_TMw3YxC.mjs.map +1 -0
  55. package/dist/ui/bubble-menu/bubble-menu.css +285 -0
  56. package/dist/ui/index.cjs +147 -0
  57. package/dist/ui/index.d.cts +939 -0
  58. package/dist/ui/index.d.cts.map +1 -0
  59. package/dist/ui/index.d.mts +939 -0
  60. package/dist/ui/index.d.mts.map +1 -0
  61. package/dist/ui/index.mjs +60 -0
  62. package/dist/ui/index.mjs.map +1 -0
  63. package/dist/ui/slash-command/slash-command.css +44 -0
  64. package/dist/ui/themes/default.css +830 -0
  65. package/dist/utils/index.cjs +3 -0
  66. package/dist/utils/index.d.cts +7 -0
  67. package/dist/utils/index.d.cts.map +1 -0
  68. package/dist/utils/index.d.mts +7 -0
  69. package/dist/utils/index.d.mts.map +1 -0
  70. package/dist/utils/index.mjs +3 -0
  71. package/package.json +109 -21
  72. package/dist/index.d.ts +0 -279
  73. package/dist/index.d.ts.map +0 -1
  74. package/dist/index.js +0 -1436
@@ -0,0 +1,2369 @@
1
+ const require_event_bus = require('./event-bus-fb8U7hrl.cjs');
2
+ const require_styles = require('./styles-C-cCyJCn.cjs');
3
+ const require_global_content = require('./global-content-bJgotqmA.cjs');
4
+ let _tiptap_extensions = require("@tiptap/extensions");
5
+ let _tiptap_react = require("@tiptap/react");
6
+ let react = require("react");
7
+ react = require_event_bus.__toESM(react);
8
+ let _tiptap_html = require("@tiptap/html");
9
+ let _react_email_components = require("@react-email/components");
10
+ _react_email_components = require_event_bus.__toESM(_react_email_components);
11
+ let react_jsx_runtime = require("react/jsx-runtime");
12
+ let _tiptap_core = require("@tiptap/core");
13
+ let _tiptap_starter_kit = require("@tiptap/starter-kit");
14
+ _tiptap_starter_kit = require_event_bus.__toESM(_tiptap_starter_kit);
15
+ let _tiptap_extension_blockquote = require("@tiptap/extension-blockquote");
16
+ _tiptap_extension_blockquote = require_event_bus.__toESM(_tiptap_extension_blockquote);
17
+ let _tiptap_extension_bold = require("@tiptap/extension-bold");
18
+ _tiptap_extension_bold = require_event_bus.__toESM(_tiptap_extension_bold);
19
+ let _tiptap_extension_bullet_list = require("@tiptap/extension-bullet-list");
20
+ _tiptap_extension_bullet_list = require_event_bus.__toESM(_tiptap_extension_bullet_list);
21
+ let _tiptap_extension_code = require("@tiptap/extension-code");
22
+ _tiptap_extension_code = require_event_bus.__toESM(_tiptap_extension_code);
23
+ let _tiptap_extension_code_block = require("@tiptap/extension-code-block");
24
+ _tiptap_extension_code_block = require_event_bus.__toESM(_tiptap_extension_code_block);
25
+ let _tiptap_pm_state = require("@tiptap/pm/state");
26
+ let _tiptap_pm_view = require("@tiptap/pm/view");
27
+ let hast_util_from_html = require("hast-util-from-html");
28
+ let prismjs = require("prismjs");
29
+ prismjs = require_event_bus.__toESM(prismjs);
30
+ let _tiptap_extension_horizontal_rule = require("@tiptap/extension-horizontal-rule");
31
+ _tiptap_extension_horizontal_rule = require_event_bus.__toESM(_tiptap_extension_horizontal_rule);
32
+ let _tiptap_extension_hard_break = require("@tiptap/extension-hard-break");
33
+ _tiptap_extension_hard_break = require_event_bus.__toESM(_tiptap_extension_hard_break);
34
+ let _tiptap_extension_heading = require("@tiptap/extension-heading");
35
+ let _tiptap_extension_italic = require("@tiptap/extension-italic");
36
+ _tiptap_extension_italic = require_event_bus.__toESM(_tiptap_extension_italic);
37
+ let _tiptap_extension_link = require("@tiptap/extension-link");
38
+ _tiptap_extension_link = require_event_bus.__toESM(_tiptap_extension_link);
39
+ let _tiptap_extension_list_item = require("@tiptap/extension-list-item");
40
+ _tiptap_extension_list_item = require_event_bus.__toESM(_tiptap_extension_list_item);
41
+ let _tiptap_extension_ordered_list = require("@tiptap/extension-ordered-list");
42
+ _tiptap_extension_ordered_list = require_event_bus.__toESM(_tiptap_extension_ordered_list);
43
+ let _tiptap_extension_paragraph = require("@tiptap/extension-paragraph");
44
+ _tiptap_extension_paragraph = require_event_bus.__toESM(_tiptap_extension_paragraph);
45
+ let _tiptap_extension_placeholder = require("@tiptap/extension-placeholder");
46
+ _tiptap_extension_placeholder = require_event_bus.__toESM(_tiptap_extension_placeholder);
47
+ let _tiptap_extension_strike = require("@tiptap/extension-strike");
48
+ _tiptap_extension_strike = require_event_bus.__toESM(_tiptap_extension_strike);
49
+ let _tiptap_extension_superscript = require("@tiptap/extension-superscript");
50
+ _tiptap_extension_superscript = require_event_bus.__toESM(_tiptap_extension_superscript);
51
+ let _tiptap_extension_text = require("@tiptap/extension-text");
52
+ let _tiptap_extension_underline = require("@tiptap/extension-underline");
53
+ _tiptap_extension_underline = require_event_bus.__toESM(_tiptap_extension_underline);
54
+
55
+ //#region src/core/create-drop-handler.ts
56
+ function createDropHandler({ onPaste, onUploadImage }) {
57
+ return (view, event, _slice, moved) => {
58
+ if (!moved && event.dataTransfer && event.dataTransfer.files && event.dataTransfer.files[0]) {
59
+ event.preventDefault();
60
+ const file = event.dataTransfer.files[0];
61
+ if (onPaste?.(file, view)) return true;
62
+ if (file.type.includes("image/") && onUploadImage) {
63
+ onUploadImage(file, view, (view.posAtCoords({
64
+ left: event.clientX,
65
+ top: event.clientY
66
+ })?.pos || 0) - 1);
67
+ return true;
68
+ }
69
+ }
70
+ return false;
71
+ };
72
+ }
73
+
74
+ //#endregion
75
+ //#region src/utils/paste-sanitizer.ts
76
+ /**
77
+ * Sanitizes pasted HTML.
78
+ * - From editor (has node-* classes): pass through as-is
79
+ * - From external: strip all styles/classes, keep only semantic HTML
80
+ */
81
+ /**
82
+ * Detects content from the Resend editor by checking for node-* class names.
83
+ */
84
+ const EDITOR_CLASS_PATTERN = /class="[^"]*node-/;
85
+ /**
86
+ * Attributes to preserve on specific elements for EXTERNAL content.
87
+ * Only functional attributes - NO style or class.
88
+ */
89
+ const PRESERVED_ATTRIBUTES = {
90
+ a: [
91
+ "href",
92
+ "target",
93
+ "rel"
94
+ ],
95
+ img: [
96
+ "src",
97
+ "alt",
98
+ "width",
99
+ "height"
100
+ ],
101
+ td: ["colspan", "rowspan"],
102
+ th: [
103
+ "colspan",
104
+ "rowspan",
105
+ "scope"
106
+ ],
107
+ table: [
108
+ "border",
109
+ "cellpadding",
110
+ "cellspacing"
111
+ ],
112
+ "*": ["id"]
113
+ };
114
+ function isFromEditor(html) {
115
+ return EDITOR_CLASS_PATTERN.test(html);
116
+ }
117
+ function sanitizePastedHtml(html) {
118
+ if (isFromEditor(html)) return html;
119
+ const doc = new DOMParser().parseFromString(html, "text/html");
120
+ sanitizeNode(doc.body);
121
+ return doc.body.innerHTML;
122
+ }
123
+ function sanitizeNode(node) {
124
+ if (node.nodeType === Node.ELEMENT_NODE) sanitizeElement(node);
125
+ for (const child of Array.from(node.childNodes)) sanitizeNode(child);
126
+ }
127
+ function sanitizeElement(el) {
128
+ const allowedForTag = PRESERVED_ATTRIBUTES[el.tagName.toLowerCase()] || [];
129
+ const allowedGlobal = PRESERVED_ATTRIBUTES["*"] || [];
130
+ const allowed = new Set([...allowedForTag, ...allowedGlobal]);
131
+ const attributesToRemove = [];
132
+ for (const attr of Array.from(el.attributes)) {
133
+ if (attr.name.startsWith("data-")) {
134
+ attributesToRemove.push(attr.name);
135
+ continue;
136
+ }
137
+ if (!allowed.has(attr.name)) attributesToRemove.push(attr.name);
138
+ }
139
+ for (const attr of attributesToRemove) el.removeAttribute(attr);
140
+ }
141
+
142
+ //#endregion
143
+ //#region src/core/create-paste-handler.ts
144
+ function createPasteHandler({ onPaste, onUploadImage, extensions }) {
145
+ return (view, event, slice) => {
146
+ const text = event.clipboardData?.getData("text/plain");
147
+ if (text && onPaste?.(text, view)) {
148
+ event.preventDefault();
149
+ return true;
150
+ }
151
+ if (event.clipboardData?.files?.[0]) {
152
+ const file = event.clipboardData.files[0];
153
+ if (onPaste?.(file, view)) {
154
+ event.preventDefault();
155
+ return true;
156
+ }
157
+ if (file.type.includes("image/") && onUploadImage) {
158
+ const pos = view.state.selection.from;
159
+ onUploadImage(file, view, pos);
160
+ return true;
161
+ }
162
+ }
163
+ /**
164
+ * If the coming content has a single child, we can assume
165
+ * it's a plain text and doesn't need to be parsed and
166
+ * be introduced in a new line
167
+ */
168
+ if (slice.content.childCount === 1) return false;
169
+ if (event.clipboardData?.getData?.("text/html")) {
170
+ event.preventDefault();
171
+ const jsonContent = (0, _tiptap_html.generateJSON)(sanitizePastedHtml(event.clipboardData.getData("text/html")), extensions);
172
+ const node = view.state.schema.nodeFromJSON(jsonContent);
173
+ const transaction = view.state.tr.replaceSelectionWith(node, false);
174
+ view.dispatch(transaction);
175
+ return true;
176
+ }
177
+ return false;
178
+ };
179
+ }
180
+
181
+ //#endregion
182
+ //#region src/core/serializer/default-base-template.tsx
183
+ function DefaultBaseTemplate({ children, previewText }) {
184
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_react_email_components.Html, { children: [
185
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_react_email_components.Head, { children: [
186
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("meta", {
187
+ content: "width=device-width",
188
+ name: "viewport"
189
+ }),
190
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("meta", {
191
+ content: "IE=edge",
192
+ httpEquiv: "X-UA-Compatible"
193
+ }),
194
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("meta", { name: "x-apple-disable-message-reformatting" }),
195
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("meta", {
196
+ content: "telephone=no,address=no,email=no,date=no,url=no",
197
+ name: "format-detection"
198
+ })
199
+ ] }),
200
+ previewText && previewText !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_react_email_components.Preview, { children: previewText }),
201
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_react_email_components.Body, { children })
202
+ ] });
203
+ }
204
+
205
+ //#endregion
206
+ //#region src/core/serializer/email-mark.ts
207
+ var EmailMark = class EmailMark extends _tiptap_core.Mark {
208
+ constructor(config) {
209
+ super(config);
210
+ }
211
+ /**
212
+ * Create a new Mark instance
213
+ * @param config - Mark configuration object or a function that returns a configuration object
214
+ */
215
+ static create(config) {
216
+ return new EmailMark(typeof config === "function" ? config() : config);
217
+ }
218
+ static from(mark, renderToReactEmail) {
219
+ const customMark = EmailMark.create({});
220
+ Object.assign(customMark, { ...mark });
221
+ customMark.config = {
222
+ ...mark.config,
223
+ renderToReactEmail
224
+ };
225
+ return customMark;
226
+ }
227
+ configure(options) {
228
+ return super.configure(options);
229
+ }
230
+ extend(extendedConfig) {
231
+ const resolvedConfig = typeof extendedConfig === "function" ? extendedConfig() : extendedConfig;
232
+ return super.extend(resolvedConfig);
233
+ }
234
+ };
235
+
236
+ //#endregion
237
+ //#region src/core/serializer/compose-react-email.tsx
238
+ const NODES_WITH_INCREMENTED_CHILD_DEPTH = new Set(["bulletList", "orderedList"]);
239
+ const composeReactEmail = async ({ editor, preview }) => {
240
+ const data = editor.getJSON();
241
+ const extensions = editor.extensionManager.extensions;
242
+ const serializerPlugin = extensions.map((ext) => ext.options?.serializerPlugin).filter((p) => Boolean(p)).at(-1);
243
+ const typeToExtensionMap = Object.fromEntries(extensions.map((extension) => [extension.name, extension]));
244
+ function parseContent(content, depth = 0) {
245
+ if (!content) return;
246
+ return content.map((node, index) => {
247
+ const style = serializerPlugin?.getNodeStyles(node, depth, editor) ?? {};
248
+ const inlineStyles = require_styles.inlineCssToJs(node.attrs?.style);
249
+ if (!node.type) return null;
250
+ const emailNode = typeToExtensionMap[node.type];
251
+ if (!emailNode || !(emailNode instanceof require_event_bus.EmailNode)) return null;
252
+ const NodeComponent = emailNode.config.renderToReactEmail;
253
+ const childDepth = NODES_WITH_INCREMENTED_CHILD_DEPTH.has(node.type) ? depth + 1 : depth;
254
+ let renderedNode = node.text ? node.text : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(NodeComponent, {
255
+ node: node.type === "table" && inlineStyles.width && !node.attrs?.width ? {
256
+ ...node,
257
+ attrs: {
258
+ ...node.attrs,
259
+ width: inlineStyles.width
260
+ }
261
+ } : node,
262
+ style,
263
+ extension: emailNode,
264
+ children: parseContent(node.content, childDepth)
265
+ }, index);
266
+ if (node.marks) for (const mark of node.marks) {
267
+ const emailMark = typeToExtensionMap[mark.type];
268
+ if (emailMark instanceof EmailMark) {
269
+ const MarkComponent = emailMark.config.renderToReactEmail;
270
+ renderedNode = /* @__PURE__ */ (0, react_jsx_runtime.jsx)(MarkComponent, {
271
+ mark,
272
+ node,
273
+ style: serializerPlugin?.getNodeStyles({
274
+ type: mark.type,
275
+ attrs: mark.attrs ?? {}
276
+ }, depth, editor) ?? {},
277
+ extension: emailMark,
278
+ children: renderedNode
279
+ });
280
+ }
281
+ }
282
+ return renderedNode;
283
+ });
284
+ }
285
+ const unformattedHtml = await (0, _react_email_components.render)(/* @__PURE__ */ (0, react_jsx_runtime.jsx)(serializerPlugin?.BaseTemplate ?? DefaultBaseTemplate, {
286
+ previewText: preview,
287
+ editor,
288
+ children: parseContent(data.content)
289
+ }));
290
+ const [prettyHtml, text] = await Promise.all([(0, _react_email_components.pretty)(unformattedHtml), (0, _react_email_components.toPlainText)(unformattedHtml)]);
291
+ return {
292
+ html: prettyHtml,
293
+ text
294
+ };
295
+ };
296
+
297
+ //#endregion
298
+ //#region src/extensions/alignment-attribute.tsx
299
+ const AlignmentAttribute = _tiptap_core.Extension.create({
300
+ name: "alignmentAttribute",
301
+ addOptions() {
302
+ return {
303
+ types: [],
304
+ alignments: [
305
+ "left",
306
+ "center",
307
+ "right",
308
+ "justify"
309
+ ]
310
+ };
311
+ },
312
+ addGlobalAttributes() {
313
+ return [{
314
+ types: this.options.types,
315
+ attributes: { alignment: {
316
+ parseHTML: (element) => {
317
+ const explicitAlign = element.getAttribute("align") || element.getAttribute("alignment") || element.style.textAlign;
318
+ if (explicitAlign && this.options.alignments.includes(explicitAlign)) return explicitAlign;
319
+ return null;
320
+ },
321
+ renderHTML: (attributes) => {
322
+ if (attributes.alignment === "left") return {};
323
+ return { alignment: attributes.alignment };
324
+ }
325
+ } }
326
+ }];
327
+ },
328
+ addCommands() {
329
+ return { setAlignment: (alignment) => ({ commands }) => {
330
+ if (!this.options.alignments.includes(alignment)) return false;
331
+ return this.options.types.every((type) => commands.updateAttributes(type, { alignment }));
332
+ } };
333
+ },
334
+ addKeyboardShortcuts() {
335
+ return {
336
+ Enter: () => {
337
+ const { from } = this.editor.state.selection;
338
+ const currentAlignment = this.editor.state.doc.nodeAt(from)?.attrs?.alignment;
339
+ if (currentAlignment) requestAnimationFrame(() => {
340
+ this.editor.commands.setAlignment(currentAlignment);
341
+ });
342
+ return false;
343
+ },
344
+ "Mod-Shift-l": () => this.editor.commands.setAlignment("left"),
345
+ "Mod-Shift-e": () => this.editor.commands.setAlignment("center"),
346
+ "Mod-Shift-r": () => this.editor.commands.setAlignment("right"),
347
+ "Mod-Shift-j": () => this.editor.commands.setAlignment("justify")
348
+ };
349
+ }
350
+ });
351
+
352
+ //#endregion
353
+ //#region src/utils/get-text-alignment.ts
354
+ function getTextAlignment(alignment) {
355
+ switch (alignment) {
356
+ case "left": return { textAlign: "left" };
357
+ case "center": return { textAlign: "center" };
358
+ case "right": return { textAlign: "right" };
359
+ default: return {};
360
+ }
361
+ }
362
+
363
+ //#endregion
364
+ //#region src/extensions/blockquote.tsx
365
+ const Blockquote = require_event_bus.EmailNode.from(_tiptap_extension_blockquote.default, ({ children, node, style }) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("blockquote", {
366
+ className: node.attrs?.class || void 0,
367
+ style: {
368
+ ...style,
369
+ ...require_styles.inlineCssToJs(node.attrs?.style),
370
+ ...getTextAlignment(node.attrs?.align || node.attrs?.alignment)
371
+ },
372
+ children
373
+ }));
374
+
375
+ //#endregion
376
+ //#region src/extensions/body.tsx
377
+ const Body = require_event_bus.EmailNode.create({
378
+ name: "body",
379
+ group: "block",
380
+ content: "block+",
381
+ defining: true,
382
+ isolating: true,
383
+ addAttributes() {
384
+ return { ...require_event_bus.createStandardAttributes([...require_event_bus.COMMON_HTML_ATTRIBUTES, ...require_event_bus.LAYOUT_ATTRIBUTES]) };
385
+ },
386
+ parseHTML() {
387
+ return [{
388
+ tag: "body",
389
+ getAttrs: (node) => {
390
+ if (typeof node === "string") return false;
391
+ const element = node;
392
+ const attrs = {};
393
+ Array.from(element.attributes).forEach((attr) => {
394
+ attrs[attr.name] = attr.value;
395
+ });
396
+ return attrs;
397
+ }
398
+ }];
399
+ },
400
+ renderHTML({ HTMLAttributes }) {
401
+ return [
402
+ "div",
403
+ (0, _tiptap_core.mergeAttributes)(this.options.HTMLAttributes, HTMLAttributes),
404
+ 0
405
+ ];
406
+ },
407
+ renderToReactEmail({ children, node, style }) {
408
+ const inlineStyles = require_styles.inlineCssToJs(node.attrs?.style);
409
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
410
+ className: node.attrs?.class || void 0,
411
+ style: {
412
+ ...style,
413
+ ...inlineStyles
414
+ },
415
+ children
416
+ });
417
+ }
418
+ });
419
+
420
+ //#endregion
421
+ //#region src/extensions/bold.tsx
422
+ const BoldWithoutFontWeightInference = _tiptap_extension_bold.default.extend({ parseHTML() {
423
+ return [
424
+ { tag: "strong" },
425
+ {
426
+ tag: "b",
427
+ getAttrs: (node) => node.style.fontWeight !== "normal" && null
428
+ },
429
+ {
430
+ style: "font-weight=400",
431
+ clearMark: (mark) => mark.type.name === this.name
432
+ }
433
+ ];
434
+ } });
435
+ const Bold = EmailMark.from(BoldWithoutFontWeightInference, ({ children, style }) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", {
436
+ style,
437
+ children
438
+ }));
439
+
440
+ //#endregion
441
+ //#region src/extensions/bullet-list.tsx
442
+ const BulletList = require_event_bus.EmailNode.from(_tiptap_extension_bullet_list.default, ({ children, node, style }) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("ul", {
443
+ className: node.attrs?.class || void 0,
444
+ style: {
445
+ ...style,
446
+ ...require_styles.inlineCssToJs(node.attrs?.style)
447
+ },
448
+ children
449
+ }));
450
+
451
+ //#endregion
452
+ //#region src/extensions/button.tsx
453
+ const Button = require_event_bus.EmailNode.create({
454
+ name: "button",
455
+ group: "block",
456
+ content: "inline*",
457
+ defining: true,
458
+ draggable: true,
459
+ marks: "bold",
460
+ addAttributes() {
461
+ return {
462
+ class: { default: "button" },
463
+ href: { default: "#" },
464
+ alignment: { default: "left" }
465
+ };
466
+ },
467
+ parseHTML() {
468
+ return [{
469
+ tag: "a[data-id=\"react-email-button\"]",
470
+ getAttrs: (node) => {
471
+ if (typeof node === "string") return false;
472
+ const element = node;
473
+ const attrs = {};
474
+ Array.from(element.attributes).forEach((attr) => {
475
+ attrs[attr.name] = attr.value;
476
+ });
477
+ return attrs;
478
+ }
479
+ }];
480
+ },
481
+ renderHTML({ HTMLAttributes }) {
482
+ return [
483
+ "div",
484
+ (0, _tiptap_core.mergeAttributes)({ class: `align-${HTMLAttributes?.alignment}` }),
485
+ [
486
+ "a",
487
+ (0, _tiptap_core.mergeAttributes)({
488
+ class: `node-button ${HTMLAttributes?.class}`,
489
+ style: HTMLAttributes?.style,
490
+ "data-id": "react-email-button",
491
+ "data-href": HTMLAttributes?.href
492
+ }),
493
+ 0
494
+ ]
495
+ ];
496
+ },
497
+ addCommands() {
498
+ return {
499
+ updateButton: (attributes) => ({ commands }) => {
500
+ return commands.updateAttributes("button", attributes);
501
+ },
502
+ setButton: () => ({ commands }) => {
503
+ return commands.insertContent({
504
+ type: "button",
505
+ content: [{
506
+ type: "text",
507
+ text: "Button"
508
+ }]
509
+ });
510
+ }
511
+ };
512
+ },
513
+ renderToReactEmail({ children, node, style }) {
514
+ const inlineStyles = require_styles.inlineCssToJs(node.attrs?.style);
515
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_react_email_components.Row, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_react_email_components.Column, {
516
+ align: node.attrs?.align || node.attrs?.alignment,
517
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_react_email_components.Button, {
518
+ className: node.attrs?.class || void 0,
519
+ href: node.attrs?.href,
520
+ style: {
521
+ ...style,
522
+ ...inlineStyles
523
+ },
524
+ children
525
+ })
526
+ }) });
527
+ }
528
+ });
529
+
530
+ //#endregion
531
+ //#region src/extensions/class-attribute.tsx
532
+ const ClassAttribute = _tiptap_core.Extension.create({
533
+ name: "classAttribute",
534
+ addOptions() {
535
+ return {
536
+ types: [],
537
+ class: []
538
+ };
539
+ },
540
+ addGlobalAttributes() {
541
+ return [{
542
+ types: this.options.types,
543
+ attributes: { class: {
544
+ default: "",
545
+ parseHTML: (element) => element.className || "",
546
+ renderHTML: (attributes) => {
547
+ return attributes.class ? { class: attributes.class } : {};
548
+ }
549
+ } }
550
+ }];
551
+ },
552
+ addCommands() {
553
+ return {
554
+ unsetClass: () => ({ commands }) => {
555
+ return this.options.types.every((type) => commands.resetAttributes(type, "class"));
556
+ },
557
+ setClass: (classList) => ({ commands }) => {
558
+ return this.options.types.every((type) => commands.updateAttributes(type, { class: classList }));
559
+ }
560
+ };
561
+ },
562
+ addKeyboardShortcuts() {
563
+ return { Enter: ({ editor }) => {
564
+ requestAnimationFrame(() => {
565
+ editor.commands.resetAttributes("paragraph", "class");
566
+ });
567
+ return false;
568
+ } };
569
+ }
570
+ });
571
+
572
+ //#endregion
573
+ //#region src/extensions/code.tsx
574
+ const Code = EmailMark.from(_tiptap_extension_code.default, ({ children, node, style }) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("code", {
575
+ style: {
576
+ ...style,
577
+ ...require_styles.inlineCssToJs(node.attrs?.style)
578
+ },
579
+ children
580
+ }));
581
+
582
+ //#endregion
583
+ //#region src/utils/prism-utils.ts
584
+ const publicURL = "/styles/prism";
585
+ function loadPrismTheme(theme) {
586
+ const link = document.createElement("link");
587
+ link.rel = "stylesheet";
588
+ link.href = `${publicURL}/prism-${theme}.css`;
589
+ link.setAttribute("data-prism-theme", "");
590
+ document.head.appendChild(link);
591
+ }
592
+ function removePrismTheme() {
593
+ const existingTheme = document.querySelectorAll("link[rel=\"stylesheet\"][data-prism-theme]");
594
+ if (existingTheme.length > 0) existingTheme.forEach((cssLinkTag) => {
595
+ cssLinkTag.remove();
596
+ });
597
+ }
598
+ function hasPrismThemeLoaded(theme) {
599
+ return !!document.querySelector(`link[rel="stylesheet"][data-prism-theme][href="${publicURL}/prism-${theme}.css"]`);
600
+ }
601
+
602
+ //#endregion
603
+ //#region src/extensions/prism-plugin.ts
604
+ const PRISM_LANGUAGE_LOADED_META = "prismLanguageLoaded";
605
+ function parseNodes(nodes, className = []) {
606
+ return nodes.flatMap((node) => {
607
+ const classes = [...className, ...node.properties ? node.properties.className : []];
608
+ if (node.children) return parseNodes(node.children, classes);
609
+ return {
610
+ text: node.value ?? "",
611
+ classes
612
+ };
613
+ });
614
+ }
615
+ function getHighlightNodes(html) {
616
+ return (0, hast_util_from_html.fromHtml)(html, { fragment: true }).children;
617
+ }
618
+ function registeredLang(aliasOrLanguage) {
619
+ const allSupportLang = Object.keys(prismjs.default.languages).filter((id) => typeof prismjs.default.languages[id] === "object");
620
+ return Boolean(allSupportLang.find((x) => x === aliasOrLanguage));
621
+ }
622
+ function getDecorations({ doc, name, defaultLanguage, defaultTheme, loadingLanguages, onLanguageLoaded }) {
623
+ const decorations = [];
624
+ (0, _tiptap_core.findChildren)(doc, (node) => node.type.name === name).forEach((block) => {
625
+ let from = block.pos + 1;
626
+ const language = block.node.attrs.language || defaultLanguage;
627
+ const theme = block.node.attrs.theme || defaultTheme;
628
+ let html = "";
629
+ try {
630
+ if (!registeredLang(language) && !loadingLanguages.has(language)) {
631
+ loadingLanguages.add(language);
632
+ import(`prismjs/components/prism-${language}`).then(() => {
633
+ loadingLanguages.delete(language);
634
+ onLanguageLoaded(language);
635
+ }).catch(() => {
636
+ loadingLanguages.delete(language);
637
+ });
638
+ }
639
+ if (!hasPrismThemeLoaded(theme)) loadPrismTheme(theme);
640
+ html = prismjs.default.highlight(block.node.textContent, prismjs.default.languages[language], language);
641
+ } catch {
642
+ html = prismjs.default.highlight(block.node.textContent, prismjs.default.languages.javascript, "js");
643
+ }
644
+ parseNodes(getHighlightNodes(html)).forEach((node) => {
645
+ const to = from + node.text.length;
646
+ if (node.classes.length) {
647
+ const decoration = _tiptap_pm_view.Decoration.inline(from, to, { class: node.classes.join(" ") });
648
+ decorations.push(decoration);
649
+ }
650
+ from = to;
651
+ });
652
+ });
653
+ return _tiptap_pm_view.DecorationSet.create(doc, decorations);
654
+ }
655
+ function PrismPlugin({ name, defaultLanguage, defaultTheme }) {
656
+ if (!defaultLanguage) throw Error("You must specify the defaultLanguage parameter");
657
+ const loadingLanguages = /* @__PURE__ */ new Set();
658
+ let pluginView = null;
659
+ const onLanguageLoaded = (language) => {
660
+ if (pluginView) pluginView.dispatch(pluginView.state.tr.setMeta(PRISM_LANGUAGE_LOADED_META, language));
661
+ };
662
+ const prismjsPlugin = new _tiptap_pm_state.Plugin({
663
+ key: new _tiptap_pm_state.PluginKey("prism"),
664
+ view(view) {
665
+ pluginView = view;
666
+ return { destroy() {
667
+ pluginView = null;
668
+ } };
669
+ },
670
+ state: {
671
+ init: (_, { doc }) => {
672
+ return getDecorations({
673
+ doc,
674
+ name,
675
+ defaultLanguage,
676
+ defaultTheme,
677
+ loadingLanguages,
678
+ onLanguageLoaded
679
+ });
680
+ },
681
+ apply: (transaction, decorationSet, oldState, newState) => {
682
+ const oldNodeName = oldState.selection.$head.parent.type.name;
683
+ const newNodeName = newState.selection.$head.parent.type.name;
684
+ const oldNodes = (0, _tiptap_core.findChildren)(oldState.doc, (node) => node.type.name === name);
685
+ const newNodes = (0, _tiptap_core.findChildren)(newState.doc, (node) => node.type.name === name);
686
+ if (transaction.getMeta(PRISM_LANGUAGE_LOADED_META) || transaction.docChanged && ([oldNodeName, newNodeName].includes(name) || newNodes.length !== oldNodes.length || transaction.steps.some((step) => {
687
+ const rangeStep = step;
688
+ return rangeStep.from !== void 0 && rangeStep.to !== void 0 && oldNodes.some((node) => {
689
+ return node.pos >= rangeStep.from && node.pos + node.node.nodeSize <= rangeStep.to;
690
+ });
691
+ }))) return getDecorations({
692
+ doc: transaction.doc,
693
+ name,
694
+ defaultLanguage,
695
+ defaultTheme,
696
+ loadingLanguages,
697
+ onLanguageLoaded
698
+ });
699
+ return decorationSet.map(transaction.mapping, transaction.doc);
700
+ }
701
+ },
702
+ props: { decorations(state) {
703
+ return prismjsPlugin.getState(state);
704
+ } },
705
+ destroy() {
706
+ pluginView = null;
707
+ removePrismTheme();
708
+ }
709
+ });
710
+ return prismjsPlugin;
711
+ }
712
+
713
+ //#endregion
714
+ //#region src/extensions/code-block.tsx
715
+ const CodeBlockPrism = require_event_bus.EmailNode.from(_tiptap_extension_code_block.default.extend({
716
+ addOptions() {
717
+ return {
718
+ languageClassPrefix: "language-",
719
+ exitOnTripleEnter: false,
720
+ exitOnArrowDown: false,
721
+ enableTabIndentation: true,
722
+ tabSize: 2,
723
+ defaultLanguage: "javascript",
724
+ defaultTheme: "default",
725
+ HTMLAttributes: {}
726
+ };
727
+ },
728
+ addAttributes() {
729
+ return {
730
+ ...this.parent?.(),
731
+ language: {
732
+ default: this.options.defaultLanguage,
733
+ parseHTML: (element) => {
734
+ if (!element) return null;
735
+ const { languageClassPrefix } = this.options;
736
+ if (!languageClassPrefix) return null;
737
+ const language = [...element.firstElementChild?.classList || []].filter((className) => className.startsWith(languageClassPrefix || "")).map((className) => className.replace(languageClassPrefix, ""))[0];
738
+ if (!language) return null;
739
+ return language;
740
+ },
741
+ rendered: false
742
+ },
743
+ theme: {
744
+ default: this.options.defaultTheme,
745
+ rendered: false
746
+ }
747
+ };
748
+ },
749
+ renderHTML({ node, HTMLAttributes }) {
750
+ return [
751
+ "pre",
752
+ (0, _tiptap_core.mergeAttributes)(this.options.HTMLAttributes, HTMLAttributes, { class: node.attrs.language ? `${this.options.languageClassPrefix}${node.attrs.language}` : null }, { "data-theme": node.attrs.theme }),
753
+ [
754
+ "code",
755
+ { class: node.attrs.language ? `${this.options.languageClassPrefix}${node.attrs.language} node-codeTag` : "node-codeTag" },
756
+ 0
757
+ ]
758
+ ];
759
+ },
760
+ addKeyboardShortcuts() {
761
+ return {
762
+ ...this.parent?.(),
763
+ "Mod-a": ({ editor }) => {
764
+ const { state } = editor;
765
+ const { selection } = state;
766
+ const { $from } = selection;
767
+ for (let depth = $from.depth; depth >= 1; depth--) if ($from.node(depth).type.name === this.name) {
768
+ const blockStart = $from.start(depth);
769
+ const blockEnd = $from.end(depth);
770
+ if (selection.from === blockStart && selection.to === blockEnd) return false;
771
+ const tr = state.tr.setSelection(_tiptap_pm_state.TextSelection.create(state.doc, blockStart, blockEnd));
772
+ editor.view.dispatch(tr);
773
+ return true;
774
+ }
775
+ return false;
776
+ }
777
+ };
778
+ },
779
+ addProseMirrorPlugins() {
780
+ return [...this.parent?.() || [], PrismPlugin({
781
+ name: this.name,
782
+ defaultLanguage: this.options.defaultLanguage,
783
+ defaultTheme: this.options.defaultTheme
784
+ })];
785
+ }
786
+ }), ({ node, style }) => {
787
+ const language = node.attrs?.language ? `${node.attrs.language}` : "javascript";
788
+ const userTheme = _react_email_components[node.attrs?.theme];
789
+ const theme = userTheme ? {
790
+ ...userTheme,
791
+ base: {
792
+ ...userTheme.base,
793
+ borderRadius: "0.125rem",
794
+ padding: "0.75rem 1rem"
795
+ }
796
+ } : { base: {
797
+ color: "#1e293b",
798
+ background: "#f1f5f9",
799
+ lineHeight: "1.5",
800
+ fontFamily: "\"Fira Code\", \"Fira Mono\", Menlo, Consolas, \"DejaVu Sans Mono\", monospace",
801
+ padding: "0.75rem 1rem",
802
+ borderRadius: "0.125rem"
803
+ } };
804
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_react_email_components.CodeBlock, {
805
+ code: node.content?.[0]?.text ?? "",
806
+ language,
807
+ theme,
808
+ style: {
809
+ width: "auto",
810
+ ...style
811
+ }
812
+ });
813
+ });
814
+
815
+ //#endregion
816
+ //#region src/utils/is-collaboration.ts
817
+ const COLLABORATION_EXTENSION_NAMES = new Set(["liveblocksExtension", "collaboration"]);
818
+ function hasCollaborationExtension(exts) {
819
+ return exts.some((ext) => COLLABORATION_EXTENSION_NAMES.has(ext.name));
820
+ }
821
+
822
+ //#endregion
823
+ //#region src/extensions/container.tsx
824
+ function hasContainerNode(doc) {
825
+ let found = false;
826
+ doc.forEach((node) => {
827
+ if (node.type.name === "container") found = true;
828
+ });
829
+ return found;
830
+ }
831
+ function wrapInContainer(state) {
832
+ const { doc } = state;
833
+ const containerType = state.schema.nodes.container;
834
+ const contentNodes = [];
835
+ const globalContentNodes = [];
836
+ doc.forEach((node) => {
837
+ if (node.type.name === "globalContent") globalContentNodes.push(node);
838
+ else contentNodes.push(node);
839
+ });
840
+ const containerContent = contentNodes.length > 0 ? contentNodes : [state.schema.nodes.paragraph.create()];
841
+ const containerNode = containerType.create(null, containerContent);
842
+ const newDocContent = [...globalContentNodes, containerNode];
843
+ const tr = state.tr;
844
+ tr.replaceWith(0, doc.content.size, newDocContent);
845
+ tr.setMeta("addToHistory", false);
846
+ return tr;
847
+ }
848
+ const Container = require_event_bus.EmailNode.create({
849
+ name: "container",
850
+ group: "block",
851
+ content: "block+",
852
+ defining: true,
853
+ isolating: true,
854
+ selectable: false,
855
+ draggable: false,
856
+ addOptions() {
857
+ return { HTMLAttributes: {} };
858
+ },
859
+ parseHTML() {
860
+ return [{ tag: "div[data-type=\"container\"]" }, {
861
+ tag: "table[role=\"presentation\"]",
862
+ priority: 60,
863
+ getAttrs: (node) => {
864
+ if (typeof node === "string") return false;
865
+ const table = node;
866
+ if (!table.style.maxWidth) return false;
867
+ if (!table.querySelector(":scope > tbody > tr:only-child > td:only-child")) return false;
868
+ return null;
869
+ },
870
+ contentElement: (node) => node.querySelector(":scope > tbody > tr > td")
871
+ }];
872
+ },
873
+ renderHTML({ HTMLAttributes }) {
874
+ return [
875
+ "div",
876
+ (0, _tiptap_core.mergeAttributes)({
877
+ "data-type": "container",
878
+ class: "node-container"
879
+ }, this.options.HTMLAttributes, HTMLAttributes),
880
+ 0
881
+ ];
882
+ },
883
+ addProseMirrorPlugins() {
884
+ const isCollaborative = hasCollaborationExtension(this.editor.extensionManager.extensions);
885
+ return [new _tiptap_pm_state.Plugin({
886
+ key: new _tiptap_pm_state.PluginKey("containerEnforcer"),
887
+ view: isCollaborative ? void 0 : (editorView) => {
888
+ if (!hasContainerNode(editorView.state.doc)) {
889
+ const tr = wrapInContainer(editorView.state);
890
+ editorView.dispatch(tr);
891
+ }
892
+ return {};
893
+ },
894
+ appendTransaction(_transactions, oldState, newState) {
895
+ if (hasContainerNode(newState.doc)) return null;
896
+ if (newState.doc.eq(oldState.doc)) return null;
897
+ return wrapInContainer(newState);
898
+ }
899
+ })];
900
+ },
901
+ renderToReactEmail({ children, node, style }) {
902
+ const inlineStyles = require_styles.inlineCssToJs(node.attrs?.style);
903
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_react_email_components.Container, {
904
+ className: node.attrs?.class || void 0,
905
+ style: {
906
+ ...style,
907
+ ...inlineStyles,
908
+ width: "100%",
909
+ maxWidth: style?.width ?? style?.maxWidth
910
+ },
911
+ children
912
+ });
913
+ }
914
+ });
915
+
916
+ //#endregion
917
+ //#region src/extensions/div.tsx
918
+ const Div = require_event_bus.EmailNode.create({
919
+ name: "div",
920
+ group: "block",
921
+ content: "block+",
922
+ defining: true,
923
+ isolating: true,
924
+ parseHTML() {
925
+ return [{
926
+ tag: "div:not([data-type])",
927
+ getAttrs: (node) => {
928
+ if (typeof node === "string") return false;
929
+ const element = node;
930
+ const attrs = {};
931
+ Array.from(element.attributes).forEach((attr) => {
932
+ attrs[attr.name] = attr.value;
933
+ });
934
+ return attrs;
935
+ }
936
+ }];
937
+ },
938
+ renderHTML({ HTMLAttributes }) {
939
+ return [
940
+ "div",
941
+ (0, _tiptap_core.mergeAttributes)(this.options.HTMLAttributes, HTMLAttributes),
942
+ 0
943
+ ];
944
+ },
945
+ addAttributes() {
946
+ return { ...require_event_bus.createStandardAttributes([...require_event_bus.COMMON_HTML_ATTRIBUTES, ...require_event_bus.LAYOUT_ATTRIBUTES]) };
947
+ },
948
+ renderToReactEmail({ children, node, style }) {
949
+ const inlineStyles = require_styles.inlineCssToJs(node.attrs?.style);
950
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
951
+ className: node.attrs?.class || void 0,
952
+ style: {
953
+ ...style,
954
+ ...inlineStyles
955
+ },
956
+ children
957
+ });
958
+ }
959
+ });
960
+
961
+ //#endregion
962
+ //#region src/core/is-document-visually-empty.ts
963
+ function isDocumentVisuallyEmpty(doc) {
964
+ let nonGlobalNodeCount = 0;
965
+ let firstNonGlobalNode = null;
966
+ for (let index = 0; index < doc.childCount; index += 1) {
967
+ const node = doc.child(index);
968
+ if (node.type.name === "globalContent") continue;
969
+ nonGlobalNodeCount += 1;
970
+ if (firstNonGlobalNode === null) firstNonGlobalNode = node;
971
+ }
972
+ if (nonGlobalNodeCount === 0) return true;
973
+ if (nonGlobalNodeCount !== 1) return false;
974
+ if (firstNonGlobalNode.type.name === "container") return hasOnlyEmptyParagraph(firstNonGlobalNode);
975
+ return isEmptyParagraph(firstNonGlobalNode);
976
+ }
977
+ function hasOnlyEmptyParagraph(node) {
978
+ if (node.childCount === 0) return true;
979
+ if (node.childCount !== 1) return false;
980
+ return isEmptyParagraph(node.child(0));
981
+ }
982
+ function isEmptyParagraph(node) {
983
+ return node.type.name === "paragraph" && node.textContent.length === 0;
984
+ }
985
+
986
+ //#endregion
987
+ //#region src/core/use-editor.ts
988
+ function useEditor({ content, extensions = [], onUpdate, onPaste, onUploadImage, onReady, editable = true, ...rest }) {
989
+ const [contentError, setContentError] = react.useState(null);
990
+ const isCollaborative = hasCollaborationExtension(extensions);
991
+ const effectiveExtensions = react.useMemo(() => [
992
+ StarterKit,
993
+ ...isCollaborative ? [] : [_tiptap_extensions.UndoRedo],
994
+ ...extensions
995
+ ], [extensions, isCollaborative]);
996
+ const editor = (0, _tiptap_react.useEditor)({
997
+ content: isCollaborative ? void 0 : content,
998
+ extensions: effectiveExtensions,
999
+ editable,
1000
+ immediatelyRender: false,
1001
+ enableContentCheck: true,
1002
+ onContentError({ editor: editor$1, error, disableCollaboration }) {
1003
+ disableCollaboration();
1004
+ setContentError(error);
1005
+ console.error(error);
1006
+ editor$1.setEditable(false);
1007
+ },
1008
+ onCreate({ editor: editor$1 }) {
1009
+ onReady?.(editor$1);
1010
+ },
1011
+ onUpdate({ editor: editor$1, transaction }) {
1012
+ onUpdate?.(editor$1, transaction);
1013
+ },
1014
+ editorProps: {
1015
+ handleDOMEvents: { click: (view, event) => {
1016
+ if (!view.editable) {
1017
+ if (event.target.closest("a")) {
1018
+ event.preventDefault();
1019
+ return true;
1020
+ }
1021
+ }
1022
+ return false;
1023
+ } },
1024
+ handlePaste: createPasteHandler({
1025
+ onPaste,
1026
+ onUploadImage,
1027
+ extensions: effectiveExtensions
1028
+ }),
1029
+ handleDrop: createDropHandler({
1030
+ onPaste,
1031
+ onUploadImage
1032
+ })
1033
+ },
1034
+ ...rest
1035
+ });
1036
+ return {
1037
+ editor,
1038
+ isEditorEmpty: (0, _tiptap_react.useEditorState)({
1039
+ editor,
1040
+ selector: (context) => {
1041
+ if (!context.editor) return true;
1042
+ return isDocumentVisuallyEmpty(context.editor.state.doc);
1043
+ }
1044
+ }) ?? true,
1045
+ extensions: effectiveExtensions,
1046
+ contentError,
1047
+ isCollaborative
1048
+ };
1049
+ }
1050
+
1051
+ //#endregion
1052
+ //#region src/extensions/divider.tsx
1053
+ const Divider = require_event_bus.EmailNode.from(_tiptap_extension_horizontal_rule.default.extend({
1054
+ addAttributes() {
1055
+ return { class: { default: "divider" } };
1056
+ },
1057
+ addInputRules() {
1058
+ return [new _tiptap_core.InputRule({
1059
+ find: /^(?:---|—-|___\s|\*\*\*\s)$/,
1060
+ handler: ({ state, range }) => {
1061
+ const attributes = {};
1062
+ const { tr } = state;
1063
+ const start = range.from;
1064
+ const end = range.to;
1065
+ tr.insert(start - 1, this.type.create(attributes)).delete(tr.mapping.map(start), tr.mapping.map(end));
1066
+ }
1067
+ })];
1068
+ },
1069
+ addNodeView() {
1070
+ return (0, _tiptap_react.ReactNodeViewRenderer)((props) => {
1071
+ const node = props.node;
1072
+ const { class: className, ...rest } = node.attrs;
1073
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_tiptap_react.NodeViewWrapper, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_react_email_components.Hr, {
1074
+ ...rest,
1075
+ className: "node-hr",
1076
+ style: require_styles.inlineCssToJs(node.attrs.style)
1077
+ }) });
1078
+ });
1079
+ }
1080
+ }), ({ node, style }) => {
1081
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_react_email_components.Hr, {
1082
+ className: node.attrs?.class || void 0,
1083
+ style: {
1084
+ ...style,
1085
+ ...require_styles.inlineCssToJs(node.attrs?.style)
1086
+ }
1087
+ });
1088
+ });
1089
+
1090
+ //#endregion
1091
+ //#region src/extensions/hard-break.tsx
1092
+ const HardBreak = require_event_bus.EmailNode.from(_tiptap_extension_hard_break.default, () => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("br", {}));
1093
+
1094
+ //#endregion
1095
+ //#region src/extensions/heading.tsx
1096
+ const Heading = require_event_bus.EmailNode.from(_tiptap_extension_heading.Heading.extend({ addNodeView() {
1097
+ return (0, _tiptap_react.ReactNodeViewRenderer)(({ node }) => {
1098
+ const level = node.attrs.level ?? 1;
1099
+ const { class: className, ...rest } = node.attrs;
1100
+ const attrs = {
1101
+ ...rest,
1102
+ className: `node-h${level} ${className}`,
1103
+ style: require_styles.inlineCssToJs(node.attrs.style)
1104
+ };
1105
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_tiptap_react.NodeViewWrapper, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_react_email_components.Heading, {
1106
+ as: `h${level}`,
1107
+ ...attrs,
1108
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_tiptap_react.NodeViewContent, {})
1109
+ }) });
1110
+ });
1111
+ } }), ({ children, node, style }) => {
1112
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_react_email_components.Heading, {
1113
+ as: `h${node.attrs?.level ?? 1}`,
1114
+ className: node.attrs?.class || void 0,
1115
+ style: {
1116
+ ...style,
1117
+ ...require_styles.inlineCssToJs(node.attrs?.style),
1118
+ ...getTextAlignment(node.attrs?.align ?? node.attrs?.alignment)
1119
+ },
1120
+ children
1121
+ });
1122
+ });
1123
+
1124
+ //#endregion
1125
+ //#region src/extensions/italic.tsx
1126
+ const Italic = EmailMark.from(_tiptap_extension_italic.default, ({ children, style }) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("em", {
1127
+ style,
1128
+ children
1129
+ }));
1130
+
1131
+ //#endregion
1132
+ //#region src/extensions/preserved-style.tsx
1133
+ const PreservedStyle = EmailMark.create({
1134
+ name: "preservedStyle",
1135
+ addAttributes() {
1136
+ return { style: {
1137
+ default: null,
1138
+ parseHTML: (element) => element.getAttribute("style"),
1139
+ renderHTML: (attributes) => {
1140
+ if (!attributes.style) return {};
1141
+ return { style: attributes.style };
1142
+ }
1143
+ } };
1144
+ },
1145
+ parseHTML() {
1146
+ return [{
1147
+ tag: "span[style]",
1148
+ getAttrs: (element) => {
1149
+ if (typeof element === "string") return false;
1150
+ const style = element.getAttribute("style");
1151
+ if (style && hasPreservableStyles(style)) return { style };
1152
+ return false;
1153
+ }
1154
+ }];
1155
+ },
1156
+ renderHTML({ HTMLAttributes }) {
1157
+ return [
1158
+ "span",
1159
+ (0, _tiptap_core.mergeAttributes)(HTMLAttributes),
1160
+ 0
1161
+ ];
1162
+ },
1163
+ renderToReactEmail({ children, mark }) {
1164
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1165
+ style: mark.attrs?.style ? require_styles.inlineCssToJs(mark.attrs.style) : void 0,
1166
+ children
1167
+ });
1168
+ }
1169
+ });
1170
+ const LINK_INDICATOR_STYLES = [
1171
+ "color",
1172
+ "text-decoration",
1173
+ "text-decoration-line",
1174
+ "text-decoration-color",
1175
+ "text-decoration-style"
1176
+ ];
1177
+ function parseStyleString(styleString) {
1178
+ const temp = document.createElement("div");
1179
+ temp.style.cssText = styleString;
1180
+ return temp.style;
1181
+ }
1182
+ function hasBackground(style) {
1183
+ const bgColor = style.backgroundColor;
1184
+ const bg = style.background;
1185
+ if (bgColor && bgColor !== "transparent" && bgColor !== "rgba(0, 0, 0, 0)") return true;
1186
+ if (bg && bg !== "transparent" && bg !== "none" && bg !== "rgba(0, 0, 0, 0)") return true;
1187
+ return false;
1188
+ }
1189
+ function hasPreservableStyles(styleString) {
1190
+ return processStylesForUnlink(styleString) !== null;
1191
+ }
1192
+ /**
1193
+ * Processes styles when unlinking:
1194
+ * - Has background (button-like): preserve all styles
1195
+ * - No background: strip link-indicator styles (color, text-decoration), keep the rest
1196
+ */
1197
+ function processStylesForUnlink(styleString) {
1198
+ if (!styleString) return null;
1199
+ const style = parseStyleString(styleString);
1200
+ if (hasBackground(style)) return styleString;
1201
+ const filtered = [];
1202
+ for (let i = 0; i < style.length; i++) {
1203
+ const prop = style[i];
1204
+ if (LINK_INDICATOR_STYLES.includes(prop)) continue;
1205
+ const value = style.getPropertyValue(prop);
1206
+ if (value) filtered.push(`${prop}: ${value}`);
1207
+ }
1208
+ return filtered.length > 0 ? filtered.join("; ") : null;
1209
+ }
1210
+
1211
+ //#endregion
1212
+ //#region src/extensions/link.tsx
1213
+ const Link = EmailMark.from(_tiptap_extension_link.default, ({ children, mark, style }) => {
1214
+ const linkMarkStyle = mark.attrs?.style ? require_styles.inlineCssToJs(mark.attrs.style) : {};
1215
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_react_email_components.Link, {
1216
+ href: mark.attrs?.href ?? void 0,
1217
+ rel: mark.attrs?.rel ?? void 0,
1218
+ style: {
1219
+ ...style,
1220
+ ...linkMarkStyle
1221
+ },
1222
+ target: mark.attrs?.target ?? void 0,
1223
+ ...mark.attrs?.["ses:no-track"] ? { "ses:no-track": mark.attrs["ses:no-track"] } : {},
1224
+ children
1225
+ });
1226
+ }).extend({
1227
+ parseHTML() {
1228
+ return [{
1229
+ tag: "a[target]:not([data-id=\"react-email-button\"])",
1230
+ getAttrs: (node) => {
1231
+ if (typeof node === "string") return false;
1232
+ const element = node;
1233
+ const attrs = {};
1234
+ Array.from(element.attributes).forEach((attr) => {
1235
+ attrs[attr.name] = attr.value;
1236
+ });
1237
+ return attrs;
1238
+ }
1239
+ }, {
1240
+ tag: "a[href]:not([data-id=\"react-email-button\"])",
1241
+ getAttrs: (node) => {
1242
+ if (typeof node === "string") return false;
1243
+ const element = node;
1244
+ const attrs = {};
1245
+ Array.from(element.attributes).forEach((attr) => {
1246
+ attrs[attr.name] = attr.value;
1247
+ });
1248
+ return attrs;
1249
+ }
1250
+ }];
1251
+ },
1252
+ addAttributes() {
1253
+ return {
1254
+ ...this.parent?.(),
1255
+ "ses:no-track": {
1256
+ default: null,
1257
+ parseHTML: (element) => element.getAttribute("ses:no-track")
1258
+ }
1259
+ };
1260
+ },
1261
+ addCommands() {
1262
+ return {
1263
+ ...this.parent?.(),
1264
+ unsetLink: () => ({ state, chain }) => {
1265
+ const { from } = state.selection;
1266
+ const linkStyle = state.doc.resolve(from).marks().find((m) => m.type.name === "link")?.attrs?.style ?? null;
1267
+ const preservedStyle = processStylesForUnlink(linkStyle);
1268
+ const shouldRemoveUnderline = preservedStyle !== linkStyle;
1269
+ if (preservedStyle) {
1270
+ const cmd = chain().extendMarkRange("link").unsetMark("link").setMark("preservedStyle", { style: preservedStyle });
1271
+ return shouldRemoveUnderline ? cmd.unsetMark("underline").run() : cmd.run();
1272
+ }
1273
+ return chain().extendMarkRange("link").unsetMark("link").unsetMark("underline").run();
1274
+ }
1275
+ };
1276
+ },
1277
+ addKeyboardShortcuts() {
1278
+ return { "Mod-k": () => {
1279
+ require_event_bus.editorEventBus.dispatch("bubble-menu:add-link", void 0);
1280
+ return this.editor.chain().focus().toggleLink({ href: "" }).run();
1281
+ } };
1282
+ }
1283
+ });
1284
+
1285
+ //#endregion
1286
+ //#region src/extensions/list-item.tsx
1287
+ const ListItem = require_event_bus.EmailNode.from(_tiptap_extension_list_item.default, ({ children, node, style }) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("li", {
1288
+ className: node.attrs?.class || void 0,
1289
+ style: {
1290
+ ...style,
1291
+ ...require_styles.inlineCssToJs(node.attrs?.style),
1292
+ ...getTextAlignment(node.attrs?.align || node.attrs?.alignment)
1293
+ },
1294
+ children
1295
+ }));
1296
+
1297
+ //#endregion
1298
+ //#region src/extensions/max-nesting.ts
1299
+ const MaxNesting = _tiptap_core.Extension.create({
1300
+ name: "maxNesting",
1301
+ addOptions() {
1302
+ return {
1303
+ maxDepth: 3,
1304
+ nodeTypes: void 0
1305
+ };
1306
+ },
1307
+ addProseMirrorPlugins() {
1308
+ const { maxDepth, nodeTypes } = this.options;
1309
+ if (typeof maxDepth !== "number" || maxDepth < 1) throw new Error("maxDepth must be a positive number");
1310
+ return [new _tiptap_pm_state.Plugin({
1311
+ key: new _tiptap_pm_state.PluginKey("maxNesting"),
1312
+ appendTransaction(transactions, _oldState, newState) {
1313
+ if (!transactions.some((tr$1) => tr$1.docChanged)) return null;
1314
+ const rangesToLift = [];
1315
+ newState.doc.descendants((node, pos) => {
1316
+ let depth = 0;
1317
+ let currentPos = pos;
1318
+ let currentNode = node;
1319
+ while (currentNode && depth <= maxDepth) {
1320
+ if (!nodeTypes || nodeTypes.includes(currentNode.type.name)) depth++;
1321
+ const $pos = newState.doc.resolve(currentPos);
1322
+ if ($pos.depth === 0) break;
1323
+ currentPos = $pos.before($pos.depth);
1324
+ currentNode = newState.doc.nodeAt(currentPos);
1325
+ }
1326
+ if (depth > maxDepth) {
1327
+ const $pos = newState.doc.resolve(pos);
1328
+ if ($pos.depth > 0) {
1329
+ const range = $pos.blockRange();
1330
+ if (range && "canReplace" in newState.schema.nodes.doc && typeof newState.schema.nodes.doc.canReplace === "function" && newState.schema.nodes.doc.canReplace(range.start - 1, range.end + 1, newState.doc.slice(range.start, range.end).content)) rangesToLift.push({
1331
+ range,
1332
+ target: range.start - 1
1333
+ });
1334
+ }
1335
+ }
1336
+ });
1337
+ if (rangesToLift.length === 0) return null;
1338
+ const tr = newState.tr;
1339
+ for (let i = rangesToLift.length - 1; i >= 0; i--) {
1340
+ const { range, target } = rangesToLift[i];
1341
+ tr.lift(range, target);
1342
+ }
1343
+ return tr;
1344
+ },
1345
+ filterTransaction(tr) {
1346
+ if (!tr.docChanged) return true;
1347
+ let wouldCreateDeepNesting = false;
1348
+ const newDoc = tr.doc;
1349
+ newDoc.descendants((node, pos) => {
1350
+ if (wouldCreateDeepNesting) return false;
1351
+ let depth = 0;
1352
+ let currentPos = pos;
1353
+ let currentNode = node;
1354
+ while (currentNode && depth <= maxDepth) {
1355
+ if (!nodeTypes || nodeTypes.includes(currentNode.type.name)) depth++;
1356
+ const $pos = newDoc.resolve(currentPos);
1357
+ if ($pos.depth === 0) break;
1358
+ currentPos = $pos.before($pos.depth);
1359
+ currentNode = newDoc.nodeAt(currentPos);
1360
+ }
1361
+ if (depth > maxDepth) {
1362
+ wouldCreateDeepNesting = true;
1363
+ return false;
1364
+ }
1365
+ });
1366
+ return !wouldCreateDeepNesting;
1367
+ }
1368
+ })];
1369
+ }
1370
+ });
1371
+
1372
+ //#endregion
1373
+ //#region src/extensions/ordered-list.tsx
1374
+ const OrderedList = require_event_bus.EmailNode.from(_tiptap_extension_ordered_list.default, ({ children, node, style }) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("ol", {
1375
+ className: node.attrs?.class || void 0,
1376
+ start: node.attrs?.start,
1377
+ style: {
1378
+ ...style,
1379
+ ...require_styles.inlineCssToJs(node.attrs?.style)
1380
+ },
1381
+ children
1382
+ }));
1383
+
1384
+ //#endregion
1385
+ //#region src/extensions/paragraph.tsx
1386
+ const Paragraph = require_event_bus.EmailNode.from(_tiptap_extension_paragraph.default, ({ children, node, style }) => {
1387
+ const isEmpty = !node.content || node.content.length === 0;
1388
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1389
+ className: node.attrs?.class || void 0,
1390
+ style: {
1391
+ ...style,
1392
+ ...require_styles.inlineCssToJs(node.attrs?.style),
1393
+ ...getTextAlignment(node.attrs?.align || node.attrs?.alignment)
1394
+ },
1395
+ children: isEmpty ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("br", {}) : children
1396
+ });
1397
+ });
1398
+
1399
+ //#endregion
1400
+ //#region src/extensions/placeholder.ts
1401
+ const Placeholder = _tiptap_extension_placeholder.default.configure({
1402
+ placeholder: ({ node }) => {
1403
+ if (node.type.name === "heading") return `Heading ${node.attrs.level}`;
1404
+ return "Press '/' for commands";
1405
+ },
1406
+ includeChildren: true
1407
+ });
1408
+
1409
+ //#endregion
1410
+ //#region src/extensions/preview-text.ts
1411
+ const PreviewText = _tiptap_core.Node.create({
1412
+ name: "previewText",
1413
+ group: "block",
1414
+ selectable: false,
1415
+ draggable: false,
1416
+ atom: true,
1417
+ addOptions() {
1418
+ return { HTMLAttributes: {} };
1419
+ },
1420
+ addStorage() {
1421
+ return { previewText: null };
1422
+ },
1423
+ renderHTML() {
1424
+ return ["div", { style: "display: none" }];
1425
+ },
1426
+ parseHTML() {
1427
+ return [{
1428
+ tag: "div[data-skip-in-text=\"true\"]",
1429
+ getAttrs: (node) => {
1430
+ if (typeof node === "string") return false;
1431
+ const element = node;
1432
+ let directText = "";
1433
+ for (const child of element.childNodes) if (child.nodeType === 3) directText += child.textContent || "";
1434
+ const cleanText = directText.trim();
1435
+ if (cleanText) this.storage.previewText = cleanText;
1436
+ return false;
1437
+ }
1438
+ }, {
1439
+ tag: "span.preheader",
1440
+ getAttrs: (node) => {
1441
+ if (typeof node === "string") return false;
1442
+ const preheaderText = node.textContent?.trim();
1443
+ if (preheaderText) this.storage.previewText = preheaderText;
1444
+ return false;
1445
+ }
1446
+ }];
1447
+ }
1448
+ });
1449
+
1450
+ //#endregion
1451
+ //#region src/extensions/section.tsx
1452
+ const Section$1 = require_event_bus.EmailNode.create({
1453
+ name: "section",
1454
+ group: "block",
1455
+ content: "block+",
1456
+ isolating: true,
1457
+ defining: true,
1458
+ parseHTML() {
1459
+ return [{ tag: "section[data-type=\"section\"]" }];
1460
+ },
1461
+ renderHTML({ HTMLAttributes }) {
1462
+ return [
1463
+ "section",
1464
+ (0, _tiptap_core.mergeAttributes)({
1465
+ "data-type": "section",
1466
+ class: "node-section"
1467
+ }, HTMLAttributes),
1468
+ 0
1469
+ ];
1470
+ },
1471
+ addCommands() {
1472
+ return { insertSection: () => ({ commands }) => {
1473
+ return commands.insertContent({
1474
+ type: this.name,
1475
+ content: [{
1476
+ type: "paragraph",
1477
+ content: []
1478
+ }]
1479
+ });
1480
+ } };
1481
+ },
1482
+ renderToReactEmail({ children, node, style }) {
1483
+ const inlineStyles = require_styles.inlineCssToJs(node.attrs?.style);
1484
+ const textAlign = node.attrs?.align || node.attrs?.alignment;
1485
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_react_email_components.Section, {
1486
+ className: node.attrs?.class || void 0,
1487
+ align: textAlign,
1488
+ style: {
1489
+ ...style,
1490
+ ...inlineStyles,
1491
+ ...getTextAlignment(textAlign)
1492
+ },
1493
+ children
1494
+ });
1495
+ }
1496
+ });
1497
+
1498
+ //#endregion
1499
+ //#region src/extensions/strike.tsx
1500
+ const Strike = EmailMark.from(_tiptap_extension_strike.default, ({ children, style }) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("s", {
1501
+ style,
1502
+ children
1503
+ }));
1504
+
1505
+ //#endregion
1506
+ //#region src/extensions/style-attribute.tsx
1507
+ const StyleAttribute = _tiptap_core.Extension.create({
1508
+ name: "styleAttribute",
1509
+ priority: 101,
1510
+ addOptions() {
1511
+ return {
1512
+ types: [],
1513
+ style: []
1514
+ };
1515
+ },
1516
+ addGlobalAttributes() {
1517
+ return [{
1518
+ types: this.options.types,
1519
+ attributes: { style: {
1520
+ default: "",
1521
+ parseHTML: (element) => element.getAttribute("style") || "",
1522
+ renderHTML: (attributes) => {
1523
+ return { style: attributes.style ?? "" };
1524
+ }
1525
+ } }
1526
+ }];
1527
+ },
1528
+ addCommands() {
1529
+ return {
1530
+ unsetStyle: () => ({ commands }) => {
1531
+ return this.options.types.every((type) => commands.resetAttributes(type, "style"));
1532
+ },
1533
+ setStyle: (style) => ({ commands }) => {
1534
+ return this.options.types.every((type) => commands.updateAttributes(type, { style }));
1535
+ }
1536
+ };
1537
+ },
1538
+ addKeyboardShortcuts() {
1539
+ return { Enter: ({ editor }) => {
1540
+ const { state } = editor.view;
1541
+ const { selection } = state;
1542
+ const { $from } = selection;
1543
+ const textBefore = $from.nodeBefore?.text || "";
1544
+ if (textBefore.includes("{{") || textBefore.includes("{{{")) return false;
1545
+ requestAnimationFrame(() => {
1546
+ editor.commands.resetAttributes("paragraph", "style");
1547
+ });
1548
+ return false;
1549
+ } };
1550
+ }
1551
+ });
1552
+
1553
+ //#endregion
1554
+ //#region src/extensions/sup.tsx
1555
+ const SupBase = _tiptap_extension_superscript.default.extend({
1556
+ name: "sup",
1557
+ addCommands() {
1558
+ return {
1559
+ ...this.parent?.(),
1560
+ setSup: () => ({ commands }) => {
1561
+ return commands.setMark(this.name);
1562
+ },
1563
+ toggleSup: () => ({ commands }) => {
1564
+ return commands.toggleMark(this.name);
1565
+ },
1566
+ unsetSup: () => ({ commands }) => {
1567
+ return commands.unsetMark(this.name);
1568
+ }
1569
+ };
1570
+ }
1571
+ });
1572
+ const Sup = EmailMark.from(SupBase, ({ children, style }) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("sup", {
1573
+ style,
1574
+ children
1575
+ }));
1576
+
1577
+ //#endregion
1578
+ //#region src/extensions/table.tsx
1579
+ const Table = require_event_bus.EmailNode.create({
1580
+ name: "table",
1581
+ group: "block",
1582
+ content: "tableRow+",
1583
+ isolating: true,
1584
+ tableRole: "table",
1585
+ addAttributes() {
1586
+ return { ...require_event_bus.createStandardAttributes([
1587
+ ...require_event_bus.TABLE_ATTRIBUTES,
1588
+ ...require_event_bus.LAYOUT_ATTRIBUTES,
1589
+ ...require_event_bus.COMMON_HTML_ATTRIBUTES
1590
+ ]) };
1591
+ },
1592
+ parseHTML() {
1593
+ return [{
1594
+ tag: "table",
1595
+ getAttrs: (node) => {
1596
+ if (typeof node === "string") return false;
1597
+ const element = node;
1598
+ const attrs = {};
1599
+ Array.from(element.attributes).forEach((attr) => {
1600
+ attrs[attr.name] = attr.value;
1601
+ });
1602
+ return attrs;
1603
+ }
1604
+ }];
1605
+ },
1606
+ renderHTML({ HTMLAttributes }) {
1607
+ return [
1608
+ "table",
1609
+ (0, _tiptap_core.mergeAttributes)(this.options.HTMLAttributes, HTMLAttributes),
1610
+ [
1611
+ "tbody",
1612
+ {},
1613
+ 0
1614
+ ]
1615
+ ];
1616
+ },
1617
+ renderToReactEmail({ children, node, style }) {
1618
+ const inlineStyles = require_styles.inlineCssToJs(node.attrs?.style);
1619
+ const alignment = node.attrs?.align || node.attrs?.alignment;
1620
+ const width = node.attrs?.width;
1621
+ const centeringStyles = alignment === "center" ? {
1622
+ marginLeft: "auto",
1623
+ marginRight: "auto"
1624
+ } : {};
1625
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_react_email_components.Section, {
1626
+ className: node.attrs?.class || void 0,
1627
+ align: alignment,
1628
+ style: require_styles.resolveConflictingStyles(style, {
1629
+ ...inlineStyles,
1630
+ ...centeringStyles
1631
+ }),
1632
+ ...width !== void 0 ? { width } : {},
1633
+ children
1634
+ });
1635
+ }
1636
+ });
1637
+ const TableRow = require_event_bus.EmailNode.create({
1638
+ name: "tableRow",
1639
+ group: "tableRow",
1640
+ content: "(tableCell | tableHeader)+",
1641
+ addAttributes() {
1642
+ return { ...require_event_bus.createStandardAttributes([
1643
+ ...require_event_bus.TABLE_CELL_ATTRIBUTES,
1644
+ ...require_event_bus.LAYOUT_ATTRIBUTES,
1645
+ ...require_event_bus.COMMON_HTML_ATTRIBUTES
1646
+ ]) };
1647
+ },
1648
+ parseHTML() {
1649
+ return [{
1650
+ tag: "tr",
1651
+ getAttrs: (node) => {
1652
+ if (typeof node === "string") return false;
1653
+ const element = node;
1654
+ const attrs = {};
1655
+ Array.from(element.attributes).forEach((attr) => {
1656
+ attrs[attr.name] = attr.value;
1657
+ });
1658
+ return attrs;
1659
+ }
1660
+ }];
1661
+ },
1662
+ renderHTML({ HTMLAttributes }) {
1663
+ return [
1664
+ "tr",
1665
+ HTMLAttributes,
1666
+ 0
1667
+ ];
1668
+ },
1669
+ renderToReactEmail({ children, node, style }) {
1670
+ const inlineStyles = require_styles.inlineCssToJs(node.attrs?.style);
1671
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("tr", {
1672
+ className: node.attrs?.class || void 0,
1673
+ style: {
1674
+ ...style,
1675
+ ...inlineStyles
1676
+ },
1677
+ children
1678
+ });
1679
+ }
1680
+ });
1681
+ const TableCell = require_event_bus.EmailNode.create({
1682
+ name: "tableCell",
1683
+ group: "tableCell",
1684
+ content: "block+",
1685
+ isolating: true,
1686
+ addAttributes() {
1687
+ return { ...require_event_bus.createStandardAttributes([
1688
+ ...require_event_bus.TABLE_CELL_ATTRIBUTES,
1689
+ ...require_event_bus.LAYOUT_ATTRIBUTES,
1690
+ ...require_event_bus.COMMON_HTML_ATTRIBUTES
1691
+ ]) };
1692
+ },
1693
+ parseHTML() {
1694
+ return [{
1695
+ tag: "td",
1696
+ getAttrs: (node) => {
1697
+ if (typeof node === "string") return false;
1698
+ const element = node;
1699
+ const attrs = {};
1700
+ Array.from(element.attributes).forEach((attr) => {
1701
+ attrs[attr.name] = attr.value;
1702
+ });
1703
+ return attrs;
1704
+ }
1705
+ }];
1706
+ },
1707
+ renderHTML({ HTMLAttributes }) {
1708
+ return [
1709
+ "td",
1710
+ HTMLAttributes,
1711
+ 0
1712
+ ];
1713
+ },
1714
+ renderToReactEmail({ children, node, style }) {
1715
+ const inlineStyles = require_styles.inlineCssToJs(node.attrs?.style);
1716
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_react_email_components.Column, {
1717
+ className: node.attrs?.class || void 0,
1718
+ align: node.attrs?.align || node.attrs?.alignment,
1719
+ style: {
1720
+ ...style,
1721
+ ...inlineStyles
1722
+ },
1723
+ children
1724
+ });
1725
+ }
1726
+ });
1727
+ const TableHeader = _tiptap_core.Node.create({
1728
+ name: "tableHeader",
1729
+ group: "tableCell",
1730
+ content: "block+",
1731
+ isolating: true,
1732
+ addAttributes() {
1733
+ return { ...require_event_bus.createStandardAttributes([
1734
+ ...require_event_bus.TABLE_HEADER_ATTRIBUTES,
1735
+ ...require_event_bus.TABLE_CELL_ATTRIBUTES,
1736
+ ...require_event_bus.LAYOUT_ATTRIBUTES,
1737
+ ...require_event_bus.COMMON_HTML_ATTRIBUTES
1738
+ ]) };
1739
+ },
1740
+ parseHTML() {
1741
+ return [{
1742
+ tag: "th",
1743
+ getAttrs: (node) => {
1744
+ if (typeof node === "string") return false;
1745
+ const element = node;
1746
+ const attrs = {};
1747
+ Array.from(element.attributes).forEach((attr) => {
1748
+ attrs[attr.name] = attr.value;
1749
+ });
1750
+ return attrs;
1751
+ }
1752
+ }];
1753
+ },
1754
+ renderHTML({ HTMLAttributes }) {
1755
+ return [
1756
+ "th",
1757
+ HTMLAttributes,
1758
+ 0
1759
+ ];
1760
+ }
1761
+ });
1762
+
1763
+ //#endregion
1764
+ //#region src/extensions/text.tsx
1765
+ const Text = require_event_bus.EmailNode.from(_tiptap_extension_text.Text, ({ children }) => {
1766
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, { children });
1767
+ });
1768
+
1769
+ //#endregion
1770
+ //#region src/extensions/trailing-node.tsx
1771
+ const skipTrailingNodeMeta = "skipTrailingNode";
1772
+ function nodeEqualsType({ types, node }) {
1773
+ return node && Array.isArray(types) && types.includes(node.type) || node?.type === types;
1774
+ }
1775
+ /**
1776
+ * This extension allows you to add an extra node at the end of a node.
1777
+ *
1778
+ * Differently from TipTap's native one, it allows you to pick which node to append the trailing node to.
1779
+ * @see https://www.tiptap.dev/api/extensions/trailing-node
1780
+ *
1781
+ * We could contribute this to TipTap's core extensions and I think we should at some once we get some time.
1782
+ */
1783
+ const TrailingNode = _tiptap_core.Extension.create({
1784
+ name: "trailingNode",
1785
+ addOptions() {
1786
+ return {
1787
+ node: void 0,
1788
+ appendTo: "doc",
1789
+ notAfter: []
1790
+ };
1791
+ },
1792
+ addProseMirrorPlugins() {
1793
+ const plugin = new _tiptap_pm_state.PluginKey(this.name);
1794
+ const defaultNode = this.options.node || this.editor.schema.topNodeType.contentMatch.defaultType?.name || "paragraph";
1795
+ const notAfter = Array.isArray(this.options.notAfter) ? this.options.notAfter : [this.options.notAfter].filter(Boolean);
1796
+ const disabledNodes = Object.entries(this.editor.schema.nodes).map(([, value]) => value).filter((node) => notAfter.concat(defaultNode).includes(node.name));
1797
+ const appendToType = this.editor.schema.nodes[this.options.appendTo || "doc"];
1798
+ const getInsertPositions = (doc) => {
1799
+ const positions = [];
1800
+ if (doc.type === appendToType) {
1801
+ if (!nodeEqualsType({
1802
+ node: doc.lastChild,
1803
+ types: disabledNodes
1804
+ })) positions.push(doc.content.size);
1805
+ }
1806
+ doc.descendants((node, pos) => {
1807
+ if (node.type !== appendToType) return;
1808
+ if (!nodeEqualsType({
1809
+ node: node.lastChild,
1810
+ types: disabledNodes
1811
+ })) positions.push(pos + node.nodeSize - 1);
1812
+ });
1813
+ return positions;
1814
+ };
1815
+ return [new _tiptap_pm_state.Plugin({
1816
+ key: plugin,
1817
+ appendTransaction: (transactions, __, state) => {
1818
+ const { doc, tr, schema } = state;
1819
+ const shouldInsert = plugin.getState(state);
1820
+ const type = schema.nodes[defaultNode];
1821
+ if (transactions.some((transaction) => transaction.getMeta(skipTrailingNodeMeta))) return;
1822
+ if (!shouldInsert) return;
1823
+ const positions = getInsertPositions(doc);
1824
+ for (const pos of positions.sort((a, b) => b - a)) tr.insert(pos, type.create());
1825
+ return positions.length > 0 ? tr : void 0;
1826
+ },
1827
+ state: {
1828
+ init: (_, state) => {
1829
+ return getInsertPositions(state.doc).length > 0;
1830
+ },
1831
+ apply: (tr, value) => {
1832
+ if (!tr.docChanged) return value;
1833
+ if (tr.getMeta("__uniqueIDTransaction")) return value;
1834
+ return getInsertPositions(tr.doc).length > 0;
1835
+ }
1836
+ }
1837
+ })];
1838
+ }
1839
+ });
1840
+
1841
+ //#endregion
1842
+ //#region src/extensions/underline.tsx
1843
+ const Underline = EmailMark.from(_tiptap_extension_underline.default, ({ children, style }) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("u", {
1844
+ style,
1845
+ children
1846
+ }));
1847
+
1848
+ //#endregion
1849
+ //#region src/extensions/uppercase.tsx
1850
+ const Uppercase = EmailMark.create({
1851
+ name: "uppercase",
1852
+ addOptions() {
1853
+ return { HTMLAttributes: {} };
1854
+ },
1855
+ parseHTML() {
1856
+ return [{
1857
+ tag: "span",
1858
+ getAttrs: (node) => {
1859
+ if (node.style.textTransform === "uppercase") return {};
1860
+ return false;
1861
+ }
1862
+ }];
1863
+ },
1864
+ renderHTML({ HTMLAttributes }) {
1865
+ return [
1866
+ "span",
1867
+ (0, _tiptap_core.mergeAttributes)(this.options.HTMLAttributes, HTMLAttributes, { style: "text-transform: uppercase" }),
1868
+ 0
1869
+ ];
1870
+ },
1871
+ renderToReactEmail({ children, style }) {
1872
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1873
+ style: {
1874
+ ...style,
1875
+ textTransform: "uppercase"
1876
+ },
1877
+ children
1878
+ });
1879
+ },
1880
+ addCommands() {
1881
+ return {
1882
+ setUppercase: () => ({ commands }) => {
1883
+ return commands.setMark(this.name);
1884
+ },
1885
+ toggleUppercase: () => ({ commands }) => {
1886
+ return commands.toggleMark(this.name);
1887
+ },
1888
+ unsetUppercase: () => ({ commands }) => {
1889
+ return commands.unsetMark(this.name);
1890
+ }
1891
+ };
1892
+ }
1893
+ });
1894
+
1895
+ //#endregion
1896
+ //#region src/extensions/index.ts
1897
+ const starterKitExtensions = {
1898
+ CodeBlockPrism,
1899
+ Code,
1900
+ TwoColumns: require_event_bus.TwoColumns,
1901
+ ThreeColumns: require_event_bus.ThreeColumns,
1902
+ FourColumns: require_event_bus.FourColumns,
1903
+ Container,
1904
+ ColumnsColumn: require_event_bus.ColumnsColumn,
1905
+ Paragraph,
1906
+ BulletList,
1907
+ OrderedList,
1908
+ Blockquote,
1909
+ ListItem,
1910
+ HardBreak,
1911
+ Italic,
1912
+ Placeholder,
1913
+ PreviewText,
1914
+ TrailingNode,
1915
+ Bold,
1916
+ Strike,
1917
+ Heading,
1918
+ Divider,
1919
+ Link,
1920
+ Sup,
1921
+ Underline,
1922
+ Uppercase,
1923
+ PreservedStyle,
1924
+ Table,
1925
+ TableRow,
1926
+ TableCell,
1927
+ TableHeader,
1928
+ Body,
1929
+ Div,
1930
+ Button,
1931
+ Section: Section$1,
1932
+ GlobalContent: require_global_content.GlobalContent,
1933
+ Text,
1934
+ AlignmentAttribute,
1935
+ StyleAttribute,
1936
+ ClassAttribute,
1937
+ MaxNesting
1938
+ };
1939
+ const StarterKit = _tiptap_core.Extension.create({
1940
+ name: "reactEmailStarterKit",
1941
+ addOptions() {
1942
+ return {
1943
+ TiptapStarterKit: {},
1944
+ CodeBlockPrism: {
1945
+ defaultLanguage: "javascript",
1946
+ HTMLAttributes: { class: "prism node-codeBlock" }
1947
+ },
1948
+ TrailingNode: {
1949
+ node: "paragraph",
1950
+ appendTo: "container"
1951
+ },
1952
+ Code: { HTMLAttributes: {
1953
+ class: "node-inlineCode",
1954
+ spellcheck: "false"
1955
+ } },
1956
+ TwoColumns: {},
1957
+ ThreeColumns: {},
1958
+ FourColumns: {},
1959
+ ColumnsColumn: {},
1960
+ Paragraph: { HTMLAttributes: { class: "node-paragraph" } },
1961
+ BulletList: { HTMLAttributes: { class: "node-bulletList" } },
1962
+ OrderedList: { HTMLAttributes: { class: "node-orderedList" } },
1963
+ Blockquote: { HTMLAttributes: { class: "node-blockquote" } },
1964
+ ListItem: {},
1965
+ HardBreak: {},
1966
+ Italic: {},
1967
+ Placeholder: {},
1968
+ PreviewText: {},
1969
+ Bold: {},
1970
+ Strike: {},
1971
+ Heading: {},
1972
+ Divider: {},
1973
+ Link: {
1974
+ openOnClick: false,
1975
+ HTMLAttributes: { class: "node-link" }
1976
+ },
1977
+ Sup: {},
1978
+ Underline: {},
1979
+ Uppercase: {},
1980
+ PreservedStyle: {},
1981
+ Table: {},
1982
+ TableRow: {},
1983
+ TableCell: {},
1984
+ TableHeader: {},
1985
+ Body: {},
1986
+ Container: {},
1987
+ Div: {},
1988
+ Button: {},
1989
+ Section: {},
1990
+ GlobalContent: {},
1991
+ AlignmentAttribute: { types: [
1992
+ "heading",
1993
+ "paragraph",
1994
+ "image",
1995
+ "blockquote",
1996
+ "codeBlock",
1997
+ "bulletList",
1998
+ "orderedList",
1999
+ "listItem",
2000
+ "button",
2001
+ "youtube",
2002
+ "twitter",
2003
+ "table",
2004
+ "tableRow",
2005
+ "tableCell",
2006
+ "tableHeader",
2007
+ "columnsColumn"
2008
+ ] },
2009
+ StyleAttribute: { types: [
2010
+ "heading",
2011
+ "paragraph",
2012
+ "image",
2013
+ "blockquote",
2014
+ "codeBlock",
2015
+ "bulletList",
2016
+ "orderedList",
2017
+ "listItem",
2018
+ "button",
2019
+ "youtube",
2020
+ "twitter",
2021
+ "horizontalRule",
2022
+ "footer",
2023
+ "section",
2024
+ "div",
2025
+ "body",
2026
+ "table",
2027
+ "tableRow",
2028
+ "tableCell",
2029
+ "tableHeader",
2030
+ "columnsColumn",
2031
+ "link"
2032
+ ] },
2033
+ Text: {},
2034
+ ClassAttribute: { types: [
2035
+ "heading",
2036
+ "paragraph",
2037
+ "image",
2038
+ "blockquote",
2039
+ "bulletList",
2040
+ "orderedList",
2041
+ "listItem",
2042
+ "button",
2043
+ "youtube",
2044
+ "twitter",
2045
+ "horizontalRule",
2046
+ "footer",
2047
+ "section",
2048
+ "div",
2049
+ "body",
2050
+ "table",
2051
+ "tableRow",
2052
+ "tableCell",
2053
+ "tableHeader",
2054
+ "columnsColumn",
2055
+ "link"
2056
+ ] },
2057
+ MaxNesting: {
2058
+ maxDepth: 50,
2059
+ nodeTypes: [
2060
+ "section",
2061
+ "bulletList",
2062
+ "orderedList"
2063
+ ]
2064
+ }
2065
+ };
2066
+ },
2067
+ addExtensions() {
2068
+ const extensions = [];
2069
+ if (this.options.TiptapStarterKit !== false) extensions.push(_tiptap_starter_kit.default.configure({
2070
+ undoRedo: false,
2071
+ heading: false,
2072
+ link: false,
2073
+ underline: false,
2074
+ trailingNode: false,
2075
+ bold: false,
2076
+ italic: false,
2077
+ strike: false,
2078
+ code: false,
2079
+ paragraph: false,
2080
+ bulletList: false,
2081
+ orderedList: false,
2082
+ listItem: false,
2083
+ blockquote: false,
2084
+ hardBreak: false,
2085
+ gapcursor: false,
2086
+ codeBlock: false,
2087
+ text: false,
2088
+ horizontalRule: false,
2089
+ dropcursor: {
2090
+ color: "#61a8f8",
2091
+ class: "rounded-full animate-[fade-in_300ms_ease-in-out] !z-40",
2092
+ width: 4
2093
+ },
2094
+ ...this.options.TiptapStarterKit
2095
+ }));
2096
+ for (const [name, extension] of Object.entries(starterKitExtensions)) {
2097
+ const key = name;
2098
+ const extensionOptions = this.options[key];
2099
+ if (extensionOptions !== false) extensions.push(extension.configure(extensionOptions));
2100
+ }
2101
+ return extensions;
2102
+ }
2103
+ });
2104
+
2105
+ //#endregion
2106
+ Object.defineProperty(exports, 'AlignmentAttribute', {
2107
+ enumerable: true,
2108
+ get: function () {
2109
+ return AlignmentAttribute;
2110
+ }
2111
+ });
2112
+ Object.defineProperty(exports, 'Blockquote', {
2113
+ enumerable: true,
2114
+ get: function () {
2115
+ return Blockquote;
2116
+ }
2117
+ });
2118
+ Object.defineProperty(exports, 'Body', {
2119
+ enumerable: true,
2120
+ get: function () {
2121
+ return Body;
2122
+ }
2123
+ });
2124
+ Object.defineProperty(exports, 'Bold', {
2125
+ enumerable: true,
2126
+ get: function () {
2127
+ return Bold;
2128
+ }
2129
+ });
2130
+ Object.defineProperty(exports, 'BulletList', {
2131
+ enumerable: true,
2132
+ get: function () {
2133
+ return BulletList;
2134
+ }
2135
+ });
2136
+ Object.defineProperty(exports, 'Button', {
2137
+ enumerable: true,
2138
+ get: function () {
2139
+ return Button;
2140
+ }
2141
+ });
2142
+ Object.defineProperty(exports, 'ClassAttribute', {
2143
+ enumerable: true,
2144
+ get: function () {
2145
+ return ClassAttribute;
2146
+ }
2147
+ });
2148
+ Object.defineProperty(exports, 'Code', {
2149
+ enumerable: true,
2150
+ get: function () {
2151
+ return Code;
2152
+ }
2153
+ });
2154
+ Object.defineProperty(exports, 'CodeBlockPrism', {
2155
+ enumerable: true,
2156
+ get: function () {
2157
+ return CodeBlockPrism;
2158
+ }
2159
+ });
2160
+ Object.defineProperty(exports, 'Container', {
2161
+ enumerable: true,
2162
+ get: function () {
2163
+ return Container;
2164
+ }
2165
+ });
2166
+ Object.defineProperty(exports, 'Div', {
2167
+ enumerable: true,
2168
+ get: function () {
2169
+ return Div;
2170
+ }
2171
+ });
2172
+ Object.defineProperty(exports, 'Divider', {
2173
+ enumerable: true,
2174
+ get: function () {
2175
+ return Divider;
2176
+ }
2177
+ });
2178
+ Object.defineProperty(exports, 'EmailMark', {
2179
+ enumerable: true,
2180
+ get: function () {
2181
+ return EmailMark;
2182
+ }
2183
+ });
2184
+ Object.defineProperty(exports, 'HardBreak', {
2185
+ enumerable: true,
2186
+ get: function () {
2187
+ return HardBreak;
2188
+ }
2189
+ });
2190
+ Object.defineProperty(exports, 'Heading', {
2191
+ enumerable: true,
2192
+ get: function () {
2193
+ return Heading;
2194
+ }
2195
+ });
2196
+ Object.defineProperty(exports, 'Italic', {
2197
+ enumerable: true,
2198
+ get: function () {
2199
+ return Italic;
2200
+ }
2201
+ });
2202
+ Object.defineProperty(exports, 'Link', {
2203
+ enumerable: true,
2204
+ get: function () {
2205
+ return Link;
2206
+ }
2207
+ });
2208
+ Object.defineProperty(exports, 'ListItem', {
2209
+ enumerable: true,
2210
+ get: function () {
2211
+ return ListItem;
2212
+ }
2213
+ });
2214
+ Object.defineProperty(exports, 'MaxNesting', {
2215
+ enumerable: true,
2216
+ get: function () {
2217
+ return MaxNesting;
2218
+ }
2219
+ });
2220
+ Object.defineProperty(exports, 'OrderedList', {
2221
+ enumerable: true,
2222
+ get: function () {
2223
+ return OrderedList;
2224
+ }
2225
+ });
2226
+ Object.defineProperty(exports, 'Paragraph', {
2227
+ enumerable: true,
2228
+ get: function () {
2229
+ return Paragraph;
2230
+ }
2231
+ });
2232
+ Object.defineProperty(exports, 'Placeholder', {
2233
+ enumerable: true,
2234
+ get: function () {
2235
+ return Placeholder;
2236
+ }
2237
+ });
2238
+ Object.defineProperty(exports, 'PreservedStyle', {
2239
+ enumerable: true,
2240
+ get: function () {
2241
+ return PreservedStyle;
2242
+ }
2243
+ });
2244
+ Object.defineProperty(exports, 'PreviewText', {
2245
+ enumerable: true,
2246
+ get: function () {
2247
+ return PreviewText;
2248
+ }
2249
+ });
2250
+ Object.defineProperty(exports, 'Section', {
2251
+ enumerable: true,
2252
+ get: function () {
2253
+ return Section$1;
2254
+ }
2255
+ });
2256
+ Object.defineProperty(exports, 'StarterKit', {
2257
+ enumerable: true,
2258
+ get: function () {
2259
+ return StarterKit;
2260
+ }
2261
+ });
2262
+ Object.defineProperty(exports, 'Strike', {
2263
+ enumerable: true,
2264
+ get: function () {
2265
+ return Strike;
2266
+ }
2267
+ });
2268
+ Object.defineProperty(exports, 'StyleAttribute', {
2269
+ enumerable: true,
2270
+ get: function () {
2271
+ return StyleAttribute;
2272
+ }
2273
+ });
2274
+ Object.defineProperty(exports, 'Sup', {
2275
+ enumerable: true,
2276
+ get: function () {
2277
+ return Sup;
2278
+ }
2279
+ });
2280
+ Object.defineProperty(exports, 'Table', {
2281
+ enumerable: true,
2282
+ get: function () {
2283
+ return Table;
2284
+ }
2285
+ });
2286
+ Object.defineProperty(exports, 'TableCell', {
2287
+ enumerable: true,
2288
+ get: function () {
2289
+ return TableCell;
2290
+ }
2291
+ });
2292
+ Object.defineProperty(exports, 'TableHeader', {
2293
+ enumerable: true,
2294
+ get: function () {
2295
+ return TableHeader;
2296
+ }
2297
+ });
2298
+ Object.defineProperty(exports, 'TableRow', {
2299
+ enumerable: true,
2300
+ get: function () {
2301
+ return TableRow;
2302
+ }
2303
+ });
2304
+ Object.defineProperty(exports, 'Text', {
2305
+ enumerable: true,
2306
+ get: function () {
2307
+ return Text;
2308
+ }
2309
+ });
2310
+ Object.defineProperty(exports, 'TrailingNode', {
2311
+ enumerable: true,
2312
+ get: function () {
2313
+ return TrailingNode;
2314
+ }
2315
+ });
2316
+ Object.defineProperty(exports, 'Underline', {
2317
+ enumerable: true,
2318
+ get: function () {
2319
+ return Underline;
2320
+ }
2321
+ });
2322
+ Object.defineProperty(exports, 'Uppercase', {
2323
+ enumerable: true,
2324
+ get: function () {
2325
+ return Uppercase;
2326
+ }
2327
+ });
2328
+ Object.defineProperty(exports, 'composeReactEmail', {
2329
+ enumerable: true,
2330
+ get: function () {
2331
+ return composeReactEmail;
2332
+ }
2333
+ });
2334
+ Object.defineProperty(exports, 'createDropHandler', {
2335
+ enumerable: true,
2336
+ get: function () {
2337
+ return createDropHandler;
2338
+ }
2339
+ });
2340
+ Object.defineProperty(exports, 'createPasteHandler', {
2341
+ enumerable: true,
2342
+ get: function () {
2343
+ return createPasteHandler;
2344
+ }
2345
+ });
2346
+ Object.defineProperty(exports, 'isDocumentVisuallyEmpty', {
2347
+ enumerable: true,
2348
+ get: function () {
2349
+ return isDocumentVisuallyEmpty;
2350
+ }
2351
+ });
2352
+ Object.defineProperty(exports, 'processStylesForUnlink', {
2353
+ enumerable: true,
2354
+ get: function () {
2355
+ return processStylesForUnlink;
2356
+ }
2357
+ });
2358
+ Object.defineProperty(exports, 'skipTrailingNodeMeta', {
2359
+ enumerable: true,
2360
+ get: function () {
2361
+ return skipTrailingNodeMeta;
2362
+ }
2363
+ });
2364
+ Object.defineProperty(exports, 'useEditor', {
2365
+ enumerable: true,
2366
+ get: function () {
2367
+ return useEditor;
2368
+ }
2369
+ });