@flozy/editor 3.8.0 → 3.8.1

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.
Files changed (97) hide show
  1. package/dist/Editor/CommonEditor.js +169 -111
  2. package/dist/Editor/Editor.css +1 -12
  3. package/dist/Editor/Elements/AI/AIInput.js +16 -5
  4. package/dist/Editor/Elements/AI/PopoverAIInput.js +31 -17
  5. package/dist/Editor/Elements/AI/Styles.js +2 -1
  6. package/dist/Editor/Elements/AI/VoiceToText/AudioWave.js +73 -0
  7. package/dist/Editor/Elements/AI/VoiceToText/index.js +167 -0
  8. package/dist/Editor/Elements/AI/VoiceToText/style.js +40 -0
  9. package/dist/Editor/Elements/Accordion/Accordion.js +74 -7
  10. package/dist/Editor/Elements/Accordion/AccordionBtnPopup.js +3 -2
  11. package/dist/Editor/Elements/Accordion/AccordionSummary.js +7 -74
  12. package/dist/Editor/Elements/AppHeader/AppHeader.js +26 -4
  13. package/dist/Editor/Elements/Button/EditorButton.js +28 -16
  14. package/dist/Editor/Elements/Color Picker/ColorButtons.js +60 -17
  15. package/dist/Editor/Elements/Color Picker/ColorPicker.css +25 -1
  16. package/dist/Editor/Elements/Color Picker/ColorPicker.js +4 -4
  17. package/dist/Editor/Elements/Color Picker/Styles.js +2 -1
  18. package/dist/Editor/Elements/Embed/Image.js +28 -20
  19. package/dist/Editor/Elements/Embed/Video.js +15 -11
  20. package/dist/Editor/Elements/Form/Workflow/UserInputs.js +2 -1
  21. package/dist/Editor/Elements/Grid/Grid.js +2 -0
  22. package/dist/Editor/Elements/Grid/GridItem.js +3 -1
  23. package/dist/Editor/Elements/Link/Link.js +6 -1
  24. package/dist/Editor/Elements/Link/LinkButton.js +4 -2
  25. package/dist/Editor/Elements/Link/LinkPopup.js +11 -3
  26. package/dist/Editor/Elements/Link/LinkPopupStyles.js +28 -0
  27. package/dist/Editor/Elements/Table/Table.js +1 -1
  28. package/dist/Editor/Elements/Table/TableCell.js +1 -1
  29. package/dist/Editor/MiniEditor.js +3 -1
  30. package/dist/Editor/Toolbar/Basic/index.js +4 -2
  31. package/dist/Editor/Toolbar/FormatTools/Dropdown.js +26 -2
  32. package/dist/Editor/Toolbar/FormatTools/MarkButton.js +2 -2
  33. package/dist/Editor/Toolbar/FormatTools/TextSize.js +5 -11
  34. package/dist/Editor/Toolbar/PopupTool/MiniTextFormat/SelectFontSize.js +4 -11
  35. package/dist/Editor/Toolbar/PopupTool/MiniTextFormat/SelectTypography.js +213 -86
  36. package/dist/Editor/Toolbar/PopupTool/MiniTextFormat/index.js +2 -1
  37. package/dist/Editor/Toolbar/PopupTool/PopupToolStyle.js +20 -13
  38. package/dist/Editor/Toolbar/PopupTool/TextFormat.js +52 -7
  39. package/dist/Editor/Toolbar/PopupTool/ThemeTextFormat.js +438 -0
  40. package/dist/Editor/Toolbar/PopupTool/index.js +6 -5
  41. package/dist/Editor/Toolbar/toolbarGroups.js +48 -6
  42. package/dist/Editor/assets/svg/AIIcons.js +153 -1
  43. package/dist/Editor/assets/svg/ThemeIcons.js +291 -0
  44. package/dist/Editor/common/ColorPickerButton.js +25 -9
  45. package/dist/Editor/common/CustomColorPicker/index.js +106 -0
  46. package/dist/Editor/common/CustomColorPicker/style.js +53 -0
  47. package/dist/Editor/common/CustomDialog/index.js +94 -0
  48. package/dist/Editor/common/CustomDialog/style.js +67 -0
  49. package/dist/Editor/common/CustomSelect.js +33 -0
  50. package/dist/Editor/common/DnD/DragHandleButton.js +1 -1
  51. package/dist/Editor/common/EditorCmds.js +35 -0
  52. package/dist/Editor/common/Icon.js +30 -2
  53. package/dist/Editor/common/LinkSettings/NavComponents.js +5 -2
  54. package/dist/Editor/common/LinkSettings/index.js +2 -1
  55. package/dist/Editor/common/LinkSettings/navOptions.js +7 -2
  56. package/dist/Editor/common/MentionsPopup/Styles.js +5 -2
  57. package/dist/Editor/common/Shorthands/elements.js +54 -0
  58. package/dist/Editor/common/StyleBuilder/accordionTitleBtnStyle.js +7 -7
  59. package/dist/Editor/common/StyleBuilder/accordionTitleStyle.js +16 -16
  60. package/dist/Editor/common/StyleBuilder/buttonStyle.js +4 -2
  61. package/dist/Editor/common/StyleBuilder/fieldTypes/bannerSpacing.js +33 -29
  62. package/dist/Editor/common/StyleBuilder/fieldTypes/borderRadius.js +31 -25
  63. package/dist/Editor/common/StyleBuilder/fieldTypes/buttonLink.js +1 -1
  64. package/dist/Editor/common/StyleBuilder/fieldTypes/color.js +31 -7
  65. package/dist/Editor/common/StyleBuilder/fieldTypes/fontSize.js +13 -4
  66. package/dist/Editor/common/StyleBuilder/fieldTypes/textOptions.js +14 -4
  67. package/dist/Editor/common/StyleBuilder/index.js +1 -1
  68. package/dist/Editor/helper/theme.js +189 -4
  69. package/dist/Editor/hooks/useEditorTheme.js +139 -0
  70. package/dist/Editor/hooks/useMouseMove.js +4 -2
  71. package/dist/Editor/plugins/withEmbeds.js +1 -1
  72. package/dist/Editor/plugins/withHTML.js +47 -5
  73. package/dist/Editor/plugins/withLayout.js +15 -10
  74. package/dist/Editor/plugins/withTable.js +2 -2
  75. package/dist/Editor/theme/ThemeList.js +50 -173
  76. package/dist/Editor/theme/index.js +144 -0
  77. package/dist/Editor/themeSettings/ActiveTheme.js +72 -0
  78. package/dist/Editor/themeSettings/buttons/index.js +290 -0
  79. package/dist/Editor/themeSettings/buttons/style.js +21 -0
  80. package/dist/Editor/themeSettings/colorTheme/index.js +290 -0
  81. package/dist/Editor/themeSettings/colorTheme/style.js +77 -0
  82. package/dist/Editor/themeSettings/fonts/PreviewElement.js +123 -0
  83. package/dist/Editor/themeSettings/fonts/index.js +213 -0
  84. package/dist/Editor/themeSettings/fonts/style.js +44 -0
  85. package/dist/Editor/themeSettings/icons.js +60 -0
  86. package/dist/Editor/themeSettings/index.js +320 -0
  87. package/dist/Editor/themeSettings/style.js +152 -0
  88. package/dist/Editor/themeSettingsAI/icons.js +96 -0
  89. package/dist/Editor/themeSettingsAI/index.js +356 -0
  90. package/dist/Editor/themeSettingsAI/saveTheme.js +190 -0
  91. package/dist/Editor/themeSettingsAI/style.js +247 -0
  92. package/dist/Editor/utils/SlateUtilityFunctions.js +161 -25
  93. package/dist/Editor/utils/button.js +1 -17
  94. package/dist/Editor/utils/events.js +11 -4
  95. package/dist/Editor/utils/font.js +40 -37
  96. package/dist/Editor/utils/helper.js +73 -13
  97. package/package.json +2 -1
@@ -2,28 +2,36 @@ import React from "react";
2
2
  import { Grid, Typography, Slider, FormControlLabel, Checkbox, Box } from "@mui/material";
3
3
  import { radiusStyle } from "./radiusStyle";
4
4
  import useWindowResize from "../../../hooks/useWindowResize";
5
- import { getBreakPointsValue, getCustomizationValue } from "../../../helper/theme";
5
+ import { getBreakPointsValue } from "../../../helper/theme";
6
+ import { useEditorTheme } from "../../../hooks/useEditorTheme";
6
7
  import { jsx as _jsx } from "react/jsx-runtime";
7
8
  import { jsxs as _jsxs } from "react/jsx-runtime";
8
9
  const BORDER_RADIUS_KEYS = ["topLeft", "topRight", "bottomLeft", "bottomRight"];
9
10
  const BorderRadius = props => {
10
11
  const {
11
- value: val,
12
12
  data,
13
13
  onChange,
14
14
  elementProps,
15
15
  classes
16
16
  } = props;
17
- let {
18
- lockRadius
19
- } = elementProps;
20
- if (lockRadius === undefined) {
21
- lockRadius = true;
22
- }
23
17
  const {
24
18
  key
25
19
  } = data;
26
20
  const [size] = useWindowResize();
21
+ const {
22
+ selectedTheme
23
+ } = useEditorTheme();
24
+ const {
25
+ borderRadius,
26
+ lockRadius: themeLockRadius
27
+ } = selectedTheme?.elementProps?.button || {};
28
+ const isUserValue = Object.keys(props?.value || {})?.length;
29
+ const isUserLockedRadius = typeof elementProps?.lockRadius === "boolean";
30
+ const val = isUserValue ? props?.value : borderRadius;
31
+ let lockRadius = isUserLockedRadius ? elementProps?.lockRadius : themeLockRadius;
32
+ if (lockRadius === undefined) {
33
+ lockRadius = true;
34
+ }
27
35
  const value = getBreakPointsValue(val, size?.device);
28
36
  const handleChange = e => {
29
37
  let changeAll = {};
@@ -80,13 +88,11 @@ const BorderRadius = props => {
80
88
  }), /*#__PURE__*/_jsx(Box, {
81
89
  sx: classes.sapcingInput,
82
90
  component: "input",
83
- value: !lockRadius ? "" : getCustomizationValue(value?.topLeft),
84
- className: "sliderInput removeScroll",
91
+ value: !lockRadius ? "" : value?.topLeft || 0,
92
+ className: "sliderInput",
85
93
  name: "topLeft",
86
94
  disabled: !lockRadius,
87
- onChange: handleChange,
88
- type: "number",
89
- placeholder: "0"
95
+ onChange: handleChange
90
96
  })]
91
97
  }), /*#__PURE__*/_jsx(FormControlLabel, {
92
98
  className: "ccheckbox-primary",
@@ -127,10 +133,10 @@ const BorderRadius = props => {
127
133
  borderRadius: `${value?.topLeft}px ${value?.topRight}px ${value?.bottomLeft}px ${value?.bottomRight}px`
128
134
  },
129
135
  children: [/*#__PURE__*/_jsx("input", {
130
- type: "number",
136
+ type: "text",
131
137
  name: "topLeft",
132
- value: getCustomizationValue(value?.topLeft),
133
- className: "borderInput removeScroll",
138
+ value: value?.topLeft,
139
+ className: "borderInput",
134
140
  placeholder: "0",
135
141
  style: {
136
142
  ...radiusStyle.topLeft,
@@ -138,10 +144,10 @@ const BorderRadius = props => {
138
144
  },
139
145
  onChange: handleChange
140
146
  }), /*#__PURE__*/_jsx("input", {
141
- type: "number",
147
+ type: "text",
142
148
  name: "topRight",
143
- value: getCustomizationValue(value?.topRight),
144
- className: "borderInput removeScroll",
149
+ value: value?.topRight,
150
+ className: "borderInput",
145
151
  placeholder: "0",
146
152
  style: {
147
153
  ...radiusStyle.topRight,
@@ -150,10 +156,10 @@ const BorderRadius = props => {
150
156
  },
151
157
  onChange: handleChange
152
158
  }), /*#__PURE__*/_jsx("input", {
153
- type: "number",
159
+ type: "text",
154
160
  name: "bottomLeft",
155
- value: getCustomizationValue(value?.bottomLeft),
156
- className: "borderInput removeScroll",
161
+ value: value?.bottomLeft,
162
+ className: "borderInput",
157
163
  placeholder: "0",
158
164
  style: {
159
165
  ...radiusStyle.bottomLeft,
@@ -162,10 +168,10 @@ const BorderRadius = props => {
162
168
  },
163
169
  onChange: handleChange
164
170
  }), /*#__PURE__*/_jsx("input", {
165
- type: "number",
171
+ type: "text",
166
172
  name: "bottomRight",
167
- value: getCustomizationValue(value?.bottomRight),
168
- className: "borderInput removeScroll",
173
+ value: value?.bottomRight,
174
+ className: "borderInput",
169
175
  placeholder: "0",
170
176
  style: {
171
177
  ...radiusStyle.bottomRight,
@@ -59,7 +59,7 @@ const ButtonLink = props => {
59
59
  value: elementProps?.url
60
60
  })
61
61
  });
62
- } else if (value?.linkType === "actionTrigger") {
62
+ } else if (value?.linkType === "prevTrigger" || value?.linkType === "nextTrigger") {
63
63
  return null;
64
64
  }
65
65
  };
@@ -1,22 +1,44 @@
1
- import React, { useEffect, useState } from "react";
1
+ import React, { useEffect, useMemo, useState } from "react";
2
2
  import { Grid, TextField, InputAdornment, Typography } from "@mui/material";
3
3
  import ColorPickerButton from "../../ColorPickerButton";
4
+ import { useSlateStatic } from "slate-react";
5
+ import { getElementStyle, getVariableValue } from "../../../helper/theme";
4
6
  import { jsx as _jsx } from "react/jsx-runtime";
5
7
  import { jsxs as _jsxs } from "react/jsx-runtime";
8
+ const MAP_STYLE_PROPS = {
9
+ bgColor: "background-color",
10
+ textColor: "color"
11
+ };
6
12
  const Color = props => {
7
13
  const {
8
- value,
14
+ value: val,
9
15
  data,
10
16
  onChange,
11
- classes
17
+ classes,
18
+ elementProps,
19
+ handleClose,
20
+ customProps
12
21
  } = props;
13
22
  const {
14
23
  key,
15
24
  label
16
25
  } = data;
17
26
  const [recentColors, setRecentColors] = useState({});
27
+ const editor = useSlateStatic();
28
+ const {
29
+ value,
30
+ inputValue
31
+ } = useMemo(() => {
32
+ const isVariable = val && val.startsWith("var");
33
+ const value = isVariable ? val : getElementStyle(editor, elementProps, MAP_STYLE_PROPS[key]);
34
+ const inputValue = isVariable ? getVariableValue(val) : getElementStyle(editor, elementProps, MAP_STYLE_PROPS[key]);
35
+ return {
36
+ value: value || val,
37
+ inputValue: inputValue || val
38
+ };
39
+ }, [editor, val]);
18
40
  useEffect(() => {
19
- const storedColors = JSON.parse(localStorage.getItem('recentColors'));
41
+ const storedColors = JSON.parse(localStorage.getItem("recentColors"));
20
42
  if (storedColors) {
21
43
  setRecentColors(storedColors);
22
44
  }
@@ -39,7 +61,7 @@ const Color = props => {
39
61
  [key]: updatedColors
40
62
  };
41
63
  setRecentColors(updatedColors);
42
- localStorage.setItem('recentColors', JSON.stringify(updatedColors));
64
+ localStorage.setItem("recentColors", JSON.stringify(updatedColors));
43
65
  };
44
66
  return /*#__PURE__*/_jsxs(Grid, {
45
67
  item: true,
@@ -56,7 +78,7 @@ const Color = props => {
56
78
  children: label
57
79
  }), /*#__PURE__*/_jsx(TextField, {
58
80
  fullWidth: true,
59
- value: value,
81
+ value: inputValue,
60
82
  placeholder: `${label} color code`,
61
83
  InputLabelProps: {
62
84
  shrink: true
@@ -68,7 +90,9 @@ const Color = props => {
68
90
  classes: classes,
69
91
  value: value,
70
92
  onSave: onSave,
71
- recentColors: recentColors[key]
93
+ recentColors: recentColors[key],
94
+ handleClose: handleClose,
95
+ disableEditTheme: customProps?.disableEditTheme
72
96
  })
73
97
  })
74
98
  }
@@ -1,19 +1,26 @@
1
- import React from "react";
1
+ import React, { useMemo } from "react";
2
2
  import { TextField, IconButton, Grid, Typography } from "@mui/material";
3
3
  import { sizeMap } from "../../../utils/font.js";
4
4
  import { TextMinusIcon, TextPlusIcon } from "../../../common/iconslist.js";
5
+ import { getElementStyle } from "../../../helper/theme.js";
6
+ import { useSlateStatic } from "slate-react";
5
7
  import { jsx as _jsx } from "react/jsx-runtime";
6
8
  import { jsxs as _jsxs } from "react/jsx-runtime";
7
9
  const FontSize = props => {
8
10
  const {
9
- value,
11
+ value: val,
10
12
  data,
11
- onChange
13
+ onChange,
14
+ elementProps
12
15
  } = props;
13
16
  const {
14
17
  key,
15
18
  width
16
19
  } = data;
20
+ const editor = useSlateStatic();
21
+ const value = useMemo(() => {
22
+ return getElementStyle(editor, elementProps, "font-size") || val;
23
+ }, [editor, val]);
17
24
  const handleChange = e => {
18
25
  let inc = parseInt(e.target.value) || 16;
19
26
  inc = inc > 200 ? 200 : inc;
@@ -24,7 +31,9 @@ const FontSize = props => {
24
31
  const getSizeVal = () => {
25
32
  try {
26
33
  const size = `${value}`?.indexOf("px") >= 0 ? value : sizeMap[value] || value;
27
- return parseInt(size || 16);
34
+ const defaultSize = 16;
35
+ const val = parseInt(size || defaultSize);
36
+ return isNaN(val) ? defaultSize : val;
28
37
  } catch (err) {
29
38
  return "";
30
39
  }
@@ -1,7 +1,8 @@
1
- import React from "react";
1
+ import React, { useMemo } from "react";
2
2
  import { FormControl, Grid, ListItemIcon, ListSubheader, MenuItem, Select, Typography } from "@mui/material";
3
- import { getBreakPointsValue } from "../../../helper/theme";
3
+ import { getBreakPointsValue, getElementStyle } from "../../../helper/theme";
4
4
  import useWindowResize from "../../../hooks/useWindowResize";
5
+ import { useSlateStatic } from "slate-react";
5
6
  import { jsx as _jsx } from "react/jsx-runtime";
6
7
  import { jsxs as _jsxs } from "react/jsx-runtime";
7
8
  import { Fragment as _Fragment } from "react/jsx-runtime";
@@ -22,10 +23,19 @@ const TextOptions = props => {
22
23
  isBreakpoint,
23
24
  options,
24
25
  renderOption,
25
- width
26
+ width,
27
+ themeEnabled
26
28
  } = data;
27
29
  const [size] = useWindowResize();
28
- const value = isBreakpoint ? getBreakPointsValue(val, size?.device) : val;
30
+ const editor = useSlateStatic();
31
+ const value = useMemo(() => {
32
+ const userValue = isBreakpoint ? getBreakPointsValue(val, size?.device) : val;
33
+ if (themeEnabled) {
34
+ // editor takes a little amount of time to update the new style in element, in that case userValue will be returned
35
+ return getElementStyle(editor, elementProps, key) || userValue;
36
+ }
37
+ return userValue;
38
+ }, [editor, isBreakpoint, val, size?.device]);
29
39
  const metaDataMappingOptions = metaMappings?.boards || [];
30
40
  const updatedOption = elementProps?.metadatamapping ? [...options, ...metaDataMappingOptions] : options;
31
41
  const handleChange = (e, d) => {
@@ -87,7 +87,7 @@ const StyleBuilder = props => {
87
87
  ...data,
88
88
  field_type: data?.element
89
89
  });
90
- if (data?.hasOwnProperty('name')) {
90
+ if (data?.hasOwnProperty("name")) {
91
91
  setElementProps({
92
92
  ...elementProps,
93
93
  ...data,
@@ -1,4 +1,6 @@
1
- import { sizeMap } from "../utils/font";
1
+ import { ReactEditor } from "slate-react";
2
+ import { fontFamilyMap, sizeMap } from "../utils/font";
3
+ import { Editor, Node } from "slate";
2
4
  export const breakpoints = {
3
5
  small: 0,
4
6
  mobile: 600,
@@ -27,7 +29,7 @@ const overrideValues = (value, ot) => {
27
29
  return Object.keys(value).reduce((a, b) => {
28
30
  return {
29
31
  ...a,
30
- [b]: overrides[ot] ? overrides[ot](value[b]) : value
32
+ [b]: overrides[ot] ? overrides[ot](value[b], value) : value
31
33
  };
32
34
  }, {});
33
35
  };
@@ -44,7 +46,15 @@ const overrides = {
44
46
  overrideReSizeH: val => {
45
47
  return `${val?.height}px`;
46
48
  },
47
- overrideBorderRadius: val => {
49
+ overrideBorderRadius: (val, breakpointValues) => {
50
+ if (!val?.topLeft) {
51
+ Object.values(breakpointValues || {}).forEach(v => {
52
+ if (v) {
53
+ // Applying the values from breakpoints that exist to those that do not have
54
+ val = v;
55
+ }
56
+ });
57
+ }
48
58
  return `${val?.topLeft}px ${val?.topRight}px ${val?.bottomLeft}px ${val?.bottomRight}px`;
49
59
  }
50
60
  };
@@ -98,4 +108,179 @@ export const getTRBLBreakPoints = (value, breakpoint) => {
98
108
  console.log(err);
99
109
  }
100
110
  };
101
- export const getCustomizationValue = value => isNaN(parseInt(value)) ? null : parseInt(value);
111
+ export function getElementStyle(editor, element, stylePropertyName) {
112
+ try {
113
+ const path = ReactEditor.findPath(editor, element);
114
+ if (path?.length) {
115
+ const currentEle = Node.get(editor, path);
116
+ const dom = ReactEditor.toDOMNode(editor, currentEle);
117
+ const editorBtn = dom?.querySelector("button.theme-element");
118
+ const elementStyle = window.getComputedStyle(editorBtn);
119
+ const style = elementStyle[stylePropertyName];
120
+ if (stylePropertyName === "fontFamily") {
121
+ const val = Object.entries(fontFamilyMap).find(([key, value]) => value === style)?.[0];
122
+ return val;
123
+ }
124
+ return style;
125
+ }
126
+ } catch (err) {
127
+ // console.log(err);
128
+ }
129
+ }
130
+ export function getTextSizeVal(editor) {
131
+ try {
132
+ const currentNode = Node.get(editor, editor.selection.anchor.path);
133
+ const currentElement = ReactEditor.toDOMNode(editor, currentNode);
134
+ if (currentElement) {
135
+ const element = document.querySelector('span[data-slate-string="true"]');
136
+ const computedStyle = window.getComputedStyle(element);
137
+ return computedStyle.getPropertyValue("font-size") || "";
138
+ }
139
+ } catch (err) {
140
+ // console.log(err);
141
+ }
142
+ }
143
+ export function getVariableValue(val) {
144
+ const bodyElement = document.body;
145
+ const computedStyle = getComputedStyle(bodyElement);
146
+ const [, variableName] = val?.match(/var\((--[^)]+)\)/) || [];
147
+ const varValue = computedStyle.getPropertyValue(variableName).trim();
148
+ return varValue;
149
+ }
150
+ export const textThemeFields = ["fontFamily", "fontSize", "color", "bold", "italic"
151
+ // "underline",
152
+ // "strikethrough",
153
+ ];
154
+
155
+ const themeElements = ["headingOne", "headingTwo", "headingThree", "headingFour", "headingFive", "headingSix", "paragraphOne", "paragraphTwo", "paragraphThree"];
156
+ export const isTextCustomized = editor => {
157
+ try {
158
+ if (editor.selection) {
159
+ const currentElement = Node.parent(editor, editor?.selection?.anchor?.path);
160
+ if (!currentElement) {
161
+ return false;
162
+ }
163
+ const {
164
+ children,
165
+ type
166
+ } = currentElement;
167
+ if (!themeElements.includes(type)) {
168
+ return false;
169
+ }
170
+ if (children?.length > 1) {
171
+ return true;
172
+ }
173
+ const customized = textThemeFields.some(field => {
174
+ const element = children[0] || {};
175
+ const value = element[field];
176
+ if (field === "fontSize") {
177
+ return Object.keys(value || {}).length;
178
+ } else {
179
+ return value;
180
+ }
181
+ });
182
+ return customized;
183
+ } else {
184
+ return null;
185
+ }
186
+ } catch (err) {
187
+ return null;
188
+ }
189
+ };
190
+ const addToTheme = (field, value, element) => {
191
+ switch (field) {
192
+ case "fontFamily":
193
+ return {
194
+ fontFamily: fontFamilyMap[value]
195
+ };
196
+ case "fontSize":
197
+ return {
198
+ fontSize: value?.lg
199
+ };
200
+ case "color":
201
+ return {
202
+ color: value
203
+ };
204
+ case "bold":
205
+ return {
206
+ fontWeight: "bold"
207
+ };
208
+ case "italic":
209
+ return {
210
+ fontStyle: "italic"
211
+ };
212
+ // case "underline":
213
+ // case "strikethrough":
214
+ // let textDecoration = "";
215
+
216
+ // if (element.underline) {
217
+ // textDecoration = "underline";
218
+ // }
219
+
220
+ // if (element.strikethrough) {
221
+ // textDecoration += " strikethrough";
222
+ // }
223
+
224
+ // return { textDecoration };
225
+ default:
226
+ return {};
227
+ }
228
+ };
229
+ const MAP_TEXT_THEME_FIELD = {
230
+ headingOne: "h1",
231
+ headingTwo: "h2",
232
+ headingThree: "h3",
233
+ headingFour: "h4",
234
+ headingFive: "h5",
235
+ headingSix: "h6",
236
+ paragraphOne: "para1",
237
+ paragraphTwo: "para2",
238
+ paragraphThree: "para3"
239
+ };
240
+ export const saveToTheme = editor => {
241
+ try {
242
+ if (editor.selection) {
243
+ const currentElement = Node.parent(editor, editor?.selection?.anchor?.path);
244
+ if (!currentElement) {
245
+ return false;
246
+ }
247
+ const {
248
+ children
249
+ } = currentElement;
250
+ if (children?.length > 1) {
251
+ return true;
252
+ }
253
+ let theme = {};
254
+ textThemeFields.forEach(field => {
255
+ const element = children[0] || {};
256
+ const value = element[field];
257
+ let style = {};
258
+ let isValueExist = false;
259
+ if (value) {
260
+ isValueExist = true;
261
+ if (field === "fontSize") {
262
+ isValueExist = !!Object.keys(value).length;
263
+ }
264
+ }
265
+ if (isValueExist) {
266
+ style = addToTheme(field, value, element);
267
+ }
268
+ theme = {
269
+ ...theme,
270
+ ...style
271
+ };
272
+ });
273
+ textThemeFields.forEach(field => {
274
+ Editor.removeMark(editor, field);
275
+ });
276
+ return {
277
+ field: MAP_TEXT_THEME_FIELD[currentElement?.type],
278
+ theme
279
+ };
280
+ }
281
+ } catch (err) {
282
+ return;
283
+ }
284
+ };
285
+ export const HEADING_THEME_FIELDS = ["h1", "h2", "h3", "h4", "h5", "h6"];
286
+ export const PARAGRAPH_THEME_FIELDS = ["para1", "para2", "para3"];
@@ -0,0 +1,139 @@
1
+ import { useSlate } from "slate-react";
2
+ import { defaultTheme } from "../theme";
3
+ import { getPageSettings, updatePageSettings } from "../utils/pageSettings";
4
+ import { HEADING_THEME_FIELDS, PARAGRAPH_THEME_FIELDS } from "../helper/theme";
5
+ const MAP_FIELDS = {
6
+ HEADING: HEADING_THEME_FIELDS,
7
+ PARAGRAPH: PARAGRAPH_THEME_FIELDS
8
+ };
9
+ function getUpdatePayload(prevTheme = {}, update, actionData) {
10
+ const {
11
+ action,
12
+ fieldName
13
+ } = actionData || {};
14
+ const {
15
+ theme: prev
16
+ } = prevTheme;
17
+ let theme = {};
18
+ let themeProps = {};
19
+ switch (action) {
20
+ case "THEME_CHANGE":
21
+ theme = update;
22
+ break;
23
+ case "CSS_VAR_CHANGE":
24
+ const prevCssVars = prev?.cssVars || {};
25
+ const prevValue = prevCssVars[fieldName] || {};
26
+ themeProps = {
27
+ ...(prev || {}),
28
+ cssVars: {
29
+ ...prevCssVars,
30
+ [fieldName]: {
31
+ ...prevValue,
32
+ ...update
33
+ }
34
+ }
35
+ };
36
+ theme = {
37
+ ...prevTheme,
38
+ theme: themeProps
39
+ };
40
+ break;
41
+ case "ELEMENT_PROPS_CHANGE":
42
+ const prevEleProps = prev?.elementProps || {};
43
+ const prevEleValue = prevEleProps[fieldName] || {};
44
+ themeProps = {
45
+ ...(prev || {}),
46
+ elementProps: {
47
+ ...prevEleProps,
48
+ [fieldName]: {
49
+ ...prevEleValue,
50
+ ...update
51
+ }
52
+ }
53
+ };
54
+ theme = {
55
+ ...prevTheme,
56
+ theme: themeProps
57
+ };
58
+ break;
59
+ case "OTHER_PROPS_CHANGE":
60
+ themeProps = {
61
+ ...(prev || {}),
62
+ otherProps: {
63
+ ...(prev.otherProps || {}),
64
+ ...update
65
+ }
66
+ };
67
+ theme = {
68
+ ...prevTheme,
69
+ theme: themeProps
70
+ };
71
+ break;
72
+ case "FONT_CHANGE":
73
+ const {
74
+ elementProps = {},
75
+ otherProps = {}
76
+ } = prev;
77
+ const fields = MAP_FIELDS[actionData?.fieldType];
78
+ const headingUpdate = {};
79
+ fields?.forEach(field => {
80
+ const prevHeadingData = elementProps[field];
81
+ headingUpdate[field] = {
82
+ ...prevHeadingData,
83
+ ...update
84
+ };
85
+ });
86
+ themeProps = {
87
+ ...(prev || {}),
88
+ elementProps: {
89
+ ...elementProps,
90
+ ...headingUpdate
91
+ },
92
+ otherProps: {
93
+ ...otherProps,
94
+ headingFontFamily: update?.fontFamily
95
+ }
96
+ };
97
+ theme = {
98
+ ...prevTheme,
99
+ theme: themeProps
100
+ };
101
+ break;
102
+ default:
103
+ theme = {
104
+ ...prevTheme,
105
+ ...(update || {})
106
+ };
107
+ break;
108
+ }
109
+ return theme;
110
+ }
111
+ const updateTheme = (editor, pageSt, update, actionData) => {
112
+ const {
113
+ pageProps
114
+ } = pageSt || {};
115
+ const {
116
+ theme
117
+ } = pageProps || {};
118
+ updatePageSettings(editor, {
119
+ ...(pageProps || {}),
120
+ theme: getUpdatePayload(theme, update, actionData)
121
+ });
122
+ };
123
+ export const useEditorTheme = () => {
124
+ const editor = useSlate();
125
+ const {
126
+ element: pageSt
127
+ } = getPageSettings(editor) || {};
128
+ const {
129
+ pageProps
130
+ } = pageSt || {};
131
+ const {
132
+ theme
133
+ } = pageProps || {};
134
+ return {
135
+ selectedTheme: theme?.theme || defaultTheme?.theme,
136
+ updateTheme: (update, actionData) => updateTheme(editor, pageSt, update, actionData),
137
+ theme
138
+ };
139
+ };
@@ -29,6 +29,7 @@ export const EditorProvider = ({
29
29
  const path = event?.target?.getAttribute("data-path");
30
30
  const [popupType, setPopupType] = useState(""); // opened popup name in the editor will be stored
31
31
  const [openAI, setOpenAI] = useState("");
32
+ const [selectedTheme, setSelectedTheme] = useState({});
32
33
  const onDrop = () => {
33
34
  setDrop(drop + 1);
34
35
  };
@@ -55,7 +56,9 @@ export const EditorProvider = ({
55
56
  popupType,
56
57
  setPopupType,
57
58
  openAI,
58
- setOpenAI
59
+ setOpenAI,
60
+ selectedTheme,
61
+ setSelectedTheme
59
62
  },
60
63
  children: children
61
64
  });
@@ -75,7 +78,6 @@ const useMouseMove = () => {
75
78
  }, []);
76
79
  const onMouseMove = e => {
77
80
  const dpath = e?.target?.closest(".dpath");
78
- console.log(dpath);
79
81
  if (dpath) {
80
82
  console.log(`Stopped position: (${e.clientX}, ${e.clientY})`, dpath);
81
83
  setEvent({
@@ -1,5 +1,5 @@
1
1
  import { Transforms, Path, Node } from "slate";
2
- const AvoidCopying = ["headingOne", "headingTwo", "headingThree", "blockquote"];
2
+ const AvoidCopying = ["headingOne", "headingTwo", "headingThree", "headingFour", "headingFive", "headingSix", "paragraphOne", "paragraphTwo", "paragraphThree", "blockquote"];
3
3
  const withEmbeds = editor => {
4
4
  const {
5
5
  isVoid,