@kgalexander/mcreate 1.0.8 → 1.0.9

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.
@@ -14702,6 +14702,16 @@ function validate_editor_onPreview(template, mergeFields) {
14702
14702
  const is_over_size_limit = templateSize > 50 * 1024;
14703
14703
  return { invalid_merge_fields, missing_links, is_over_size_limit, placeholder_property_images };
14704
14704
  }
14705
+ function validate_campaign_onCreate() {
14706
+ return true;
14707
+ }
14708
+ function campaign_validation_warnings() {
14709
+ return {
14710
+ invalid_merge_fields: true,
14711
+ missing_properties_attributes: true,
14712
+ missing_links: true
14713
+ };
14714
+ }
14705
14715
 
14706
14716
  // src/core/editor/components/preview.tsx
14707
14717
  import { jsx as jsx49, jsxs as jsxs30 } from "react/jsx-runtime";
@@ -16079,6 +16089,9 @@ export {
16079
16089
  SidebarProvider,
16080
16090
  useSidebarContext,
16081
16091
  Textarea,
16092
+ validate_editor_onPreview,
16093
+ validate_campaign_onCreate,
16094
+ campaign_validation_warnings,
16082
16095
  Preview,
16083
16096
  History,
16084
16097
  MAILLOW_EMAIL_EDITOR_VERSION,
@@ -5,7 +5,7 @@ import {
5
5
  MAILLOW_EMAIL_EDITOR_VERSION,
6
6
  Preview,
7
7
  useEditorStore
8
- } from "./chunk-FJ4KXNNM.mjs";
8
+ } from "./chunk-R3LRNUKL.mjs";
9
9
  export {
10
10
  Editor,
11
11
  History,
package/dist/index.d.mts CHANGED
@@ -320,6 +320,38 @@ declare function TemplatePage({ templateId, initialTemplate, onSave, onToast, on
320
320
 
321
321
  declare const MAX_TEMPLATE_SIZE: number;
322
322
 
323
+ interface MergeFieldType {
324
+ label: string;
325
+ value: string;
326
+ }
327
+ interface MissingLinkType {
328
+ type: 'button' | 'social-item';
329
+ label: string;
330
+ }
331
+ interface PreviewValidationType {
332
+ invalid_merge_fields: string[];
333
+ missing_links: MissingLinkType[];
334
+ is_over_size_limit: boolean;
335
+ placeholder_property_images: number;
336
+ }
337
+
338
+ /**
339
+ * Validate a template when the user previews the template
340
+ */
341
+ declare function validate_editor_onPreview(template: any, mergeFields: MergeFieldType[]): PreviewValidationType;
342
+ /**
343
+ * Validate a campaign template when the user creates a new campaign
344
+ */
345
+ declare function validate_campaign_onCreate(): boolean;
346
+ /**
347
+ * Return validation warnings for a campaign template
348
+ */
349
+ declare function campaign_validation_warnings(): {
350
+ invalid_merge_fields: boolean;
351
+ missing_properties_attributes: boolean;
352
+ missing_links: boolean;
353
+ };
354
+
323
355
  /**
324
356
  * JSON to MJML Converter
325
357
  * Converts template JSON to MJML string for rendering
@@ -338,4 +370,4 @@ interface RenderOptions {
338
370
  */
339
371
  declare function json2mjml(template: TemplateJSON, mode?: RenderMode, options?: RenderOptions): string;
340
372
 
341
- 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 };
373
+ export { Editor, type ImageData, MAX_TEMPLATE_SIZE, type MergeField, type MergeFieldType, type MissingLinkType, type OnDeleteCallback, type OnDuplicateCallback, type OnExitCallback, type OnImageUploadCallback, type OnSaveCallback, type OnToastCallback, type PaidLevel, type PreviewValidationType, type TemplateJSON, TemplatePage, type ToastOptions, type ToastType, campaign_validation_warnings, json2mjml, validate_campaign_onCreate, validate_editor_onPreview };
package/dist/index.d.ts CHANGED
@@ -320,6 +320,38 @@ declare function TemplatePage({ templateId, initialTemplate, onSave, onToast, on
320
320
 
321
321
  declare const MAX_TEMPLATE_SIZE: number;
322
322
 
323
+ interface MergeFieldType {
324
+ label: string;
325
+ value: string;
326
+ }
327
+ interface MissingLinkType {
328
+ type: 'button' | 'social-item';
329
+ label: string;
330
+ }
331
+ interface PreviewValidationType {
332
+ invalid_merge_fields: string[];
333
+ missing_links: MissingLinkType[];
334
+ is_over_size_limit: boolean;
335
+ placeholder_property_images: number;
336
+ }
337
+
338
+ /**
339
+ * Validate a template when the user previews the template
340
+ */
341
+ declare function validate_editor_onPreview(template: any, mergeFields: MergeFieldType[]): PreviewValidationType;
342
+ /**
343
+ * Validate a campaign template when the user creates a new campaign
344
+ */
345
+ declare function validate_campaign_onCreate(): boolean;
346
+ /**
347
+ * Return validation warnings for a campaign template
348
+ */
349
+ declare function campaign_validation_warnings(): {
350
+ invalid_merge_fields: boolean;
351
+ missing_properties_attributes: boolean;
352
+ missing_links: boolean;
353
+ };
354
+
323
355
  /**
324
356
  * JSON to MJML Converter
325
357
  * Converts template JSON to MJML string for rendering
@@ -338,4 +370,4 @@ interface RenderOptions {
338
370
  */
339
371
  declare function json2mjml(template: TemplateJSON, mode?: RenderMode, options?: RenderOptions): string;
340
372
 
341
- 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 };
373
+ export { Editor, type ImageData, MAX_TEMPLATE_SIZE, type MergeField, type MergeFieldType, type MissingLinkType, type OnDeleteCallback, type OnDuplicateCallback, type OnExitCallback, type OnImageUploadCallback, type OnSaveCallback, type OnToastCallback, type PaidLevel, type PreviewValidationType, type TemplateJSON, TemplatePage, type ToastOptions, type ToastType, campaign_validation_warnings, json2mjml, validate_campaign_onCreate, validate_editor_onPreview };
package/dist/index.js CHANGED
@@ -15409,6 +15409,16 @@ function validate_editor_onPreview(template, mergeFields) {
15409
15409
  const is_over_size_limit = templateSize > 50 * 1024;
15410
15410
  return { invalid_merge_fields, missing_links, is_over_size_limit, placeholder_property_images };
15411
15411
  }
15412
+ function validate_campaign_onCreate() {
15413
+ return true;
15414
+ }
15415
+ function campaign_validation_warnings() {
15416
+ return {
15417
+ invalid_merge_fields: true,
15418
+ missing_properties_attributes: true,
15419
+ missing_links: true
15420
+ };
15421
+ }
15412
15422
  var PROPERTY_CARD_TYPES;
15413
15423
  var init_validate = __esm({
15414
15424
  "src/validate/index.ts"() {
@@ -16804,7 +16814,10 @@ __export(index_exports, {
16804
16814
  Editor: () => Editor,
16805
16815
  MAX_TEMPLATE_SIZE: () => MAX_TEMPLATE_SIZE,
16806
16816
  TemplatePage: () => TemplatePage,
16807
- json2mjml: () => json2mjml
16817
+ campaign_validation_warnings: () => campaign_validation_warnings,
16818
+ json2mjml: () => json2mjml,
16819
+ validate_campaign_onCreate: () => validate_campaign_onCreate,
16820
+ validate_editor_onPreview: () => validate_editor_onPreview
16808
16821
  });
16809
16822
  module.exports = __toCommonJS(index_exports);
16810
16823
  init_core();
@@ -19583,7 +19596,7 @@ init_editor();
19583
19596
  init_label();
19584
19597
  init_popover();
19585
19598
 
19586
- // node_modules/color-name/index.js
19599
+ // node_modules/color-string/node_modules/color-name/index.js
19587
19600
  var colors = {
19588
19601
  aliceblue: [240, 248, 255],
19589
19602
  antiquewhite: [250, 235, 215],
@@ -19905,10 +19918,164 @@ function hexDouble(number_) {
19905
19918
  }
19906
19919
  var color_string_default = cs;
19907
19920
 
19908
- // node_modules/color-convert/conversions.js
19921
+ // node_modules/color/node_modules/color-name/index.js
19922
+ var colors2 = {
19923
+ aliceblue: [240, 248, 255],
19924
+ antiquewhite: [250, 235, 215],
19925
+ aqua: [0, 255, 255],
19926
+ aquamarine: [127, 255, 212],
19927
+ azure: [240, 255, 255],
19928
+ beige: [245, 245, 220],
19929
+ bisque: [255, 228, 196],
19930
+ black: [0, 0, 0],
19931
+ blanchedalmond: [255, 235, 205],
19932
+ blue: [0, 0, 255],
19933
+ blueviolet: [138, 43, 226],
19934
+ brown: [165, 42, 42],
19935
+ burlywood: [222, 184, 135],
19936
+ cadetblue: [95, 158, 160],
19937
+ chartreuse: [127, 255, 0],
19938
+ chocolate: [210, 105, 30],
19939
+ coral: [255, 127, 80],
19940
+ cornflowerblue: [100, 149, 237],
19941
+ cornsilk: [255, 248, 220],
19942
+ crimson: [220, 20, 60],
19943
+ cyan: [0, 255, 255],
19944
+ darkblue: [0, 0, 139],
19945
+ darkcyan: [0, 139, 139],
19946
+ darkgoldenrod: [184, 134, 11],
19947
+ darkgray: [169, 169, 169],
19948
+ darkgreen: [0, 100, 0],
19949
+ darkgrey: [169, 169, 169],
19950
+ darkkhaki: [189, 183, 107],
19951
+ darkmagenta: [139, 0, 139],
19952
+ darkolivegreen: [85, 107, 47],
19953
+ darkorange: [255, 140, 0],
19954
+ darkorchid: [153, 50, 204],
19955
+ darkred: [139, 0, 0],
19956
+ darksalmon: [233, 150, 122],
19957
+ darkseagreen: [143, 188, 143],
19958
+ darkslateblue: [72, 61, 139],
19959
+ darkslategray: [47, 79, 79],
19960
+ darkslategrey: [47, 79, 79],
19961
+ darkturquoise: [0, 206, 209],
19962
+ darkviolet: [148, 0, 211],
19963
+ deeppink: [255, 20, 147],
19964
+ deepskyblue: [0, 191, 255],
19965
+ dimgray: [105, 105, 105],
19966
+ dimgrey: [105, 105, 105],
19967
+ dodgerblue: [30, 144, 255],
19968
+ firebrick: [178, 34, 34],
19969
+ floralwhite: [255, 250, 240],
19970
+ forestgreen: [34, 139, 34],
19971
+ fuchsia: [255, 0, 255],
19972
+ gainsboro: [220, 220, 220],
19973
+ ghostwhite: [248, 248, 255],
19974
+ gold: [255, 215, 0],
19975
+ goldenrod: [218, 165, 32],
19976
+ gray: [128, 128, 128],
19977
+ green: [0, 128, 0],
19978
+ greenyellow: [173, 255, 47],
19979
+ grey: [128, 128, 128],
19980
+ honeydew: [240, 255, 240],
19981
+ hotpink: [255, 105, 180],
19982
+ indianred: [205, 92, 92],
19983
+ indigo: [75, 0, 130],
19984
+ ivory: [255, 255, 240],
19985
+ khaki: [240, 230, 140],
19986
+ lavender: [230, 230, 250],
19987
+ lavenderblush: [255, 240, 245],
19988
+ lawngreen: [124, 252, 0],
19989
+ lemonchiffon: [255, 250, 205],
19990
+ lightblue: [173, 216, 230],
19991
+ lightcoral: [240, 128, 128],
19992
+ lightcyan: [224, 255, 255],
19993
+ lightgoldenrodyellow: [250, 250, 210],
19994
+ lightgray: [211, 211, 211],
19995
+ lightgreen: [144, 238, 144],
19996
+ lightgrey: [211, 211, 211],
19997
+ lightpink: [255, 182, 193],
19998
+ lightsalmon: [255, 160, 122],
19999
+ lightseagreen: [32, 178, 170],
20000
+ lightskyblue: [135, 206, 250],
20001
+ lightslategray: [119, 136, 153],
20002
+ lightslategrey: [119, 136, 153],
20003
+ lightsteelblue: [176, 196, 222],
20004
+ lightyellow: [255, 255, 224],
20005
+ lime: [0, 255, 0],
20006
+ limegreen: [50, 205, 50],
20007
+ linen: [250, 240, 230],
20008
+ magenta: [255, 0, 255],
20009
+ maroon: [128, 0, 0],
20010
+ mediumaquamarine: [102, 205, 170],
20011
+ mediumblue: [0, 0, 205],
20012
+ mediumorchid: [186, 85, 211],
20013
+ mediumpurple: [147, 112, 219],
20014
+ mediumseagreen: [60, 179, 113],
20015
+ mediumslateblue: [123, 104, 238],
20016
+ mediumspringgreen: [0, 250, 154],
20017
+ mediumturquoise: [72, 209, 204],
20018
+ mediumvioletred: [199, 21, 133],
20019
+ midnightblue: [25, 25, 112],
20020
+ mintcream: [245, 255, 250],
20021
+ mistyrose: [255, 228, 225],
20022
+ moccasin: [255, 228, 181],
20023
+ navajowhite: [255, 222, 173],
20024
+ navy: [0, 0, 128],
20025
+ oldlace: [253, 245, 230],
20026
+ olive: [128, 128, 0],
20027
+ olivedrab: [107, 142, 35],
20028
+ orange: [255, 165, 0],
20029
+ orangered: [255, 69, 0],
20030
+ orchid: [218, 112, 214],
20031
+ palegoldenrod: [238, 232, 170],
20032
+ palegreen: [152, 251, 152],
20033
+ paleturquoise: [175, 238, 238],
20034
+ palevioletred: [219, 112, 147],
20035
+ papayawhip: [255, 239, 213],
20036
+ peachpuff: [255, 218, 185],
20037
+ peru: [205, 133, 63],
20038
+ pink: [255, 192, 203],
20039
+ plum: [221, 160, 221],
20040
+ powderblue: [176, 224, 230],
20041
+ purple: [128, 0, 128],
20042
+ rebeccapurple: [102, 51, 153],
20043
+ red: [255, 0, 0],
20044
+ rosybrown: [188, 143, 143],
20045
+ royalblue: [65, 105, 225],
20046
+ saddlebrown: [139, 69, 19],
20047
+ salmon: [250, 128, 114],
20048
+ sandybrown: [244, 164, 96],
20049
+ seagreen: [46, 139, 87],
20050
+ seashell: [255, 245, 238],
20051
+ sienna: [160, 82, 45],
20052
+ silver: [192, 192, 192],
20053
+ skyblue: [135, 206, 235],
20054
+ slateblue: [106, 90, 205],
20055
+ slategray: [112, 128, 144],
20056
+ slategrey: [112, 128, 144],
20057
+ snow: [255, 250, 250],
20058
+ springgreen: [0, 255, 127],
20059
+ steelblue: [70, 130, 180],
20060
+ tan: [210, 180, 140],
20061
+ teal: [0, 128, 128],
20062
+ thistle: [216, 191, 216],
20063
+ tomato: [255, 99, 71],
20064
+ turquoise: [64, 224, 208],
20065
+ violet: [238, 130, 238],
20066
+ wheat: [245, 222, 179],
20067
+ white: [255, 255, 255],
20068
+ whitesmoke: [245, 245, 245],
20069
+ yellow: [255, 255, 0],
20070
+ yellowgreen: [154, 205, 50]
20071
+ };
20072
+ for (const key in colors2) Object.freeze(colors2[key]);
20073
+ var color_name_default2 = Object.freeze(colors2);
20074
+
20075
+ // node_modules/color/node_modules/color-convert/conversions.js
19909
20076
  var reverseKeywords = {};
19910
- for (const key of Object.keys(color_name_default)) {
19911
- reverseKeywords[color_name_default[key]] = key;
20077
+ for (const key of Object.keys(color_name_default2)) {
20078
+ reverseKeywords[color_name_default2[key]] = key;
19912
20079
  }
19913
20080
  var convert = {
19914
20081
  rgb: { channels: 3, labels: "rgb" },
@@ -20084,8 +20251,8 @@ convert.rgb.keyword = function(rgb) {
20084
20251
  }
20085
20252
  let currentClosestDistance = Number.POSITIVE_INFINITY;
20086
20253
  let currentClosestKeyword;
20087
- for (const keyword of Object.keys(color_name_default)) {
20088
- const value = color_name_default[keyword];
20254
+ for (const keyword of Object.keys(color_name_default2)) {
20255
+ const value = color_name_default2[keyword];
20089
20256
  const distance = comparativeDistance(rgb, value);
20090
20257
  if (distance < currentClosestDistance) {
20091
20258
  currentClosestDistance = distance;
@@ -20095,7 +20262,7 @@ convert.rgb.keyword = function(rgb) {
20095
20262
  return currentClosestKeyword;
20096
20263
  };
20097
20264
  convert.keyword.rgb = function(keyword) {
20098
- return [...color_name_default[keyword]];
20265
+ return [...color_name_default2[keyword]];
20099
20266
  };
20100
20267
  convert.rgb.xyz = function(rgb) {
20101
20268
  const r = srgbNonlinearTransformInv(rgb[0] / 255);
@@ -20653,7 +20820,7 @@ convert.rgb.gray = function(rgb) {
20653
20820
  return [value / 255 * 100];
20654
20821
  };
20655
20822
 
20656
- // node_modules/color-convert/route.js
20823
+ // node_modules/color/node_modules/color-convert/route.js
20657
20824
  function buildGraph() {
20658
20825
  const graph = {};
20659
20826
  const models2 = Object.keys(conversions_default);
@@ -20719,7 +20886,7 @@ function route(fromModel) {
20719
20886
  }
20720
20887
  var route_default = route;
20721
20888
 
20722
- // node_modules/color-convert/index.js
20889
+ // node_modules/color/node_modules/color-convert/index.js
20723
20890
  var convert2 = {};
20724
20891
  var models = Object.keys(conversions_default);
20725
20892
  function wrapRaw(fn) {
@@ -21356,7 +21523,7 @@ var ColorPickerEyeDropper = ({ className, ...props }) => {
21356
21523
  return /* @__PURE__ */ (0, import_jsx_runtime77.jsx)(
21357
21524
  Button,
21358
21525
  {
21359
- className: cn("shrink-0 text-muted-foreground", className),
21526
+ className: cn("shrink-0 text-muted-foreground shadow-none", className),
21360
21527
  onClick: handleEyeDropper,
21361
21528
  size: "icon",
21362
21529
  type: "button",
@@ -21388,26 +21555,23 @@ var ColorPickerFormat = ({ className, ...props }) => {
21388
21555
  const color = color_default.hsl(hue, saturation, lightness, alpha2 / 100);
21389
21556
  if (mode === "hex") {
21390
21557
  const hex = color.hex();
21391
- return /* @__PURE__ */ (0, import_jsx_runtime77.jsxs)(
21558
+ return /* @__PURE__ */ (0, import_jsx_runtime77.jsx)(
21392
21559
  "div",
21393
21560
  {
21394
21561
  className: cn(
21395
- "-space-x-px relative flex w-full items-center rounded-md shadow-sm",
21562
+ "-space-x-px relative flex w-full items-center rounded-[12px] shadow-none",
21396
21563
  className
21397
21564
  ),
21398
21565
  ...props,
21399
- children: [
21400
- /* @__PURE__ */ (0, import_jsx_runtime77.jsx)(
21401
- Input,
21402
- {
21403
- className: "h-8 rounded-r-none bg-secondary px-2 text-xs shadow-none",
21404
- readOnly: true,
21405
- type: "text",
21406
- value: hex
21407
- }
21408
- ),
21409
- /* @__PURE__ */ (0, import_jsx_runtime77.jsx)(PercentageInput, { value: alpha2 })
21410
- ]
21566
+ children: /* @__PURE__ */ (0, import_jsx_runtime77.jsx)(
21567
+ Input,
21568
+ {
21569
+ className: "h-[32px] py-0 pr-10 bg-accent dark:bg-accent border-border placeholder:text-muted-foreground rounded-[12px] shadow-none w-full",
21570
+ readOnly: true,
21571
+ type: "text",
21572
+ value: hex
21573
+ }
21574
+ )
21411
21575
  }
21412
21576
  );
21413
21577
  }
@@ -21636,14 +21800,11 @@ function ColorSelection({ setActiveView, lastView, onColorSelect, colorType = "C
21636
21800
  ] }) })
21637
21801
  ] }),
21638
21802
  colorPalettes.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("div", { className: "w-full mb-4", children: [
21639
- /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("div", { className: "flex flex-row items-center justify-between w-full mb-1", children: [
21640
- /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("div", { className: "flex flex-row items-center gap-2 h-[44px]", children: [
21641
- /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(import_lucide_react49.Hexagon, { className: "w-4 h-4 text-muted-foreground" }),
21642
- /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("p", { className: "text-sm font-medium", children: "Brand colors" })
21643
- ] }),
21644
- /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(Button, { variant: "link", className: "text-sm pr-0 cursor-pointer", children: "Edit" })
21645
- ] }),
21646
- /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("div", { className: "w-full flex flex-col gap-4", children: colorPalettes.map((palette) => /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("div", { className: "flex flex-col gap-2", children: [
21803
+ /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("div", { className: "flex flex-row items-center justify-between w-full mb-1", children: /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("div", { className: "flex flex-row items-center gap-2 h-[44px]", children: [
21804
+ /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(import_lucide_react49.Hexagon, { className: "w-4 h-4 text-muted-foreground" }),
21805
+ /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("p", { className: "text-sm font-medium", children: "Brand colors" })
21806
+ ] }) }),
21807
+ /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("div", { className: "w-full flex flex-col gap-4", children: colorPalettes.map((palette) => palette.colors.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("div", { className: "flex flex-col gap-2", children: [
21647
21808
  /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(Label, { className: "text-xs font-medium text-muted-foreground", children: palette.name }),
21648
21809
  /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("div", { className: "w-full grid grid-cols-7 gap-2", children: palette.colors.map((c) => /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(ColorButton, { colorName: c.name, color: c.hex, onColorSelect, currentColor }, c.color_id)) })
21649
21810
  ] }, palette.palette_id)) })
@@ -24134,6 +24295,15 @@ var parseFontSize = (value) => {
24134
24295
  // src/core/editor/components/element-gear/text/toolbar.tsx
24135
24296
  var import_jsx_runtime102 = require("react/jsx-runtime");
24136
24297
  var ALIGNMENTS = ["left", "center", "right", "justify"];
24298
+ var TEXT_TYPE_TO_BRAND_FONT = {
24299
+ h1: "heading",
24300
+ h2: "subheading",
24301
+ h3: "subheading",
24302
+ paragraph: "body",
24303
+ list: "body",
24304
+ "numbered-list": "body",
24305
+ ordered: "body"
24306
+ };
24137
24307
  var HEADING_MULTIPLIERS = {
24138
24308
  paragraph: 1,
24139
24309
  h1: 2,
@@ -24153,7 +24323,16 @@ var TextToolbar = () => {
24153
24323
  const textEditingStyles = useEditorStore((s) => s.textEditing?.styles);
24154
24324
  const template = useEditorStore((s) => s.template);
24155
24325
  const mergeFields = useEditorStore((s) => s.mergeFields);
24326
+ const userData = useEditorStore((s) => s.userData);
24156
24327
  const { activeView, colorTarget, setActiveView, setColorType, setColorTarget } = useSidebarContext();
24328
+ const brandFonts = (0, import_react71.useMemo)(() => {
24329
+ const fonts = userData?.brand_kits?.[0]?.fonts ?? [];
24330
+ const map = {};
24331
+ for (const f of fonts) {
24332
+ map[f.type] = f;
24333
+ }
24334
+ return map;
24335
+ }, [userData]);
24157
24336
  const [updateCounter, forceUpdate] = (0, import_react71.useState)(0);
24158
24337
  const [overflowOpen, setOverflowOpen] = (0, import_react71.useState)(false);
24159
24338
  const isInSectionColumn = (0, import_react71.useMemo)(() => {
@@ -24277,8 +24456,28 @@ var TextToolbar = () => {
24277
24456
  };
24278
24457
  const level = levelMap[type];
24279
24458
  tiptapEditor.chain().focus().setHeadingLevel(level).run();
24459
+ const brandFontType = TEXT_TYPE_TO_BRAND_FONT[type];
24460
+ const brandFont = brandFontType ? brandFonts[brandFontType] : null;
24461
+ if (brandFont) {
24462
+ const { from, to } = tiptapEditor.state.selection;
24463
+ const $from = tiptapEditor.state.doc.resolve(from);
24464
+ const paragraphStart = $from.start($from.depth);
24465
+ const paragraphEnd = $from.end($from.depth);
24466
+ let chain = tiptapEditor.chain().setTextSelection({ from: paragraphStart, to: paragraphEnd }).setFontFamily(brandFont.family).setFontSize(`${brandFont.size}px`);
24467
+ if (level > 0 && !brandFont.isBold) {
24468
+ chain = chain.unsetMark("bold");
24469
+ } else if (level === 0 && brandFont.isBold) {
24470
+ chain = chain.setMark("bold");
24471
+ }
24472
+ if (brandFont.isItalic) {
24473
+ chain = chain.setMark("italic");
24474
+ } else {
24475
+ chain = chain.unsetMark("italic");
24476
+ }
24477
+ chain.setTextSelection({ from, to }).focus().run();
24478
+ }
24280
24479
  forceUpdate((n) => n + 1);
24281
- }, [tiptapEditor]);
24480
+ }, [tiptapEditor, brandFonts]);
24282
24481
  const handleDelete = () => {
24283
24482
  if (focusIdx) {
24284
24483
  deleteElement(focusIdx);
@@ -28812,11 +29011,15 @@ function TemplatePage({
28812
29011
 
28813
29012
  // src/index.tsx
28814
29013
  init_configuration();
29014
+ init_validate();
28815
29015
  init_json2mjml();
28816
29016
  // Annotate the CommonJS export names for ESM import in node:
28817
29017
  0 && (module.exports = {
28818
29018
  Editor,
28819
29019
  MAX_TEMPLATE_SIZE,
28820
29020
  TemplatePage,
28821
- json2mjml
29021
+ campaign_validation_warnings,
29022
+ json2mjml,
29023
+ validate_campaign_onCreate,
29024
+ validate_editor_onPreview
28822
29025
  });
package/dist/index.mjs CHANGED
@@ -48,6 +48,7 @@ import {
48
48
  Tooltip,
49
49
  TooltipContent,
50
50
  TooltipTrigger,
51
+ campaign_validation_warnings,
51
52
  cn,
52
53
  formatBorder,
53
54
  getElementDisplayName,
@@ -59,8 +60,10 @@ import {
59
60
  parsePrice,
60
61
  setupDragImage,
61
62
  useEditorStore,
62
- useSidebarContext
63
- } from "./chunk-FJ4KXNNM.mjs";
63
+ useSidebarContext,
64
+ validate_campaign_onCreate,
65
+ validate_editor_onPreview
66
+ } from "./chunk-R3LRNUKL.mjs";
64
67
 
65
68
  // src/core/editor/components/email-template-v2/header.tsx
66
69
  import { ArrowLeftIcon, CopyIcon, MegaphoneIcon, MoreHorizontalIcon, PencilIcon, SendIcon, TrashIcon } from "lucide-react";
@@ -2761,7 +2764,7 @@ function useTemplateColors() {
2761
2764
  return useMemo3(() => getTemplateColors(template), [template]);
2762
2765
  }
2763
2766
 
2764
- // node_modules/color-name/index.js
2767
+ // node_modules/color-string/node_modules/color-name/index.js
2765
2768
  var colors = {
2766
2769
  aliceblue: [240, 248, 255],
2767
2770
  antiquewhite: [250, 235, 215],
@@ -3083,10 +3086,164 @@ function hexDouble(number_) {
3083
3086
  }
3084
3087
  var color_string_default = cs;
3085
3088
 
3086
- // node_modules/color-convert/conversions.js
3089
+ // node_modules/color/node_modules/color-name/index.js
3090
+ var colors2 = {
3091
+ aliceblue: [240, 248, 255],
3092
+ antiquewhite: [250, 235, 215],
3093
+ aqua: [0, 255, 255],
3094
+ aquamarine: [127, 255, 212],
3095
+ azure: [240, 255, 255],
3096
+ beige: [245, 245, 220],
3097
+ bisque: [255, 228, 196],
3098
+ black: [0, 0, 0],
3099
+ blanchedalmond: [255, 235, 205],
3100
+ blue: [0, 0, 255],
3101
+ blueviolet: [138, 43, 226],
3102
+ brown: [165, 42, 42],
3103
+ burlywood: [222, 184, 135],
3104
+ cadetblue: [95, 158, 160],
3105
+ chartreuse: [127, 255, 0],
3106
+ chocolate: [210, 105, 30],
3107
+ coral: [255, 127, 80],
3108
+ cornflowerblue: [100, 149, 237],
3109
+ cornsilk: [255, 248, 220],
3110
+ crimson: [220, 20, 60],
3111
+ cyan: [0, 255, 255],
3112
+ darkblue: [0, 0, 139],
3113
+ darkcyan: [0, 139, 139],
3114
+ darkgoldenrod: [184, 134, 11],
3115
+ darkgray: [169, 169, 169],
3116
+ darkgreen: [0, 100, 0],
3117
+ darkgrey: [169, 169, 169],
3118
+ darkkhaki: [189, 183, 107],
3119
+ darkmagenta: [139, 0, 139],
3120
+ darkolivegreen: [85, 107, 47],
3121
+ darkorange: [255, 140, 0],
3122
+ darkorchid: [153, 50, 204],
3123
+ darkred: [139, 0, 0],
3124
+ darksalmon: [233, 150, 122],
3125
+ darkseagreen: [143, 188, 143],
3126
+ darkslateblue: [72, 61, 139],
3127
+ darkslategray: [47, 79, 79],
3128
+ darkslategrey: [47, 79, 79],
3129
+ darkturquoise: [0, 206, 209],
3130
+ darkviolet: [148, 0, 211],
3131
+ deeppink: [255, 20, 147],
3132
+ deepskyblue: [0, 191, 255],
3133
+ dimgray: [105, 105, 105],
3134
+ dimgrey: [105, 105, 105],
3135
+ dodgerblue: [30, 144, 255],
3136
+ firebrick: [178, 34, 34],
3137
+ floralwhite: [255, 250, 240],
3138
+ forestgreen: [34, 139, 34],
3139
+ fuchsia: [255, 0, 255],
3140
+ gainsboro: [220, 220, 220],
3141
+ ghostwhite: [248, 248, 255],
3142
+ gold: [255, 215, 0],
3143
+ goldenrod: [218, 165, 32],
3144
+ gray: [128, 128, 128],
3145
+ green: [0, 128, 0],
3146
+ greenyellow: [173, 255, 47],
3147
+ grey: [128, 128, 128],
3148
+ honeydew: [240, 255, 240],
3149
+ hotpink: [255, 105, 180],
3150
+ indianred: [205, 92, 92],
3151
+ indigo: [75, 0, 130],
3152
+ ivory: [255, 255, 240],
3153
+ khaki: [240, 230, 140],
3154
+ lavender: [230, 230, 250],
3155
+ lavenderblush: [255, 240, 245],
3156
+ lawngreen: [124, 252, 0],
3157
+ lemonchiffon: [255, 250, 205],
3158
+ lightblue: [173, 216, 230],
3159
+ lightcoral: [240, 128, 128],
3160
+ lightcyan: [224, 255, 255],
3161
+ lightgoldenrodyellow: [250, 250, 210],
3162
+ lightgray: [211, 211, 211],
3163
+ lightgreen: [144, 238, 144],
3164
+ lightgrey: [211, 211, 211],
3165
+ lightpink: [255, 182, 193],
3166
+ lightsalmon: [255, 160, 122],
3167
+ lightseagreen: [32, 178, 170],
3168
+ lightskyblue: [135, 206, 250],
3169
+ lightslategray: [119, 136, 153],
3170
+ lightslategrey: [119, 136, 153],
3171
+ lightsteelblue: [176, 196, 222],
3172
+ lightyellow: [255, 255, 224],
3173
+ lime: [0, 255, 0],
3174
+ limegreen: [50, 205, 50],
3175
+ linen: [250, 240, 230],
3176
+ magenta: [255, 0, 255],
3177
+ maroon: [128, 0, 0],
3178
+ mediumaquamarine: [102, 205, 170],
3179
+ mediumblue: [0, 0, 205],
3180
+ mediumorchid: [186, 85, 211],
3181
+ mediumpurple: [147, 112, 219],
3182
+ mediumseagreen: [60, 179, 113],
3183
+ mediumslateblue: [123, 104, 238],
3184
+ mediumspringgreen: [0, 250, 154],
3185
+ mediumturquoise: [72, 209, 204],
3186
+ mediumvioletred: [199, 21, 133],
3187
+ midnightblue: [25, 25, 112],
3188
+ mintcream: [245, 255, 250],
3189
+ mistyrose: [255, 228, 225],
3190
+ moccasin: [255, 228, 181],
3191
+ navajowhite: [255, 222, 173],
3192
+ navy: [0, 0, 128],
3193
+ oldlace: [253, 245, 230],
3194
+ olive: [128, 128, 0],
3195
+ olivedrab: [107, 142, 35],
3196
+ orange: [255, 165, 0],
3197
+ orangered: [255, 69, 0],
3198
+ orchid: [218, 112, 214],
3199
+ palegoldenrod: [238, 232, 170],
3200
+ palegreen: [152, 251, 152],
3201
+ paleturquoise: [175, 238, 238],
3202
+ palevioletred: [219, 112, 147],
3203
+ papayawhip: [255, 239, 213],
3204
+ peachpuff: [255, 218, 185],
3205
+ peru: [205, 133, 63],
3206
+ pink: [255, 192, 203],
3207
+ plum: [221, 160, 221],
3208
+ powderblue: [176, 224, 230],
3209
+ purple: [128, 0, 128],
3210
+ rebeccapurple: [102, 51, 153],
3211
+ red: [255, 0, 0],
3212
+ rosybrown: [188, 143, 143],
3213
+ royalblue: [65, 105, 225],
3214
+ saddlebrown: [139, 69, 19],
3215
+ salmon: [250, 128, 114],
3216
+ sandybrown: [244, 164, 96],
3217
+ seagreen: [46, 139, 87],
3218
+ seashell: [255, 245, 238],
3219
+ sienna: [160, 82, 45],
3220
+ silver: [192, 192, 192],
3221
+ skyblue: [135, 206, 235],
3222
+ slateblue: [106, 90, 205],
3223
+ slategray: [112, 128, 144],
3224
+ slategrey: [112, 128, 144],
3225
+ snow: [255, 250, 250],
3226
+ springgreen: [0, 255, 127],
3227
+ steelblue: [70, 130, 180],
3228
+ tan: [210, 180, 140],
3229
+ teal: [0, 128, 128],
3230
+ thistle: [216, 191, 216],
3231
+ tomato: [255, 99, 71],
3232
+ turquoise: [64, 224, 208],
3233
+ violet: [238, 130, 238],
3234
+ wheat: [245, 222, 179],
3235
+ white: [255, 255, 255],
3236
+ whitesmoke: [245, 245, 245],
3237
+ yellow: [255, 255, 0],
3238
+ yellowgreen: [154, 205, 50]
3239
+ };
3240
+ for (const key in colors2) Object.freeze(colors2[key]);
3241
+ var color_name_default2 = Object.freeze(colors2);
3242
+
3243
+ // node_modules/color/node_modules/color-convert/conversions.js
3087
3244
  var reverseKeywords = {};
3088
- for (const key of Object.keys(color_name_default)) {
3089
- reverseKeywords[color_name_default[key]] = key;
3245
+ for (const key of Object.keys(color_name_default2)) {
3246
+ reverseKeywords[color_name_default2[key]] = key;
3090
3247
  }
3091
3248
  var convert = {
3092
3249
  rgb: { channels: 3, labels: "rgb" },
@@ -3262,8 +3419,8 @@ convert.rgb.keyword = function(rgb) {
3262
3419
  }
3263
3420
  let currentClosestDistance = Number.POSITIVE_INFINITY;
3264
3421
  let currentClosestKeyword;
3265
- for (const keyword of Object.keys(color_name_default)) {
3266
- const value = color_name_default[keyword];
3422
+ for (const keyword of Object.keys(color_name_default2)) {
3423
+ const value = color_name_default2[keyword];
3267
3424
  const distance = comparativeDistance(rgb, value);
3268
3425
  if (distance < currentClosestDistance) {
3269
3426
  currentClosestDistance = distance;
@@ -3273,7 +3430,7 @@ convert.rgb.keyword = function(rgb) {
3273
3430
  return currentClosestKeyword;
3274
3431
  };
3275
3432
  convert.keyword.rgb = function(keyword) {
3276
- return [...color_name_default[keyword]];
3433
+ return [...color_name_default2[keyword]];
3277
3434
  };
3278
3435
  convert.rgb.xyz = function(rgb) {
3279
3436
  const r = srgbNonlinearTransformInv(rgb[0] / 255);
@@ -3831,7 +3988,7 @@ convert.rgb.gray = function(rgb) {
3831
3988
  return [value / 255 * 100];
3832
3989
  };
3833
3990
 
3834
- // node_modules/color-convert/route.js
3991
+ // node_modules/color/node_modules/color-convert/route.js
3835
3992
  function buildGraph() {
3836
3993
  const graph = {};
3837
3994
  const models2 = Object.keys(conversions_default);
@@ -3897,7 +4054,7 @@ function route(fromModel) {
3897
4054
  }
3898
4055
  var route_default = route;
3899
4056
 
3900
- // node_modules/color-convert/index.js
4057
+ // node_modules/color/node_modules/color-convert/index.js
3901
4058
  var convert2 = {};
3902
4059
  var models = Object.keys(conversions_default);
3903
4060
  function wrapRaw(fn) {
@@ -4540,7 +4697,7 @@ var ColorPickerEyeDropper = ({ className, ...props }) => {
4540
4697
  return /* @__PURE__ */ jsx25(
4541
4698
  Button,
4542
4699
  {
4543
- className: cn("shrink-0 text-muted-foreground", className),
4700
+ className: cn("shrink-0 text-muted-foreground shadow-none", className),
4544
4701
  onClick: handleEyeDropper,
4545
4702
  size: "icon",
4546
4703
  type: "button",
@@ -4572,26 +4729,23 @@ var ColorPickerFormat = ({ className, ...props }) => {
4572
4729
  const color = color_default.hsl(hue, saturation, lightness, alpha / 100);
4573
4730
  if (mode === "hex") {
4574
4731
  const hex = color.hex();
4575
- return /* @__PURE__ */ jsxs23(
4732
+ return /* @__PURE__ */ jsx25(
4576
4733
  "div",
4577
4734
  {
4578
4735
  className: cn(
4579
- "-space-x-px relative flex w-full items-center rounded-md shadow-sm",
4736
+ "-space-x-px relative flex w-full items-center rounded-[12px] shadow-none",
4580
4737
  className
4581
4738
  ),
4582
4739
  ...props,
4583
- children: [
4584
- /* @__PURE__ */ jsx25(
4585
- Input,
4586
- {
4587
- className: "h-8 rounded-r-none bg-secondary px-2 text-xs shadow-none",
4588
- readOnly: true,
4589
- type: "text",
4590
- value: hex
4591
- }
4592
- ),
4593
- /* @__PURE__ */ jsx25(PercentageInput, { value: alpha })
4594
- ]
4740
+ children: /* @__PURE__ */ jsx25(
4741
+ Input,
4742
+ {
4743
+ className: "h-[32px] py-0 pr-10 bg-accent dark:bg-accent border-border placeholder:text-muted-foreground rounded-[12px] shadow-none w-full",
4744
+ readOnly: true,
4745
+ type: "text",
4746
+ value: hex
4747
+ }
4748
+ )
4595
4749
  }
4596
4750
  );
4597
4751
  }
@@ -4820,14 +4974,11 @@ function ColorSelection({ setActiveView, lastView, onColorSelect, colorType = "C
4820
4974
  ] }) })
4821
4975
  ] }),
4822
4976
  colorPalettes.length > 0 && /* @__PURE__ */ jsxs24("div", { className: "w-full mb-4", children: [
4823
- /* @__PURE__ */ jsxs24("div", { className: "flex flex-row items-center justify-between w-full mb-1", children: [
4824
- /* @__PURE__ */ jsxs24("div", { className: "flex flex-row items-center gap-2 h-[44px]", children: [
4825
- /* @__PURE__ */ jsx26(Hexagon, { className: "w-4 h-4 text-muted-foreground" }),
4826
- /* @__PURE__ */ jsx26("p", { className: "text-sm font-medium", children: "Brand colors" })
4827
- ] }),
4828
- /* @__PURE__ */ jsx26(Button, { variant: "link", className: "text-sm pr-0 cursor-pointer", children: "Edit" })
4829
- ] }),
4830
- /* @__PURE__ */ jsx26("div", { className: "w-full flex flex-col gap-4", children: colorPalettes.map((palette) => /* @__PURE__ */ jsxs24("div", { className: "flex flex-col gap-2", children: [
4977
+ /* @__PURE__ */ jsx26("div", { className: "flex flex-row items-center justify-between w-full mb-1", children: /* @__PURE__ */ jsxs24("div", { className: "flex flex-row items-center gap-2 h-[44px]", children: [
4978
+ /* @__PURE__ */ jsx26(Hexagon, { className: "w-4 h-4 text-muted-foreground" }),
4979
+ /* @__PURE__ */ jsx26("p", { className: "text-sm font-medium", children: "Brand colors" })
4980
+ ] }) }),
4981
+ /* @__PURE__ */ jsx26("div", { className: "w-full flex flex-col gap-4", children: colorPalettes.map((palette) => palette.colors.length > 0 && /* @__PURE__ */ jsxs24("div", { className: "flex flex-col gap-2", children: [
4831
4982
  /* @__PURE__ */ jsx26(Label, { className: "text-xs font-medium text-muted-foreground", children: palette.name }),
4832
4983
  /* @__PURE__ */ jsx26("div", { className: "w-full grid grid-cols-7 gap-2", children: palette.colors.map((c) => /* @__PURE__ */ jsx26(ColorButton, { colorName: c.name, color: c.hex, onColorSelect, currentColor }, c.color_id)) })
4833
4984
  ] }, palette.palette_id)) })
@@ -7236,6 +7387,15 @@ var parseFontSize = (value) => {
7236
7387
  // src/core/editor/components/element-gear/text/toolbar.tsx
7237
7388
  import { Fragment as Fragment4, jsx as jsx50, jsxs as jsxs39 } from "react/jsx-runtime";
7238
7389
  var ALIGNMENTS = ["left", "center", "right", "justify"];
7390
+ var TEXT_TYPE_TO_BRAND_FONT = {
7391
+ h1: "heading",
7392
+ h2: "subheading",
7393
+ h3: "subheading",
7394
+ paragraph: "body",
7395
+ list: "body",
7396
+ "numbered-list": "body",
7397
+ ordered: "body"
7398
+ };
7239
7399
  var HEADING_MULTIPLIERS = {
7240
7400
  paragraph: 1,
7241
7401
  h1: 2,
@@ -7255,7 +7415,16 @@ var TextToolbar = () => {
7255
7415
  const textEditingStyles = useEditorStore((s) => s.textEditing?.styles);
7256
7416
  const template = useEditorStore((s) => s.template);
7257
7417
  const mergeFields = useEditorStore((s) => s.mergeFields);
7418
+ const userData = useEditorStore((s) => s.userData);
7258
7419
  const { activeView, colorTarget, setActiveView, setColorType, setColorTarget } = useSidebarContext();
7420
+ const brandFonts = useMemo14(() => {
7421
+ const fonts = userData?.brand_kits?.[0]?.fonts ?? [];
7422
+ const map = {};
7423
+ for (const f of fonts) {
7424
+ map[f.type] = f;
7425
+ }
7426
+ return map;
7427
+ }, [userData]);
7259
7428
  const [updateCounter, forceUpdate] = useState17(0);
7260
7429
  const [overflowOpen, setOverflowOpen] = useState17(false);
7261
7430
  const isInSectionColumn = useMemo14(() => {
@@ -7379,8 +7548,28 @@ var TextToolbar = () => {
7379
7548
  };
7380
7549
  const level = levelMap[type];
7381
7550
  tiptapEditor.chain().focus().setHeadingLevel(level).run();
7551
+ const brandFontType = TEXT_TYPE_TO_BRAND_FONT[type];
7552
+ const brandFont = brandFontType ? brandFonts[brandFontType] : null;
7553
+ if (brandFont) {
7554
+ const { from, to } = tiptapEditor.state.selection;
7555
+ const $from = tiptapEditor.state.doc.resolve(from);
7556
+ const paragraphStart = $from.start($from.depth);
7557
+ const paragraphEnd = $from.end($from.depth);
7558
+ let chain = tiptapEditor.chain().setTextSelection({ from: paragraphStart, to: paragraphEnd }).setFontFamily(brandFont.family).setFontSize(`${brandFont.size}px`);
7559
+ if (level > 0 && !brandFont.isBold) {
7560
+ chain = chain.unsetMark("bold");
7561
+ } else if (level === 0 && brandFont.isBold) {
7562
+ chain = chain.setMark("bold");
7563
+ }
7564
+ if (brandFont.isItalic) {
7565
+ chain = chain.setMark("italic");
7566
+ } else {
7567
+ chain = chain.unsetMark("italic");
7568
+ }
7569
+ chain.setTextSelection({ from, to }).focus().run();
7570
+ }
7382
7571
  forceUpdate((n) => n + 1);
7383
- }, [tiptapEditor]);
7572
+ }, [tiptapEditor, brandFonts]);
7384
7573
  const handleDelete = () => {
7385
7574
  if (focusIdx) {
7386
7575
  deleteElement(focusIdx);
@@ -11709,7 +11898,7 @@ function useAutoSave() {
11709
11898
  // src/core/editor/components/email-template-v2/template-page.tsx
11710
11899
  import "react-json-view-lite/dist/index.css";
11711
11900
  import { jsx as jsx74, jsxs as jsxs59 } from "react/jsx-runtime";
11712
- var Editor2 = lazy(() => import("./core-OW5KVXX7.mjs").then((module) => ({
11901
+ var Editor2 = lazy(() => import("./core-HIQH4BAG.mjs").then((module) => ({
11713
11902
  default: module.Editor
11714
11903
  })));
11715
11904
  function TemplatePage({
@@ -11792,5 +11981,8 @@ export {
11792
11981
  Editor,
11793
11982
  MAX_TEMPLATE_SIZE,
11794
11983
  TemplatePage,
11795
- json2mjml
11984
+ campaign_validation_warnings,
11985
+ json2mjml,
11986
+ validate_campaign_onCreate,
11987
+ validate_editor_onPreview
11796
11988
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kgalexander/mcreate",
3
- "version": "1.0.8",
3
+ "version": "1.0.9",
4
4
  "description": "Maillow email template editor",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",