@savvycal/mjml-editor 0.0.1 → 0.0.2

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 (173) hide show
  1. package/README.md +176 -0
  2. package/dist/components/editor/BlockIcon.d.ts +7 -0
  3. package/dist/components/editor/BlockIcon.d.ts.map +1 -0
  4. package/dist/components/editor/BlockInspector.d.ts +6 -0
  5. package/dist/components/editor/BlockInspector.d.ts.map +1 -0
  6. package/dist/components/editor/BlockInspector.js +380 -0
  7. package/dist/components/editor/EditorCanvas.d.ts +11 -0
  8. package/dist/components/editor/EditorCanvas.d.ts.map +1 -0
  9. package/dist/components/editor/EditorCanvas.js +116 -0
  10. package/dist/components/editor/FontEditor.d.ts +2 -0
  11. package/dist/components/editor/FontEditor.d.ts.map +1 -0
  12. package/dist/components/editor/FontEditor.js +227 -0
  13. package/dist/components/editor/GlobalStylesPanel.d.ts +7 -0
  14. package/dist/components/editor/GlobalStylesPanel.d.ts.map +1 -0
  15. package/dist/components/editor/GlobalStylesPanel.js +310 -0
  16. package/dist/components/editor/InteractivePreview.d.ts +8 -0
  17. package/dist/components/editor/InteractivePreview.d.ts.map +1 -0
  18. package/dist/components/editor/InteractivePreview.js +120 -0
  19. package/dist/components/editor/LiquidAutocomplete.d.ts +10 -0
  20. package/dist/components/editor/LiquidAutocomplete.d.ts.map +1 -0
  21. package/dist/components/editor/LiquidAutocomplete.js +70 -0
  22. package/dist/components/editor/LiquidInput.d.ts +12 -0
  23. package/dist/components/editor/LiquidInput.d.ts.map +1 -0
  24. package/dist/components/editor/LiquidInput.js +185 -0
  25. package/dist/components/editor/MjmlEditor.d.ts +11 -0
  26. package/dist/components/editor/MjmlEditor.d.ts.map +1 -0
  27. package/dist/components/editor/MjmlEditor.js +111 -0
  28. package/dist/components/editor/OutlineTree.d.ts +7 -0
  29. package/dist/components/editor/OutlineTree.d.ts.map +1 -0
  30. package/dist/components/editor/OutlineTree.js +282 -0
  31. package/dist/components/editor/SourceEditor.d.ts +2 -0
  32. package/dist/components/editor/SourceEditor.d.ts.map +1 -0
  33. package/dist/components/editor/SourceEditor.js +70 -0
  34. package/dist/components/editor/SourcePreview.d.ts +7 -0
  35. package/dist/components/editor/SourcePreview.d.ts.map +1 -0
  36. package/dist/components/editor/SourcePreview.js +55 -0
  37. package/dist/components/editor/TiptapEditor.d.ts +12 -0
  38. package/dist/components/editor/TiptapEditor.d.ts.map +1 -0
  39. package/dist/components/editor/TiptapEditor.js +330 -0
  40. package/dist/components/editor/VisualEditor.d.ts +7 -0
  41. package/dist/components/editor/VisualEditor.d.ts.map +1 -0
  42. package/dist/components/editor/VisualEditor.js +51 -0
  43. package/dist/components/editor/visual-blocks/VisualBlock.d.ts +7 -0
  44. package/dist/components/editor/visual-blocks/VisualBlock.d.ts.map +1 -0
  45. package/dist/components/editor/visual-blocks/VisualBlock.js +34 -0
  46. package/dist/components/editor/visual-blocks/VisualButton.d.ts +7 -0
  47. package/dist/components/editor/visual-blocks/VisualButton.d.ts.map +1 -0
  48. package/dist/components/editor/visual-blocks/VisualButton.js +111 -0
  49. package/dist/components/editor/visual-blocks/VisualColumn.d.ts +8 -0
  50. package/dist/components/editor/visual-blocks/VisualColumn.d.ts.map +1 -0
  51. package/dist/components/editor/visual-blocks/VisualColumn.js +44 -0
  52. package/dist/components/editor/visual-blocks/VisualDivider.d.ts +7 -0
  53. package/dist/components/editor/visual-blocks/VisualDivider.d.ts.map +1 -0
  54. package/dist/components/editor/visual-blocks/VisualDivider.js +41 -0
  55. package/dist/components/editor/visual-blocks/VisualImage.d.ts +7 -0
  56. package/dist/components/editor/visual-blocks/VisualImage.d.ts.map +1 -0
  57. package/dist/components/editor/visual-blocks/VisualImage.js +48 -0
  58. package/dist/components/editor/visual-blocks/VisualRaw.d.ts +7 -0
  59. package/dist/components/editor/visual-blocks/VisualRaw.d.ts.map +1 -0
  60. package/dist/components/editor/visual-blocks/VisualRaw.js +32 -0
  61. package/dist/components/editor/visual-blocks/VisualSection.d.ts +7 -0
  62. package/dist/components/editor/visual-blocks/VisualSection.d.ts.map +1 -0
  63. package/dist/components/editor/visual-blocks/VisualSection.js +131 -0
  64. package/dist/components/editor/visual-blocks/VisualSocial.d.ts +7 -0
  65. package/dist/components/editor/visual-blocks/VisualSocial.d.ts.map +1 -0
  66. package/dist/components/editor/visual-blocks/VisualSocial.js +62 -0
  67. package/dist/components/editor/visual-blocks/VisualSpacer.d.ts +7 -0
  68. package/dist/components/editor/visual-blocks/VisualSpacer.d.ts.map +1 -0
  69. package/dist/components/editor/visual-blocks/VisualSpacer.js +30 -0
  70. package/dist/components/editor/visual-blocks/VisualText.d.ts +7 -0
  71. package/dist/components/editor/visual-blocks/VisualText.d.ts.map +1 -0
  72. package/dist/components/editor/visual-blocks/VisualText.js +103 -0
  73. package/dist/components/editor/visual-blocks/helpers.d.ts +13 -0
  74. package/dist/components/editor/visual-blocks/helpers.d.ts.map +1 -0
  75. package/dist/components/editor/visual-blocks/helpers.js +44 -0
  76. package/dist/components/editor/visual-blocks/useResolvedAttributes.d.ts +7 -0
  77. package/dist/components/editor/visual-blocks/useResolvedAttributes.d.ts.map +1 -0
  78. package/dist/components/editor/visual-blocks/useResolvedAttributes.js +12 -0
  79. package/dist/components/ui/badge.d.ts +10 -0
  80. package/dist/components/ui/badge.d.ts.map +1 -0
  81. package/dist/components/ui/badge.js +26 -0
  82. package/dist/components/ui/button.d.ts +11 -0
  83. package/dist/components/ui/button.d.ts.map +1 -0
  84. package/dist/components/ui/button.js +54 -0
  85. package/dist/components/ui/card.d.ts +10 -0
  86. package/dist/components/ui/card.d.ts.map +1 -0
  87. package/dist/components/ui/collapsible.d.ts +6 -0
  88. package/dist/components/ui/collapsible.d.ts.map +1 -0
  89. package/dist/components/ui/collapsible.js +7 -0
  90. package/dist/components/ui/floating-panel.d.ts +12 -0
  91. package/dist/components/ui/floating-panel.d.ts.map +1 -0
  92. package/dist/components/ui/floating-panel.js +54 -0
  93. package/dist/components/ui/input.d.ts +4 -0
  94. package/dist/components/ui/input.d.ts.map +1 -0
  95. package/dist/components/ui/input.js +26 -0
  96. package/dist/components/ui/label.d.ts +5 -0
  97. package/dist/components/ui/label.d.ts.map +1 -0
  98. package/dist/components/ui/label.js +23 -0
  99. package/dist/components/ui/popover.d.ts +8 -0
  100. package/dist/components/ui/popover.d.ts.map +1 -0
  101. package/dist/components/ui/popover.js +39 -0
  102. package/dist/components/ui/resizable-split-pane.d.ts +10 -0
  103. package/dist/components/ui/resizable-split-pane.d.ts.map +1 -0
  104. package/dist/components/ui/resizable-split-pane.js +65 -0
  105. package/dist/components/ui/scroll-area.d.ts +10 -0
  106. package/dist/components/ui/scroll-area.d.ts.map +1 -0
  107. package/dist/components/ui/scroll-area.js +69 -0
  108. package/dist/components/ui/select.d.ts +16 -0
  109. package/dist/components/ui/select.d.ts.map +1 -0
  110. package/dist/components/ui/select.js +145 -0
  111. package/dist/components/ui/separator.d.ts +5 -0
  112. package/dist/components/ui/separator.d.ts.map +1 -0
  113. package/dist/components/ui/tabs.d.ts +8 -0
  114. package/dist/components/ui/tabs.d.ts.map +1 -0
  115. package/dist/components/ui/tabs.js +68 -0
  116. package/dist/components/ui/theme-toggle.d.ts +2 -0
  117. package/dist/components/ui/theme-toggle.d.ts.map +1 -0
  118. package/dist/components/ui/theme-toggle.js +58 -0
  119. package/dist/context/EditorContext.d.ts +40 -0
  120. package/dist/context/EditorContext.d.ts.map +1 -0
  121. package/dist/context/EditorContext.js +576 -0
  122. package/dist/context/LiquidSchemaContext.d.ts +10 -0
  123. package/dist/context/LiquidSchemaContext.d.ts.map +1 -0
  124. package/dist/context/LiquidSchemaContext.js +16 -0
  125. package/dist/context/ThemeContext.d.ts +18 -0
  126. package/dist/context/ThemeContext.d.ts.map +1 -0
  127. package/dist/context/ThemeContext.js +53 -0
  128. package/dist/extensions/LiquidHighlight.d.ts +3 -0
  129. package/dist/extensions/LiquidHighlight.d.ts.map +1 -0
  130. package/dist/extensions/LiquidHighlight.js +58 -0
  131. package/dist/extensions/LiquidSuggestion.d.ts +18 -0
  132. package/dist/extensions/LiquidSuggestion.d.ts.map +1 -0
  133. package/dist/extensions/LiquidSuggestion.js +119 -0
  134. package/dist/hooks/useFontLoader.d.ts +6 -0
  135. package/dist/hooks/useFontLoader.d.ts.map +1 -0
  136. package/dist/hooks/useFontLoader.js +21 -0
  137. package/dist/hooks/useStyleLoader.d.ts +11 -0
  138. package/dist/hooks/useStyleLoader.d.ts.map +1 -0
  139. package/dist/hooks/useStyleLoader.js +26 -0
  140. package/dist/index.d.ts +6 -150
  141. package/dist/index.d.ts.map +1 -0
  142. package/dist/index.js +7 -57452
  143. package/dist/lib/html-utils.d.ts +23 -0
  144. package/dist/lib/html-utils.d.ts.map +1 -0
  145. package/dist/lib/html-utils.js +25 -0
  146. package/dist/lib/mjml/attributes.d.ts +100 -0
  147. package/dist/lib/mjml/attributes.d.ts.map +1 -0
  148. package/dist/lib/mjml/attributes.js +105 -0
  149. package/dist/lib/mjml/parser.d.ts +67 -0
  150. package/dist/lib/mjml/parser.d.ts.map +1 -0
  151. package/dist/lib/mjml/parser.js +184 -0
  152. package/dist/lib/mjml/parser.test.d.ts +2 -0
  153. package/dist/lib/mjml/parser.test.d.ts.map +1 -0
  154. package/dist/lib/mjml/renderer.d.ts +23 -0
  155. package/dist/lib/mjml/renderer.d.ts.map +1 -0
  156. package/dist/lib/mjml/renderer.js +72 -0
  157. package/dist/lib/mjml/schema.d.ts +21 -0
  158. package/dist/lib/mjml/schema.d.ts.map +1 -0
  159. package/dist/lib/mjml/schema.js +1307 -0
  160. package/dist/lib/mjml/scopeCSS.d.ts +21 -0
  161. package/dist/lib/mjml/scopeCSS.d.ts.map +1 -0
  162. package/dist/lib/mjml/scopeCSS.js +67 -0
  163. package/dist/lib/utils.d.ts +3 -0
  164. package/dist/lib/utils.d.ts.map +1 -0
  165. package/dist/lib/utils.js +8 -0
  166. package/dist/styles.d.ts +1 -0
  167. package/dist/styles.d.ts.map +1 -0
  168. package/dist/styles.js +1 -0
  169. package/dist/types/liquid.d.ts +28 -0
  170. package/dist/types/liquid.d.ts.map +1 -0
  171. package/dist/types/mjml.d.ts +101 -0
  172. package/dist/types/mjml.d.ts.map +1 -0
  173. package/package.json +12 -9
@@ -0,0 +1,7 @@
1
+ import { MjmlNode } from '../../../types/mjml';
2
+ interface VisualImageProps {
3
+ node: MjmlNode;
4
+ }
5
+ export declare function VisualImage({ node }: VisualImageProps): import("react/jsx-runtime").JSX.Element;
6
+ export {};
7
+ //# sourceMappingURL=VisualImage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"VisualImage.d.ts","sourceRoot":"","sources":["../../../../src/components/editor/visual-blocks/VisualImage.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAI7C,UAAU,gBAAgB;IACxB,IAAI,EAAE,QAAQ,CAAC;CAChB;AAED,wBAAgB,WAAW,CAAC,EAAE,IAAI,EAAE,EAAE,gBAAgB,2CAyFrD"}
@@ -0,0 +1,48 @@
1
+ import { jsx as n } from "react/jsx-runtime";
2
+ import { useEditor as v } from "../../../context/EditorContext.js";
3
+ import { cn as w } from "../../../lib/utils.js";
4
+ import { buildPadding as N } from "./helpers.js";
5
+ import { useResolvedAttributes as S } from "./useResolvedAttributes.js";
6
+ function A({ node: r }) {
7
+ const { state: p, selectBlock: x } = v(), y = p.selectedBlockId === r._id, t = S(r), k = (j) => {
8
+ j.stopPropagation(), x(r._id);
9
+ }, c = t.src || "", C = t.alt || "", i = t.width || "100%", s = t.height || "auto", d = t.align || "center", B = N(t, "10px 25px"), l = t.border, a = t["border-top"], g = t["border-right"], f = t["border-bottom"], m = t["border-left"], e = t["border-radius"], b = t["max-height"], h = t["container-background-color"], R = t.title, u = {
10
+ padding: B,
11
+ display: "flex",
12
+ justifyContent: d === "left" ? "flex-start" : d === "right" ? "flex-end" : "center"
13
+ };
14
+ h && (u.backgroundColor = h);
15
+ const o = {
16
+ width: i,
17
+ height: s,
18
+ maxWidth: "100%",
19
+ display: "block"
20
+ };
21
+ return b && (o.maxHeight = b), l && (o.border = l), a && (o.borderTop = a), g && (o.borderRight = g), f && (o.borderBottom = f), m && (o.borderLeft = m), e && (o.borderRadius = e), /* @__PURE__ */ n(
22
+ "div",
23
+ {
24
+ className: w(
25
+ "relative cursor-pointer transition-all",
26
+ y && "ring-2 ring-indigo-500 ring-inset",
27
+ t["css-class"]
28
+ ),
29
+ style: u,
30
+ onClick: k,
31
+ children: c ? /* @__PURE__ */ n("img", { src: c, alt: C, title: R, style: o }) : /* @__PURE__ */ n(
32
+ "div",
33
+ {
34
+ className: "bg-muted flex items-center justify-center text-muted-foreground",
35
+ style: {
36
+ width: i === "100%" ? "100%" : i,
37
+ height: s === "auto" ? "150px" : s,
38
+ ...e && { borderRadius: e }
39
+ },
40
+ children: "No image"
41
+ }
42
+ )
43
+ }
44
+ );
45
+ }
46
+ export {
47
+ A as VisualImage
48
+ };
@@ -0,0 +1,7 @@
1
+ import { MjmlNode } from '../../../types/mjml';
2
+ interface VisualRawProps {
3
+ node: MjmlNode;
4
+ }
5
+ export declare function VisualRaw({ node }: VisualRawProps): import("react/jsx-runtime").JSX.Element;
6
+ export {};
7
+ //# sourceMappingURL=VisualRaw.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"VisualRaw.d.ts","sourceRoot":"","sources":["../../../../src/components/editor/visual-blocks/VisualRaw.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAE7C,UAAU,cAAc;IACtB,IAAI,EAAE,QAAQ,CAAC;CAChB;AAED,wBAAgB,SAAS,CAAC,EAAE,IAAI,EAAE,EAAE,cAAc,2CAsCjD"}
@@ -0,0 +1,32 @@
1
+ import { jsxs as e, jsx as r } from "react/jsx-runtime";
2
+ import { useEditor as l } from "../../../context/EditorContext.js";
3
+ import { cn as d } from "../../../lib/utils.js";
4
+ function g({ node: t }) {
5
+ const { state: o, selectBlock: s } = l(), c = o.selectedBlockId === t._id, i = (a) => {
6
+ a.stopPropagation(), s(t._id);
7
+ }, n = t.content && t.content.trim().length > 0;
8
+ return /* @__PURE__ */ e(
9
+ "div",
10
+ {
11
+ className: d(
12
+ "relative cursor-pointer transition-all p-4",
13
+ c && "ring-2 ring-indigo-500 ring-inset",
14
+ "bg-muted border border-dashed border-border"
15
+ ),
16
+ onClick: i,
17
+ children: [
18
+ /* @__PURE__ */ e("div", { className: "flex items-center gap-2 text-muted-foreground", children: [
19
+ /* @__PURE__ */ r("span", { className: "text-xs font-mono bg-secondary px-1.5 py-0.5 rounded", children: "</>" }),
20
+ /* @__PURE__ */ r("span", { className: "text-sm", children: n ? "Raw HTML Block" : "Empty Raw HTML Block" })
21
+ ] }),
22
+ n && /* @__PURE__ */ e("div", { className: "mt-2 text-xs font-mono text-muted-foreground truncate max-w-full", children: [
23
+ t.content?.substring(0, 100),
24
+ (t.content?.length || 0) > 100 && "..."
25
+ ] })
26
+ ]
27
+ }
28
+ );
29
+ }
30
+ export {
31
+ g as VisualRaw
32
+ };
@@ -0,0 +1,7 @@
1
+ import { MjmlNode } from '../../../types/mjml';
2
+ interface VisualSectionProps {
3
+ node: MjmlNode;
4
+ }
5
+ export declare function VisualSection({ node }: VisualSectionProps): import("react/jsx-runtime").JSX.Element;
6
+ export {};
7
+ //# sourceMappingURL=VisualSection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"VisualSection.d.ts","sourceRoot":"","sources":["../../../../src/components/editor/visual-blocks/VisualSection.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAI7C,UAAU,kBAAkB;IAC1B,IAAI,EAAE,QAAQ,CAAC;CAChB;AAED,wBAAgB,aAAa,CAAC,EAAE,IAAI,EAAE,EAAE,kBAAkB,2CAyNzD"}
@@ -0,0 +1,131 @@
1
+ import { jsx as e, jsxs as _ } from "react/jsx-runtime";
2
+ import { useEditor as L } from "../../../context/EditorContext.js";
3
+ import { VisualColumn as j } from "./VisualColumn.js";
4
+ import { cn as C } from "../../../lib/utils.js";
5
+ import { buildPadding as w } from "./helpers.js";
6
+ import { useResolvedAttributes as T } from "./useResolvedAttributes.js";
7
+ function W({ node: t }) {
8
+ const { state: z, selectBlock: $ } = L(), h = z.selectedBlockId === t._id, o = T(t), x = (i) => {
9
+ i.stopPropagation(), $(t._id);
10
+ };
11
+ if (t.tagName === "mj-wrapper") {
12
+ const i = o["background-color"] || "transparent", c = w(o, "20px 0"), s = o["full-width"] === "full-width", R = o["text-align"] || "center", d = o["background-url"], N = o["background-size"] || "auto", P = o["background-repeat"] || "repeat", y = o["background-position"] || "top center", a = o["background-position-x"], l = o["background-position-y"], g = o.border, b = o["border-top"], u = o["border-right"], p = o["border-bottom"], m = o["border-left"], f = o["border-radius"], S = o.gap;
13
+ let k = y;
14
+ (a || l) && (k = `${a || "center"} ${l || "center"}`);
15
+ const r = {
16
+ backgroundColor: i,
17
+ backgroundImage: d ? `url(${d})` : void 0,
18
+ backgroundSize: N,
19
+ backgroundRepeat: P,
20
+ backgroundPosition: k,
21
+ padding: c,
22
+ textAlign: R
23
+ };
24
+ g && (r.border = g), b && (r.borderTop = b), u && (r.borderRight = u), p && (r.borderBottom = p), m && (r.borderLeft = m), f && (r.borderRadius = f);
25
+ const B = {
26
+ margin: "0 auto",
27
+ maxWidth: s ? "100%" : "600px",
28
+ display: "flex",
29
+ flexDirection: "column",
30
+ gap: S || void 0
31
+ };
32
+ return /* @__PURE__ */ e(
33
+ "div",
34
+ {
35
+ className: C(
36
+ "relative cursor-pointer transition-all",
37
+ h && "ring-2 ring-indigo-500 ring-inset",
38
+ o["css-class"]
39
+ ),
40
+ style: r,
41
+ onClick: x,
42
+ children: /* @__PURE__ */ e("div", { style: B, children: t.children?.map((n) => /* @__PURE__ */ e(W, { node: n }, n._id)) })
43
+ }
44
+ );
45
+ }
46
+ if (t.tagName === "mj-section") {
47
+ const i = o["background-color"] || "transparent", c = w(o, "20px 0"), s = o["full-width"] === "full-width", R = o["text-align"] || "center", d = o["background-url"], N = o["background-size"] || "auto", P = o["background-repeat"] || "repeat", y = o["background-position"] || "top center", a = o["background-position-x"], l = o["background-position-y"], g = o.border, b = o["border-top"], u = o["border-right"], p = o["border-bottom"], m = o["border-left"], f = o["border-radius"], S = o.direction || "ltr";
48
+ let k = y;
49
+ (a || l) && (k = `${a || "center"} ${l || "center"}`);
50
+ const r = t.children?.filter((v) => v.tagName === "mj-column") || [], B = r.length || 1, n = {
51
+ backgroundColor: i,
52
+ backgroundImage: d ? `url(${d})` : void 0,
53
+ backgroundSize: N,
54
+ backgroundRepeat: P,
55
+ backgroundPosition: k,
56
+ padding: c,
57
+ textAlign: R,
58
+ direction: S
59
+ };
60
+ return g && (n.border = g), b && (n.borderTop = b), u && (n.borderRight = u), p && (n.borderBottom = p), m && (n.borderLeft = m), f && (n.borderRadius = f), /* @__PURE__ */ e(
61
+ "div",
62
+ {
63
+ className: C(
64
+ "relative cursor-pointer transition-all",
65
+ h && "ring-2 ring-indigo-500 ring-inset",
66
+ o["css-class"]
67
+ ),
68
+ style: n,
69
+ onClick: x,
70
+ children: /* @__PURE__ */ e(
71
+ "div",
72
+ {
73
+ className: "flex",
74
+ style: {
75
+ margin: "0 auto",
76
+ maxWidth: s ? "100%" : "600px",
77
+ minHeight: r.length === 0 ? "20px" : void 0
78
+ },
79
+ children: r.map((v) => /* @__PURE__ */ e(
80
+ j,
81
+ {
82
+ node: v,
83
+ totalColumns: B
84
+ },
85
+ v._id
86
+ ))
87
+ }
88
+ )
89
+ }
90
+ );
91
+ }
92
+ if (t.tagName === "mj-group") {
93
+ const i = t.children?.filter((s) => s.tagName === "mj-column") || [], c = i.length || 1;
94
+ return /* @__PURE__ */ e(
95
+ "div",
96
+ {
97
+ className: C(
98
+ "relative cursor-pointer transition-all flex",
99
+ h && "ring-2 ring-indigo-500 ring-inset",
100
+ o["css-class"]
101
+ ),
102
+ onClick: x,
103
+ children: i.map((s) => /* @__PURE__ */ e(
104
+ j,
105
+ {
106
+ node: s,
107
+ totalColumns: c
108
+ },
109
+ s._id
110
+ ))
111
+ }
112
+ );
113
+ }
114
+ return /* @__PURE__ */ e(
115
+ "div",
116
+ {
117
+ className: C(
118
+ "p-4 bg-muted border border-dashed border-border cursor-pointer",
119
+ h && "ring-2 ring-indigo-500"
120
+ ),
121
+ onClick: x,
122
+ children: /* @__PURE__ */ _("span", { className: "text-sm text-muted-foreground", children: [
123
+ "Unknown: ",
124
+ t.tagName
125
+ ] })
126
+ }
127
+ );
128
+ }
129
+ export {
130
+ W as VisualSection
131
+ };
@@ -0,0 +1,7 @@
1
+ import { MjmlNode } from '../../../types/mjml';
2
+ interface VisualSocialProps {
3
+ node: MjmlNode;
4
+ }
5
+ export declare function VisualSocial({ node }: VisualSocialProps): import("react/jsx-runtime").JSX.Element;
6
+ export {};
7
+ //# sourceMappingURL=VisualSocial.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"VisualSocial.d.ts","sourceRoot":"","sources":["../../../../src/components/editor/visual-blocks/VisualSocial.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAG7C,UAAU,iBAAiB;IACzB,IAAI,EAAE,QAAQ,CAAC;CAChB;AAYD,wBAAgB,YAAY,CAAC,EAAE,IAAI,EAAE,EAAE,iBAAiB,2CAsEvD"}
@@ -0,0 +1,62 @@
1
+ import { jsx as n, jsxs as k } from "react/jsx-runtime";
2
+ import { useEditor as v } from "../../../context/EditorContext.js";
3
+ import { cn as l } from "../../../lib/utils.js";
4
+ import { useResolvedAttributes as y } from "./useResolvedAttributes.js";
5
+ const C = {
6
+ facebook: "f",
7
+ twitter: "𝕏",
8
+ instagram: "📷",
9
+ linkedin: "in",
10
+ youtube: "▶",
11
+ github: "⌥"
12
+ };
13
+ function S({ node: i }) {
14
+ const { state: r, selectBlock: a } = v(), d = r.selectedBlockId === i._id, e = y(i), m = (t) => {
15
+ t.stopPropagation(), a(i._id);
16
+ }, u = e.mode || "horizontal", s = e.align || "center", f = e.padding || "10px 25px", o = e["icon-size"] || "20px", c = i.children?.filter((t) => t.tagName === "mj-social-element") || [], g = s === "left" ? "flex-start" : s === "right" ? "flex-end" : "center";
17
+ return /* @__PURE__ */ n(
18
+ "div",
19
+ {
20
+ className: l(
21
+ "relative cursor-pointer transition-all",
22
+ d && "ring-2 ring-indigo-500 ring-inset",
23
+ e["css-class"]
24
+ ),
25
+ style: { padding: f },
26
+ onClick: m,
27
+ children: /* @__PURE__ */ k(
28
+ "div",
29
+ {
30
+ className: l(
31
+ "flex gap-2",
32
+ u === "vertical" && "flex-col items-center"
33
+ ),
34
+ style: { justifyContent: g },
35
+ children: [
36
+ c.map((t, p) => {
37
+ const h = t.attributes.name || "link", x = t.attributes["background-color"] || "#333", b = C[h.toLowerCase()] || "🔗";
38
+ return /* @__PURE__ */ n(
39
+ "div",
40
+ {
41
+ className: "rounded-full flex items-center justify-center text-white font-bold",
42
+ style: {
43
+ width: o,
44
+ height: o,
45
+ backgroundColor: x,
46
+ fontSize: `calc(${o} * 0.5)`
47
+ },
48
+ children: b
49
+ },
50
+ t._id || p
51
+ );
52
+ }),
53
+ c.length === 0 && /* @__PURE__ */ n("span", { className: "text-sm text-muted-foreground", children: "Add social icons" })
54
+ ]
55
+ }
56
+ )
57
+ }
58
+ );
59
+ }
60
+ export {
61
+ S as VisualSocial
62
+ };
@@ -0,0 +1,7 @@
1
+ import { MjmlNode } from '../../../types/mjml';
2
+ interface VisualSpacerProps {
3
+ node: MjmlNode;
4
+ }
5
+ export declare function VisualSpacer({ node }: VisualSpacerProps): import("react/jsx-runtime").JSX.Element;
6
+ export {};
7
+ //# sourceMappingURL=VisualSpacer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"VisualSpacer.d.ts","sourceRoot":"","sources":["../../../../src/components/editor/visual-blocks/VisualSpacer.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAI7C,UAAU,iBAAiB;IACzB,IAAI,EAAE,QAAQ,CAAC;CAChB;AAED,wBAAgB,YAAY,CAAC,EAAE,IAAI,EAAE,EAAE,iBAAiB,2CAyCvD"}
@@ -0,0 +1,30 @@
1
+ import { jsx as o } from "react/jsx-runtime";
2
+ import { useEditor as g } from "../../../context/EditorContext.js";
3
+ import { cn as m } from "../../../lib/utils.js";
4
+ import { buildPadding as p } from "./helpers.js";
5
+ import { useResolvedAttributes as u } from "./useResolvedAttributes.js";
6
+ function v({ node: i }) {
7
+ const { state: c, selectBlock: l } = g(), e = c.selectedBlockId === i._id, t = u(i), a = (d) => {
8
+ d.stopPropagation(), l(i._id);
9
+ }, s = t.height || "20px", r = p(t), n = t["container-background-color"];
10
+ return /* @__PURE__ */ o(
11
+ "div",
12
+ {
13
+ className: m(
14
+ "relative cursor-pointer transition-all",
15
+ e && "ring-2 ring-indigo-500 ring-inset bg-indigo-50/50",
16
+ t["css-class"]
17
+ ),
18
+ style: {
19
+ height: s,
20
+ ...r && { padding: r },
21
+ ...n && { backgroundColor: n }
22
+ },
23
+ onClick: a,
24
+ children: e && /* @__PURE__ */ o("div", { className: "absolute inset-0 flex items-center justify-center", children: /* @__PURE__ */ o("span", { className: "text-xs text-indigo-600 bg-white px-1 rounded shadow-sm", children: s }) })
25
+ }
26
+ );
27
+ }
28
+ export {
29
+ v as VisualSpacer
30
+ };
@@ -0,0 +1,7 @@
1
+ import { MjmlNode } from '../../../types/mjml';
2
+ interface VisualTextProps {
3
+ node: MjmlNode;
4
+ }
5
+ export declare function VisualText({ node }: VisualTextProps): import("react/jsx-runtime").JSX.Element;
6
+ export {};
7
+ //# sourceMappingURL=VisualText.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"VisualText.d.ts","sourceRoot":"","sources":["../../../../src/components/editor/visual-blocks/VisualText.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAK7C,UAAU,eAAe;IACvB,IAAI,EAAE,QAAQ,CAAC;CAChB;AAED,wBAAgB,UAAU,CAAC,EAAE,IAAI,EAAE,EAAE,eAAe,2CAoLnD"}
@@ -0,0 +1,103 @@
1
+ import { jsxs as F, jsx as r } from "react/jsx-runtime";
2
+ import { useState as f, useRef as C, useCallback as p, useEffect as S, useMemo as K } from "react";
3
+ import { useEditor as V } from "../../../context/EditorContext.js";
4
+ import { cn as g } from "../../../lib/utils.js";
5
+ import { highlightLiquidTags as W } from "../../../lib/html-utils.js";
6
+ import { buildPadding as G } from "./helpers.js";
7
+ import { useResolvedAttributes as J } from "./useResolvedAttributes.js";
8
+ import { TiptapEditor as Q } from "../TiptapEditor.js";
9
+ function rt({ node: o }) {
10
+ const { state: w, selectBlock: _, updateContent: m } = V(), h = w.selectedBlockId === o._id, [n, c] = f(!1), [s, l] = f(null), a = C(null), x = C(null), [L, T] = f(!1), D = (e) => {
11
+ e.stopPropagation(), _(o._id);
12
+ }, A = (e) => {
13
+ e.stopPropagation(), T(!0), c(!0), setTimeout(() => {
14
+ x.current?.focus();
15
+ }, 0);
16
+ }, H = p((e) => {
17
+ l(e);
18
+ }, []), b = p(() => {
19
+ s !== null && s !== o.content && m(o._id, s), l(null), c(!1);
20
+ }, [s, o.content, o._id, m]), v = p(() => {
21
+ l(null), c(!1);
22
+ }, []);
23
+ S(() => {
24
+ if (!n) return;
25
+ const e = (i) => {
26
+ if (a.current && !a.current.contains(i.target)) {
27
+ if (document.querySelector(
28
+ "[data-radix-popper-content-wrapper]"
29
+ )?.contains(i.target) || document.querySelector(".tippy-box")?.contains(i.target))
30
+ return;
31
+ b();
32
+ }
33
+ };
34
+ return document.addEventListener("mousedown", e), () => document.removeEventListener("mousedown", e);
35
+ }, [n, b]), S(() => {
36
+ if (!n) return;
37
+ const e = (i) => {
38
+ i.key === "Escape" && v();
39
+ };
40
+ return document.addEventListener("keydown", e), () => document.removeEventListener("keydown", e);
41
+ }, [n, v]);
42
+ const t = J(o), M = t.color || "#000000", N = t["font-size"] || "13px", P = t["font-family"] || "Ubuntu, Helvetica, Arial, sans-serif", R = t["font-weight"] || "normal", q = t["font-style"] || "normal", B = t.align || "left", I = t["line-height"] || "1", y = t["letter-spacing"], O = t["text-decoration"] || "none", U = t["text-transform"] || "none", j = G(t, "10px 25px"), k = t.height, E = t["container-background-color"], d = {
43
+ color: M,
44
+ fontSize: N,
45
+ fontFamily: P,
46
+ fontWeight: R,
47
+ fontStyle: q,
48
+ textAlign: B,
49
+ lineHeight: I,
50
+ textDecoration: O,
51
+ textTransform: U
52
+ };
53
+ y && (d.letterSpacing = y);
54
+ const u = o.content || "", z = K(
55
+ () => W(u) || " ",
56
+ [u]
57
+ );
58
+ return /* @__PURE__ */ F(
59
+ "div",
60
+ {
61
+ ref: a,
62
+ className: g(
63
+ "relative cursor-pointer transition-all",
64
+ h && !n && "ring-2 ring-indigo-500 ring-inset",
65
+ n && "ring-2 ring-indigo-500"
66
+ ),
67
+ style: {
68
+ padding: j,
69
+ ...k && { height: k },
70
+ ...E && { backgroundColor: E }
71
+ },
72
+ onClick: D,
73
+ onDoubleClick: A,
74
+ children: [
75
+ /* @__PURE__ */ r(
76
+ "div",
77
+ {
78
+ className: g(
79
+ "[&_a]:text-inherit [&_a]:underline",
80
+ n && "hidden",
81
+ t["css-class"]
82
+ ),
83
+ style: d,
84
+ dangerouslySetInnerHTML: { __html: z }
85
+ }
86
+ ),
87
+ L && /* @__PURE__ */ r("div", { className: g(!n && "hidden"), children: /* @__PURE__ */ r(
88
+ Q,
89
+ {
90
+ ref: x,
91
+ content: u,
92
+ onUpdate: H,
93
+ style: d
94
+ }
95
+ ) }),
96
+ h && !n && /* @__PURE__ */ r("div", { className: "absolute -top-6 left-0 text-xs text-indigo-600 bg-white px-1 rounded shadow-sm", children: "Double-click to edit" })
97
+ ]
98
+ }
99
+ );
100
+ }
101
+ export {
102
+ rt as VisualText
103
+ };
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Builds a CSS padding value from MJML attributes.
3
+ *
4
+ * MJML behavior: Individual padding attributes (padding-top, padding-right,
5
+ * padding-bottom, padding-left) override specific sides of the base padding.
6
+ * The base padding comes from the unified `padding` attribute or the default.
7
+ *
8
+ * @param attrs - The node's attributes object
9
+ * @param defaultPadding - Default padding when no padding attributes are set
10
+ * @returns CSS padding string
11
+ */
12
+ export declare function buildPadding(attrs: Record<string, string>, defaultPadding?: string): string;
13
+ //# sourceMappingURL=helpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../../../src/components/editor/visual-blocks/helpers.ts"],"names":[],"mappings":"AA4CA;;;;;;;;;;GAUG;AACH,wBAAgB,YAAY,CAC1B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC7B,cAAc,GAAE,MAAY,GAC3B,MAAM,CA4BR"}
@@ -0,0 +1,44 @@
1
+ function h(o) {
2
+ const t = o.trim().split(/\s+/);
3
+ switch (t.length) {
4
+ case 1:
5
+ return {
6
+ top: t[0],
7
+ right: t[0],
8
+ bottom: t[0],
9
+ left: t[0]
10
+ };
11
+ case 2:
12
+ return {
13
+ top: t[0],
14
+ right: t[1],
15
+ bottom: t[0],
16
+ left: t[1]
17
+ };
18
+ case 3:
19
+ return {
20
+ top: t[0],
21
+ right: t[1],
22
+ bottom: t[2],
23
+ left: t[1]
24
+ };
25
+ default:
26
+ return {
27
+ top: t[0],
28
+ right: t[1],
29
+ bottom: t[2],
30
+ left: t[3]
31
+ };
32
+ }
33
+ }
34
+ function f(o, t = "0") {
35
+ const d = o["padding-top"], i = o["padding-right"], e = o["padding-bottom"], g = o["padding-left"];
36
+ if (d !== void 0 || i !== void 0 || e !== void 0 || g !== void 0) {
37
+ const p = o.padding || t, n = h(p), a = d ?? n.top, s = i ?? n.right, c = e ?? n.bottom, r = g ?? n.left;
38
+ return `${a} ${s} ${c} ${r}`;
39
+ }
40
+ return o.padding || t;
41
+ }
42
+ export {
43
+ f as buildPadding
44
+ };
@@ -0,0 +1,7 @@
1
+ import { MjmlNode } from '../../../types/mjml';
2
+ /**
3
+ * Hook for visual blocks to get resolved attributes.
4
+ * Combines mj-attributes defaults with per-element attributes.
5
+ */
6
+ export declare function useResolvedAttributes(node: MjmlNode): Record<string, string>;
7
+ //# sourceMappingURL=useResolvedAttributes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useResolvedAttributes.d.ts","sourceRoot":"","sources":["../../../../src/components/editor/visual-blocks/useResolvedAttributes.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAE7C;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAM5E"}
@@ -0,0 +1,12 @@
1
+ import { useMemo as o } from "react";
2
+ import { useEditor as r } from "../../../context/EditorContext.js";
3
+ function i(t) {
4
+ const { getResolvedAttributes: e } = r();
5
+ return o(
6
+ () => e(t),
7
+ [e, t]
8
+ );
9
+ }
10
+ export {
11
+ i as useResolvedAttributes
12
+ };
@@ -0,0 +1,10 @@
1
+ import { VariantProps } from 'class-variance-authority';
2
+ import * as React from 'react';
3
+ declare const badgeVariants: (props?: ({
4
+ variant?: "default" | "destructive" | "outline" | "secondary" | null | undefined;
5
+ } & import('class-variance-authority/types').ClassProp) | undefined) => string;
6
+ export interface BadgeProps extends React.HTMLAttributes<HTMLDivElement>, VariantProps<typeof badgeVariants> {
7
+ }
8
+ declare function Badge({ className, variant, ...props }: BadgeProps): import("react/jsx-runtime").JSX.Element;
9
+ export { Badge };
10
+ //# sourceMappingURL=badge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"badge.d.ts","sourceRoot":"","sources":["../../../src/components/ui/badge.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAGlE,QAAA,MAAM,aAAa;;8EAkBlB,CAAC;AAEF,MAAM,WAAW,UACf,SACE,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,EACpC,YAAY,CAAC,OAAO,aAAa,CAAC;CAAG;AAEzC,iBAAS,KAAK,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,KAAK,EAAE,EAAE,UAAU,2CAI1D;AAED,OAAO,EAAE,KAAK,EAAE,CAAC"}
@@ -0,0 +1,26 @@
1
+ import { jsx as o } from "react/jsx-runtime";
2
+ import "react";
3
+ import { cva as n } from "class-variance-authority";
4
+ import { cn as a } from "../../lib/utils.js";
5
+ const i = n(
6
+ "inline-flex items-center rounded-md border px-2 py-0.5 text-xs font-medium transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
7
+ {
8
+ variants: {
9
+ variant: {
10
+ default: "border-transparent bg-primary text-primary-foreground shadow hover:bg-primary/80",
11
+ secondary: "border-transparent bg-muted text-foreground hover:bg-muted/80",
12
+ destructive: "border-transparent bg-destructive text-destructive-foreground shadow hover:bg-destructive/80",
13
+ outline: "text-foreground"
14
+ }
15
+ },
16
+ defaultVariants: {
17
+ variant: "default"
18
+ }
19
+ }
20
+ );
21
+ function m({ className: r, variant: t, ...e }) {
22
+ return /* @__PURE__ */ o("div", { className: a(i({ variant: t }), r), ...e });
23
+ }
24
+ export {
25
+ m as Badge
26
+ };
@@ -0,0 +1,11 @@
1
+ import { VariantProps } from 'class-variance-authority';
2
+ import * as React from 'react';
3
+ declare const buttonVariants: (props?: ({
4
+ variant?: "link" | "default" | "destructive" | "outline" | "secondary" | "ghost" | null | undefined;
5
+ size?: "default" | "sm" | "lg" | "icon" | "icon-sm" | "icon-lg" | null | undefined;
6
+ } & import('class-variance-authority/types').ClassProp) | undefined) => string;
7
+ declare function Button({ className, variant, size, asChild, ...props }: React.ComponentProps<'button'> & VariantProps<typeof buttonVariants> & {
8
+ asChild?: boolean;
9
+ }): import("react/jsx-runtime").JSX.Element;
10
+ export { Button, buttonVariants };
11
+ //# sourceMappingURL=button.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"button.d.ts","sourceRoot":"","sources":["../../../src/components/ui/button.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAIlE,QAAA,MAAM,cAAc;;;8EA4BnB,CAAC;AAEF,iBAAS,MAAM,CAAC,EACd,SAAS,EACT,OAAmB,EACnB,IAAgB,EAChB,OAAe,EACf,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,QAAQ,CAAC,GAC/B,YAAY,CAAC,OAAO,cAAc,CAAC,GAAG;IACpC,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,2CAYF;AAED,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,CAAC"}