@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.
- package/dist/Editor/CommonEditor.js +169 -111
- package/dist/Editor/Editor.css +1 -12
- package/dist/Editor/Elements/AI/AIInput.js +16 -5
- package/dist/Editor/Elements/AI/PopoverAIInput.js +31 -17
- package/dist/Editor/Elements/AI/Styles.js +2 -1
- package/dist/Editor/Elements/AI/VoiceToText/AudioWave.js +73 -0
- package/dist/Editor/Elements/AI/VoiceToText/index.js +167 -0
- package/dist/Editor/Elements/AI/VoiceToText/style.js +40 -0
- package/dist/Editor/Elements/Accordion/Accordion.js +74 -7
- package/dist/Editor/Elements/Accordion/AccordionBtnPopup.js +3 -2
- package/dist/Editor/Elements/Accordion/AccordionSummary.js +7 -74
- package/dist/Editor/Elements/AppHeader/AppHeader.js +26 -4
- package/dist/Editor/Elements/Button/EditorButton.js +28 -16
- package/dist/Editor/Elements/Color Picker/ColorButtons.js +60 -17
- package/dist/Editor/Elements/Color Picker/ColorPicker.css +25 -1
- package/dist/Editor/Elements/Color Picker/ColorPicker.js +4 -4
- package/dist/Editor/Elements/Color Picker/Styles.js +2 -1
- package/dist/Editor/Elements/Embed/Image.js +28 -20
- package/dist/Editor/Elements/Embed/Video.js +15 -11
- package/dist/Editor/Elements/Form/Workflow/UserInputs.js +2 -1
- package/dist/Editor/Elements/Grid/Grid.js +2 -0
- package/dist/Editor/Elements/Grid/GridItem.js +3 -1
- package/dist/Editor/Elements/Link/Link.js +6 -1
- package/dist/Editor/Elements/Link/LinkButton.js +4 -2
- package/dist/Editor/Elements/Link/LinkPopup.js +11 -3
- package/dist/Editor/Elements/Link/LinkPopupStyles.js +28 -0
- package/dist/Editor/Elements/Table/Table.js +1 -1
- package/dist/Editor/Elements/Table/TableCell.js +1 -1
- package/dist/Editor/MiniEditor.js +3 -1
- package/dist/Editor/Toolbar/Basic/index.js +4 -2
- package/dist/Editor/Toolbar/FormatTools/Dropdown.js +26 -2
- package/dist/Editor/Toolbar/FormatTools/MarkButton.js +2 -2
- package/dist/Editor/Toolbar/FormatTools/TextSize.js +5 -11
- package/dist/Editor/Toolbar/PopupTool/MiniTextFormat/SelectFontSize.js +4 -11
- package/dist/Editor/Toolbar/PopupTool/MiniTextFormat/SelectTypography.js +213 -86
- package/dist/Editor/Toolbar/PopupTool/MiniTextFormat/index.js +2 -1
- package/dist/Editor/Toolbar/PopupTool/PopupToolStyle.js +20 -13
- package/dist/Editor/Toolbar/PopupTool/TextFormat.js +52 -7
- package/dist/Editor/Toolbar/PopupTool/ThemeTextFormat.js +438 -0
- package/dist/Editor/Toolbar/PopupTool/index.js +6 -5
- package/dist/Editor/Toolbar/toolbarGroups.js +48 -6
- package/dist/Editor/assets/svg/AIIcons.js +153 -1
- package/dist/Editor/assets/svg/ThemeIcons.js +291 -0
- package/dist/Editor/common/ColorPickerButton.js +25 -9
- package/dist/Editor/common/CustomColorPicker/index.js +106 -0
- package/dist/Editor/common/CustomColorPicker/style.js +53 -0
- package/dist/Editor/common/CustomDialog/index.js +94 -0
- package/dist/Editor/common/CustomDialog/style.js +67 -0
- package/dist/Editor/common/CustomSelect.js +33 -0
- package/dist/Editor/common/DnD/DragHandleButton.js +1 -1
- package/dist/Editor/common/EditorCmds.js +35 -0
- package/dist/Editor/common/Icon.js +30 -2
- package/dist/Editor/common/LinkSettings/NavComponents.js +5 -2
- package/dist/Editor/common/LinkSettings/index.js +2 -1
- package/dist/Editor/common/LinkSettings/navOptions.js +7 -2
- package/dist/Editor/common/MentionsPopup/Styles.js +5 -2
- package/dist/Editor/common/Shorthands/elements.js +54 -0
- package/dist/Editor/common/StyleBuilder/accordionTitleBtnStyle.js +7 -7
- package/dist/Editor/common/StyleBuilder/accordionTitleStyle.js +16 -16
- package/dist/Editor/common/StyleBuilder/buttonStyle.js +4 -2
- package/dist/Editor/common/StyleBuilder/fieldTypes/bannerSpacing.js +33 -29
- package/dist/Editor/common/StyleBuilder/fieldTypes/borderRadius.js +31 -25
- package/dist/Editor/common/StyleBuilder/fieldTypes/buttonLink.js +1 -1
- package/dist/Editor/common/StyleBuilder/fieldTypes/color.js +31 -7
- package/dist/Editor/common/StyleBuilder/fieldTypes/fontSize.js +13 -4
- package/dist/Editor/common/StyleBuilder/fieldTypes/textOptions.js +14 -4
- package/dist/Editor/common/StyleBuilder/index.js +1 -1
- package/dist/Editor/helper/theme.js +189 -4
- package/dist/Editor/hooks/useEditorTheme.js +139 -0
- package/dist/Editor/hooks/useMouseMove.js +4 -2
- package/dist/Editor/plugins/withEmbeds.js +1 -1
- package/dist/Editor/plugins/withHTML.js +47 -5
- package/dist/Editor/plugins/withLayout.js +15 -10
- package/dist/Editor/plugins/withTable.js +2 -2
- package/dist/Editor/theme/ThemeList.js +50 -173
- package/dist/Editor/theme/index.js +144 -0
- package/dist/Editor/themeSettings/ActiveTheme.js +72 -0
- package/dist/Editor/themeSettings/buttons/index.js +290 -0
- package/dist/Editor/themeSettings/buttons/style.js +21 -0
- package/dist/Editor/themeSettings/colorTheme/index.js +290 -0
- package/dist/Editor/themeSettings/colorTheme/style.js +77 -0
- package/dist/Editor/themeSettings/fonts/PreviewElement.js +123 -0
- package/dist/Editor/themeSettings/fonts/index.js +213 -0
- package/dist/Editor/themeSettings/fonts/style.js +44 -0
- package/dist/Editor/themeSettings/icons.js +60 -0
- package/dist/Editor/themeSettings/index.js +320 -0
- package/dist/Editor/themeSettings/style.js +152 -0
- package/dist/Editor/themeSettingsAI/icons.js +96 -0
- package/dist/Editor/themeSettingsAI/index.js +356 -0
- package/dist/Editor/themeSettingsAI/saveTheme.js +190 -0
- package/dist/Editor/themeSettingsAI/style.js +247 -0
- package/dist/Editor/utils/SlateUtilityFunctions.js +161 -25
- package/dist/Editor/utils/button.js +1 -17
- package/dist/Editor/utils/events.js +11 -4
- package/dist/Editor/utils/font.js +40 -37
- package/dist/Editor/utils/helper.js +73 -13
- 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
|
|
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 ? "" :
|
|
84
|
-
className: "sliderInput
|
|
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: "
|
|
136
|
+
type: "text",
|
|
131
137
|
name: "topLeft",
|
|
132
|
-
value:
|
|
133
|
-
className: "borderInput
|
|
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: "
|
|
147
|
+
type: "text",
|
|
142
148
|
name: "topRight",
|
|
143
|
-
value:
|
|
144
|
-
className: "borderInput
|
|
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: "
|
|
159
|
+
type: "text",
|
|
154
160
|
name: "bottomLeft",
|
|
155
|
-
value:
|
|
156
|
-
className: "borderInput
|
|
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: "
|
|
171
|
+
type: "text",
|
|
166
172
|
name: "bottomRight",
|
|
167
|
-
value:
|
|
168
|
-
className: "borderInput
|
|
173
|
+
value: value?.bottomRight,
|
|
174
|
+
className: "borderInput",
|
|
169
175
|
placeholder: "0",
|
|
170
176
|
style: {
|
|
171
177
|
...radiusStyle.bottomRight,
|
|
@@ -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(
|
|
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(
|
|
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:
|
|
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
|
-
|
|
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
|
|
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) => {
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import {
|
|
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
|
|
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,
|