@kgalexander/mcreate 0.0.10 → 0.0.12

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.
@@ -216,7 +216,7 @@ function formatOpenHouseTime(time24) {
216
216
  function propertyCardMockMjml(block, context) {
217
217
  const a = block.attributes;
218
218
  const trackingClasses = context.mode === "editing" ? getTrackingClasses(context.idx, "property-card") : "";
219
- const href = a["href"] || a["link"] || "#";
219
+ const href = a["href"] || "";
220
220
  const price = formatPrice(a["price"] || "$0");
221
221
  const address = a["address"] || "123 Main Street";
222
222
  const city = a["city"] || "City, ST 00000";
@@ -384,7 +384,7 @@ function propertyCardSingleTwoMockMjml(block, context) {
384
384
  const a = block.attributes;
385
385
  const trackingClasses = context.mode === "editing" ? getTrackingClasses(context.idx, "property-card-single-two") : "";
386
386
  const uniqueId = Math.random().toString(36).slice(2, 8);
387
- const href = a["href"] || a["link"] || "#";
387
+ const href = a["href"] || "";
388
388
  const price = formatPrice(a["price"] || "$0");
389
389
  const address = a["address"] || "123 Main Street";
390
390
  const city = a["city"] || "City, ST 00000";
@@ -577,7 +577,7 @@ function propertyCardSingleTwoMockMjml(block, context) {
577
577
  // src/render/Mockup/mock-property-triple-better.ts
578
578
  function renderCard(child, childIdx, context, uniqueId, borderRadius, imageHeight, border, fontFamily, textColor, backgroundColor, innerBorderRadius) {
579
579
  const attrs = child.attributes;
580
- const href = attrs["href"] || attrs["link"] || "#";
580
+ const href = attrs["href"] || "";
581
581
  const price = formatPrice(attrs["price"] || "$0");
582
582
  const beds = formatNumber(attrs["beds"] || "--");
583
583
  const baths = formatNumber(attrs["baths"] || "--");
@@ -880,7 +880,7 @@ function propertyCardTripleToMjml(block, context) {
880
880
  const cardNum = index + 1;
881
881
  const childAttrs = child.attributes || {};
882
882
  productionAttrs[`image-src-${cardNum}`] = childAttrs["image-src"] || "";
883
- productionAttrs[`href-${cardNum}`] = childAttrs["href"] || childAttrs["link"] || "#";
883
+ productionAttrs[`href-${cardNum}`] = childAttrs["href"] || "";
884
884
  productionAttrs[`price-${cardNum}`] = childAttrs["price"] || "$0";
885
885
  productionAttrs[`beds-${cardNum}`] = childAttrs["beds"] || "--";
886
886
  productionAttrs[`baths-${cardNum}`] = childAttrs["baths"] || "--";
@@ -1008,7 +1008,7 @@ function rootChildrenToMjml(children, parentContext) {
1008
1008
  function json2mjml(template, mode = "production", options = {}) {
1009
1009
  const showCompanyFooter = template.content[0]?.data?.value?.showCompanyFooter ?? true;
1010
1010
  const footerMutation = needsCompanyFooterMutation(template);
1011
- const needsProductionFilter = mode === "production" && options?.isPaid && !showCompanyFooter;
1011
+ const needsProductionFilter = mode === "production" && (options?.isPaidLevel ?? 0) >= 1 && !showCompanyFooter;
1012
1012
  if (footerMutation || needsProductionFilter) {
1013
1013
  template = typeof structuredClone !== "undefined" ? structuredClone(template) : JSON.parse(JSON.stringify(template));
1014
1014
  }
@@ -1061,7 +1061,6 @@ function json2mjml(template, mode = "production", options = {}) {
1061
1061
  p { margin: 0px 0px 0px 0px !important; }
1062
1062
  a { color: ${linkColor}; text-decoration: none; }
1063
1063
  a span { text-decoration: underline; }
1064
- p span { text-decoration: underline; }
1065
1064
 
1066
1065
  .property-details-separator {font-family:Arial,sans-serif;color:#C3C3C3;padding:0 4px 0 2px;}
1067
1066
 
@@ -1406,7 +1405,7 @@ function createPropertyCardElement(payload) {
1406
1405
  "beds": "--",
1407
1406
  "baths": "--",
1408
1407
  "sqft": "--",
1409
- "link": "#",
1408
+ "href": "",
1410
1409
  "status": "Empty",
1411
1410
  "is-status": "show",
1412
1411
  "status-color": "#B8B8B8",
@@ -1435,7 +1434,7 @@ function createPropertyCardSingleTwoElement(payload) {
1435
1434
  "beds": "--",
1436
1435
  "baths": "--",
1437
1436
  "sqft": "--",
1438
- "link": "#",
1437
+ "href": "",
1439
1438
  "status": "Empty",
1440
1439
  "is-status": "show",
1441
1440
  "status-color": "#B8B8B8",
@@ -1522,7 +1521,7 @@ function createPropertyCardTripleItemElement(payload) {
1522
1521
  data: { value: {} },
1523
1522
  attributes: {
1524
1523
  "image-src": payload?.attributes?.["image-src"] || "https://cornerstonepropertymgmt.com/wp-content/themes/cornerstone/assets/img/nofeaturedimage.jpg",
1525
- "link": payload?.attributes?.["link"] || "#",
1524
+ "href": payload?.attributes?.["href"] || "",
1526
1525
  "price": payload?.attributes?.["price"] || "$0",
1527
1526
  "beds": payload?.attributes?.["beds"] || "--",
1528
1527
  "baths": payload?.attributes?.["baths"] || "--",
@@ -1542,6 +1541,7 @@ function createPropertyCardTripleElement(payload) {
1542
1541
  "gap": "24px",
1543
1542
  "border-radius": "0px",
1544
1543
  "border": "1px solid #d1d1d5",
1544
+ "background-color": "#ffffff",
1545
1545
  "image-height": "102px",
1546
1546
  ...payload?.attributes
1547
1547
  },
@@ -1870,6 +1870,7 @@ var defaultTemplate = {
1870
1870
  id: page.id || generateId()
1871
1871
  }))
1872
1872
  };
1873
+ var MAX_PAID_LEVEL = 3;
1873
1874
  var useEditorStore = create()(
1874
1875
  devtools(
1875
1876
  immer((set) => ({
@@ -1898,12 +1899,15 @@ var useEditorStore = create()(
1898
1899
  // Auto-save tracking
1899
1900
  lastSavedSnapshot: null,
1900
1901
  isSaving: false,
1902
+ // Subscription level (0 = free, 1-3 = paid tiers)
1903
+ isPaidLevel: 0,
1901
1904
  // Initialize store with external template (for npm package usage)
1902
- initializeWithTemplate: (templateId, template, onSave) => {
1905
+ initializeWithTemplate: (templateId, template, onSave, isPaidLevel) => {
1903
1906
  set((state) => {
1904
1907
  state.templateId = templateId;
1905
1908
  state.template = template;
1906
1909
  state.onSave = onSave ?? null;
1910
+ state.isPaidLevel = isPaidLevel ?? 0;
1907
1911
  state.templateSize = calculateTemplateSize(template);
1908
1912
  state.isAtSizeLimit = false;
1909
1913
  state.history = [cloneDeep(template)];
@@ -3055,7 +3059,7 @@ function setValueAtPath(template, path, value) {
3055
3059
  }
3056
3060
 
3057
3061
  // src/core/editor/components/ShadowDomRenderer.tsx
3058
- import { useEffect, useRef } from "react";
3062
+ import { useEffect, useRef, memo } from "react";
3059
3063
 
3060
3064
  // src/core/editor/constant/configuration.ts
3061
3065
  import { AlignCenterIcon, AlignJustifyIcon, AlignLeftIcon, AlignRightIcon, Heading1Icon, Heading2Icon, Heading3Icon, LinkIcon, ListIcon, ListOrderedIcon, MailIcon, PhoneIcon, Pilcrow } from "lucide-react";
@@ -3495,7 +3499,7 @@ function getEditorStyles(isDragButtonHovered, textEditingIdx) {
3495
3499
  cssCache.set(cacheKey, css);
3496
3500
  return css;
3497
3501
  }
3498
- function ShadowDomRenderer({
3502
+ var ShadowDomRenderer = memo(function ShadowDomRenderer2({
3499
3503
  html,
3500
3504
  focusIdx,
3501
3505
  hoverIdx,
@@ -3523,6 +3527,8 @@ function ShadowDomRenderer({
3523
3527
  const shadowRootRef = useRef(null);
3524
3528
  const rafRef = useRef(null);
3525
3529
  const lastBlockNodeRef = useRef(null);
3530
+ const hoverRafRef = useRef(null);
3531
+ const lastHoverIdxRef = useRef(null);
3526
3532
  const callbackRefs = useRef({
3527
3533
  onElementClick,
3528
3534
  onElementHover,
@@ -3753,14 +3759,19 @@ function ShadowDomRenderer({
3753
3759
  const handleMouseOver = (e) => {
3754
3760
  const target = e.target;
3755
3761
  const blockNode = target.closest(`.${EMAIL_BLOCK_CLASS_NAME}`);
3756
- if (blockNode && callbackRefs.current.onElementHover) {
3757
- const idx = getIdxFromElement(blockNode);
3758
- callbackRefs.current.onElementHover(idx || null);
3759
- }
3762
+ const newIdx = blockNode ? getIdxFromElement(blockNode) : null;
3763
+ if (newIdx === lastHoverIdxRef.current) return;
3764
+ if (hoverRafRef.current) return;
3765
+ hoverRafRef.current = requestAnimationFrame(() => {
3766
+ hoverRafRef.current = null;
3767
+ lastHoverIdxRef.current = newIdx;
3768
+ callbackRefs.current.onElementHover?.(newIdx);
3769
+ });
3760
3770
  };
3761
3771
  const handleMouseOut = (e) => {
3762
3772
  const relatedTarget = e.relatedTarget;
3763
3773
  if (!relatedTarget || !shadowRoot.contains(relatedTarget)) {
3774
+ lastHoverIdxRef.current = null;
3764
3775
  callbackRefs.current.onElementHover?.(null);
3765
3776
  }
3766
3777
  };
@@ -3991,6 +4002,11 @@ function ShadowDomRenderer({
3991
4002
  rafRef.current = null;
3992
4003
  }
3993
4004
  lastBlockNodeRef.current = null;
4005
+ if (hoverRafRef.current) {
4006
+ cancelAnimationFrame(hoverRafRef.current);
4007
+ hoverRafRef.current = null;
4008
+ }
4009
+ lastHoverIdxRef.current = null;
3994
4010
  shadowRoot.removeEventListener("mousedown", handleMouseDown);
3995
4011
  shadowRoot.removeEventListener("click", handleLinkClick, true);
3996
4012
  shadowRoot.removeEventListener("mouseover", handleMouseOver);
@@ -4067,7 +4083,7 @@ function ShadowDomRenderer({
4067
4083
  }
4068
4084
  )
4069
4085
  ] });
4070
- }
4086
+ });
4071
4087
  function getIdxFromElement(element) {
4072
4088
  const classList = element.classList;
4073
4089
  for (let i = 0; i < classList.length; i++) {
@@ -12260,7 +12276,7 @@ var useHref = () => {
12260
12276
  }
12261
12277
  }
12262
12278
  }, [href]);
12263
- const hasHref = Boolean(href && href !== "#" && href.trim() !== "");
12279
+ const hasHref = Boolean(href && href !== "" && href.trim() !== "");
12264
12280
  return {
12265
12281
  href,
12266
12282
  setHref,
@@ -13976,20 +13992,11 @@ async function compileMjml(mjml) {
13976
13992
  return result;
13977
13993
  }
13978
13994
 
13979
- // src/core/editor/hooks/use-user.ts
13980
- function useUser() {
13981
- return {
13982
- isPaid: true
13983
- // toggle to true for testing paid features
13984
- };
13985
- }
13986
-
13987
13995
  // src/core/editor/components/preview.tsx
13988
13996
  import { useEffect as useEffect18, useState as useState14, useRef as useRef10 } from "react";
13989
13997
  import { jsx as jsx47, jsxs as jsxs28 } from "react/jsx-runtime";
13990
13998
  function Preview() {
13991
- const { isPaid } = useUser();
13992
- const { template, setPreviewMode, previewMode } = useEditorStore();
13999
+ const { template, setPreviewMode, previewMode, isPaidLevel } = useEditorStore();
13993
14000
  const [html, setHtml] = useState14("");
13994
14001
  const [isLoading, setIsLoading] = useState14(false);
13995
14002
  const lastTemplateRef = useRef10("");
@@ -14009,7 +14016,7 @@ function Preview() {
14009
14016
  setIsLoading(true);
14010
14017
  const convertMjml = async () => {
14011
14018
  try {
14012
- const mjmlString = json2mjml(template, "production", { isPaid });
14019
+ const mjmlString = json2mjml(template, "production", { isPaidLevel });
14013
14020
  console.log("MJML string:", mjmlString);
14014
14021
  const result = await compileMjml(mjmlString);
14015
14022
  if (result.errors?.length > 0) {
@@ -15065,6 +15072,7 @@ export {
15065
15072
  parsePrice,
15066
15073
  json2mjml,
15067
15074
  MAX_TEMPLATE_SIZE,
15075
+ MAX_PAID_LEVEL,
15068
15076
  useEditorStore,
15069
15077
  BUTTON_ALIGNMENTS,
15070
15078
  ALIGNMENT_ICONS,
@@ -15113,7 +15121,6 @@ export {
15113
15121
  SidebarProvider,
15114
15122
  useSidebarContext,
15115
15123
  Textarea,
15116
- useUser,
15117
15124
  Preview,
15118
15125
  History,
15119
15126
  MAILLOW_EMAIL_EDITOR_VERSION,
@@ -5,7 +5,7 @@ import {
5
5
  MAILLOW_EMAIL_EDITOR_VERSION,
6
6
  Preview,
7
7
  useEditorStore
8
- } from "./chunk-WO43X63M.mjs";
8
+ } from "./chunk-PL5EKNN6.mjs";
9
9
  export {
10
10
  Editor,
11
11
  History,
package/dist/index.d.mts CHANGED
@@ -260,6 +260,7 @@ type TemplateJSON = {
260
260
  };
261
261
 
262
262
  type OnSaveCallback = (templateId: string, template: TemplateJSON) => void | Promise<void>;
263
+ type PaidLevel = 0 | 1 | 2 | 3;
263
264
 
264
265
  interface EditorProps {
265
266
  setEditorLoading?: (loading: boolean) => void;
@@ -267,10 +268,11 @@ interface EditorProps {
267
268
  }
268
269
  declare function Editor({ setEditorLoading }: EditorProps): react_jsx_runtime.JSX.Element;
269
270
 
270
- declare function TemplatePage({ templateId, initialTemplate, onSave }: {
271
+ declare function TemplatePage({ templateId, initialTemplate, onSave, isPaidLevel }: {
271
272
  templateId: string;
272
273
  initialTemplate: TemplateJSON;
273
274
  onSave?: OnSaveCallback;
275
+ isPaidLevel?: PaidLevel;
274
276
  }): react_jsx_runtime.JSX.Element;
275
277
 
276
278
  /**
@@ -280,7 +282,7 @@ declare function TemplatePage({ templateId, initialTemplate, onSave }: {
280
282
 
281
283
  type RenderMode = 'production' | 'editing';
282
284
  interface RenderOptions {
283
- isPaid?: boolean;
285
+ isPaidLevel?: number;
284
286
  }
285
287
  /**
286
288
  * Convert template JSON to MJML string
@@ -291,4 +293,4 @@ interface RenderOptions {
291
293
  */
292
294
  declare function json2mjml(template: TemplateJSON, mode?: RenderMode, options?: RenderOptions): string;
293
295
 
294
- export { Editor, type OnSaveCallback, type TemplateJSON, TemplatePage, json2mjml };
296
+ export { Editor, type OnSaveCallback, type PaidLevel, type TemplateJSON, TemplatePage, json2mjml };
package/dist/index.d.ts CHANGED
@@ -260,6 +260,7 @@ type TemplateJSON = {
260
260
  };
261
261
 
262
262
  type OnSaveCallback = (templateId: string, template: TemplateJSON) => void | Promise<void>;
263
+ type PaidLevel = 0 | 1 | 2 | 3;
263
264
 
264
265
  interface EditorProps {
265
266
  setEditorLoading?: (loading: boolean) => void;
@@ -267,10 +268,11 @@ interface EditorProps {
267
268
  }
268
269
  declare function Editor({ setEditorLoading }: EditorProps): react_jsx_runtime.JSX.Element;
269
270
 
270
- declare function TemplatePage({ templateId, initialTemplate, onSave }: {
271
+ declare function TemplatePage({ templateId, initialTemplate, onSave, isPaidLevel }: {
271
272
  templateId: string;
272
273
  initialTemplate: TemplateJSON;
273
274
  onSave?: OnSaveCallback;
275
+ isPaidLevel?: PaidLevel;
274
276
  }): react_jsx_runtime.JSX.Element;
275
277
 
276
278
  /**
@@ -280,7 +282,7 @@ declare function TemplatePage({ templateId, initialTemplate, onSave }: {
280
282
 
281
283
  type RenderMode = 'production' | 'editing';
282
284
  interface RenderOptions {
283
- isPaid?: boolean;
285
+ isPaidLevel?: number;
284
286
  }
285
287
  /**
286
288
  * Convert template JSON to MJML string
@@ -291,4 +293,4 @@ interface RenderOptions {
291
293
  */
292
294
  declare function json2mjml(template: TemplateJSON, mode?: RenderMode, options?: RenderOptions): string;
293
295
 
294
- export { Editor, type OnSaveCallback, type TemplateJSON, TemplatePage, json2mjml };
296
+ export { Editor, type OnSaveCallback, type PaidLevel, type TemplateJSON, TemplatePage, json2mjml };