@kgalexander/mcreate 1.0.2 → 1.0.3

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.
@@ -815,15 +815,15 @@ function propertyCardTripleMockMjml(block, context) {
815
815
  ${responsiveStyles}
816
816
  <mj-table align="center" width="${width}" padding="0" css-class="${trackingClasses}">
817
817
  <tr class="property-triple-row-${uniqueId}">
818
- <th class="property-triple-card-wrapper-${uniqueId}" valign="top" align="center" width="100px"">
818
+ <th class="property-triple-card-wrapper-${uniqueId}" valign="top" align="center" width="100px">
819
819
  ${cards[0] || ""}
820
820
  </th>
821
821
  <th class="property-triple-spacer-${uniqueId}" style="font-size:0px;line-height:16px;font-weight:normal;width:4px; height:4px">&nbsp;</th>
822
- <th class="property-triple-card-wrapper-${uniqueId}" valign="top" align="center" width="100px" ">
822
+ <th class="property-triple-card-wrapper-${uniqueId}" valign="top" align="center" width="100px">
823
823
  ${cards[1] || ""}
824
824
  </th>
825
825
  <th class="property-triple-spacer-${uniqueId}" style="font-size:0px;line-height:16px;font-weight:normal;width:4px; height:4px">&nbsp;</th>
826
- <th class="property-triple-card-wrapper-${uniqueId}" valign="top" align="center" width="100px" ">
826
+ <th class="property-triple-card-wrapper-${uniqueId}" valign="top" align="center" width="100px">
827
827
  ${cards[2] || ""}
828
828
  </th>
829
829
  </tr>
@@ -1823,6 +1823,7 @@ var useEditorStore = create()(
1823
1823
  onImageUpload: null,
1824
1824
  onDuplicate: null,
1825
1825
  onDelete: null,
1826
+ onTemplateCapture: null,
1826
1827
  previewMode: false,
1827
1828
  focusIdx: null,
1828
1829
  hoverIdx: null,
@@ -1863,7 +1864,7 @@ var useEditorStore = create()(
1863
1864
  });
1864
1865
  },
1865
1866
  // Initialize store with external template (for npm package usage)
1866
- initializeWithTemplate: (templateId, template, onSave, onToast, data, onExit, onImageUpload, onDuplicate, onDelete) => {
1867
+ initializeWithTemplate: (templateId, template, onSave, onToast, data, onExit, onImageUpload, onDuplicate, onDelete, onTemplateCapture) => {
1867
1868
  set((state) => {
1868
1869
  state.templateId = templateId;
1869
1870
  state.template = template;
@@ -1873,6 +1874,7 @@ var useEditorStore = create()(
1873
1874
  state.onImageUpload = onImageUpload ?? null;
1874
1875
  state.onDuplicate = onDuplicate ?? null;
1875
1876
  state.onDelete = onDelete ?? null;
1877
+ state.onTemplateCapture = onTemplateCapture ?? null;
1876
1878
  state.isPaidLevel = data?.isPaidLevel ?? 0;
1877
1879
  state.images = data?.images ?? [];
1878
1880
  state.userData = data?.userData ?? null;
@@ -5,7 +5,7 @@ import {
5
5
  MAILLOW_EMAIL_EDITOR_VERSION,
6
6
  Preview,
7
7
  useEditorStore
8
- } from "./chunk-G7F7GRJC.mjs";
8
+ } from "./chunk-JWS6HO2H.mjs";
9
9
  export {
10
10
  Editor,
11
11
  History,
package/dist/index.d.mts CHANGED
@@ -292,6 +292,7 @@ type OnExitCallback = () => void;
292
292
  type OnImageUploadCallback = (file: File) => Promise<ImageData>;
293
293
  type OnDuplicateCallback = (templateId: string, template: TemplateJSON) => void | Promise<void>;
294
294
  type OnDeleteCallback = (templateId: string) => void | Promise<void>;
295
+ type OnTemplateCaptureCallback = (templateId: string, imageDataUrl: string) => void | Promise<void>;
295
296
  type PaidLevel = 0 | 1 | 2 | 3;
296
297
 
297
298
  interface EditorProps {
@@ -300,7 +301,7 @@ interface EditorProps {
300
301
  }
301
302
  declare function Editor({ setEditorLoading }: EditorProps): react_jsx_runtime.JSX.Element;
302
303
 
303
- declare function TemplatePage({ templateId, initialTemplate, onSave, onToast, onExit, onImageUpload, onDuplicate, onDelete, data, }: {
304
+ declare function TemplatePage({ templateId, initialTemplate, onSave, onToast, onExit, onImageUpload, onDuplicate, onDelete, onTemplateCapture, data, }: {
304
305
  templateId: string;
305
306
  initialTemplate: TemplateJSON;
306
307
  onSave?: OnSaveCallback;
@@ -309,6 +310,7 @@ declare function TemplatePage({ templateId, initialTemplate, onSave, onToast, on
309
310
  onImageUpload?: OnImageUploadCallback;
310
311
  onDuplicate?: OnDuplicateCallback;
311
312
  onDelete?: OnDeleteCallback;
313
+ onTemplateCapture?: OnTemplateCaptureCallback;
312
314
  data?: {
313
315
  isPaidLevel?: PaidLevel;
314
316
  images?: ImageData[];
@@ -337,4 +339,4 @@ interface RenderOptions {
337
339
  */
338
340
  declare function json2mjml(template: TemplateJSON, mode?: RenderMode, options?: RenderOptions): string;
339
341
 
340
- export { Editor, type ImageData, MAX_TEMPLATE_SIZE, type MergeField, type OnDeleteCallback, type OnDuplicateCallback, type OnExitCallback, type OnImageUploadCallback, type OnSaveCallback, type OnToastCallback, type PaidLevel, type TemplateJSON, TemplatePage, type ToastOptions, type ToastType, json2mjml };
342
+ export { Editor, type ImageData, MAX_TEMPLATE_SIZE, type MergeField, type OnDeleteCallback, type OnDuplicateCallback, type OnExitCallback, type OnImageUploadCallback, type OnSaveCallback, type OnTemplateCaptureCallback, type OnToastCallback, type PaidLevel, type TemplateJSON, TemplatePage, type ToastOptions, type ToastType, json2mjml };
package/dist/index.d.ts CHANGED
@@ -292,6 +292,7 @@ type OnExitCallback = () => void;
292
292
  type OnImageUploadCallback = (file: File) => Promise<ImageData>;
293
293
  type OnDuplicateCallback = (templateId: string, template: TemplateJSON) => void | Promise<void>;
294
294
  type OnDeleteCallback = (templateId: string) => void | Promise<void>;
295
+ type OnTemplateCaptureCallback = (templateId: string, imageDataUrl: string) => void | Promise<void>;
295
296
  type PaidLevel = 0 | 1 | 2 | 3;
296
297
 
297
298
  interface EditorProps {
@@ -300,7 +301,7 @@ interface EditorProps {
300
301
  }
301
302
  declare function Editor({ setEditorLoading }: EditorProps): react_jsx_runtime.JSX.Element;
302
303
 
303
- declare function TemplatePage({ templateId, initialTemplate, onSave, onToast, onExit, onImageUpload, onDuplicate, onDelete, data, }: {
304
+ declare function TemplatePage({ templateId, initialTemplate, onSave, onToast, onExit, onImageUpload, onDuplicate, onDelete, onTemplateCapture, data, }: {
304
305
  templateId: string;
305
306
  initialTemplate: TemplateJSON;
306
307
  onSave?: OnSaveCallback;
@@ -309,6 +310,7 @@ declare function TemplatePage({ templateId, initialTemplate, onSave, onToast, on
309
310
  onImageUpload?: OnImageUploadCallback;
310
311
  onDuplicate?: OnDuplicateCallback;
311
312
  onDelete?: OnDeleteCallback;
313
+ onTemplateCapture?: OnTemplateCaptureCallback;
312
314
  data?: {
313
315
  isPaidLevel?: PaidLevel;
314
316
  images?: ImageData[];
@@ -337,4 +339,4 @@ interface RenderOptions {
337
339
  */
338
340
  declare function json2mjml(template: TemplateJSON, mode?: RenderMode, options?: RenderOptions): string;
339
341
 
340
- export { Editor, type ImageData, MAX_TEMPLATE_SIZE, type MergeField, type OnDeleteCallback, type OnDuplicateCallback, type OnExitCallback, type OnImageUploadCallback, type OnSaveCallback, type OnToastCallback, type PaidLevel, type TemplateJSON, TemplatePage, type ToastOptions, type ToastType, json2mjml };
342
+ export { Editor, type ImageData, MAX_TEMPLATE_SIZE, type MergeField, type OnDeleteCallback, type OnDuplicateCallback, type OnExitCallback, type OnImageUploadCallback, type OnSaveCallback, type OnTemplateCaptureCallback, type OnToastCallback, type PaidLevel, type TemplateJSON, TemplatePage, type ToastOptions, type ToastType, json2mjml };
package/dist/index.js CHANGED
@@ -890,15 +890,15 @@ function propertyCardTripleMockMjml(block, context) {
890
890
  ${responsiveStyles}
891
891
  <mj-table align="center" width="${width}" padding="0" css-class="${trackingClasses}">
892
892
  <tr class="property-triple-row-${uniqueId}">
893
- <th class="property-triple-card-wrapper-${uniqueId}" valign="top" align="center" width="100px"">
893
+ <th class="property-triple-card-wrapper-${uniqueId}" valign="top" align="center" width="100px">
894
894
  ${cards[0] || ""}
895
895
  </th>
896
896
  <th class="property-triple-spacer-${uniqueId}" style="font-size:0px;line-height:16px;font-weight:normal;width:4px; height:4px">&nbsp;</th>
897
- <th class="property-triple-card-wrapper-${uniqueId}" valign="top" align="center" width="100px" ">
897
+ <th class="property-triple-card-wrapper-${uniqueId}" valign="top" align="center" width="100px">
898
898
  ${cards[1] || ""}
899
899
  </th>
900
900
  <th class="property-triple-spacer-${uniqueId}" style="font-size:0px;line-height:16px;font-weight:normal;width:4px; height:4px">&nbsp;</th>
901
- <th class="property-triple-card-wrapper-${uniqueId}" valign="top" align="center" width="100px" ">
901
+ <th class="property-triple-card-wrapper-${uniqueId}" valign="top" align="center" width="100px">
902
902
  ${cards[2] || ""}
903
903
  </th>
904
904
  </tr>
@@ -2004,6 +2004,7 @@ var init_editor = __esm({
2004
2004
  onImageUpload: null,
2005
2005
  onDuplicate: null,
2006
2006
  onDelete: null,
2007
+ onTemplateCapture: null,
2007
2008
  previewMode: false,
2008
2009
  focusIdx: null,
2009
2010
  hoverIdx: null,
@@ -2044,7 +2045,7 @@ var init_editor = __esm({
2044
2045
  });
2045
2046
  },
2046
2047
  // Initialize store with external template (for npm package usage)
2047
- initializeWithTemplate: (templateId, template, onSave, onToast, data, onExit, onImageUpload, onDuplicate, onDelete) => {
2048
+ initializeWithTemplate: (templateId, template, onSave, onToast, data, onExit, onImageUpload, onDuplicate, onDelete, onTemplateCapture) => {
2048
2049
  set((state) => {
2049
2050
  state.templateId = templateId;
2050
2051
  state.template = template;
@@ -2054,6 +2055,7 @@ var init_editor = __esm({
2054
2055
  state.onImageUpload = onImageUpload ?? null;
2055
2056
  state.onDuplicate = onDuplicate ?? null;
2056
2057
  state.onDelete = onDelete ?? null;
2058
+ state.onTemplateCapture = onTemplateCapture ?? null;
2057
2059
  state.isPaidLevel = data?.isPaidLevel ?? 0;
2058
2060
  state.images = data?.images ?? [];
2059
2061
  state.userData = data?.userData ?? null;
@@ -16967,6 +16969,46 @@ function TemplateNameDialog() {
16967
16969
 
16968
16970
  // src/core/editor/components/email-template-v2/header.tsx
16969
16971
  init_editor();
16972
+
16973
+ // src/core/editor/utils/capture-template.ts
16974
+ var import_html_to_image = require("html-to-image");
16975
+ var CAPTURE_WIDTH = 600;
16976
+ async function captureTemplateImage(compiledHtml) {
16977
+ const container = document.createElement("div");
16978
+ container.style.position = "fixed";
16979
+ container.style.top = "0";
16980
+ container.style.left = "0";
16981
+ container.style.zIndex = "99999";
16982
+ container.style.width = `${CAPTURE_WIDTH}px`;
16983
+ container.style.backgroundColor = "#FFFFFF00";
16984
+ container.style.overflow = "hidden";
16985
+ container.style.maxHeight = "100vh";
16986
+ container.style.opacity = "0";
16987
+ container.innerHTML = compiledHtml;
16988
+ document.body.appendChild(container);
16989
+ await new Promise((resolve) => requestAnimationFrame(resolve));
16990
+ await new Promise((resolve) => setTimeout(resolve, 100));
16991
+ try {
16992
+ const dataUrl = await (0, import_html_to_image.toPng)(container, {
16993
+ width: CAPTURE_WIDTH,
16994
+ quality: 0.1,
16995
+ pixelRatio: 1,
16996
+ cacheBust: true,
16997
+ imagePlaceholder: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mN88P/BfwAJhAPkD+pMGAAAAABJRU5ErkJggg==",
16998
+ backgroundColor: "#ffffff",
16999
+ fetchRequestInit: { mode: "cors" },
17000
+ skipFonts: true,
17001
+ // Override opacity on the cloned node (real element is opacity:0 to stay invisible)
17002
+ style: { opacity: "1" }
17003
+ });
17004
+ return dataUrl;
17005
+ } finally {
17006
+ document.body.removeChild(container);
17007
+ }
17008
+ }
17009
+
17010
+ // src/core/editor/components/email-template-v2/header.tsx
17011
+ init_json2mjml();
16970
17012
  init_core();
16971
17013
  var import_jsx_runtime56 = require("react/jsx-runtime");
16972
17014
  function TemplateHeader() {
@@ -16978,14 +17020,28 @@ function TemplateHeader() {
16978
17020
  const onExit = useEditorStore((s) => s.onExit);
16979
17021
  const onDuplicate = useEditorStore((s) => s.onDuplicate);
16980
17022
  const onDelete = useEditorStore((s) => s.onDelete);
17023
+ const onTemplateCapture = useEditorStore((s) => s.onTemplateCapture);
16981
17024
  const templateName = useEditorStore((s) => s.template?.name);
16982
17025
  const handleExit = async () => {
16983
17026
  console.log("handleExit - templateId:", templateId);
16984
17027
  if (isSaving || !templateId || !onSave) return;
16985
17028
  setIsSaving(true);
16986
17029
  try {
16987
- await onSave(templateId, useEditorStore.getState().template);
17030
+ const template = useEditorStore.getState().template;
17031
+ await onSave(templateId, template);
16988
17032
  markAsSaved();
17033
+ if (onTemplateCapture) {
17034
+ try {
17035
+ const { default: mjml2html } = await import("mjml-browser");
17036
+ const mjmlString = json2mjml(template, "editing");
17037
+ const result = mjml2html(mjmlString);
17038
+ console.log("Result:", result.html);
17039
+ const imageDataUrl = await captureTemplateImage(result.html);
17040
+ await onTemplateCapture(templateId, imageDataUrl);
17041
+ } catch (err) {
17042
+ console.error("[TemplateCapture] Failed:", err?.message || JSON.stringify(err) || err, err?.stack || "");
17043
+ }
17044
+ }
16989
17045
  onExit?.();
16990
17046
  console.log("handleExit - onExit called");
16991
17047
  } catch (error) {
@@ -28692,10 +28748,11 @@ function TemplatePage({
28692
28748
  onImageUpload,
28693
28749
  onDuplicate,
28694
28750
  onDelete,
28751
+ onTemplateCapture,
28695
28752
  data
28696
28753
  }) {
28697
28754
  (0, import_react97.useState)(() => {
28698
- useEditorStore.getState().initializeWithTemplate(templateId, initialTemplate, onSave, onToast, data, onExit, onImageUpload, onDuplicate, onDelete);
28755
+ useEditorStore.getState().initializeWithTemplate(templateId, initialTemplate, onSave, onToast, data, onExit, onImageUpload, onDuplicate, onDelete, onTemplateCapture);
28699
28756
  });
28700
28757
  useAutoSave();
28701
28758
  const [editorLoading, setEditorLoading] = (0, import_react97.useState)(false);
package/dist/index.mjs CHANGED
@@ -60,7 +60,7 @@ import {
60
60
  setupDragImage,
61
61
  useEditorStore,
62
62
  useSidebarContext
63
- } from "./chunk-G7F7GRJC.mjs";
63
+ } from "./chunk-JWS6HO2H.mjs";
64
64
 
65
65
  // src/core/editor/components/email-template-v2/header.tsx
66
66
  import { ArrowLeftIcon, CopyIcon, MegaphoneIcon, MoreHorizontalIcon, PencilIcon, SendIcon, TrashIcon } from "lucide-react";
@@ -203,6 +203,43 @@ function TemplateNameDialog() {
203
203
  ] });
204
204
  }
205
205
 
206
+ // src/core/editor/utils/capture-template.ts
207
+ import { toPng } from "html-to-image";
208
+ var CAPTURE_WIDTH = 600;
209
+ async function captureTemplateImage(compiledHtml) {
210
+ const container = document.createElement("div");
211
+ container.style.position = "fixed";
212
+ container.style.top = "0";
213
+ container.style.left = "0";
214
+ container.style.zIndex = "99999";
215
+ container.style.width = `${CAPTURE_WIDTH}px`;
216
+ container.style.backgroundColor = "#FFFFFF00";
217
+ container.style.overflow = "hidden";
218
+ container.style.maxHeight = "100vh";
219
+ container.style.opacity = "0";
220
+ container.innerHTML = compiledHtml;
221
+ document.body.appendChild(container);
222
+ await new Promise((resolve) => requestAnimationFrame(resolve));
223
+ await new Promise((resolve) => setTimeout(resolve, 100));
224
+ try {
225
+ const dataUrl = await toPng(container, {
226
+ width: CAPTURE_WIDTH,
227
+ quality: 0.1,
228
+ pixelRatio: 1,
229
+ cacheBust: true,
230
+ imagePlaceholder: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mN88P/BfwAJhAPkD+pMGAAAAABJRU5ErkJggg==",
231
+ backgroundColor: "#ffffff",
232
+ fetchRequestInit: { mode: "cors" },
233
+ skipFonts: true,
234
+ // Override opacity on the cloned node (real element is opacity:0 to stay invisible)
235
+ style: { opacity: "1" }
236
+ });
237
+ return dataUrl;
238
+ } finally {
239
+ document.body.removeChild(container);
240
+ }
241
+ }
242
+
206
243
  // src/core/editor/components/email-template-v2/header.tsx
207
244
  import { jsx as jsx4, jsxs as jsxs5 } from "react/jsx-runtime";
208
245
  function TemplateHeader() {
@@ -214,14 +251,28 @@ function TemplateHeader() {
214
251
  const onExit = useEditorStore((s) => s.onExit);
215
252
  const onDuplicate = useEditorStore((s) => s.onDuplicate);
216
253
  const onDelete = useEditorStore((s) => s.onDelete);
254
+ const onTemplateCapture = useEditorStore((s) => s.onTemplateCapture);
217
255
  const templateName = useEditorStore((s) => s.template?.name);
218
256
  const handleExit = async () => {
219
257
  console.log("handleExit - templateId:", templateId);
220
258
  if (isSaving || !templateId || !onSave) return;
221
259
  setIsSaving(true);
222
260
  try {
223
- await onSave(templateId, useEditorStore.getState().template);
261
+ const template = useEditorStore.getState().template;
262
+ await onSave(templateId, template);
224
263
  markAsSaved();
264
+ if (onTemplateCapture) {
265
+ try {
266
+ const { default: mjml2html } = await import("mjml-browser");
267
+ const mjmlString = json2mjml(template, "editing");
268
+ const result = mjml2html(mjmlString);
269
+ console.log("Result:", result.html);
270
+ const imageDataUrl = await captureTemplateImage(result.html);
271
+ await onTemplateCapture(templateId, imageDataUrl);
272
+ } catch (err) {
273
+ console.error("[TemplateCapture] Failed:", err?.message || JSON.stringify(err) || err, err?.stack || "");
274
+ }
275
+ }
225
276
  onExit?.();
226
277
  console.log("handleExit - onExit called");
227
278
  } catch (error) {
@@ -11663,7 +11714,7 @@ function useAutoSave() {
11663
11714
  // src/core/editor/components/email-template-v2/template-page.tsx
11664
11715
  import "react-json-view-lite/dist/index.css";
11665
11716
  import { jsx as jsx74, jsxs as jsxs59 } from "react/jsx-runtime";
11666
- var Editor2 = lazy(() => import("./core-P3XCQRWR.mjs").then((module) => ({
11717
+ var Editor2 = lazy(() => import("./core-FT6UNZ6N.mjs").then((module) => ({
11667
11718
  default: module.Editor
11668
11719
  })));
11669
11720
  function TemplatePage({
@@ -11675,10 +11726,11 @@ function TemplatePage({
11675
11726
  onImageUpload,
11676
11727
  onDuplicate,
11677
11728
  onDelete,
11729
+ onTemplateCapture,
11678
11730
  data
11679
11731
  }) {
11680
11732
  useState25(() => {
11681
- useEditorStore.getState().initializeWithTemplate(templateId, initialTemplate, onSave, onToast, data, onExit, onImageUpload, onDuplicate, onDelete);
11733
+ useEditorStore.getState().initializeWithTemplate(templateId, initialTemplate, onSave, onToast, data, onExit, onImageUpload, onDuplicate, onDelete, onTemplateCapture);
11682
11734
  });
11683
11735
  useAutoSave();
11684
11736
  const [editorLoading, setEditorLoading] = useState25(false);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kgalexander/mcreate",
3
- "version": "1.0.2",
3
+ "version": "1.0.3",
4
4
  "description": "Maillow email template editor",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",