@lupinum/nuxt-email 0.1.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.
Files changed (159) hide show
  1. package/CHANGELOG.md +49 -0
  2. package/LICENSE +21 -0
  3. package/README.md +172 -0
  4. package/THIRD_PARTY_NOTICES +75 -0
  5. package/dist/chunks/setup.mjs +149 -0
  6. package/dist/module.d.mts +15 -0
  7. package/dist/module.json +12 -0
  8. package/dist/module.mjs +300 -0
  9. package/dist/runtime/code-block/create-component.d.ts +16 -0
  10. package/dist/runtime/code-block/create-component.js +106 -0
  11. package/dist/runtime/components/EBody.d.ts +4 -0
  12. package/dist/runtime/components/EBody.js +75 -0
  13. package/dist/runtime/components/EButton.d.ts +11 -0
  14. package/dist/runtime/components/EButton.js +89 -0
  15. package/dist/runtime/components/EButton.padding.d.ts +12 -0
  16. package/dist/runtime/components/EButton.padding.js +118 -0
  17. package/dist/runtime/components/ECodeInline.d.ts +13 -0
  18. package/dist/runtime/components/ECodeInline.js +43 -0
  19. package/dist/runtime/components/EColumn.d.ts +4 -0
  20. package/dist/runtime/components/EColumn.js +12 -0
  21. package/dist/runtime/components/EContainer.d.ts +4 -0
  22. package/dist/runtime/components/EContainer.js +35 -0
  23. package/dist/runtime/components/EFont.d.ts +24 -0
  24. package/dist/runtime/components/EFont.js +124 -0
  25. package/dist/runtime/components/EHead.d.ts +4 -0
  26. package/dist/runtime/components/EHead.js +17 -0
  27. package/dist/runtime/components/EHeading.d.ts +7 -0
  28. package/dist/runtime/components/EHeading.js +23 -0
  29. package/dist/runtime/components/EHr.d.ts +4 -0
  30. package/dist/runtime/components/EHr.js +26 -0
  31. package/dist/runtime/components/EHtml.d.ts +4 -0
  32. package/dist/runtime/components/EHtml.js +17 -0
  33. package/dist/runtime/components/EImg.d.ts +7 -0
  34. package/dist/runtime/components/EImg.js +44 -0
  35. package/dist/runtime/components/ELink.d.ts +6 -0
  36. package/dist/runtime/components/ELink.js +35 -0
  37. package/dist/runtime/components/EMarkdown.d.ts +8 -0
  38. package/dist/runtime/components/EMarkdown.js +64 -0
  39. package/dist/runtime/components/EPreview.d.ts +8 -0
  40. package/dist/runtime/components/EPreview.js +85 -0
  41. package/dist/runtime/components/ERow.d.ts +4 -0
  42. package/dist/runtime/components/ERow.js +53 -0
  43. package/dist/runtime/components/ESection.d.ts +4 -0
  44. package/dist/runtime/components/ESection.js +35 -0
  45. package/dist/runtime/components/ETailwind.d.ts +24 -0
  46. package/dist/runtime/components/ETailwind.js +49 -0
  47. package/dist/runtime/components/EText.d.ts +4 -0
  48. package/dist/runtime/components/EText.js +20 -0
  49. package/dist/runtime/components/EText.margins.d.ts +18 -0
  50. package/dist/runtime/components/EText.margins.js +81 -0
  51. package/dist/runtime/components/attributes.d.ts +4 -0
  52. package/dist/runtime/components/attributes.js +11 -0
  53. package/dist/runtime/components/email-component-names.d.ts +2 -0
  54. package/dist/runtime/components/email-component-names.js +20 -0
  55. package/dist/runtime/components/email-component-registry.d.ts +8 -0
  56. package/dist/runtime/components/email-component-registry.js +2 -0
  57. package/dist/runtime/components/index.d.ts +23 -0
  58. package/dist/runtime/components/index.js +18 -0
  59. package/dist/runtime/components/markdown/parse-css-in-js-to-inline-css.d.ts +2 -0
  60. package/dist/runtime/components/markdown/parse-css-in-js-to-inline-css.js +60 -0
  61. package/dist/runtime/components/markdown/render-markdown.d.ts +2 -0
  62. package/dist/runtime/components/markdown/render-markdown.js +137 -0
  63. package/dist/runtime/components/markdown/styles.d.ts +30 -0
  64. package/dist/runtime/components/markdown/styles.js +91 -0
  65. package/dist/runtime/components/presentation-table.d.ts +7 -0
  66. package/dist/runtime/components/presentation-table.js +11 -0
  67. package/dist/runtime/components/style.d.ts +5 -0
  68. package/dist/runtime/components/style.js +32 -0
  69. package/dist/runtime/components/table-padding.d.ts +6 -0
  70. package/dist/runtime/components/table-padding.js +20 -0
  71. package/dist/runtime/define-email.d.ts +2 -0
  72. package/dist/runtime/define-email.js +5 -0
  73. package/dist/runtime/dev-preview/page-script.d.ts +1 -0
  74. package/dist/runtime/dev-preview/page-script.js +403 -0
  75. package/dist/runtime/dev-preview/page.css.d.ts +1 -0
  76. package/dist/runtime/dev-preview/page.css.js +602 -0
  77. package/dist/runtime/dev-preview/page.get.d.ts +4 -0
  78. package/dist/runtime/dev-preview/page.get.js +119 -0
  79. package/dist/runtime/dev-preview/render.get.d.ts +3 -0
  80. package/dist/runtime/dev-preview/render.get.js +123 -0
  81. package/dist/runtime/dev-preview/templates.get.d.ts +7 -0
  82. package/dist/runtime/dev-preview/templates.get.js +14 -0
  83. package/dist/runtime/errors.d.ts +4 -0
  84. package/dist/runtime/errors.js +7 -0
  85. package/dist/runtime/render/define-email.d.ts +56 -0
  86. package/dist/runtime/render/define-email.js +40 -0
  87. package/dist/runtime/render/document.d.ts +4 -0
  88. package/dist/runtime/render/document.js +75 -0
  89. package/dist/runtime/render/errors.d.ts +4 -0
  90. package/dist/runtime/render/errors.js +8 -0
  91. package/dist/runtime/render/plain-text.d.ts +1 -0
  92. package/dist/runtime/render/plain-text.js +15 -0
  93. package/dist/runtime/render/render-component.d.ts +4 -0
  94. package/dist/runtime/render/render-component.js +46 -0
  95. package/dist/runtime/render/render-email-component.d.ts +16 -0
  96. package/dist/runtime/render/render-email-component.js +46 -0
  97. package/dist/runtime/render/types.d.ts +9 -0
  98. package/dist/runtime/render/types.js +0 -0
  99. package/dist/runtime/tailwind/engine/compatibility/escape-class-name.d.ts +8 -0
  100. package/dist/runtime/tailwind/engine/compatibility/escape-class-name.js +10 -0
  101. package/dist/runtime/tailwind/engine/compatibility/sanitize-class-name.d.ts +7 -0
  102. package/dist/runtime/tailwind/engine/compatibility/sanitize-class-name.js +17 -0
  103. package/dist/runtime/tailwind/engine/compatibility/unescape-class.d.ts +1 -0
  104. package/dist/runtime/tailwind/engine/compatibility/unescape-class.js +3 -0
  105. package/dist/runtime/tailwind/engine/css/downlevel-for-email-clients.d.ts +63 -0
  106. package/dist/runtime/tailwind/engine/css/downlevel-for-email-clients.js +107 -0
  107. package/dist/runtime/tailwind/engine/css/extract-rules-per-class.d.ts +6 -0
  108. package/dist/runtime/tailwind/engine/css/extract-rules-per-class.js +54 -0
  109. package/dist/runtime/tailwind/engine/css/get-css-property.d.ts +17 -0
  110. package/dist/runtime/tailwind/engine/css/get-css-property.js +3 -0
  111. package/dist/runtime/tailwind/engine/css/get-custom-properties.d.ts +8 -0
  112. package/dist/runtime/tailwind/engine/css/get-custom-properties.js +37 -0
  113. package/dist/runtime/tailwind/engine/css/is-part-inlinable.d.ts +2 -0
  114. package/dist/runtime/tailwind/engine/css/is-part-inlinable.js +9 -0
  115. package/dist/runtime/tailwind/engine/css/is-rule-inlinable.d.ts +2 -0
  116. package/dist/runtime/tailwind/engine/css/is-rule-inlinable.js +9 -0
  117. package/dist/runtime/tailwind/engine/css/make-inline-styles-for.d.ts +21 -0
  118. package/dist/runtime/tailwind/engine/css/make-inline-styles-for.js +62 -0
  119. package/dist/runtime/tailwind/engine/css/resolve-all-css-variables.d.ts +8 -0
  120. package/dist/runtime/tailwind/engine/css/resolve-all-css-variables.js +138 -0
  121. package/dist/runtime/tailwind/engine/css/resolve-calc-expressions.d.ts +5 -0
  122. package/dist/runtime/tailwind/engine/css/resolve-calc-expressions.js +101 -0
  123. package/dist/runtime/tailwind/engine/css/sanitize-declarations.d.ts +15 -0
  124. package/dist/runtime/tailwind/engine/css/sanitize-declarations.js +358 -0
  125. package/dist/runtime/tailwind/engine/css/sanitize-non-inlinable-rules.d.ts +17 -0
  126. package/dist/runtime/tailwind/engine/css/sanitize-non-inlinable-rules.js +30 -0
  127. package/dist/runtime/tailwind/engine/css/split-mixed-rule.d.ts +12 -0
  128. package/dist/runtime/tailwind/engine/css/split-mixed-rule.js +37 -0
  129. package/dist/runtime/tailwind/engine/css/strip-empty-tailwind-vars.d.ts +19 -0
  130. package/dist/runtime/tailwind/engine/css/strip-empty-tailwind-vars.js +44 -0
  131. package/dist/runtime/tailwind/engine/css/unwrap-value.d.ts +2 -0
  132. package/dist/runtime/tailwind/engine/css/unwrap-value.js +6 -0
  133. package/dist/runtime/tailwind/engine/index.d.ts +63 -0
  134. package/dist/runtime/tailwind/engine/index.js +53 -0
  135. package/dist/runtime/tailwind/engine/pixel-based-preset.d.ts +9 -0
  136. package/dist/runtime/tailwind/engine/pixel-based-preset.js +58 -0
  137. package/dist/runtime/tailwind/engine/sanitize-stylesheet.d.ts +10 -0
  138. package/dist/runtime/tailwind/engine/sanitize-stylesheet.js +8 -0
  139. package/dist/runtime/tailwind/engine/setup-tailwind.d.ts +23 -0
  140. package/dist/runtime/tailwind/engine/setup-tailwind.js +98 -0
  141. package/dist/runtime/tailwind/engine/stylesheets.d.ts +4 -0
  142. package/dist/runtime/tailwind/engine/stylesheets.js +1756 -0
  143. package/dist/runtime/tailwind/engine/types.d.ts +25 -0
  144. package/dist/runtime/tailwind/engine/types.js +0 -0
  145. package/dist/runtime/tailwind/errors.d.ts +7 -0
  146. package/dist/runtime/tailwind/errors.js +9 -0
  147. package/dist/runtime/tailwind/inline-utils.d.ts +19 -0
  148. package/dist/runtime/tailwind/inline-utils.js +24 -0
  149. package/dist/runtime/tailwind/nested.d.ts +59 -0
  150. package/dist/runtime/tailwind/nested.js +47 -0
  151. package/dist/runtime/tailwind/post-render.d.ts +7 -0
  152. package/dist/runtime/tailwind/post-render.js +156 -0
  153. package/dist/runtime/template-registry/errors.d.ts +5 -0
  154. package/dist/runtime/template-registry/errors.js +11 -0
  155. package/dist/runtime/template-registry/registry.d.ts +13 -0
  156. package/dist/runtime/testing/index.d.ts +13 -0
  157. package/dist/runtime/testing/index.js +2 -0
  158. package/dist/types.d.mts +5 -0
  159. package/package.json +122 -0
@@ -0,0 +1,8 @@
1
+ import type { DefineComponent, HTMLAttributes, VNodeChild } from 'vue';
2
+ import type { SafeEmailAttributes } from './attributes.js';
3
+ export declare const PREVIEW_MAX_LENGTH = 200;
4
+ export declare const PREVIEW_WHITESPACE = "\u00A0\u200C\u200B\u200D\u200E\u200F\uFEFF";
5
+ export type EPreviewProps = SafeEmailAttributes<HTMLAttributes>;
6
+ export declare function previewText(children: VNodeChild): string;
7
+ export declare function previewWhitespace(text: string): string | undefined;
8
+ export declare const EPreview: DefineComponent<EPreviewProps>;
@@ -0,0 +1,85 @@
1
+ import { Comment, defineComponent, Fragment, h, isVNode, Text } from "vue";
2
+ import { assertSafeEmailAttributes } from "./attributes.js";
3
+ import { normalizeEmailStyle } from "./style.js";
4
+ export const PREVIEW_MAX_LENGTH = 200;
5
+ export const PREVIEW_WHITESPACE = "\xA0\u200C\u200B\u200D\u200E\u200F\uFEFF";
6
+ const DEFAULT_PREVIEW_STYLE = {
7
+ display: "none",
8
+ overflow: "hidden",
9
+ lineHeight: "1px",
10
+ opacity: 0,
11
+ maxHeight: 0,
12
+ maxWidth: 0
13
+ };
14
+ const PREVIEW_READ_LIMIT = PREVIEW_MAX_LENGTH + 1;
15
+ function appendPreviewText(child, text) {
16
+ if (text.value.length >= PREVIEW_READ_LIMIT) {
17
+ return;
18
+ }
19
+ if (child === null || child === void 0 || typeof child === "boolean") {
20
+ return;
21
+ }
22
+ if (typeof child === "string" || typeof child === "number") {
23
+ const remainingLength = PREVIEW_READ_LIMIT - text.value.length;
24
+ text.value += String(child).substring(0, remainingLength);
25
+ return;
26
+ }
27
+ if (Array.isArray(child)) {
28
+ for (const nestedChild of child) {
29
+ appendPreviewText(nestedChild, text);
30
+ if (text.value.length >= PREVIEW_READ_LIMIT) {
31
+ break;
32
+ }
33
+ }
34
+ return;
35
+ }
36
+ if (!isVNode(child)) {
37
+ throw new TypeError("EPreview default slot must contain text only");
38
+ }
39
+ if (child.type === Comment) {
40
+ return;
41
+ }
42
+ if (child.type === Text) {
43
+ appendPreviewText(child.children, text);
44
+ return;
45
+ }
46
+ if (child.type === Fragment && Array.isArray(child.children)) {
47
+ appendPreviewText(child.children, text);
48
+ return;
49
+ }
50
+ throw new TypeError("EPreview default slot must contain text only");
51
+ }
52
+ export function previewText(children) {
53
+ const text = { value: "" };
54
+ appendPreviewText(children, text);
55
+ const truncated = text.value.substring(0, PREVIEW_MAX_LENGTH);
56
+ const finalCodeUnit = truncated.charCodeAt(truncated.length - 1);
57
+ return finalCodeUnit >= 55296 && finalCodeUnit <= 56319 ? truncated.slice(0, -1) : truncated;
58
+ }
59
+ export function previewWhitespace(text) {
60
+ if (text.length >= PREVIEW_MAX_LENGTH) {
61
+ return void 0;
62
+ }
63
+ return PREVIEW_WHITESPACE.repeat(PREVIEW_MAX_LENGTH - text.length);
64
+ }
65
+ export const EPreview = defineComponent({
66
+ name: "EPreview",
67
+ inheritAttrs: false,
68
+ setup(_props, { attrs, slots }) {
69
+ return () => {
70
+ assertSafeEmailAttributes("EPreview", attrs);
71
+ const text = previewText(slots.default?.() ?? []);
72
+ const filler = previewWhitespace(text);
73
+ const { style, ...attributes } = attrs;
74
+ delete attributes["data-skip-in-text"];
75
+ return h("div", {
76
+ "style": { ...normalizeEmailStyle(style), ...DEFAULT_PREVIEW_STYLE },
77
+ "data-skip-in-text": "true",
78
+ ...attributes
79
+ }, [
80
+ text,
81
+ ...filler === void 0 ? [] : [h("div", filler)]
82
+ ]);
83
+ };
84
+ }
85
+ });
@@ -0,0 +1,4 @@
1
+ import type { DefineComponent, TableHTMLAttributes } from 'vue';
2
+ import type { SafeEmailAttributes } from './attributes.js';
3
+ export type ERowProps = Omit<SafeEmailAttributes<TableHTMLAttributes>, 'border' | 'cellpadding' | 'cellspacing' | 'role'>;
4
+ export declare const ERow: DefineComponent<ERowProps>;
@@ -0,0 +1,53 @@
1
+ import { defineComponent, h, inject } from "vue";
2
+ import { resolveNestedTailwindStyle, TAILWIND_NESTED_KEY } from "../tailwind/nested.js";
3
+ import { assertSafeEmailAttributes } from "./attributes.js";
4
+ import { assertFixedPresentationTable } from "./presentation-table.js";
5
+ import { splitTablePadding } from "./table-padding.js";
6
+ export const ERow = defineComponent({
7
+ name: "ERow",
8
+ inheritAttrs: false,
9
+ setup(_props, { attrs, slots }) {
10
+ const holder = inject(TAILWIND_NESTED_KEY, null);
11
+ return () => {
12
+ assertSafeEmailAttributes("ERow", attrs);
13
+ assertFixedPresentationTable("ERow", attrs);
14
+ const { style, ...attributes } = attrs;
15
+ const effectiveStyle = resolveNestedTailwindStyle(holder, attributes, style).style;
16
+ const { tableStyle, cellStyle } = splitTablePadding(effectiveStyle);
17
+ const tableAttributes = {
18
+ align: "center",
19
+ width: "100%",
20
+ border: 0,
21
+ cellpadding: "0",
22
+ cellspacing: "0",
23
+ role: "presentation",
24
+ ...attributes,
25
+ ...Object.keys(tableStyle).length > 0 ? { style: tableStyle } : {}
26
+ };
27
+ const rowContent = [
28
+ h("tbody", { style: { width: "100%" } }, [
29
+ h("tr", { style: { width: "100%" } }, slots.default?.())
30
+ ])
31
+ ];
32
+ if (Object.keys(cellStyle).length === 0) {
33
+ return h("table", tableAttributes, rowContent);
34
+ }
35
+ return h("table", tableAttributes, [
36
+ h("tbody", [
37
+ h("tr", [
38
+ h("td", { style: cellStyle }, [
39
+ h("table", {
40
+ align: "center",
41
+ width: "100%",
42
+ border: 0,
43
+ cellpadding: "0",
44
+ cellspacing: "0",
45
+ role: "presentation"
46
+ }, rowContent)
47
+ ])
48
+ ])
49
+ ])
50
+ ]);
51
+ };
52
+ }
53
+ });
@@ -0,0 +1,4 @@
1
+ import type { DefineComponent, TableHTMLAttributes } from 'vue';
2
+ import type { SafeEmailAttributes } from './attributes.js';
3
+ export type ESectionProps = Omit<SafeEmailAttributes<TableHTMLAttributes>, 'border' | 'cellpadding' | 'cellspacing' | 'role'>;
4
+ export declare const ESection: DefineComponent<ESectionProps>;
@@ -0,0 +1,35 @@
1
+ import { defineComponent, h, inject } from "vue";
2
+ import { resolveNestedTailwindStyle, TAILWIND_NESTED_KEY } from "../tailwind/nested.js";
3
+ import { assertSafeEmailAttributes } from "./attributes.js";
4
+ import { assertFixedPresentationTable } from "./presentation-table.js";
5
+ import { splitTablePadding } from "./table-padding.js";
6
+ export const ESection = defineComponent({
7
+ name: "ESection",
8
+ inheritAttrs: false,
9
+ setup(_props, { attrs, slots }) {
10
+ const holder = inject(TAILWIND_NESTED_KEY, null);
11
+ return () => {
12
+ assertSafeEmailAttributes("ESection", attrs);
13
+ assertFixedPresentationTable("ESection", attrs);
14
+ const { style, ...attributes } = attrs;
15
+ const effectiveStyle = resolveNestedTailwindStyle(holder, attributes, style).style;
16
+ const { tableStyle, cellStyle } = splitTablePadding(effectiveStyle);
17
+ return h("table", {
18
+ align: "center",
19
+ width: "100%",
20
+ border: 0,
21
+ cellpadding: "0",
22
+ cellspacing: "0",
23
+ role: "presentation",
24
+ ...attributes,
25
+ ...Object.keys(tableStyle).length > 0 ? { style: tableStyle } : {}
26
+ }, [
27
+ h("tbody", [
28
+ h("tr", [
29
+ h("td", Object.keys(cellStyle).length > 0 ? { style: cellStyle } : {}, slots.default?.())
30
+ ])
31
+ ])
32
+ ]);
33
+ };
34
+ }
35
+ });
@@ -0,0 +1,24 @@
1
+ import type { TailwindConfig } from '../tailwind/engine/index.js';
2
+ import type { DefineComponent } from 'vue';
3
+ export interface ETailwindProps {
4
+ /** Tailwind config (everything except `content`), same shape as React Email. */
5
+ config?: TailwindConfig;
6
+ /** Raw CSS appended to the theme layer (`@theme`), same as React Email's `theme`. */
7
+ theme?: string;
8
+ /** Raw CSS appended to the utilities layer, same as React Email's `utility`. */
9
+ utility?: string;
10
+ }
11
+ /**
12
+ * Server-only Tailwind boundary. Faithful behavioural port of React Email's
13
+ * `<Tailwind>`: it compiles the Tailwind stylesheet for its config, then inlines
14
+ * the utilities used by its subtree into each element's style, moves media-query
15
+ * and pseudo-class rules into a `<style>` in the `<head>`, and rewrites residual
16
+ * class names.
17
+ *
18
+ * E* primitives self-inline through the context provided here
19
+ * ({@link TAILWIND_NESTED_KEY}). Once Vue has rendered the subtree exactly once,
20
+ * the marker-scoped post-render pass ({@link ../tailwind/post-render}) handles
21
+ * structural and native elements and inserts non-inlinable CSS into `<head>`.
22
+ * Nothing outside an `<ETailwind>` boundary is affected.
23
+ */
24
+ export declare const ETailwind: DefineComponent<ETailwindProps>;
@@ -0,0 +1,49 @@
1
+ import { createCommentVNode, defineComponent, inject, provide } from "vue";
2
+ import { getEmailRenderContext } from "../render/define-email.js";
3
+ import { createTailwindEngine } from "../tailwind/engine/index.js";
4
+ import { createTailwindRegion, TAILWIND_NESTED_KEY } from "../tailwind/nested.js";
5
+ export const ETailwind = defineComponent({
6
+ name: "ETailwind",
7
+ inheritAttrs: false,
8
+ props: {
9
+ config: {
10
+ type: Object,
11
+ default: void 0
12
+ },
13
+ theme: {
14
+ type: String,
15
+ default: void 0
16
+ },
17
+ utility: {
18
+ type: String,
19
+ default: void 0
20
+ }
21
+ },
22
+ async setup(props, { slots }) {
23
+ if (inject(TAILWIND_NESTED_KEY, null)) {
24
+ throw new TypeError("ETailwind boundaries cannot be nested; wrap the email document in one ETailwind boundary.");
25
+ }
26
+ const holder = { engine: null, region: null };
27
+ provide(TAILWIND_NESTED_KEY, holder);
28
+ const engine = await createTailwindEngine({
29
+ config: props.config,
30
+ theme: props.theme,
31
+ utility: props.utility
32
+ });
33
+ holder.engine = engine;
34
+ return () => {
35
+ const children = slots.default?.() ?? [];
36
+ const region = createTailwindRegion(engine, []);
37
+ holder.region = region;
38
+ const context = getEmailRenderContext();
39
+ if (context) {
40
+ (context.tailwindRegions ??= []).push(region);
41
+ }
42
+ return [
43
+ createCommentVNode(region.startMarker),
44
+ ...children,
45
+ createCommentVNode(region.endMarker)
46
+ ];
47
+ };
48
+ }
49
+ });
@@ -0,0 +1,4 @@
1
+ import type { DefineComponent, HTMLAttributes } from 'vue';
2
+ import type { SafeEmailAttributes } from './attributes.js';
3
+ export type ETextProps = SafeEmailAttributes<HTMLAttributes>;
4
+ export declare const EText: DefineComponent<ETextProps>;
@@ -0,0 +1,20 @@
1
+ import { defineComponent, h, inject } from "vue";
2
+ import { resolveNestedTailwindStyle, TAILWIND_NESTED_KEY } from "../tailwind/nested.js";
3
+ import { assertSafeEmailAttributes } from "./attributes.js";
4
+ import { textStyle } from "./EText.margins.js";
5
+ export const EText = defineComponent({
6
+ name: "EText",
7
+ inheritAttrs: false,
8
+ setup(_props, { attrs, slots }) {
9
+ const holder = inject(TAILWIND_NESTED_KEY, null);
10
+ return () => {
11
+ assertSafeEmailAttributes("EText", attrs);
12
+ const { style, ...attributes } = attrs;
13
+ const effectiveStyle = resolveNestedTailwindStyle(holder, attributes, style).style;
14
+ return h("p", {
15
+ ...attributes,
16
+ style: textStyle(effectiveStyle)
17
+ }, slots.default?.());
18
+ };
19
+ }
20
+ });
@@ -0,0 +1,18 @@
1
+ import type { EmailStyle } from './style.js';
2
+ type MarginValue = string | number | undefined;
3
+ export interface MarginProperties {
4
+ margin?: MarginValue;
5
+ marginTop?: MarginValue;
6
+ marginRight?: MarginValue;
7
+ marginBottom?: MarginValue;
8
+ marginLeft?: MarginValue;
9
+ }
10
+ export interface ComputedMargins {
11
+ marginTop: MarginValue;
12
+ marginRight: MarginValue;
13
+ marginBottom: MarginValue;
14
+ marginLeft: MarginValue;
15
+ }
16
+ export declare function computeTextMargins(properties: MarginProperties): ComputedMargins;
17
+ export declare function textStyle(style: unknown): EmailStyle;
18
+ export {};
@@ -0,0 +1,81 @@
1
+ import { normalizeEmailStyle } from "./style.js";
2
+ function parseMargin(value) {
3
+ const empty = {
4
+ marginTop: void 0,
5
+ marginRight: void 0,
6
+ marginBottom: void 0,
7
+ marginLeft: void 0
8
+ };
9
+ if (typeof value === "number") {
10
+ return {
11
+ marginTop: value,
12
+ marginBottom: value,
13
+ marginLeft: value,
14
+ marginRight: value
15
+ };
16
+ }
17
+ if (typeof value !== "string") {
18
+ return empty;
19
+ }
20
+ const values = value.trim().split(/\s+/);
21
+ if (values.length === 1) {
22
+ return {
23
+ marginTop: values[0],
24
+ marginBottom: values[0],
25
+ marginLeft: values[0],
26
+ marginRight: values[0]
27
+ };
28
+ }
29
+ if (values.length === 2) {
30
+ return {
31
+ marginTop: values[0],
32
+ marginBottom: values[0],
33
+ marginLeft: values[1],
34
+ marginRight: values[1]
35
+ };
36
+ }
37
+ if (values.length === 3) {
38
+ return {
39
+ marginTop: values[0],
40
+ marginBottom: values[2],
41
+ marginLeft: values[1],
42
+ marginRight: values[1]
43
+ };
44
+ }
45
+ if (values.length === 4) {
46
+ return {
47
+ marginTop: values[0],
48
+ marginBottom: values[2],
49
+ marginLeft: values[3],
50
+ marginRight: values[1]
51
+ };
52
+ }
53
+ return empty;
54
+ }
55
+ export function computeTextMargins(properties) {
56
+ let result = parseMargin(void 0);
57
+ for (const [property, value] of Object.entries(properties)) {
58
+ if (property === "margin") {
59
+ result = parseMargin(value);
60
+ } else if (property === "marginTop" || property === "marginRight" || property === "marginBottom" || property === "marginLeft") {
61
+ result[property] = value;
62
+ }
63
+ }
64
+ return result;
65
+ }
66
+ export function textStyle(style) {
67
+ const emailStyle = normalizeEmailStyle(style) ?? {};
68
+ const defaults = {};
69
+ if (emailStyle.marginTop === void 0) {
70
+ defaults.marginTop = "16px";
71
+ }
72
+ if (emailStyle.marginBottom === void 0) {
73
+ defaults.marginBottom = "16px";
74
+ }
75
+ return {
76
+ fontSize: "14px",
77
+ lineHeight: "24px",
78
+ ...emailStyle,
79
+ ...computeTextMargins({ ...defaults, ...emailStyle })
80
+ };
81
+ }
@@ -0,0 +1,4 @@
1
+ export type SafeEmailAttributes<Attributes> = {
2
+ [Key in keyof Attributes as Key extends 'innerHTML' | 'textContent' ? never : Key extends `on${string}` ? never : Key]: Attributes[Key];
3
+ };
4
+ export declare function assertSafeEmailAttributes(componentName: string, attributes: Readonly<Record<string, unknown>>): void;
@@ -0,0 +1,11 @@
1
+ const CONTENT_ATTRIBUTES = /* @__PURE__ */ new Set(["innerHTML", "textContent"]);
2
+ export function assertSafeEmailAttributes(componentName, attributes) {
3
+ const unsafeAttributes = Object.keys(attributes).filter((name) => {
4
+ return CONTENT_ATTRIBUTES.has(name) || name.length > 2 && name.slice(0, 2).toLowerCase() === "on";
5
+ });
6
+ if (unsafeAttributes.length > 0) {
7
+ throw new TypeError(
8
+ `${componentName} does not support unsafe HTML attribute${unsafeAttributes.length === 1 ? "" : "s"}: ${unsafeAttributes.join(", ")}`
9
+ );
10
+ }
11
+ }
@@ -0,0 +1,2 @@
1
+ export declare const EMAIL_COMPONENT_NAMES: readonly ["EBody", "EButton", "ECodeInline", "EColumn", "EContainer", "EFont", "EHead", "EHeading", "EHr", "EHtml", "EImg", "ELink", "EMarkdown", "EPreview", "ERow", "ESection", "ETailwind", "EText"];
2
+ export type EmailComponentName = typeof EMAIL_COMPONENT_NAMES[number];
@@ -0,0 +1,20 @@
1
+ export const EMAIL_COMPONENT_NAMES = [
2
+ "EBody",
3
+ "EButton",
4
+ "ECodeInline",
5
+ "EColumn",
6
+ "EContainer",
7
+ "EFont",
8
+ "EHead",
9
+ "EHeading",
10
+ "EHr",
11
+ "EHtml",
12
+ "EImg",
13
+ "ELink",
14
+ "EMarkdown",
15
+ "EPreview",
16
+ "ERow",
17
+ "ESection",
18
+ "ETailwind",
19
+ "EText"
20
+ ];
@@ -0,0 +1,8 @@
1
+ import type { Component } from 'vue';
2
+ import type { EmailComponentName } from './email-component-names.js';
3
+ import * as emailComponents from './index.js';
4
+ type MissingComponent = Exclude<EmailComponentName, keyof typeof emailComponents>;
5
+ type UnexpectedComponent = Exclude<keyof typeof emailComponents, EmailComponentName>;
6
+ type ExactComponentRegistry = [MissingComponent, UnexpectedComponent] extends [never, never] ? Readonly<Record<EmailComponentName, Component>> : never;
7
+ export declare const emailComponentRegistry: ExactComponentRegistry;
8
+ export {};
@@ -0,0 +1,2 @@
1
+ import * as emailComponents from "./index.js";
2
+ export const emailComponentRegistry = Object.freeze({ ...emailComponents });
@@ -0,0 +1,23 @@
1
+ export { EBody } from './EBody.js';
2
+ export { EButton } from './EButton.js';
3
+ export { ECodeInline } from './ECodeInline.js';
4
+ export { EColumn } from './EColumn.js';
5
+ export { EContainer } from './EContainer.js';
6
+ export { EFont } from './EFont.js';
7
+ export { EHead } from './EHead.js';
8
+ export { EHeading } from './EHeading.js';
9
+ export { EHr } from './EHr.js';
10
+ export { EHtml } from './EHtml.js';
11
+ export { EImg } from './EImg.js';
12
+ export { ELink } from './ELink.js';
13
+ export { EMarkdown } from './EMarkdown.js';
14
+ export { EPreview } from './EPreview.js';
15
+ export { ERow } from './ERow.js';
16
+ export { ESection } from './ESection.js';
17
+ export { ETailwind } from './ETailwind.js';
18
+ export { EText } from './EText.js';
19
+ export type { ECodeInlineProps } from './ECodeInline.js';
20
+ export type { EFontProps, FontFallback, FontFallbackList, FontFormat, FontStyle, FontWebFont, FontWeight, } from './EFont.js';
21
+ export type { EMarkdownProps } from './EMarkdown.js';
22
+ export type { ETailwindProps } from './ETailwind.js';
23
+ export type { TailwindConfig } from '../tailwind/engine/index.js';
@@ -0,0 +1,18 @@
1
+ export { EBody } from "./EBody.js";
2
+ export { EButton } from "./EButton.js";
3
+ export { ECodeInline } from "./ECodeInline.js";
4
+ export { EColumn } from "./EColumn.js";
5
+ export { EContainer } from "./EContainer.js";
6
+ export { EFont } from "./EFont.js";
7
+ export { EHead } from "./EHead.js";
8
+ export { EHeading } from "./EHeading.js";
9
+ export { EHr } from "./EHr.js";
10
+ export { EHtml } from "./EHtml.js";
11
+ export { EImg } from "./EImg.js";
12
+ export { ELink } from "./ELink.js";
13
+ export { EMarkdown } from "./EMarkdown.js";
14
+ export { EPreview } from "./EPreview.js";
15
+ export { ERow } from "./ERow.js";
16
+ export { ESection } from "./ESection.js";
17
+ export { ETailwind } from "./ETailwind.js";
18
+ export { EText } from "./EText.js";
@@ -0,0 +1,2 @@
1
+ export type MarkdownStyle = Record<string, string | number | undefined>;
2
+ export declare function parseCssInJsToInlineCss(cssProperties: MarkdownStyle | undefined): string;
@@ -0,0 +1,60 @@
1
+ function camelToKebabCase(str) {
2
+ return str.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase();
3
+ }
4
+ function escapeQuotes(value) {
5
+ if (typeof value === "string" && value.includes('"')) {
6
+ return value.replace(/"/g, "&quot;");
7
+ }
8
+ return String(value);
9
+ }
10
+ const NUMERICAL_CSS_PROPERTIES = /* @__PURE__ */ new Set([
11
+ "width",
12
+ "height",
13
+ "margin",
14
+ "marginTop",
15
+ "marginRight",
16
+ "marginBottom",
17
+ "marginLeft",
18
+ "padding",
19
+ "paddingTop",
20
+ "paddingRight",
21
+ "paddingBottom",
22
+ "paddingLeft",
23
+ "borderWidth",
24
+ "borderTopWidth",
25
+ "borderRightWidth",
26
+ "borderBottomWidth",
27
+ "borderLeftWidth",
28
+ "outlineWidth",
29
+ "top",
30
+ "right",
31
+ "bottom",
32
+ "left",
33
+ "fontSize",
34
+ "letterSpacing",
35
+ "wordSpacing",
36
+ "maxWidth",
37
+ "minWidth",
38
+ "maxHeight",
39
+ "minHeight",
40
+ "borderRadius",
41
+ "borderTopLeftRadius",
42
+ "borderTopRightRadius",
43
+ "borderBottomLeftRadius",
44
+ "borderBottomRightRadius",
45
+ "textIndent",
46
+ "gridColumnGap",
47
+ "gridRowGap",
48
+ "gridGap",
49
+ "translateX",
50
+ "translateY"
51
+ ]);
52
+ export function parseCssInJsToInlineCss(cssProperties) {
53
+ if (!cssProperties) return "";
54
+ return Object.entries(cssProperties).map(([property, value]) => {
55
+ if (typeof value === "number" && NUMERICAL_CSS_PROPERTIES.has(property)) {
56
+ return `${camelToKebabCase(property)}:${value}px`;
57
+ }
58
+ return `${camelToKebabCase(property)}:${escapeQuotes(value)}`;
59
+ }).join(";");
60
+ }
@@ -0,0 +1,2 @@
1
+ import type { StylesType } from './styles.js';
2
+ export declare function renderMarkdown(source: string, markdownCustomStyles?: StylesType): string;