easy-email-pro-theme 1.59.2 → 1.59.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/index.js CHANGED
@@ -751,6 +751,15 @@ const assignIdsToElementTree = (element, overwrite = false) => {
751
751
  loop2(newElement);
752
752
  return newElement;
753
753
  };
754
+ function shouldInsertAfterHeroSibling({
755
+ canInsertIntoParent,
756
+ canInsertIntoTarget,
757
+ isAutoCompleteEnabled,
758
+ isBottomHalf,
759
+ isHeroTarget
760
+ }) {
761
+ return isAutoCompleteEnabled && isHeroTarget && isBottomHalf && canInsertIntoTarget && canInsertIntoParent;
762
+ }
754
763
  const DraggingProviderContext = React__default.createContext({});
755
764
  const DraggingProvider = ({
756
765
  children
@@ -1037,14 +1046,30 @@ const DraggingProvider = ({
1037
1046
  const node = ReactEditor.toDOMNode(editor, dropElement);
1038
1047
  const rect = node.getBoundingClientRect();
1039
1048
  const isTop = ev.clientY < rect.y + rect.height / 2;
1049
+ const canInsertIntoDropElement = NodeUtils.isParentCategoryType(
1050
+ propsData.element.type,
1051
+ dropElement.type
1052
+ ) && !NodeUtils.isVoidBlockElement(dropElement);
1053
+ const dropParentElement = Node.get(
1054
+ editor,
1055
+ Path.parent(dropPath)
1056
+ );
1057
+ const canInsertIntoDropParent = NodeUtils.isElement(dropParentElement) && NodeUtils.isParentCategoryType(
1058
+ propsData.element.type,
1059
+ dropParentElement.type
1060
+ );
1061
+ const shouldInsertAfterHero = shouldInsertAfterHeroSibling({
1062
+ canInsertIntoParent: canInsertIntoDropParent,
1063
+ canInsertIntoTarget: canInsertIntoDropElement,
1064
+ isAutoCompleteEnabled: Boolean(editorProps.enabledAutoComplete),
1065
+ isBottomHalf: !isTop,
1066
+ isHeroTarget: NodeUtils.isHeroElement(dropElement)
1067
+ });
1040
1068
  let direction = "bottom";
1041
1069
  if (isTop) {
1042
1070
  direction = "top";
1043
1071
  }
1044
- if (NodeUtils.isParentCategoryType(
1045
- propsData.element.type,
1046
- dropElement.type
1047
- ) && !NodeUtils.isVoidBlockElement(dropElement)) {
1072
+ if (canInsertIntoDropElement && !shouldInsertAfterHero) {
1048
1073
  direction = "middle";
1049
1074
  }
1050
1075
  root2.querySelectorAll("[data-slate-dragover='true']").forEach((item2) => {
@@ -1151,10 +1176,25 @@ const DraggingProvider = ({
1151
1176
  const node = ReactEditor.toDOMNode(editor, dropElement);
1152
1177
  const rect = node.getBoundingClientRect();
1153
1178
  const isTop = ev.clientY < rect.y + rect.height / 2;
1154
- const isInsert = NodeUtils.isParentCategoryType(
1179
+ const canInsertIntoDropElement = NodeUtils.isParentCategoryType(
1155
1180
  propsData.element.type,
1156
1181
  dropElement.type
1157
1182
  ) && !NodeUtils.isVoidBlockElement(dropElement);
1183
+ const dropParentElement = Node.get(
1184
+ editor,
1185
+ Path.parent(dropPath)
1186
+ );
1187
+ const canInsertIntoDropParent = NodeUtils.isElement(dropParentElement) && NodeUtils.isParentCategoryType(
1188
+ propsData.element.type,
1189
+ dropParentElement.type
1190
+ );
1191
+ const isInsert = canInsertIntoDropElement && !shouldInsertAfterHeroSibling({
1192
+ canInsertIntoParent: canInsertIntoDropParent,
1193
+ canInsertIntoTarget: canInsertIntoDropElement,
1194
+ isAutoCompleteEnabled: Boolean(editorProps.enabledAutoComplete),
1195
+ isBottomHalf: !isTop,
1196
+ isHeroTarget: NodeUtils.isHeroElement(dropElement)
1197
+ });
1158
1198
  let targetPath = [...dropPath];
1159
1199
  if (propsData.action === "move") {
1160
1200
  if (!source)
@@ -1261,24 +1301,7 @@ const DraggingProvider = ({
1261
1301
  root2 == null ? void 0 : root2.removeEventListener("drop", onDrop);
1262
1302
  root2 == null ? void 0 : root2.removeEventListener("mousemove", onMousemove);
1263
1303
  };
1264
- }, [
1265
- autoScrollConfig,
1266
- dragoverType,
1267
- editor,
1268
- editorProps.readOnly,
1269
- inited,
1270
- isElementDragging,
1271
- quantityLimitCheck,
1272
- removeDraggingStyle,
1273
- removePlaceholder,
1274
- root2,
1275
- rootWindow,
1276
- setDragoverDirection,
1277
- setDragoverNodePath,
1278
- setHoverNodePath,
1279
- setSelectedNodePath,
1280
- standaloneElementEditing
1281
- ]);
1304
+ }, [autoScrollConfig, dragoverType, editor, editorProps.enabledAutoComplete, editorProps.readOnly, inited, isElementDragging, quantityLimitCheck, removeDraggingStyle, removePlaceholder, root2, rootWindow, setDragoverDirection, setDragoverNodePath, setHoverNodePath, setSelectedNodePath, standaloneElementEditing]);
1282
1305
  const dragHandle = useMemo(() => {
1283
1306
  return {
1284
1307
  onPointerDown(event) {
@@ -2129,6 +2152,17 @@ function useFontFamily() {
2129
2152
  const useEditorThemeState = () => {
2130
2153
  return useContext(EditorThemeStateContext);
2131
2154
  };
2155
+ const MAX_COLOR_PICKER_RECORD_SIZE = 10;
2156
+ function getColorPickerList({
2157
+ cacheColors = [],
2158
+ defaultColors = []
2159
+ }) {
2160
+ const cachedColors = cacheColors.filter(Boolean);
2161
+ if (cachedColors.length) {
2162
+ return cachedColors.slice(-MAX_COLOR_PICKER_RECORD_SIZE);
2163
+ }
2164
+ return defaultColors.filter(Boolean).slice(-MAX_COLOR_PICKER_RECORD_SIZE);
2165
+ }
2132
2166
  const CURRENT_COLORS_KEY = "CURRENT_COLORS_KEY";
2133
2167
  const MAX_RECORD_SIZE = 10;
2134
2168
  const colorDivRef = document.createElement("div");
@@ -2154,9 +2188,10 @@ const ColorContext = React__default.createContext(
2154
2188
  );
2155
2189
  const ColorProvider = ({ children }) => {
2156
2190
  const [list, setList] = useState(
2157
- [...defaultPresetColor, ...getCacheColors()].slice(
2158
- -MAX_RECORD_SIZE
2159
- )
2191
+ getColorPickerList({
2192
+ cacheColors: getCacheColors(),
2193
+ defaultColors: defaultPresetColor
2194
+ })
2160
2195
  );
2161
2196
  const addCurrentColor = useCallback(
2162
2197
  debounce$2((newColor) => {
@@ -2174,9 +2209,10 @@ const ColorProvider = ({ children }) => {
2174
2209
  );
2175
2210
  useEffect(() => {
2176
2211
  const timer = setInterval(() => {
2177
- const newColors = [...defaultPresetColor, ...getCacheColors()].slice(
2178
- -MAX_RECORD_SIZE
2179
- );
2212
+ const newColors = getColorPickerList({
2213
+ cacheColors: getCacheColors(),
2214
+ defaultColors: defaultPresetColor
2215
+ });
2180
2216
  setList(newColors);
2181
2217
  }, 1e3);
2182
2218
  return () => {
@@ -29246,6 +29282,20 @@ const LegacyColorPicker$1 = (props) => {
29246
29282
  }
29247
29283
  ));
29248
29284
  };
29285
+ const NATIVE_COLOR_INPUT_FALLBACK = "#000000";
29286
+ function getNativeColorInputValue(value) {
29287
+ if (!value)
29288
+ return NATIVE_COLOR_INPUT_FALLBACK;
29289
+ try {
29290
+ return Color$1(value).hex().toUpperCase();
29291
+ } catch (error2) {
29292
+ }
29293
+ try {
29294
+ return Color$1(`#${value}`).hex().toUpperCase();
29295
+ } catch (error2) {
29296
+ }
29297
+ return NATIVE_COLOR_INPUT_FALLBACK;
29298
+ }
29249
29299
  const getPickerValue$1 = (value) => {
29250
29300
  if (!value)
29251
29301
  return "";
@@ -29331,6 +29381,14 @@ const NewColorPicker$1 = (props) => {
29331
29381
  setPickerValue(value2);
29332
29382
  debouncedApplyPickerChange(value2);
29333
29383
  });
29384
+ const onNativeInputChange = useEventCallback(
29385
+ (event) => {
29386
+ const value2 = event.target.value.toUpperCase();
29387
+ debouncedApplyPickerChange.cancel();
29388
+ setPickerValue(value2);
29389
+ applyPickerChange(value2);
29390
+ }
29391
+ );
29334
29392
  const onClear = useEventCallback((event) => {
29335
29393
  event.stopPropagation();
29336
29394
  debouncedApplyPickerChange.cancel();
@@ -29355,38 +29413,82 @@ const NewColorPicker$1 = (props) => {
29355
29413
  };
29356
29414
  }, [onVisibleChange]);
29357
29415
  const showClearButton = allowClear && !arcoColorPickerProps.disabled && Boolean(value || pickerValue);
29358
- return /* @__PURE__ */ React__default.createElement(ArcoColorPickerConfigProvider, null, /* @__PURE__ */ React__default.createElement("div", { style: { display: "flex", alignItems: "center", width: "100%" } }, /* @__PURE__ */ React__default.createElement(
29359
- ColorPicker$2,
29360
- __spreadProps(__spreadValues({}, arcoColorPickerProps), {
29361
- value: pickerValue,
29362
- format: "hex",
29363
- style: __spreadValues({ width: "100%", flex: 1 }, arcoColorPickerProps.style),
29364
- popupVisible,
29365
- onVisibleChange,
29366
- onChange: onPickerChange,
29367
- historyColors: colors,
29368
- disabledAlpha: true,
29369
- showHistory: true,
29370
- showText: true,
29371
- triggerProps: __spreadProps(__spreadValues({}, arcoColorPickerProps.triggerProps), {
29372
- getPopupContainer: ((_b = arcoColorPickerProps.triggerProps) == null ? void 0 : _b.getPopupContainer) || getPopupContainer,
29373
- className: [
29374
- (_c = arcoColorPickerProps.triggerProps) == null ? void 0 : _c.className,
29375
- "easy-email-pro-theme-color-picker-popup"
29376
- ].filter(Boolean).join(" ")
29377
- })
29378
- })
29379
- ), showClearButton ? /* @__PURE__ */ React__default.createElement(
29380
- Button$2,
29416
+ return /* @__PURE__ */ React__default.createElement(ArcoColorPickerConfigProvider, null, /* @__PURE__ */ React__default.createElement(
29417
+ "div",
29381
29418
  {
29382
- "aria-label": "Clear color",
29383
- icon: /* @__PURE__ */ React__default.createElement(IconClose, null),
29384
- onClick: onClear,
29385
- size: "mini",
29386
- type: "text",
29387
- style: { marginLeft: 4, flex: "none" }
29388
- }
29389
- ) : null));
29419
+ style: {
29420
+ display: "flex",
29421
+ alignItems: "center",
29422
+ position: "relative",
29423
+ width: "100%"
29424
+ }
29425
+ },
29426
+ /* @__PURE__ */ React__default.createElement(
29427
+ ColorPicker$2,
29428
+ __spreadProps(__spreadValues({}, arcoColorPickerProps), {
29429
+ value: pickerValue,
29430
+ format: "hex",
29431
+ style: __spreadValues({ width: "100%", flex: 1 }, arcoColorPickerProps.style),
29432
+ popupVisible,
29433
+ onVisibleChange,
29434
+ onChange: onPickerChange,
29435
+ historyColors: colors,
29436
+ disabledAlpha: true,
29437
+ showHistory: true,
29438
+ showText: true,
29439
+ triggerProps: __spreadProps(__spreadValues({}, arcoColorPickerProps.triggerProps), {
29440
+ getPopupContainer: ((_b = arcoColorPickerProps.triggerProps) == null ? void 0 : _b.getPopupContainer) || getPopupContainer,
29441
+ className: [
29442
+ (_c = arcoColorPickerProps.triggerProps) == null ? void 0 : _c.className,
29443
+ "easy-email-pro-theme-color-picker-popup"
29444
+ ].filter(Boolean).join(" ")
29445
+ })
29446
+ })
29447
+ ),
29448
+ !arcoColorPickerProps.disabled ? /* @__PURE__ */ React__default.createElement(Tooltip, { content: t("Pick a color"), position: "top" }, /* @__PURE__ */ React__default.createElement(
29449
+ "div",
29450
+ {
29451
+ style: {
29452
+ position: "absolute",
29453
+ left: 0,
29454
+ top: 0,
29455
+ width: 32,
29456
+ height: "100%"
29457
+ }
29458
+ },
29459
+ /* @__PURE__ */ React__default.createElement(
29460
+ "input",
29461
+ {
29462
+ "aria-label": "Native color picker",
29463
+ type: "color",
29464
+ value: getNativeColorInputValue(pickerValue || mergeTagColor),
29465
+ onChange: onNativeInputChange,
29466
+ onClick: (event) => event.stopPropagation(),
29467
+ style: {
29468
+ position: "absolute",
29469
+ inset: 0,
29470
+ width: "100%",
29471
+ height: "100%",
29472
+ opacity: 0,
29473
+ cursor: "pointer",
29474
+ border: 0,
29475
+ padding: 0
29476
+ }
29477
+ }
29478
+ )
29479
+ )) : null,
29480
+ showClearButton ? /* @__PURE__ */ React__default.createElement(
29481
+ Button$2,
29482
+ {
29483
+ "aria-label": "Clear color",
29484
+ icon: /* @__PURE__ */ React__default.createElement(IconClose, null),
29485
+ onClick: onClear,
29486
+ size: "mini",
29487
+ type: "text",
29488
+ style: { marginLeft: 4, flex: "none" }
29489
+ }
29490
+ ) : null
29491
+ ));
29390
29492
  };
29391
29493
  const ColorPickerContainer = (props) => {
29392
29494
  var _b;
@@ -44865,11 +44967,92 @@ const normalizeElements = (element) => {
44865
44967
  children: sortedChildren
44866
44968
  }));
44867
44969
  };
44970
+ const HEX_COLOR_REGEXP = /#[0-9a-fA-F]{3,8}\b/g;
44971
+ const RGB_COLOR_REGEXP = /rgba?\([^)]*\)/gi;
44972
+ const COLOR_KEY_REGEXP = /color/i;
44973
+ const VARIABLE_COLOR_REGEXP = /(\{\{.*\}\}|\$\(|^var\()/i;
44974
+ function getInitialColorPickerHistoryColors(initialColors = []) {
44975
+ return [...new Set(initialColors)].filter(Boolean).slice(-10);
44976
+ }
44977
+ function isValidColor(value) {
44978
+ if (VARIABLE_COLOR_REGEXP.test(value))
44979
+ return false;
44980
+ try {
44981
+ Color$1(value);
44982
+ return true;
44983
+ } catch (error2) {
44984
+ return false;
44985
+ }
44986
+ }
44987
+ function getColorMatchesInOrder(value) {
44988
+ return [
44989
+ ...[...value.matchAll(HEX_COLOR_REGEXP)].map((match) => ({
44990
+ color: match[0],
44991
+ index: match.index || 0
44992
+ })),
44993
+ ...[...value.matchAll(RGB_COLOR_REGEXP)].map((match) => ({
44994
+ color: match[0],
44995
+ index: match.index || 0
44996
+ }))
44997
+ ].sort((a, b) => a.index - b.index).map((match) => match.color).filter(isValidColor);
44998
+ }
44999
+ function collectColorsFromJson(value, key2, result) {
45000
+ if (typeof value === "string") {
45001
+ const colorMatches = getColorMatchesInOrder(value);
45002
+ if (colorMatches.length) {
45003
+ result.push(...colorMatches);
45004
+ return;
45005
+ }
45006
+ const trimmedValue = value.trim();
45007
+ if (key2 && COLOR_KEY_REGEXP.test(key2) && isValidColor(trimmedValue)) {
45008
+ result.push(trimmedValue);
45009
+ }
45010
+ return;
45011
+ }
45012
+ if (Array.isArray(value)) {
45013
+ value.forEach((item2) => collectColorsFromJson(item2, key2, result));
45014
+ return;
45015
+ }
45016
+ if (!value || typeof value !== "object")
45017
+ return;
45018
+ Object.entries(value).forEach(
45019
+ ([childKey, childValue]) => collectColorsFromJson(childValue, childKey, result)
45020
+ );
45021
+ }
45022
+ function extractColorPickerColorsFromJson(value) {
45023
+ const result = [];
45024
+ collectColorsFromJson(value, void 0, result);
45025
+ return [...new Set(result)];
45026
+ }
45027
+ function getInitialColorPickerColors({
45028
+ colorPicker,
45029
+ content: content2
45030
+ }) {
45031
+ const initialColors = (colorPicker == null ? void 0 : colorPicker.initialColors) || [];
45032
+ const extractedColors = (colorPicker == null ? void 0 : colorPicker.autoExtractColors) ? extractColorPickerColorsFromJson(content2) : [];
45033
+ return [.../* @__PURE__ */ new Set([...initialColors, ...extractedColors])].filter(Boolean);
45034
+ }
45035
+ function syncInitialColorPickerColors({
45036
+ colorPicker,
45037
+ content: content2
45038
+ }) {
45039
+ const initialColors = getInitialColorPickerColors({ colorPicker, content: content2 });
45040
+ if (!initialColors.length)
45041
+ return;
45042
+ if (typeof localStorage === "undefined")
45043
+ return;
45044
+ localStorage.setItem(
45045
+ "CURRENT_COLORS_KEY",
45046
+ JSON.stringify(getInitialColorPickerHistoryColors(initialColors))
45047
+ );
45048
+ }
44868
45049
  const useCreateConfig$1 = (_m) => {
44869
45050
  var _n = _m, {
45051
+ colorPicker,
44870
45052
  interactiveStyle,
44871
45053
  hoveringToolbar
44872
45054
  } = _n, rest = __objRest(_n, [
45055
+ "colorPicker",
44873
45056
  "interactiveStyle",
44874
45057
  "hoveringToolbar"
44875
45058
  ]);
@@ -44889,6 +45072,10 @@ const useCreateConfig$1 = (_m) => {
44889
45072
  initialValues.content.children = widgetElement.children;
44890
45073
  initialValues.widgetElement = widgetElement;
44891
45074
  }
45075
+ syncInitialColorPickerColors({
45076
+ colorPicker,
45077
+ content: initialValues.content
45078
+ });
44892
45079
  return __spreadProps(__spreadValues({
44893
45080
  editor,
44894
45081
  withEnhanceEditor: withTheme$1,
@@ -0,0 +1,2 @@
1
+ export declare const NATIVE_COLOR_INPUT_FALLBACK = "#000000";
2
+ export declare function getNativeColorInputValue(value?: string): string;
@@ -0,0 +1,5 @@
1
+ export declare const MAX_COLOR_PICKER_RECORD_SIZE = 10;
2
+ export declare function getColorPickerList({ cacheColors, defaultColors, }: {
3
+ cacheColors?: string[];
4
+ defaultColors?: string[];
5
+ }): string[];
@@ -0,0 +1,7 @@
1
+ export declare function shouldInsertAfterHeroSibling({ canInsertIntoParent, canInsertIntoTarget, isAutoCompleteEnabled, isBottomHalf, isHeroTarget, }: {
2
+ canInsertIntoParent: boolean;
3
+ canInsertIntoTarget: boolean;
4
+ isAutoCompleteEnabled: boolean;
5
+ isBottomHalf: boolean;
6
+ isHeroTarget: boolean;
7
+ }): boolean;
@@ -2,7 +2,7 @@ import { EmailEditorProps } from "easy-email-pro-editor";
2
2
  import React from "react";
3
3
  import { ThemeConfigProps } from "../../typings";
4
4
  export declare const Retro: {
5
- useCreateConfig: ({ interactiveStyle, hoveringToolbar, ...rest }: Omit<ThemeConfigProps, "editor" | "widgetElement">) => Omit<EmailEditorProps, "children"> & Omit<EmailEditorProps, "children">;
5
+ useCreateConfig: ({ colorPicker, interactiveStyle, hoveringToolbar, ...rest }: Omit<ThemeConfigProps, "editor" | "widgetElement">) => Omit<EmailEditorProps, "children"> & Omit<EmailEditorProps, "children">;
6
6
  Layout: React.FC<{
7
7
  children?: React.ReactNode;
8
8
  header?: React.ReactNode;
@@ -0,0 +1,16 @@
1
+ import { getColorPickerList } from "../../components/Providers/colorPickerColorList";
2
+ export interface RetroColorPickerConfig {
3
+ initialColors?: string[];
4
+ autoExtractColors?: boolean;
5
+ }
6
+ export { getColorPickerList };
7
+ export declare function getInitialColorPickerHistoryColors(initialColors?: string[]): string[];
8
+ export declare function extractColorPickerColorsFromJson(value: unknown): string[];
9
+ export declare function getInitialColorPickerColors({ colorPicker, content, }: {
10
+ colorPicker?: RetroColorPickerConfig;
11
+ content?: unknown;
12
+ }): string[];
13
+ export declare function syncInitialColorPickerColors({ colorPicker, content, }: {
14
+ colorPicker?: RetroColorPickerConfig;
15
+ content?: unknown;
16
+ }): void;
@@ -206,6 +206,10 @@ export interface PluginsCustomEditorTypes {
206
206
  topTriggerArea?: number;
207
207
  scrollDelay?: number;
208
208
  } | true;
209
+ colorPicker?: {
210
+ initialColors?: string[];
211
+ autoExtractColors?: boolean;
212
+ };
209
213
  };
210
214
  EmailTemplate: BasicEmailTemplate;
211
215
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "easy-email-pro-theme",
3
- "version": "1.59.2",
3
+ "version": "1.59.3",
4
4
  "description": "",
5
5
  "files": [
6
6
  "lib"