easy-email-pro-theme 1.15.3 → 1.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/index.js CHANGED
@@ -54,14 +54,14 @@ var __async = (__this, __arguments, generator) => {
54
54
  step((generator = generator.apply(__this, __arguments)).next());
55
55
  });
56
56
  };
57
- import { classnames, useEditorState, useEditorProps, useRefState, isDOMElement, useEventCallback, useSelectedNode, validation, CustomEvent, ActiveTabKeys, EmailEditorProvider, EmailEditor, useForceUpdate, toggleFormat, TextFormat, IframeComponent, HtmlStringToReactNodes, isFormatActive } from "easy-email-pro-editor";
57
+ import { classnames, useEditorState, useEditorProps, useRefState, isDOMElement, useMergeTagsData, useEventCallback, useSelectedNode, validation, CustomEvent, ActiveTabKeys, EmailEditorProvider, EmailEditor, useForceUpdate, toggleFormat, TextFormat, IframeComponent, HtmlStringToReactNodes, isFormatActive } from "easy-email-pro-editor";
58
58
  import { useSlate, ReactEditor, useSlateStatic } from "slate-react";
59
59
  import * as React$2 from "react";
60
60
  import React__default, { useRef, useState, useEffect, useCallback as useCallback$1, useMemo as useMemo$1, createContext, useContext, useLayoutEffect, useReducer, memo, cloneElement, forwardRef, Suspense, Component, PureComponent } from "react";
61
61
  import { NodeUtils, BlockManager, ElementType, EditorCore, t, ElementCategory, classnames as classnames$1, StandardType, PluginManager, EditorAuth, ConditionOperator, ConditionOperatorSymbol } from "easy-email-pro-core";
62
62
  import { Editor, Node as Node$1, Transforms, Path, createEditor, Text as Text$2, Range, Element as Element$1, Point } from "slate";
63
63
  import ReactDOM, { createPortal, unstable_batchedUpdates } from "react-dom";
64
- import { cloneDeep, isEqual as isEqual$3, get, set, omit as omit$2, merge as merge$1, debounce as debounce$2, isUndefined as isUndefined$1, isString as isString$1, isNumber as isNumber$1, uniqueId, upperFirst, isFunction as isFunction$5, sum, flatMap, camelCase } from "lodash";
64
+ import { cloneDeep, get, isEqual as isEqual$3, set, omit as omit$2, merge as merge$1, debounce as debounce$2, isUndefined as isUndefined$1, isString as isString$1, isNumber as isNumber$1, uniqueId, camelCase, upperFirst, isFunction as isFunction$5, sum, flatMap } from "lodash";
65
65
  import { Form, Input, Modal, Collapse as Collapse$1, Space, Empty, Card, Grid, Button as Button$1, Radio, Message, Popover, Spin, Select as Select$1, Drawer, Divider as Divider$1, Switch, Tabs, Slider, Typography as Typography$1, InputNumber, Tooltip, Tag, Link as Link$1, List, Alert, Popconfirm, PageHeader, Skeleton, Layout as Layout$2 } from "@arco-design/web-react";
66
66
  import { IconDelete, IconClose, IconPlus, IconCopy, IconDragArrow, IconLock, IconUnlock, IconQuestionCircle, IconLink, IconCloud, IconEdit, IconLeft, IconUndo, IconRedo, IconMinus, IconEye, IconSubscribeAdd, IconCheckCircleFill } from "@arco-design/web-react/icon";
67
67
  import mjml from "mjml-browser";
@@ -939,16 +939,10 @@ const EditorContextProvider = (props) => {
939
939
  const { form } = Form.useFormContext();
940
940
  const values2 = form.getFieldsValue();
941
941
  const { attributesVariables } = useEditorProps();
942
- const [mergetagsData, setMergetagsData] = useState({});
942
+ const { mergetagsData, setMergetagsData } = useMergeTagsData();
943
943
  const initialValuesRef = useRef(props.initialValues);
944
944
  const lastAdapterNonPageValues = useRef({});
945
- const mergetagsDataRef = useRefState(mergetagsData);
946
945
  const [inited, setInited] = useState(false);
947
- useEffect(() => {
948
- if (isEqual$3(props.mergetagsData, mergetagsDataRef.current))
949
- return;
950
- setMergetagsData(cloneDeep(props.mergetagsData) || {});
951
- }, [mergetagsDataRef, props.mergetagsData]);
952
946
  const pageElement = editor.children[0];
953
947
  useEffect(() => {
954
948
  const timer = setInterval(() => {
@@ -1107,6 +1101,7 @@ const EditorContextProvider = (props) => {
1107
1101
  }, [
1108
1102
  adapterValues,
1109
1103
  mergetagsData,
1104
+ setMergetagsData,
1110
1105
  inited,
1111
1106
  pageDataVariables,
1112
1107
  setFieldValue,
@@ -2092,8 +2087,9 @@ const UniversalListItem = ({
2092
2087
  style: {
2093
2088
  backgroundImage: `url(${thumbnail})`,
2094
2089
  height: 120,
2095
- backgroundSize: "cover",
2096
- backgroundPosition: "center center"
2090
+ backgroundSize: "100%",
2091
+ backgroundPosition: "center center",
2092
+ backgroundRepeat: "no-repeat"
2097
2093
  }
2098
2094
  }
2099
2095
  )
@@ -16485,13 +16481,298 @@ axios.formToJSON = (thing) => formDataToJSON(utils$5.isHTMLForm(thing) ? new For
16485
16481
  axios.HttpStatusCode = HttpStatusCode$1;
16486
16482
  axios.default = axios;
16487
16483
  const axios$1 = axios;
16484
+ const HtmlNodeAdapter = (content) => {
16485
+ const div = document.createElement("div");
16486
+ div.innerHTML = content;
16487
+ return Array.from(div.childNodes).map((node) => {
16488
+ return getItemNode(node);
16489
+ });
16490
+ };
16491
+ const getItemNode = (node) => {
16492
+ var _a2;
16493
+ if (node.nodeType === Node.TEXT_NODE) {
16494
+ return {
16495
+ text: ((_a2 = node.textContent) == null ? void 0 : _a2.replace(/^\s+/, " ").replace(/\s+$/, " ")) || ""
16496
+ };
16497
+ } else if (node.nodeType === Node.ELEMENT_NODE && node instanceof Element) {
16498
+ const attrs = {};
16499
+ node.getAttributeNames().forEach((name) => {
16500
+ let key2 = camelCase(name);
16501
+ if (key2 === "class") {
16502
+ key2 = "className";
16503
+ }
16504
+ attrs[key2] = node.getAttribute(name) || "";
16505
+ });
16506
+ const tagName = node.tagName.toLowerCase();
16507
+ if (tagName === "br") {
16508
+ return BlockManager.getBlockByType(ElementType.LINE_BREAK).create({
16509
+ attributes: {},
16510
+ data: {},
16511
+ children: [{ text: "" }]
16512
+ });
16513
+ }
16514
+ return BlockManager.getBlockByType(ElementType.HTML_NODE).create({
16515
+ attributes: attrs,
16516
+ data: {
16517
+ tagName
16518
+ },
16519
+ children: Array.from(node.childNodes).map((child) => getItemNode(child))
16520
+ });
16521
+ }
16522
+ throw new Error("Invalid node");
16523
+ };
16524
+ const formatPadding = (element) => {
16525
+ if (element.attributes.padding) {
16526
+ const div = document.createElement("div");
16527
+ div.style.padding = get(element.attributes, "padding");
16528
+ if (get(element.attributes, "padding-top")) {
16529
+ div.style.paddingTop = get(element.attributes, "padding-top");
16530
+ }
16531
+ if (get(element.attributes, "padding-bottom")) {
16532
+ div.style.paddingTop = get(element.attributes, "padding-bottom");
16533
+ }
16534
+ if (get(element.attributes, "padding-left")) {
16535
+ div.style.paddingTop = get(element.attributes, "padding-left");
16536
+ }
16537
+ if (get(element.attributes, "padding-right")) {
16538
+ div.style.paddingTop = get(element.attributes, "padding-right");
16539
+ }
16540
+ delete element.attributes.padding;
16541
+ element.attributes["padding-top"] = div.style.paddingTop;
16542
+ element.attributes["padding-bottom"] = div.style.paddingBottom;
16543
+ element.attributes["padding-left"] = div.style.paddingLeft;
16544
+ element.attributes["padding-right"] = div.style.paddingRight;
16545
+ }
16546
+ if (element.attributes["inner-padding"]) {
16547
+ const div = document.createElement("div");
16548
+ div.style.padding = get(element.attributes, "inner-padding");
16549
+ if (get(element.attributes, "inner-padding-top")) {
16550
+ div.style.paddingTop = get(element.attributes, "inner-padding-top");
16551
+ }
16552
+ if (get(element.attributes, "inner-padding-bottom")) {
16553
+ div.style.paddingTop = get(element.attributes, "inner-padding-bottom");
16554
+ }
16555
+ if (get(element.attributes, "inner-padding-left")) {
16556
+ div.style.paddingTop = get(element.attributes, "inner-padding-left");
16557
+ }
16558
+ if (get(element.attributes, "inner-padding-right")) {
16559
+ div.style.paddingTop = get(element.attributes, "inner-padding-right");
16560
+ }
16561
+ delete element.attributes["inner-padding"];
16562
+ element.attributes["inner-padding-top"] = div.style.paddingTop;
16563
+ element.attributes["inner-padding-bottom"] = div.style.paddingBottom;
16564
+ element.attributes["inner-padding-left"] = div.style.paddingLeft;
16565
+ element.attributes["inner-padding-right"] = div.style.paddingRight;
16566
+ }
16567
+ return element;
16568
+ };
16569
+ function basicElementToStandardElement(element) {
16570
+ const standardType = "standard-" + element.type;
16571
+ switch (element.type) {
16572
+ case ElementType.WRAPPER:
16573
+ case ElementType.HERO:
16574
+ case ElementType.SECTION:
16575
+ case ElementType.GROUP:
16576
+ case ElementType.COLUMN:
16577
+ case ElementType.TEXT:
16578
+ case ElementType.BUTTON:
16579
+ case ElementType.IMAGE:
16580
+ case ElementType.NAVBAR:
16581
+ case ElementType.SOCIAL:
16582
+ case ElementType.SPACER:
16583
+ case ElementType.SOCIAL_ELEMENT:
16584
+ case ElementType.NAVBAR_LINK:
16585
+ const standardElement = __spreadValues({}, element);
16586
+ if ([ElementType.HERO, ElementType.SECTION].includes(
16587
+ element.type
16588
+ )) {
16589
+ standardElement.attributes["background-image-enabled"] = true;
16590
+ }
16591
+ if ([
16592
+ ElementType.BUTTON,
16593
+ ElementType.IMAGE,
16594
+ ElementType.SECTION
16595
+ ].includes(element.type)) {
16596
+ if (standardElement.attributes["border"] && standardElement.attributes["border"].trim() !== "none" || standardElement.attributes["border-width"]) {
16597
+ standardElement.attributes["border-enabled"] = true;
16598
+ }
16599
+ }
16600
+ return __spreadProps(__spreadValues({}, formatPadding(element)), {
16601
+ type: standardType
16602
+ });
16603
+ }
16604
+ return element;
16605
+ }
16606
+ const mjmlToJson = (content) => {
16607
+ const domParser = new DOMParser();
16608
+ const dom = domParser.parseFromString(content, "text/xml");
16609
+ const root2 = dom.firstChild;
16610
+ if (root2.tagName !== "mjml") {
16611
+ throw new Error("mjmlToJson: invalid mjml. First node must be mjml");
16612
+ }
16613
+ if (root2.tagName === "mjml") {
16614
+ const { json } = mjml(content, {
16615
+ validationLevel: "soft"
16616
+ });
16617
+ const parseValue = mjmlTransform(json);
16618
+ return parseValue;
16619
+ }
16620
+ const transform = (node) => {
16621
+ if (node.tagName === "parsererror") {
16622
+ throw new Error("Invalid content");
16623
+ }
16624
+ const attributes = {};
16625
+ node.getAttributeNames().forEach((name) => {
16626
+ const value = node.getAttribute(name);
16627
+ if (isString$1(value)) {
16628
+ attributes[name] = value;
16629
+ }
16630
+ });
16631
+ const type = node.tagName.replace("mj-", "");
16632
+ if (!BlockManager.getBlockByType(type)) {
16633
+ if (!node.parentElement || node.parentElement.tagName !== "mj-text")
16634
+ throw new Error("Invalid content");
16635
+ }
16636
+ const block = {
16637
+ type,
16638
+ attributes,
16639
+ data: {},
16640
+ children: [...node.children].filter((item2) => item2 instanceof Element).map(transform)
16641
+ };
16642
+ switch (type) {
16643
+ case ElementType.TEXT:
16644
+ block.data.value.content = node.innerHTML;
16645
+ block.children = [];
16646
+ }
16647
+ return block;
16648
+ };
16649
+ return transform(root2);
16650
+ };
16651
+ function mjmlTransform(data) {
16652
+ const transform = (item2) => {
16653
+ var _a2, _b, _c, _d, _e, _f, _g, _h, _i;
16654
+ const attributes = item2.attributes;
16655
+ switch (item2.tagName) {
16656
+ case "mjml":
16657
+ const body = (_a2 = item2.children) == null ? void 0 : _a2.find((item22) => item22.tagName === "mj-body");
16658
+ if (!body) {
16659
+ throw new Error("Invalid content");
16660
+ }
16661
+ const head = (_b = item2.children) == null ? void 0 : _b.find((item22) => item22.tagName === "mj-head");
16662
+ const fonts = ((_c = head == null ? void 0 : head.children) == null ? void 0 : _c.filter((child) => child.tagName === "mj-font").map((child) => ({
16663
+ name: child.attributes.name,
16664
+ href: child.attributes.href
16665
+ }))) || [];
16666
+ const headStyles = (_d = head == null ? void 0 : head.children) == null ? void 0 : _d.filter((item22) => item22.tagName === "mj-style").map((item22) => ({
16667
+ content: item22.content || "",
16668
+ inline: item22.inline
16669
+ }));
16670
+ const breakpoint = (_e = head == null ? void 0 : head.children) == null ? void 0 : _e.find(
16671
+ (item22) => item22.tagName === "mj-breakpoint"
16672
+ );
16673
+ const preheader = (_f = head == null ? void 0 : head.children) == null ? void 0 : _f.find(
16674
+ (item22) => item22.tagName === "mj-preview"
16675
+ );
16676
+ const page = BlockManager.getBlockByType(ElementType.PAGE).create({
16677
+ attributes: __spreadValues({
16678
+ "margin-top": "0px",
16679
+ "margin-bottom": "0px"
16680
+ }, body.attributes),
16681
+ children: (_g = body.children) == null ? void 0 : _g.map(transform),
16682
+ data: {
16683
+ headStyles,
16684
+ fonts,
16685
+ breakpoint: breakpoint == null ? void 0 : breakpoint.attributes.breakpoint,
16686
+ preheader: preheader == null ? void 0 : preheader.content
16687
+ }
16688
+ });
16689
+ const mjAttributes = ((_i = (_h = head == null ? void 0 : head.children) == null ? void 0 : _h.find((item22) => item22.tagName === "mj-attributes")) == null ? void 0 : _i.children) || [];
16690
+ mjAttributes.forEach((item22) => {
16691
+ item22 = formatPadding(item22);
16692
+ if (item22.tagName === "mj-all") {
16693
+ page.data.globalAttributes = __spreadValues(__spreadValues({}, page.data.globalAttributes), item22.attributes);
16694
+ } else if (item22.tagName === "mj-class") {
16695
+ const name = item22.attributes.name;
16696
+ delete item22.attributes.name;
16697
+ page.data.classAttributes = __spreadProps(__spreadValues({}, page.data.classAttributes), {
16698
+ [name]: item22.attributes
16699
+ });
16700
+ } else {
16701
+ page.data.categoryAttributes = __spreadProps(__spreadValues({}, page.data.categoryAttributes), {
16702
+ [item22.tagName.replace("mj-", "")]: item22.attributes
16703
+ });
16704
+ }
16705
+ });
16706
+ return page;
16707
+ default:
16708
+ const tag = item2.tagName.replace("mj-", "").toLowerCase();
16709
+ const block = BlockManager.getBlockByType(tag);
16710
+ if (!block) {
16711
+ throw new Error(`${tag} block no found `);
16712
+ }
16713
+ const payload = {
16714
+ type: block.type,
16715
+ attributes,
16716
+ data: {},
16717
+ children: []
16718
+ };
16719
+ switch (block.type) {
16720
+ case ElementType.TEXT:
16721
+ case ElementType.BUTTON:
16722
+ case ElementType.NAVBAR_LINK:
16723
+ case ElementType.SOCIAL_ELEMENT:
16724
+ payload.children = HtmlNodeAdapter(item2.content || "");
16725
+ break;
16726
+ default:
16727
+ if (item2.children) {
16728
+ payload.children = item2.children.map(transform);
16729
+ }
16730
+ }
16731
+ if (payload.children.length === 0) {
16732
+ payload.children = [{ text: "" }];
16733
+ }
16734
+ const blockData = block.create(payload);
16735
+ return basicElementToStandardElement(blockData);
16736
+ }
16737
+ };
16738
+ return transform(data);
16739
+ }
16740
+ const getMergeTagsByType = (mergetags, type) => {
16741
+ const list = [];
16742
+ mergetags == null ? void 0 : mergetags.forEach((item2) => {
16743
+ var _a2;
16744
+ const textItems = (_a2 = item2.children) == null ? void 0 : _a2.filter((item22) => {
16745
+ if (type === "text") {
16746
+ return !item22.type || item22.type === type;
16747
+ }
16748
+ return item22.type === type;
16749
+ });
16750
+ if (textItems && (textItems == null ? void 0 : textItems.length) > 0) {
16751
+ list.push(__spreadProps(__spreadValues({}, item2), {
16752
+ children: textItems
16753
+ }));
16754
+ }
16755
+ });
16756
+ return list;
16757
+ };
16488
16758
  function ImageUploader(props) {
16489
- const { mergetagsData, unsplash, handleUploadClick } = useEditorProps();
16490
- const { pageDataVariables } = useEditorContext();
16759
+ const { unsplash, handleUploadClick, mergetags } = useEditorProps();
16760
+ const { pageDataVariables, mergetagsData } = useEditorContext();
16491
16761
  const { setLock } = useEditorState();
16492
16762
  const [isUploading, setIsUploading] = useState(false);
16493
16763
  const [preview, setPreview] = useState(false);
16494
16764
  const [unsplashVisible, setUnsplashVisible] = useState(false);
16765
+ const [popupVisible, setPopupVisible] = useState(false);
16766
+ const onChangeMergeTag = useCallback$1(
16767
+ (mergetag) => {
16768
+ props.onChange(PluginManager.generateVariable(mergetag));
16769
+ setPopupVisible(false);
16770
+ },
16771
+ [props]
16772
+ );
16773
+ const onClose = useCallback$1(() => {
16774
+ setPopupVisible(false);
16775
+ }, []);
16495
16776
  const uploadHandlerRef = useRef(
16496
16777
  props.uploadHandler
16497
16778
  );
@@ -16640,6 +16921,9 @@ function ImageUploader(props) {
16640
16921
  const isLock = unsplashVisible && dirty;
16641
16922
  setLock(isLock);
16642
16923
  }, [dirty, setLock, unsplashVisible]);
16924
+ const formatMergetags = useMemo$1(() => {
16925
+ return getMergeTagsByType(mergetags || [], "image");
16926
+ }, [mergetags]);
16643
16927
  useCallback$1(
16644
16928
  (ev) => {
16645
16929
  ev.stopPropagation();
@@ -16731,15 +17015,33 @@ function ImageUploader(props) {
16731
17015
  style: { marginTop: 16, marginBottom: 0 },
16732
17016
  label: t("URL")
16733
17017
  },
16734
- /* @__PURE__ */ React__default.createElement(
17018
+ /* @__PURE__ */ React__default.createElement(Grid.Row, { style: { width: "100%" } }, formatMergetags.length > 0 && /* @__PURE__ */ React__default.createElement(
17019
+ SharedComponents.MergeTagComponent,
17020
+ {
17021
+ mergetags: formatMergetags,
17022
+ popupVisible,
17023
+ onVisibleChange: setPopupVisible,
17024
+ onChange: onChangeMergeTag,
17025
+ onClose,
17026
+ value: "",
17027
+ triggerElement: /* @__PURE__ */ React__default.createElement(
17028
+ Button$1,
17029
+ {
17030
+ type: "secondary",
17031
+ icon: /* @__PURE__ */ React__default.createElement(IconFont, { iconName: "icon-merge-tags" })
17032
+ }
17033
+ )
17034
+ }
17035
+ ), /* @__PURE__ */ React__default.createElement(
16735
17036
  Input,
16736
17037
  {
17038
+ style: { flex: 1 },
16737
17039
  value: props.value,
16738
17040
  onChange,
16739
17041
  onPaste,
16740
17042
  disabled: isUploading
16741
17043
  }
16742
- )
17044
+ ))
16743
17045
  ), /* @__PURE__ */ React__default.createElement(
16744
17046
  Modal,
16745
17047
  {
@@ -18804,11 +19106,23 @@ function DividerLine(props) {
18804
19106
  }, [name, path2]);
18805
19107
  }
18806
19108
  function Link(props) {
18807
- const { label = t("URL") } = props;
19109
+ const { label = t("Link address") } = props;
19110
+ const { setFieldValue } = useEditorContext();
18808
19111
  const [isUploading, setIsUploading] = useState(false);
18809
- const { showSelectFileButton, handleUploadClick, onUpload } = useEditorProps();
19112
+ const [popupVisible, setPopupVisible] = useState(false);
19113
+ const onChangeMergeTag = useCallback$1(
19114
+ (mergetag) => {
19115
+ setFieldValue(
19116
+ props.path,
19117
+ props.name,
19118
+ PluginManager.generateVariable(mergetag)
19119
+ );
19120
+ setPopupVisible(false);
19121
+ },
19122
+ [props.name, props.path, setFieldValue]
19123
+ );
19124
+ const { showSelectFileButton, handleUploadClick, onUpload, mergetags } = useEditorProps();
18810
19125
  const uploadHandlerRef = useRef(onUpload);
18811
- const { setFieldValue } = useEditorContext();
18812
19126
  const handleUpload = useCallback$1(() => {
18813
19127
  if (handleUploadClick) {
18814
19128
  handleUploadClick({
@@ -18839,29 +19153,78 @@ function Link(props) {
18839
19153
  });
18840
19154
  uploader.chooseFile();
18841
19155
  }, [handleUploadClick, isUploading, props.name, props.path, setFieldValue]);
19156
+ const formatMergetags = useMemo$1(() => {
19157
+ return getMergeTagsByType(mergetags || [], "link");
19158
+ }, [mergetags]);
18842
19159
  return useMemo$1(() => {
18843
- return /* @__PURE__ */ React__default.createElement(
19160
+ return /* @__PURE__ */ React__default.createElement("div", null, /* @__PURE__ */ React__default.createElement(Grid.Row, null, /* @__PURE__ */ React__default.createElement(Grid.Col, { style: { textAlign: "right" }, span: 7 }, /* @__PURE__ */ React__default.createElement("span", null, label)), /* @__PURE__ */ React__default.createElement(Grid.Col, { offset: 1, span: 14 }, /* @__PURE__ */ React__default.createElement(Grid.Row, { style: { width: "100%" } }, formatMergetags.length > 0 && /* @__PURE__ */ React__default.createElement(
19161
+ SharedComponents.MergeTagComponent,
19162
+ {
19163
+ mergetags: formatMergetags,
19164
+ popupVisible,
19165
+ onVisibleChange: setPopupVisible,
19166
+ onChange: onChangeMergeTag,
19167
+ onClose: () => setPopupVisible(false),
19168
+ value: "",
19169
+ triggerElement: /* @__PURE__ */ React__default.createElement(
19170
+ Button$1,
19171
+ {
19172
+ type: "secondary",
19173
+ icon: /* @__PURE__ */ React__default.createElement(IconFont, { iconName: "icon-merge-tags" })
19174
+ }
19175
+ )
19176
+ }
19177
+ ), /* @__PURE__ */ React__default.createElement(
18844
19178
  AttributeField.TextField,
18845
19179
  __spreadProps(__spreadValues({
18846
19180
  prefix: /* @__PURE__ */ React__default.createElement(IconLink, null)
18847
19181
  }, props), {
18848
- label,
19182
+ label: "",
18849
19183
  formItem: __spreadValues({
19184
+ style: {
19185
+ flex: 1
19186
+ },
19187
+ wrapperCol: {
19188
+ span: 24
19189
+ },
18850
19190
  rules: [
18851
19191
  {
18852
19192
  validator(value, callback) {
18853
19193
  const isValid = isValidHttpUrl(value) || PluginManager.isVariable(value);
18854
- if (!isValid) {
19194
+ if (value && !isValid) {
18855
19195
  callback(t("Invalid URL"));
18856
19196
  }
18857
19197
  }
18858
19198
  }
18859
- ],
18860
- help: showSelectFileButton ? /* @__PURE__ */ React__default.createElement("div", { style: { marginTop: 3 } }, /* @__PURE__ */ React__default.createElement("span", { style: { cursor: "pointer" }, onClick: handleUpload }, /* @__PURE__ */ React__default.createElement(IconCloud, null), " ", t(`Select file`))) : void 0
19199
+ ]
18861
19200
  }, props.formItem)
18862
19201
  })
18863
- );
18864
- }, [handleUpload, label, props, showSelectFileButton]);
19202
+ )))), showSelectFileButton && /* @__PURE__ */ React__default.createElement(
19203
+ Grid.Row,
19204
+ {
19205
+ style: { marginTop: -10, marginBottom: 10, textAlign: "left" }
19206
+ },
19207
+ /* @__PURE__ */ React__default.createElement(Grid.Col, { offset: 8, span: 14 }, /* @__PURE__ */ React__default.createElement(
19208
+ "span",
19209
+ {
19210
+ className: "arco-form-message-help arco-form-message",
19211
+ style: { cursor: "pointer" },
19212
+ onClick: handleUpload
19213
+ },
19214
+ /* @__PURE__ */ React__default.createElement(IconCloud, null),
19215
+ " ",
19216
+ t(`Select file`)
19217
+ ))
19218
+ ));
19219
+ }, [
19220
+ formatMergetags,
19221
+ handleUpload,
19222
+ label,
19223
+ onChangeMergeTag,
19224
+ popupVisible,
19225
+ props,
19226
+ showSelectFileButton
19227
+ ]);
18865
19228
  }
18866
19229
  const defaultOptions$1 = [
18867
19230
  {
@@ -19707,14 +20070,7 @@ function AttributesContainer$9({
19707
20070
  name: "text",
19708
20071
  label: t("Content")
19709
20072
  }
19710
- ), /* @__PURE__ */ React__default.createElement(
19711
- AttributeField.Link,
19712
- {
19713
- path: nodePath,
19714
- name: "attributes.href",
19715
- label: t("URL")
19716
- }
19717
- )), /* @__PURE__ */ React__default.createElement(Collapse$1.Item, { name: "0", header: t("Dimension") }, /* @__PURE__ */ React__default.createElement(
20073
+ ), /* @__PURE__ */ React__default.createElement(AttributeField.Link, { path: nodePath, name: "attributes.href" })), /* @__PURE__ */ React__default.createElement(Collapse$1.Item, { name: "0", header: t("Dimension") }, /* @__PURE__ */ React__default.createElement(
19718
20074
  ResponsiveField,
19719
20075
  {
19720
20076
  label: t("Width"),
@@ -19848,10 +20204,9 @@ function AttributesContainer$8({
19848
20204
  )), /* @__PURE__ */ React__default.createElement(Collapse$1.Item, { name: "1", header: t("Image settings") }, /* @__PURE__ */ React__default.createElement(
19849
20205
  ResponsiveField,
19850
20206
  {
19851
- component: AttributeField.TextField,
20207
+ component: AttributeField.Link,
19852
20208
  path: nodePath,
19853
- name: "href",
19854
- label: t("Link address")
20209
+ name: "href"
19855
20210
  }
19856
20211
  ), /* @__PURE__ */ React__default.createElement(
19857
20212
  ResponsiveField,
@@ -20135,15 +20490,7 @@ function NavbarLink({ index: index2, path: path2 }) {
20135
20490
  label: t("Text"),
20136
20491
  name: `text`
20137
20492
  }
20138
- ), /* @__PURE__ */ React__default.createElement(
20139
- AttributeField.Link,
20140
- {
20141
- label: t("Link address"),
20142
- required: true,
20143
- path: path2,
20144
- name: `attributes.href`
20145
- }
20146
- ));
20493
+ ), /* @__PURE__ */ React__default.createElement(AttributeField.Link, { required: true, path: path2, name: `attributes.href` }));
20147
20494
  }
20148
20495
  const SyncChildrenAttributes$1 = ({
20149
20496
  nodePath,
@@ -20418,15 +20765,7 @@ function SocialItem({ index: index2, path: path2 }) {
20418
20765
  name: `text`,
20419
20766
  fallbackValue: ""
20420
20767
  }
20421
- ), /* @__PURE__ */ React__default.createElement(
20422
- AttributeField.Link,
20423
- {
20424
- label: t("Link address"),
20425
- required: true,
20426
- path: path2,
20427
- name: `attributes.href`
20428
- }
20429
- ));
20768
+ ), /* @__PURE__ */ React__default.createElement(AttributeField.Link, { required: true, path: path2, name: `attributes.href` }));
20430
20769
  }
20431
20770
  const SyncChildrenAttributes = ({
20432
20771
  nodePath,
@@ -26454,7 +26793,7 @@ const EditorTabs = (props) => {
26454
26793
  return /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, /* @__PURE__ */ React__default.createElement(
26455
26794
  TabHeader,
26456
26795
  {
26457
- right: /* @__PURE__ */ React__default.createElement(Space, null, !universalElementEditing && !readOnly && /* @__PURE__ */ React__default.createElement(Tooltip, { content: t("clear the entire canvas") }, /* @__PURE__ */ React__default.createElement(Button$1, { onPointerDown }, /* @__PURE__ */ React__default.createElement(IconDelete, null))), canPreview && /* @__PURE__ */ React__default.createElement(SharedComponents.PreviewEmailDrawer, null, /* @__PURE__ */ React__default.createElement(Tooltip, { content: t("Email preview") }, /* @__PURE__ */ React__default.createElement(Button$1, { disabled: lock }, /* @__PURE__ */ React__default.createElement(IconEye, null)))), /* @__PURE__ */ React__default.createElement("div", null)),
26796
+ right: /* @__PURE__ */ React__default.createElement(Space, null, !universalElementEditing && !readOnly && /* @__PURE__ */ React__default.createElement(Tooltip, { content: t("clear the entire canvas") }, /* @__PURE__ */ React__default.createElement(Button$1, { onPointerDown }, /* @__PURE__ */ React__default.createElement(IconDelete, null))), canPreview && (lock ? /* @__PURE__ */ React__default.createElement(Tooltip, { content: t("Email preview") }, /* @__PURE__ */ React__default.createElement(Button$1, { disabled: lock }, /* @__PURE__ */ React__default.createElement(IconEye, null))) : /* @__PURE__ */ React__default.createElement(SharedComponents.PreviewEmailDrawer, null, /* @__PURE__ */ React__default.createElement(Tooltip, { content: t("Email preview") }, /* @__PURE__ */ React__default.createElement(Button$1, { disabled: lock }, /* @__PURE__ */ React__default.createElement(IconEye, null))))), /* @__PURE__ */ React__default.createElement("div", null)),
26458
26797
  left: null
26459
26798
  }
26460
26799
  ), /* @__PURE__ */ React__default.createElement("div", { style: { height: "calc(100% - 60px)", overflow: "hidden" } }, props.children));
@@ -32938,13 +33277,23 @@ const TextLink = () => {
32938
33277
  const ref2 = useRef(null);
32939
33278
  const linkNode = linkNodeEntry == null ? void 0 : linkNodeEntry[0];
32940
33279
  const { selectedNodePath } = useSelectedNode();
32941
- const { handleUploadClick, showSelectFileButton, onUpload } = useEditorProps();
33280
+ const [popupVisible, setPopupVisible] = useState(false);
33281
+ const { handleUploadClick, showSelectFileButton, onUpload, mergetags } = useEditorProps();
32942
33282
  const [isUploading, setIsUploading] = useState(false);
32943
33283
  const uploadHandlerRef = useRef(onUpload);
32944
33284
  const [formState, setFormState] = useState(__spreadProps(__spreadValues({}, linkNode == null ? void 0 : linkNode.link), {
32945
33285
  text: (linkNode == null ? void 0 : linkNode.text) || ""
32946
33286
  }));
32947
33287
  const [from] = Form.useForm();
33288
+ const onChangeMergeTag = useCallback$1(
33289
+ (mergetag) => {
33290
+ const newHref = PluginManager.generateVariable(mergetag);
33291
+ from.setFieldValue("href", newHref);
33292
+ setFormState((old) => __spreadProps(__spreadValues({}, old), { href: newHref }));
33293
+ setPopupVisible(false);
33294
+ },
33295
+ [from]
33296
+ );
32948
33297
  const handleUpload = useCallback$1(
32949
33298
  (e) => {
32950
33299
  e.stopPropagation();
@@ -33028,11 +33377,15 @@ const TextLink = () => {
33028
33377
  const onChange = (values2) => {
33029
33378
  setFormState(values2);
33030
33379
  };
33380
+ const formatMergetags = useMemo$1(() => {
33381
+ return getMergeTagsByType(mergetags || [], "link");
33382
+ }, [mergetags]);
33031
33383
  return /* @__PURE__ */ React__default.createElement(
33032
33384
  Popover,
33033
33385
  {
33034
33386
  trigger: "click",
33035
33387
  triggerProps: {
33388
+ position: "tr",
33036
33389
  popupStyle: { padding: "10px 0px 0px 0px", width: 400 }
33037
33390
  },
33038
33391
  getPopupContainer: (node) => {
@@ -33050,26 +33403,61 @@ const TextLink = () => {
33050
33403
  initialValues: formState
33051
33404
  },
33052
33405
  /* @__PURE__ */ React__default.createElement(
33053
- Form.Item,
33406
+ "div",
33407
+ {
33408
+ style: {
33409
+ paddingLeft: 15,
33410
+ paddingRight: 15,
33411
+ width: "calc(100% - 30px)",
33412
+ marginBottom: 5
33413
+ }
33414
+ },
33415
+ /* @__PURE__ */ React__default.createElement("span", null, t(`Link address`))
33416
+ ),
33417
+ /* @__PURE__ */ React__default.createElement(
33418
+ Grid.Row,
33054
33419
  {
33055
- label: "URL",
33056
- layout: "vertical",
33057
- field: "href",
33058
33420
  style: {
33059
- marginBottom: 10,
33060
33421
  paddingLeft: 15,
33061
33422
  paddingRight: 15,
33062
33423
  width: "calc(100% - 30px)"
33063
33424
  }
33064
33425
  },
33065
- /* @__PURE__ */ React__default.createElement(
33066
- Input,
33426
+ formatMergetags.length > 0 && /* @__PURE__ */ React__default.createElement(
33427
+ SharedComponents.MergeTagComponent,
33067
33428
  {
33068
- autoFocus: true,
33069
- placeholder: "Paste link here",
33070
- enterKeyHint: "enter",
33071
- allowClear: true
33429
+ mergetags: formatMergetags,
33430
+ popupVisible,
33431
+ onVisibleChange: setPopupVisible,
33432
+ onChange: onChangeMergeTag,
33433
+ onClose: () => setPopupVisible(false),
33434
+ value: "",
33435
+ triggerElement: /* @__PURE__ */ React__default.createElement(
33436
+ Button$1,
33437
+ {
33438
+ type: "secondary",
33439
+ icon: /* @__PURE__ */ React__default.createElement(IconFont, { iconName: "icon-merge-tags" })
33440
+ }
33441
+ )
33072
33442
  }
33443
+ ),
33444
+ /* @__PURE__ */ React__default.createElement(
33445
+ Form.Item,
33446
+ {
33447
+ label: "",
33448
+ layout: "vertical",
33449
+ field: "href",
33450
+ style: { flex: 1, marginBottom: 10 }
33451
+ },
33452
+ /* @__PURE__ */ React__default.createElement(
33453
+ Input,
33454
+ {
33455
+ autoFocus: true,
33456
+ placeholder: "Paste link here",
33457
+ enterKeyHint: "enter",
33458
+ allowClear: true
33459
+ }
33460
+ )
33073
33461
  )
33074
33462
  )
33075
33463
  ), /* @__PURE__ */ React__default.createElement(
@@ -33204,84 +33592,13 @@ const TurnInto = () => {
33204
33592
  })
33205
33593
  ), /* @__PURE__ */ React__default.createElement("style", null, `.TurnInto .arco-select-view { border: none; }`));
33206
33594
  };
33207
- const MergeTagComponent = React__default.memo((props) => {
33208
- const editorPorps = useEditorProps();
33209
- const ref2 = useRef(null);
33210
- const onCloseRef = useRefState(props.onClose);
33211
- const editor = useSlate();
33212
- const mergetags = useMemo$1(
33213
- () => editorPorps.mergetags || [],
33214
- [editorPorps.mergetags]
33215
- );
33216
- const onSelect = useCallback$1(
33217
- (key2) => {
33218
- props.onChange(key2);
33219
- },
33220
- [props]
33221
- );
33222
- let root2 = null;
33223
- try {
33224
- root2 = ReactEditor.getWindow(editor);
33225
- } catch (error2) {
33226
- }
33227
- useEffect(() => {
33228
- if (!root2)
33229
- return;
33230
- const onKeyDown = (ev) => {
33231
- var _a2, _b;
33232
- if (!ev.code)
33233
- return;
33234
- if (ev.code.toLowerCase() === "enter" && ((_a2 = ref2.current) == null ? void 0 : _a2.contains(document.activeElement))) {
33235
- if (document.activeElement instanceof HTMLElement) {
33236
- ev.preventDefault();
33237
- document.activeElement.click();
33238
- }
33239
- } else if (ev.code.toLowerCase() === "escape") {
33240
- ev.preventDefault();
33241
- (_b = onCloseRef.current) == null ? void 0 : _b.call(onCloseRef);
33242
- }
33243
- };
33244
- window.addEventListener("keydown", onKeyDown, true);
33245
- root2.addEventListener("keydown", onKeyDown, true);
33246
- return () => {
33247
- window.removeEventListener("keydown", onKeyDown, true);
33248
- root2 == null ? void 0 : root2.removeEventListener("keydown", onKeyDown, true);
33249
- };
33250
- }, [editor, onCloseRef, root2]);
33251
- return /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, /* @__PURE__ */ React__default.createElement(
33252
- Select$1,
33253
- __spreadProps(__spreadValues({
33254
- triggerProps: {
33255
- style: {
33256
- width: 300
33257
- },
33258
- position: "br"
33259
- },
33260
- showSearch: true
33261
- }, props), {
33262
- onChange: onSelect
33263
- }),
33264
- mergetags.map((item2, index2) => {
33265
- if (item2.children) {
33266
- return /* @__PURE__ */ React__default.createElement(Select$1.OptGroup, { label: item2.label, key: item2.label + index2 }, item2.children.map((child, cIndex) => {
33267
- return /* @__PURE__ */ React__default.createElement(
33268
- Select$1.Option,
33269
- {
33270
- value: child.value,
33271
- key: child.label + cIndex
33272
- },
33273
- child.label
33274
- );
33275
- }));
33276
- }
33277
- return /* @__PURE__ */ React__default.createElement(Select$1.Option, { value: item2.value, key: item2.label + index2 }, item2.label);
33278
- })
33279
- ));
33280
- });
33281
33595
  const MergeTag = React__default.memo(() => {
33282
33596
  const [popupVisible, setPopupVisible] = useState(false);
33283
- const value = "";
33284
33597
  const editor = useSlate();
33598
+ const { mergetags } = useEditorProps();
33599
+ const formatMergetags = useMemo$1(() => {
33600
+ return getMergeTagsByType(mergetags || [], "text");
33601
+ }, [mergetags]);
33285
33602
  const onChange = useCallback$1(
33286
33603
  (mergetag) => {
33287
33604
  editor.insertMergetag({
@@ -33295,13 +33612,14 @@ const MergeTag = React__default.memo(() => {
33295
33612
  setPopupVisible(false);
33296
33613
  }, []);
33297
33614
  return /* @__PURE__ */ React__default.createElement(
33298
- MergeTagComponent,
33615
+ SharedComponents.MergeTagComponent,
33299
33616
  {
33617
+ mergetags: formatMergetags,
33300
33618
  popupVisible,
33301
33619
  onVisibleChange: setPopupVisible,
33302
33620
  onChange,
33303
33621
  onClose,
33304
- value,
33622
+ value: "",
33305
33623
  triggerElement: /* @__PURE__ */ React__default.createElement(
33306
33624
  FormatButton,
33307
33625
  {
@@ -39802,6 +40120,82 @@ function WidgetConfigPanel({
39802
40120
  )
39803
40121
  ));
39804
40122
  }
40123
+ const MergeTagComponent = React__default.memo((props) => {
40124
+ const ref2 = useRef(null);
40125
+ const onCloseRef = useRefState(props.onClose);
40126
+ const editor = useSlate();
40127
+ const onSelect = useCallback$1(
40128
+ (key2) => {
40129
+ props.onChange(key2);
40130
+ },
40131
+ [props]
40132
+ );
40133
+ let root2 = null;
40134
+ try {
40135
+ root2 = ReactEditor.getWindow(editor);
40136
+ } catch (error2) {
40137
+ }
40138
+ useEffect(() => {
40139
+ if (!root2)
40140
+ return;
40141
+ const onKeyDown = (ev) => {
40142
+ var _a2, _b;
40143
+ if (!ev.code)
40144
+ return;
40145
+ if (ev.code.toLowerCase() === "enter" && ((_a2 = ref2.current) == null ? void 0 : _a2.contains(document.activeElement))) {
40146
+ if (document.activeElement instanceof HTMLElement) {
40147
+ ev.preventDefault();
40148
+ document.activeElement.click();
40149
+ }
40150
+ } else if (ev.code.toLowerCase() === "escape") {
40151
+ ev.preventDefault();
40152
+ (_b = onCloseRef.current) == null ? void 0 : _b.call(onCloseRef);
40153
+ }
40154
+ };
40155
+ window.addEventListener("keydown", onKeyDown, true);
40156
+ root2.addEventListener("keydown", onKeyDown, true);
40157
+ return () => {
40158
+ window.removeEventListener("keydown", onKeyDown, true);
40159
+ root2 == null ? void 0 : root2.removeEventListener("keydown", onKeyDown, true);
40160
+ };
40161
+ }, [editor, onCloseRef, root2]);
40162
+ return /* @__PURE__ */ React__default.createElement(
40163
+ "div",
40164
+ {
40165
+ onPointerDown: (e) => e.stopPropagation(),
40166
+ onClick: (e) => e.stopPropagation()
40167
+ },
40168
+ /* @__PURE__ */ React__default.createElement(
40169
+ Select$1,
40170
+ __spreadProps(__spreadValues({
40171
+ triggerProps: {
40172
+ style: {
40173
+ width: 300
40174
+ },
40175
+ position: "br"
40176
+ },
40177
+ showSearch: true
40178
+ }, props), {
40179
+ onChange: onSelect
40180
+ }),
40181
+ props.mergetags.map((item2, index2) => {
40182
+ if (item2.children) {
40183
+ return /* @__PURE__ */ React__default.createElement(Select$1.OptGroup, { label: item2.label, key: item2.label + index2 }, item2.children.map((child, cIndex) => {
40184
+ return /* @__PURE__ */ React__default.createElement(
40185
+ Select$1.Option,
40186
+ {
40187
+ value: child.value,
40188
+ key: child.label + cIndex
40189
+ },
40190
+ child.label
40191
+ );
40192
+ }));
40193
+ }
40194
+ return /* @__PURE__ */ React__default.createElement(Select$1.Option, { value: item2.value, key: item2.label + index2 }, item2.label);
40195
+ })
40196
+ )
40197
+ );
40198
+ });
39805
40199
  const SharedComponents = {
39806
40200
  PreviewEmailDrawer,
39807
40201
  PreviewEmail,
@@ -39822,7 +40216,8 @@ const SharedComponents = {
39822
40216
  FullHeightOverlayScrollbars,
39823
40217
  BlockList,
39824
40218
  UniversalListItem,
39825
- UniversalList
40219
+ UniversalList,
40220
+ MergeTagComponent
39826
40221
  };
39827
40222
  const FullScreenLoading = ({
39828
40223
  size = 40,
@@ -46784,262 +47179,6 @@ const Layout = ({ children }) => {
46784
47179
  return /* @__PURE__ */ React__default.createElement(MinimalistProvider, null, layoutContent, /* @__PURE__ */ React__default.createElement(SharedComponents.HoveringToolbar, null), controller && /* @__PURE__ */ React__default.createElement(SharedComponents.Controller, null), /* @__PURE__ */ React__default.createElement(SharedComponents.Hotkeys, null), /* @__PURE__ */ React__default.createElement(AutoSelectElement, null), /* @__PURE__ */ React__default.createElement("style", null, styleText$d, " "));
46785
47180
  };
46786
47181
  const Minimalist = { useCreateConfig, Layout };
46787
- const HtmlNodeAdapter = (content) => {
46788
- const div = document.createElement("div");
46789
- div.innerHTML = content;
46790
- return Array.from(div.childNodes).map((node) => {
46791
- return getItemNode(node);
46792
- });
46793
- };
46794
- const getItemNode = (node) => {
46795
- var _a2;
46796
- if (node.nodeType === Node.TEXT_NODE) {
46797
- return {
46798
- text: ((_a2 = node.textContent) == null ? void 0 : _a2.replace(/^\s+/, " ").replace(/\s+$/, " ")) || ""
46799
- };
46800
- } else if (node.nodeType === Node.ELEMENT_NODE && node instanceof Element) {
46801
- const attrs = {};
46802
- node.getAttributeNames().forEach((name) => {
46803
- let key2 = camelCase(name);
46804
- if (key2 === "class") {
46805
- key2 = "className";
46806
- }
46807
- attrs[key2] = node.getAttribute(name) || "";
46808
- });
46809
- const tagName = node.tagName.toLowerCase();
46810
- if (tagName === "br") {
46811
- return BlockManager.getBlockByType(ElementType.LINE_BREAK).create({
46812
- attributes: {},
46813
- data: {},
46814
- children: [{ text: "" }]
46815
- });
46816
- }
46817
- return BlockManager.getBlockByType(ElementType.HTML_NODE).create({
46818
- attributes: attrs,
46819
- data: {
46820
- tagName
46821
- },
46822
- children: Array.from(node.childNodes).map((child) => getItemNode(child))
46823
- });
46824
- }
46825
- throw new Error("Invalid node");
46826
- };
46827
- const formatPadding = (element) => {
46828
- if (element.attributes.padding) {
46829
- const div = document.createElement("div");
46830
- div.style.padding = get(element.attributes, "padding");
46831
- if (get(element.attributes, "padding-top")) {
46832
- div.style.paddingTop = get(element.attributes, "padding-top");
46833
- }
46834
- if (get(element.attributes, "padding-bottom")) {
46835
- div.style.paddingTop = get(element.attributes, "padding-bottom");
46836
- }
46837
- if (get(element.attributes, "padding-left")) {
46838
- div.style.paddingTop = get(element.attributes, "padding-left");
46839
- }
46840
- if (get(element.attributes, "padding-right")) {
46841
- div.style.paddingTop = get(element.attributes, "padding-right");
46842
- }
46843
- delete element.attributes.padding;
46844
- element.attributes["padding-top"] = div.style.paddingTop;
46845
- element.attributes["padding-bottom"] = div.style.paddingBottom;
46846
- element.attributes["padding-left"] = div.style.paddingLeft;
46847
- element.attributes["padding-right"] = div.style.paddingRight;
46848
- }
46849
- if (element.attributes["inner-padding"]) {
46850
- const div = document.createElement("div");
46851
- div.style.padding = get(element.attributes, "inner-padding");
46852
- if (get(element.attributes, "inner-padding-top")) {
46853
- div.style.paddingTop = get(element.attributes, "inner-padding-top");
46854
- }
46855
- if (get(element.attributes, "inner-padding-bottom")) {
46856
- div.style.paddingTop = get(element.attributes, "inner-padding-bottom");
46857
- }
46858
- if (get(element.attributes, "inner-padding-left")) {
46859
- div.style.paddingTop = get(element.attributes, "inner-padding-left");
46860
- }
46861
- if (get(element.attributes, "inner-padding-right")) {
46862
- div.style.paddingTop = get(element.attributes, "inner-padding-right");
46863
- }
46864
- delete element.attributes["inner-padding"];
46865
- element.attributes["inner-padding-top"] = div.style.paddingTop;
46866
- element.attributes["inner-padding-bottom"] = div.style.paddingBottom;
46867
- element.attributes["inner-padding-left"] = div.style.paddingLeft;
46868
- element.attributes["inner-padding-right"] = div.style.paddingRight;
46869
- }
46870
- return element;
46871
- };
46872
- function basicElementToStandardElement(element) {
46873
- const standardType = "standard-" + element.type;
46874
- switch (element.type) {
46875
- case ElementType.WRAPPER:
46876
- case ElementType.HERO:
46877
- case ElementType.SECTION:
46878
- case ElementType.GROUP:
46879
- case ElementType.COLUMN:
46880
- case ElementType.TEXT:
46881
- case ElementType.BUTTON:
46882
- case ElementType.IMAGE:
46883
- case ElementType.NAVBAR:
46884
- case ElementType.SOCIAL:
46885
- case ElementType.SPACER:
46886
- case ElementType.SOCIAL_ELEMENT:
46887
- case ElementType.NAVBAR_LINK:
46888
- const standardElement = __spreadValues({}, element);
46889
- if ([ElementType.HERO, ElementType.SECTION].includes(
46890
- element.type
46891
- )) {
46892
- standardElement.attributes["background-image-enabled"] = true;
46893
- }
46894
- if ([
46895
- ElementType.BUTTON,
46896
- ElementType.IMAGE,
46897
- ElementType.SECTION
46898
- ].includes(element.type)) {
46899
- if (standardElement.attributes["border"] && standardElement.attributes["border"].trim() !== "none" || standardElement.attributes["border-width"]) {
46900
- standardElement.attributes["border-enabled"] = true;
46901
- }
46902
- }
46903
- return __spreadProps(__spreadValues({}, formatPadding(element)), {
46904
- type: standardType
46905
- });
46906
- }
46907
- return element;
46908
- }
46909
- const mjmlToJson = (content) => {
46910
- const domParser = new DOMParser();
46911
- const dom = domParser.parseFromString(content, "text/xml");
46912
- const root2 = dom.firstChild;
46913
- if (root2.tagName !== "mjml") {
46914
- throw new Error("mjmlToJson: invalid mjml. First node must be mjml");
46915
- }
46916
- if (root2.tagName === "mjml") {
46917
- const { json } = mjml(content, {
46918
- validationLevel: "soft"
46919
- });
46920
- const parseValue = mjmlTransform(json);
46921
- return parseValue;
46922
- }
46923
- const transform = (node) => {
46924
- if (node.tagName === "parsererror") {
46925
- throw new Error("Invalid content");
46926
- }
46927
- const attributes = {};
46928
- node.getAttributeNames().forEach((name) => {
46929
- const value = node.getAttribute(name);
46930
- if (isString$1(value)) {
46931
- attributes[name] = value;
46932
- }
46933
- });
46934
- const type = node.tagName.replace("mj-", "");
46935
- if (!BlockManager.getBlockByType(type)) {
46936
- if (!node.parentElement || node.parentElement.tagName !== "mj-text")
46937
- throw new Error("Invalid content");
46938
- }
46939
- const block = {
46940
- type,
46941
- attributes,
46942
- data: {},
46943
- children: [...node.children].filter((item2) => item2 instanceof Element).map(transform)
46944
- };
46945
- switch (type) {
46946
- case ElementType.TEXT:
46947
- block.data.value.content = node.innerHTML;
46948
- block.children = [];
46949
- }
46950
- return block;
46951
- };
46952
- return transform(root2);
46953
- };
46954
- function mjmlTransform(data) {
46955
- const transform = (item2) => {
46956
- var _a2, _b, _c, _d, _e, _f, _g, _h, _i;
46957
- const attributes = item2.attributes;
46958
- switch (item2.tagName) {
46959
- case "mjml":
46960
- const body = (_a2 = item2.children) == null ? void 0 : _a2.find((item22) => item22.tagName === "mj-body");
46961
- if (!body) {
46962
- throw new Error("Invalid content");
46963
- }
46964
- const head = (_b = item2.children) == null ? void 0 : _b.find((item22) => item22.tagName === "mj-head");
46965
- const fonts = ((_c = head == null ? void 0 : head.children) == null ? void 0 : _c.filter((child) => child.tagName === "mj-font").map((child) => ({
46966
- name: child.attributes.name,
46967
- href: child.attributes.href
46968
- }))) || [];
46969
- const headStyles = (_d = head == null ? void 0 : head.children) == null ? void 0 : _d.filter((item22) => item22.tagName === "mj-style").map((item22) => ({
46970
- content: item22.content || "",
46971
- inline: item22.inline
46972
- }));
46973
- const breakpoint = (_e = head == null ? void 0 : head.children) == null ? void 0 : _e.find(
46974
- (item22) => item22.tagName === "mj-breakpoint"
46975
- );
46976
- const preheader = (_f = head == null ? void 0 : head.children) == null ? void 0 : _f.find(
46977
- (item22) => item22.tagName === "mj-preview"
46978
- );
46979
- const page = BlockManager.getBlockByType(ElementType.PAGE).create({
46980
- attributes: __spreadValues({
46981
- "margin-top": "0px",
46982
- "margin-bottom": "0px"
46983
- }, body.attributes),
46984
- children: (_g = body.children) == null ? void 0 : _g.map(transform),
46985
- data: {
46986
- headStyles,
46987
- fonts,
46988
- breakpoint: breakpoint == null ? void 0 : breakpoint.attributes.breakpoint,
46989
- preheader: preheader == null ? void 0 : preheader.content
46990
- }
46991
- });
46992
- const mjAttributes = ((_i = (_h = head == null ? void 0 : head.children) == null ? void 0 : _h.find((item22) => item22.tagName === "mj-attributes")) == null ? void 0 : _i.children) || [];
46993
- mjAttributes.forEach((item22) => {
46994
- item22 = formatPadding(item22);
46995
- if (item22.tagName === "mj-all") {
46996
- page.data.globalAttributes = __spreadValues(__spreadValues({}, page.data.globalAttributes), item22.attributes);
46997
- } else if (item22.tagName === "mj-class") {
46998
- const name = item22.attributes.name;
46999
- delete item22.attributes.name;
47000
- page.data.classAttributes = __spreadProps(__spreadValues({}, page.data.classAttributes), {
47001
- [name]: item22.attributes
47002
- });
47003
- } else {
47004
- page.data.categoryAttributes = __spreadProps(__spreadValues({}, page.data.categoryAttributes), {
47005
- [item22.tagName.replace("mj-", "")]: item22.attributes
47006
- });
47007
- }
47008
- });
47009
- return page;
47010
- default:
47011
- const tag = item2.tagName.replace("mj-", "").toLowerCase();
47012
- const block = BlockManager.getBlockByType(tag);
47013
- if (!block) {
47014
- throw new Error(`${tag} block no found `);
47015
- }
47016
- const payload = {
47017
- type: block.type,
47018
- attributes,
47019
- data: {},
47020
- children: []
47021
- };
47022
- switch (block.type) {
47023
- case ElementType.TEXT:
47024
- case ElementType.BUTTON:
47025
- case ElementType.NAVBAR_LINK:
47026
- case ElementType.SOCIAL_ELEMENT:
47027
- payload.children = HtmlNodeAdapter(item2.content || "");
47028
- break;
47029
- default:
47030
- if (item2.children) {
47031
- payload.children = item2.children.map(transform);
47032
- }
47033
- }
47034
- if (payload.children.length === 0) {
47035
- payload.children = [{ text: "" }];
47036
- }
47037
- const blockData = block.create(payload);
47038
- return basicElementToStandardElement(blockData);
47039
- }
47040
- };
47041
- return transform(data);
47042
- }
47043
47182
  export {
47044
47183
  AttributeField,
47045
47184
  AttributesPanelWrapper,
@@ -47055,6 +47194,7 @@ export {
47055
47194
  ResponsiveTabs,
47056
47195
  Retro,
47057
47196
  SharedComponents,
47197
+ getMergeTagsByType,
47058
47198
  mjmlToJson,
47059
47199
  previewLoadImage,
47060
47200
  useColorContext,
@@ -1,7 +1,9 @@
1
1
  import React from "react";
2
2
  import { SelectProps } from "@arco-design/web-react";
3
+ import { MergetagItem } from "easy-email-pro-editor";
3
4
  export declare const MergeTagComponent: React.FC<{
4
5
  onChange: (v: string) => void;
5
6
  value: string;
6
7
  onClose?: () => void;
8
+ mergetags: MergetagItem[];
7
9
  } & SelectProps>;
@@ -74,6 +74,12 @@ export declare const SharedComponents: {
74
74
  thumbnail: string;
75
75
  }) => JSX.Element;
76
76
  UniversalList: () => JSX.Element | null;
77
+ MergeTagComponent: import("react").FC<{
78
+ onChange: (v: string) => void;
79
+ value: string;
80
+ onClose?: (() => void) | undefined;
81
+ mergetags: import("easy-email-pro-editor").MergetagItem[];
82
+ } & import("@arco-design/web-react").SelectProps>;
77
83
  };
78
84
  export { CollapseWrapper } from "./ConfigurationPanel/components/CollapseWrapper";
79
85
  export { AttributesPanelWrapper } from "./ConfigurationPanel/components/AttributesPanelWrapper";
@@ -0,0 +1,2 @@
1
+ import { MergetagItem } from "easy-email-pro-editor";
2
+ export declare const getMergeTagsByType: (mergetags: MergetagItem[], type: MergetagItem["type"]) => MergetagItem[];
@@ -1,2 +1,3 @@
1
1
  export * from "./mjmlToJson";
2
2
  export * from "./previewLoadImage";
3
+ export * from "./getMergeTagsByType";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "easy-email-pro-theme",
3
- "version": "1.15.3",
3
+ "version": "1.16.0",
4
4
  "description": "",
5
5
  "files": [
6
6
  "lib"