@flozy/editor 1.2.3 → 1.2.4
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 +15 -14
- package/dist/Editor/Editor.css +4 -4
- package/dist/Editor/Elements/Color Picker/ColorPicker.js +23 -21
- package/dist/Editor/Elements/Color Picker/LogoIcon.js +59 -0
- package/dist/Editor/Elements/Title/title.js +16 -0
- package/dist/Editor/Toolbar/FormatTools/BlockButton.js +22 -0
- package/dist/Editor/Toolbar/FormatTools/Dropdown.js +40 -0
- package/dist/Editor/Toolbar/FormatTools/MarkButton.js +22 -0
- package/dist/Editor/Toolbar/FormatTools/index.js +4 -0
- package/dist/Editor/Toolbar/PopupTool/PopupToolStyle.js +34 -0
- package/dist/Editor/Toolbar/PopupTool/TextFormat.js +81 -0
- package/dist/Editor/Toolbar/PopupTool/index.js +69 -0
- package/dist/Editor/Toolbar/Toolbar.js +9 -71
- package/dist/Editor/hooks/withCommon.js +2 -1
- package/dist/Editor/plugins/withLayout.js +62 -0
- package/dist/Editor/utils/SlateUtilityFunctions.js +7 -2
- package/package.json +1 -1
- package/dist/Editor/hooks/useTimeout.js +0 -21
|
@@ -12,10 +12,10 @@ import { RemoteCursorOverlay } from "./RemoteCursorOverlay/Overlay";
|
|
|
12
12
|
import { mentionsEvent, commands } from "./utils/events";
|
|
13
13
|
import withCommon from "./hooks/withCommon";
|
|
14
14
|
import DialogWrapper from "./DialogWrapper";
|
|
15
|
-
import useTimeout from "./hooks/useTimeout";
|
|
16
15
|
import "./Editor.css";
|
|
17
16
|
import { serialize } from "./utils/serializer";
|
|
18
17
|
import { getThumbnailImage } from "./helper";
|
|
18
|
+
import PopupTool from "./Toolbar/PopupTool";
|
|
19
19
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
20
20
|
import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
21
21
|
const PREVIEW_IMAGE_HIDE_CLASS = ["grid-container-toolbar", "grid-item-toolbar", "element-toolbar"];
|
|
@@ -40,18 +40,16 @@ const CommonEditor = /*#__PURE__*/forwardRef((props, ref) => {
|
|
|
40
40
|
onSave,
|
|
41
41
|
editor: collaborativeEditor,
|
|
42
42
|
readOnly,
|
|
43
|
-
otherProps
|
|
44
|
-
timeoutInMS = 1000
|
|
43
|
+
otherProps
|
|
45
44
|
} = props;
|
|
46
45
|
const editorWrapper = useRef();
|
|
47
46
|
const convertedContent = draftToSlate({
|
|
48
47
|
data: content
|
|
49
48
|
});
|
|
50
49
|
const [value, setValue] = useState(convertedContent);
|
|
50
|
+
const [loadedValue] = useState(value);
|
|
51
|
+
const [isInteracted, setIsInteracted] = useState(false);
|
|
51
52
|
const [deboundedValue] = useDebounce(value, 500);
|
|
52
|
-
const [count] = useTimeout({
|
|
53
|
-
timeoutInMS: timeoutInMS
|
|
54
|
-
});
|
|
55
53
|
const editor = useMemo(() => {
|
|
56
54
|
if (collaborativeEditor) return collaborativeEditor;
|
|
57
55
|
return withCommon(createEditor());
|
|
@@ -76,13 +74,13 @@ const CommonEditor = /*#__PURE__*/forwardRef((props, ref) => {
|
|
|
76
74
|
}));
|
|
77
75
|
}, [id, content]);
|
|
78
76
|
useEffect(() => {
|
|
79
|
-
if (
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
}
|
|
77
|
+
if (editorWrapper && editorWrapper?.current && loadedValue !== deboundedValue && isInteracted) {
|
|
78
|
+
const text = serialize(deboundedValue);
|
|
79
|
+
const title = deboundedValue?.find(f => f.type === "title");
|
|
80
|
+
onSave(JSON.stringify(deboundedValue), {
|
|
81
|
+
text: text,
|
|
82
|
+
title: serialize(title?.children) || "Untitled"
|
|
83
|
+
});
|
|
86
84
|
}
|
|
87
85
|
}, [deboundedValue]);
|
|
88
86
|
const getPreviewImage = async (needBackground = false, options = {}) => {
|
|
@@ -144,6 +142,9 @@ const CommonEditor = /*#__PURE__*/forwardRef((props, ref) => {
|
|
|
144
142
|
const chars = CHARACTERS.filter(c => c.toLowerCase().startsWith(search?.toLowerCase())).slice(0, 10);
|
|
145
143
|
const handleEditorChange = newValue => {
|
|
146
144
|
setValue(newValue);
|
|
145
|
+
if (!isInteracted) {
|
|
146
|
+
setIsInteracted(true);
|
|
147
|
+
}
|
|
147
148
|
};
|
|
148
149
|
const customProps = {
|
|
149
150
|
...(otherProps || {})
|
|
@@ -215,7 +216,7 @@ const CommonEditor = /*#__PURE__*/forwardRef((props, ref) => {
|
|
|
215
216
|
paddingTop: `${bannerSpacing?.top}px`,
|
|
216
217
|
paddingBottom: `${bannerSpacing?.bottom}px`
|
|
217
218
|
},
|
|
218
|
-
children: [/*#__PURE__*/_jsx(Editable, {
|
|
219
|
+
children: [/*#__PURE__*/_jsx(PopupTool, {}), /*#__PURE__*/_jsx(Editable, {
|
|
219
220
|
className: "innert-editor-textbox",
|
|
220
221
|
readOnly: isReadOnly,
|
|
221
222
|
placeholder: "Write something",
|
package/dist/Editor/Editor.css
CHANGED
|
@@ -1,9 +1,5 @@
|
|
|
1
1
|
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@100;200;300;400;500;600;700;800;900&display=swap');
|
|
2
2
|
|
|
3
|
-
* {
|
|
4
|
-
font-family: 'Inter', sans-serif;
|
|
5
|
-
}
|
|
6
|
-
|
|
7
3
|
.ml-1 {
|
|
8
4
|
margin-left: 10px;
|
|
9
5
|
}
|
|
@@ -437,4 +433,8 @@ html{
|
|
|
437
433
|
|
|
438
434
|
.toolbar svg {
|
|
439
435
|
/* fill: 'red' */
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
.MuiIconButton-root.btnActive {
|
|
439
|
+
background-color: #ccc;
|
|
440
440
|
}
|
|
@@ -1,31 +1,23 @@
|
|
|
1
1
|
import React, { useRef, useState } from "react";
|
|
2
|
-
import {
|
|
3
|
-
import "
|
|
2
|
+
import { ReactEditor } from "slate-react";
|
|
3
|
+
import Button from "../../common/Button";
|
|
4
4
|
import { colors } from "./defaultColors";
|
|
5
5
|
import { addMarkData, activeMark } from "../../utils/SlateUtilityFunctions";
|
|
6
6
|
import { Transforms } from "slate";
|
|
7
7
|
import usePopup from "../../utils/customHooks/usePopup";
|
|
8
|
-
import {
|
|
8
|
+
import { logo } from "./LogoIcon";
|
|
9
|
+
import "./ColorPicker.css";
|
|
9
10
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
10
11
|
import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
11
12
|
import { Fragment as _Fragment } from "react/jsx-runtime";
|
|
12
|
-
const
|
|
13
|
-
color:
|
|
14
|
-
|
|
15
|
-
style: {
|
|
16
|
-
fill: '#64748B'
|
|
17
|
-
}
|
|
18
|
-
}),
|
|
19
|
-
bgColor: /*#__PURE__*/_jsx(MdFormatColorFill, {
|
|
20
|
-
size: 17,
|
|
21
|
-
style: {
|
|
22
|
-
fill: '#64748B'
|
|
23
|
-
}
|
|
24
|
-
})
|
|
13
|
+
const DEFAULT_COLOR = {
|
|
14
|
+
color: "#000000",
|
|
15
|
+
bgcolor: "#FFFFFF"
|
|
25
16
|
};
|
|
26
17
|
const ColorPicker = ({
|
|
27
18
|
format,
|
|
28
|
-
editor
|
|
19
|
+
editor,
|
|
20
|
+
showHex
|
|
29
21
|
}) => {
|
|
30
22
|
const [selection, setSelection] = useState();
|
|
31
23
|
const [hexValue, setHexValue] = useState("");
|
|
@@ -68,17 +60,27 @@ const ColorPicker = ({
|
|
|
68
60
|
setValidHex(isValideHexSix.test(newHex) || isValideHexThree.test(newHex));
|
|
69
61
|
setHexValue(newHex);
|
|
70
62
|
};
|
|
63
|
+
const activeColor = showOptions ? DEFAULT_COLOR[format] : activeMark(editor, format);
|
|
71
64
|
return /*#__PURE__*/_jsxs("div", {
|
|
72
65
|
className: "color-picker popup-wrapper1 color-picker-dialog",
|
|
73
66
|
ref: colorPickerRef,
|
|
74
|
-
|
|
67
|
+
style: {
|
|
68
|
+
display: "flex",
|
|
69
|
+
alignItems: "center"
|
|
70
|
+
},
|
|
71
|
+
children: [showHex ? /*#__PURE__*/_jsx("div", {
|
|
72
|
+
style: {
|
|
73
|
+
display: "flex"
|
|
74
|
+
},
|
|
75
|
+
children: activeColor
|
|
76
|
+
}) : null, /*#__PURE__*/_jsx(Button, {
|
|
75
77
|
style: {
|
|
76
|
-
color:
|
|
78
|
+
color: activeColor,
|
|
77
79
|
opacity: "1"
|
|
78
80
|
},
|
|
79
81
|
className: showOptions ? "clicked" : "",
|
|
80
82
|
onClick: toggleOption,
|
|
81
|
-
children: logo[format]
|
|
83
|
+
children: logo[format](activeColor)
|
|
82
84
|
}), showOptions && /*#__PURE__*/_jsxs(_Fragment, {
|
|
83
85
|
children: [/*#__PURE__*/_jsx("div", {
|
|
84
86
|
className: "backdrop",
|
|
@@ -125,7 +127,7 @@ const ColorPicker = ({
|
|
|
125
127
|
className: "colorSaveBtn",
|
|
126
128
|
style: {
|
|
127
129
|
background: validHex ? "#2563EB" : "#64748B",
|
|
128
|
-
color:
|
|
130
|
+
color: "#fff"
|
|
129
131
|
},
|
|
130
132
|
type: "submit",
|
|
131
133
|
children: "Save"
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
export const logo = {
|
|
4
|
+
color: color => /*#__PURE__*/_jsx("svg", {
|
|
5
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
6
|
+
fill: "#000000",
|
|
7
|
+
height: "20px",
|
|
8
|
+
width: "20px",
|
|
9
|
+
version: "1.1",
|
|
10
|
+
id: "Icons",
|
|
11
|
+
viewBox: "0 0 32 32",
|
|
12
|
+
children: /*#__PURE__*/_jsxs("g", {
|
|
13
|
+
children: [/*#__PURE__*/_jsx("path", {
|
|
14
|
+
d: "M29,27H3c-0.6,0-1,0.4-1,1s0.4,1,1,1h26c0.6,0,1-0.4,1-1S29.6,27,29,27z",
|
|
15
|
+
fill: color || "#000"
|
|
16
|
+
}), /*#__PURE__*/_jsx("path", {
|
|
17
|
+
d: "M5,24h4c0.6,0,1-0.4,1-1s-0.4-1-1-1H8.6l1.9-4h11.1l1.9,4H23c-0.6,0-1,0.4-1,1s0.4,1,1,1h4c0.6,0,1-0.4,1-1s-0.4-1-1-1 h-1.4L16.9,3.6C16.7,3.2,16.4,3,16,3s-0.7,0.2-0.9,0.6L6.4,22H5c-0.6,0-1,0.4-1,1S4.4,24,5,24z M16,6.3l4.6,9.7h-9.2L16,6.3z"
|
|
18
|
+
})]
|
|
19
|
+
})
|
|
20
|
+
}),
|
|
21
|
+
bgColor: color => /*#__PURE__*/_jsxs("svg", {
|
|
22
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
23
|
+
width: "24px",
|
|
24
|
+
height: "24px",
|
|
25
|
+
viewBox: "0 0 50 50",
|
|
26
|
+
fill: "none",
|
|
27
|
+
children: [/*#__PURE__*/_jsx("rect", {
|
|
28
|
+
width: "48",
|
|
29
|
+
height: "48",
|
|
30
|
+
fill: "white",
|
|
31
|
+
fillOpacity: "0.01"
|
|
32
|
+
}), /*#__PURE__*/_jsx("path", {
|
|
33
|
+
fillRule: "evenodd",
|
|
34
|
+
clipRule: "evenodd",
|
|
35
|
+
d: "M37 37C39.2091 37 41 35.2091 41 33C41 31.5272 39.6667 29.5272 37 27C34.3333 29.5272 33 31.5272 33 33C33 35.2091 34.7909 37 37 37Z",
|
|
36
|
+
fill: "#000000"
|
|
37
|
+
}), /*#__PURE__*/_jsx("path", {
|
|
38
|
+
d: "M20.8535 5.50439L24.389 9.03993",
|
|
39
|
+
stroke: "#000000",
|
|
40
|
+
strokeWidth: "4",
|
|
41
|
+
strokeLinecap: "round"
|
|
42
|
+
}), /*#__PURE__*/_jsx("path", {
|
|
43
|
+
d: "M23.6818 8.33281L8.12549 23.8892L19.4392 35.2029L34.9955 19.6465L23.6818 8.33281Z",
|
|
44
|
+
stroke: "#000000",
|
|
45
|
+
strokeWidth: "4",
|
|
46
|
+
strokeLinejoin: "round"
|
|
47
|
+
}), /*#__PURE__*/_jsx("path", {
|
|
48
|
+
d: "M12 20.0732L28.961 25.6496",
|
|
49
|
+
stroke: "#000000",
|
|
50
|
+
strokeWidth: "4",
|
|
51
|
+
strokeLinecap: "round"
|
|
52
|
+
}), /*#__PURE__*/_jsx("path", {
|
|
53
|
+
d: "M4 43H44",
|
|
54
|
+
stroke: color || "#FFF",
|
|
55
|
+
strokeWidth: "4",
|
|
56
|
+
strokeLinecap: "round"
|
|
57
|
+
})]
|
|
58
|
+
})
|
|
59
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
const Title = props => {
|
|
4
|
+
const {
|
|
5
|
+
attributes,
|
|
6
|
+
children
|
|
7
|
+
} = props;
|
|
8
|
+
return /*#__PURE__*/_jsx("div", {
|
|
9
|
+
...attributes,
|
|
10
|
+
style: {
|
|
11
|
+
fontWeight: "bold"
|
|
12
|
+
},
|
|
13
|
+
children: children
|
|
14
|
+
});
|
|
15
|
+
};
|
|
16
|
+
export default Title;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import Icon from "../../common/Icon";
|
|
3
|
+
import Button from "../../common/Button";
|
|
4
|
+
import { toggleBlock, isBlockActive } from "../../utils/SlateUtilityFunctions.js";
|
|
5
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
6
|
+
const BlockButton = ({
|
|
7
|
+
editor,
|
|
8
|
+
format
|
|
9
|
+
}) => {
|
|
10
|
+
return /*#__PURE__*/_jsx(Button, {
|
|
11
|
+
active: isBlockActive(editor, format),
|
|
12
|
+
format: format,
|
|
13
|
+
onMouseDown: e => {
|
|
14
|
+
e.preventDefault();
|
|
15
|
+
toggleBlock(editor, format);
|
|
16
|
+
},
|
|
17
|
+
children: /*#__PURE__*/_jsx(Icon, {
|
|
18
|
+
icon: format
|
|
19
|
+
})
|
|
20
|
+
});
|
|
21
|
+
};
|
|
22
|
+
export default BlockButton;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { Select, MenuItem } from "@mui/material";
|
|
3
|
+
import { addMarkData, activeMark } from "../../utils/SlateUtilityFunctions.js";
|
|
4
|
+
import { fontFamilyMap } from "../../utils/font";
|
|
5
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
6
|
+
const Dropdown = ({
|
|
7
|
+
editor,
|
|
8
|
+
format,
|
|
9
|
+
options
|
|
10
|
+
}) => {
|
|
11
|
+
const value = activeMark(editor, format);
|
|
12
|
+
const changeMarkData = (event, format) => {
|
|
13
|
+
event.preventDefault();
|
|
14
|
+
const value = event.target.value;
|
|
15
|
+
addMarkData(editor, {
|
|
16
|
+
format,
|
|
17
|
+
value
|
|
18
|
+
});
|
|
19
|
+
};
|
|
20
|
+
return /*#__PURE__*/_jsx(Select, {
|
|
21
|
+
value: value,
|
|
22
|
+
className: "editor-dd",
|
|
23
|
+
onChange: e => changeMarkData(e, format),
|
|
24
|
+
style: {
|
|
25
|
+
fontFamily: fontFamilyMap[value],
|
|
26
|
+
width: "100%",
|
|
27
|
+
height: "36px",
|
|
28
|
+
overflow: "hidden",
|
|
29
|
+
borderRadius: "10px"
|
|
30
|
+
},
|
|
31
|
+
children: options.map((item, index) => /*#__PURE__*/_jsx(MenuItem, {
|
|
32
|
+
style: {
|
|
33
|
+
fontFamily: item.text
|
|
34
|
+
},
|
|
35
|
+
value: item.value,
|
|
36
|
+
children: item.text
|
|
37
|
+
}, index))
|
|
38
|
+
});
|
|
39
|
+
};
|
|
40
|
+
export default Dropdown;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import Icon from "../../common/Icon";
|
|
3
|
+
import Button from "../../common/Button";
|
|
4
|
+
import { toggleMark, isMarkActive } from "../../utils/SlateUtilityFunctions.js";
|
|
5
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
6
|
+
const MarkButton = ({
|
|
7
|
+
editor,
|
|
8
|
+
format
|
|
9
|
+
}) => {
|
|
10
|
+
return /*#__PURE__*/_jsx(Button, {
|
|
11
|
+
active: isMarkActive(editor, format),
|
|
12
|
+
format: format,
|
|
13
|
+
onMouseDown: e => {
|
|
14
|
+
e.preventDefault();
|
|
15
|
+
toggleMark(editor, format);
|
|
16
|
+
},
|
|
17
|
+
children: /*#__PURE__*/_jsx(Icon, {
|
|
18
|
+
icon: format
|
|
19
|
+
})
|
|
20
|
+
});
|
|
21
|
+
};
|
|
22
|
+
export default MarkButton;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
const usePopupStyle = () => ({
|
|
2
|
+
popupWrapper: {
|
|
3
|
+
boxShadow: "0px 4px 10px 0px rgba(0, 0, 0, 0.16)"
|
|
4
|
+
},
|
|
5
|
+
textFormatWrapper: {
|
|
6
|
+
padding: "0px 24px 24px 24px",
|
|
7
|
+
width: "350px"
|
|
8
|
+
},
|
|
9
|
+
textFormatLabel: {
|
|
10
|
+
display: "flex",
|
|
11
|
+
alignItems: "center",
|
|
12
|
+
fontWeight: 600,
|
|
13
|
+
fontSize: "14px",
|
|
14
|
+
lineHeight: "25px",
|
|
15
|
+
marginTop: "8px",
|
|
16
|
+
marginBottom: "8px",
|
|
17
|
+
color: "rgba(169, 169, 169, 1)"
|
|
18
|
+
},
|
|
19
|
+
textFormatField: {
|
|
20
|
+
marginBottom: "8px"
|
|
21
|
+
},
|
|
22
|
+
textFormatFieldBorder: {
|
|
23
|
+
display: "flex",
|
|
24
|
+
alignItems: "center",
|
|
25
|
+
marginBottom: "8px",
|
|
26
|
+
border: "1px solid rgba(169, 169, 169, 1)",
|
|
27
|
+
padding: "0px 8px",
|
|
28
|
+
borderRadius: "10px"
|
|
29
|
+
},
|
|
30
|
+
textFormatCG: {
|
|
31
|
+
marginBottom: "8px"
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
export default usePopupStyle;
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { Grid } from "@mui/material";
|
|
3
|
+
import toolbarGroups from "../toolbarGroups";
|
|
4
|
+
import { Dropdown, MarkButton } from "../FormatTools";
|
|
5
|
+
import ColorPicker from "../../Elements/Color Picker/ColorPicker";
|
|
6
|
+
import { activeMark } from "../../utils/SlateUtilityFunctions";
|
|
7
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
8
|
+
import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
9
|
+
const allTools = toolbarGroups.flat();
|
|
10
|
+
const TextFormat = props => {
|
|
11
|
+
const {
|
|
12
|
+
classes,
|
|
13
|
+
editor
|
|
14
|
+
} = props;
|
|
15
|
+
const fontFamily = allTools.find(f => f.format === "fontFamily");
|
|
16
|
+
const fontStyle = allTools.filter(f => f.type === "mark");
|
|
17
|
+
return /*#__PURE__*/_jsxs(Grid, {
|
|
18
|
+
container: true,
|
|
19
|
+
sx: classes.textFormatWrapper,
|
|
20
|
+
children: [/*#__PURE__*/_jsx(Grid, {
|
|
21
|
+
item: true,
|
|
22
|
+
xs: 12,
|
|
23
|
+
sx: classes.textFormatLabel,
|
|
24
|
+
children: "TEXT COLOR"
|
|
25
|
+
}), /*#__PURE__*/_jsx(Grid, {
|
|
26
|
+
item: true,
|
|
27
|
+
xs: 12,
|
|
28
|
+
sx: classes.textFormatFieldBorder,
|
|
29
|
+
children: /*#__PURE__*/_jsx(ColorPicker, {
|
|
30
|
+
format: "color",
|
|
31
|
+
activeMark: activeMark,
|
|
32
|
+
editor: editor,
|
|
33
|
+
showHex: true
|
|
34
|
+
})
|
|
35
|
+
}), /*#__PURE__*/_jsx(Grid, {
|
|
36
|
+
item: true,
|
|
37
|
+
xs: 12,
|
|
38
|
+
sx: classes.textFormatLabel,
|
|
39
|
+
children: "BACKGROUND COLOR"
|
|
40
|
+
}), /*#__PURE__*/_jsx(Grid, {
|
|
41
|
+
item: true,
|
|
42
|
+
xs: 12,
|
|
43
|
+
sx: classes.textFormatFieldBorder,
|
|
44
|
+
children: /*#__PURE__*/_jsx(ColorPicker, {
|
|
45
|
+
format: "bgColor",
|
|
46
|
+
activeMark: activeMark,
|
|
47
|
+
editor: editor,
|
|
48
|
+
showHex: true
|
|
49
|
+
})
|
|
50
|
+
}), /*#__PURE__*/_jsx(Grid, {
|
|
51
|
+
item: true,
|
|
52
|
+
xs: 12,
|
|
53
|
+
sx: classes.textFormatLabel,
|
|
54
|
+
children: "FONT FAMILY"
|
|
55
|
+
}), /*#__PURE__*/_jsx(Grid, {
|
|
56
|
+
item: true,
|
|
57
|
+
xs: 12,
|
|
58
|
+
sx: classes.textFormatField,
|
|
59
|
+
children: /*#__PURE__*/_jsx(Dropdown, {
|
|
60
|
+
...fontFamily,
|
|
61
|
+
editor: editor
|
|
62
|
+
})
|
|
63
|
+
}), /*#__PURE__*/_jsx(Grid, {
|
|
64
|
+
item: true,
|
|
65
|
+
xs: 12,
|
|
66
|
+
sx: classes.textFormatLabel,
|
|
67
|
+
children: "FONT STYLE"
|
|
68
|
+
}), /*#__PURE__*/_jsx(Grid, {
|
|
69
|
+
item: true,
|
|
70
|
+
xs: 12,
|
|
71
|
+
sx: classes.textFormatCG,
|
|
72
|
+
children: fontStyle?.map((m, i) => {
|
|
73
|
+
return /*#__PURE__*/_jsx(MarkButton, {
|
|
74
|
+
editor: editor,
|
|
75
|
+
...m
|
|
76
|
+
}, `pptool_mark_${i}_${m.id}`);
|
|
77
|
+
})
|
|
78
|
+
})]
|
|
79
|
+
});
|
|
80
|
+
};
|
|
81
|
+
export default TextFormat;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import React, { useEffect, useState } from "react";
|
|
2
|
+
import { Popper, Fade, Paper, IconButton } from "@mui/material";
|
|
3
|
+
import CloseIcon from "@mui/icons-material/Close";
|
|
4
|
+
import { Editor, Range } from "slate";
|
|
5
|
+
import { useSlate, useFocused } from "slate-react";
|
|
6
|
+
import TextFormat from "./TextFormat";
|
|
7
|
+
import usePopupStyle from "./PopupToolStyle";
|
|
8
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
9
|
+
import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
10
|
+
const PopupTool = () => {
|
|
11
|
+
const classes = usePopupStyle();
|
|
12
|
+
const [anchorEl, setAnchorEl] = useState(null);
|
|
13
|
+
const editor = useSlate();
|
|
14
|
+
const inFocus = useFocused();
|
|
15
|
+
const {
|
|
16
|
+
selection
|
|
17
|
+
} = editor;
|
|
18
|
+
const open = Boolean(anchorEl);
|
|
19
|
+
const id = open ? "popup-edit-tool" : "";
|
|
20
|
+
useEffect(() => {
|
|
21
|
+
if (!selection || !inFocus || Range.isCollapsed(selection) || Editor.string(editor, selection) === "") {
|
|
22
|
+
setAnchorEl(null);
|
|
23
|
+
} else {
|
|
24
|
+
const domSelection = window.getSelection();
|
|
25
|
+
const domRange = domSelection.getRangeAt(0);
|
|
26
|
+
const rect = domRange.getBoundingClientRect();
|
|
27
|
+
setAnchorEl({
|
|
28
|
+
clientWidth: rect.width,
|
|
29
|
+
clientHeight: rect.height,
|
|
30
|
+
getBoundingClientRect: () => rect
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
}, [selection]);
|
|
34
|
+
const handleClose = () => {
|
|
35
|
+
setAnchorEl(null);
|
|
36
|
+
};
|
|
37
|
+
return /*#__PURE__*/_jsx(Popper, {
|
|
38
|
+
id: id,
|
|
39
|
+
open: open,
|
|
40
|
+
disablePortal: false,
|
|
41
|
+
anchorEl: anchorEl,
|
|
42
|
+
transition: true,
|
|
43
|
+
placement: "bottom-start",
|
|
44
|
+
onMouseDown: e => e.preventDefault(),
|
|
45
|
+
sx: classes.popupWrapper,
|
|
46
|
+
children: ({
|
|
47
|
+
TransitionProps
|
|
48
|
+
}) => /*#__PURE__*/_jsx(Fade, {
|
|
49
|
+
...TransitionProps,
|
|
50
|
+
timeout: 350,
|
|
51
|
+
children: /*#__PURE__*/_jsxs(Paper, {
|
|
52
|
+
children: [/*#__PURE__*/_jsx("div", {
|
|
53
|
+
style: {
|
|
54
|
+
display: "flex",
|
|
55
|
+
justifyContent: "end"
|
|
56
|
+
},
|
|
57
|
+
children: /*#__PURE__*/_jsx(IconButton, {
|
|
58
|
+
onClick: handleClose,
|
|
59
|
+
children: /*#__PURE__*/_jsx(CloseIcon, {})
|
|
60
|
+
})
|
|
61
|
+
}), /*#__PURE__*/_jsx(TextFormat, {
|
|
62
|
+
editor: editor,
|
|
63
|
+
classes: classes
|
|
64
|
+
})]
|
|
65
|
+
})
|
|
66
|
+
})
|
|
67
|
+
});
|
|
68
|
+
};
|
|
69
|
+
export default PopupTool;
|
|
@@ -1,13 +1,9 @@
|
|
|
1
1
|
import React, { useEffect, useState } from "react";
|
|
2
|
-
import { Select, MenuItem } from "@mui/material";
|
|
3
2
|
import { useSlate } from "slate-react";
|
|
4
|
-
import
|
|
5
|
-
import Icon from "../common/Icon";
|
|
6
|
-
import { toggleBlock, toggleMark, isMarkActive, addMarkData, isBlockActive, activeMark } from "../utils/SlateUtilityFunctions.js";
|
|
7
|
-
import { fontFamilyMap } from "../utils/font";
|
|
3
|
+
import { isBlockActive, activeMark } from "../utils/SlateUtilityFunctions.js";
|
|
8
4
|
import useFormat from "../utils/customHooks/useFormat.js";
|
|
9
5
|
import defaultToolbarGroups from "./toolbarGroups.js";
|
|
10
|
-
import "./
|
|
6
|
+
import { BlockButton, MarkButton, Dropdown } from "./FormatTools";
|
|
11
7
|
import ColorPicker from "../Elements/Color Picker/ColorPicker";
|
|
12
8
|
import LinkButton from "../Elements/Link/LinkButton";
|
|
13
9
|
import Embed from "../Elements/Embed/Embed";
|
|
@@ -26,6 +22,7 @@ import CarouselButton from "../Elements/Carousel/CarouselButton";
|
|
|
26
22
|
import ChipTextButton from "../Elements/ChipText/ChipTextButton";
|
|
27
23
|
import DrawerMenuButton from "../Elements/DrawerMenu/DrawerMenuButton";
|
|
28
24
|
import AppHeaderButton from "../Elements/AppHeader/AppHeaderButton";
|
|
25
|
+
import "./styles.css";
|
|
29
26
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
30
27
|
import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
31
28
|
const Toolbar = props => {
|
|
@@ -48,68 +45,6 @@ const Toolbar = props => {
|
|
|
48
45
|
setToolbarGroups(filteredGroups);
|
|
49
46
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
50
47
|
}, [isTable]);
|
|
51
|
-
const BlockButton = ({
|
|
52
|
-
format
|
|
53
|
-
}) => {
|
|
54
|
-
return /*#__PURE__*/_jsx(Button, {
|
|
55
|
-
active: isBlockActive(editor, format),
|
|
56
|
-
format: format,
|
|
57
|
-
onMouseDown: e => {
|
|
58
|
-
e.preventDefault();
|
|
59
|
-
toggleBlock(editor, format);
|
|
60
|
-
},
|
|
61
|
-
children: /*#__PURE__*/_jsx(Icon, {
|
|
62
|
-
icon: format
|
|
63
|
-
})
|
|
64
|
-
});
|
|
65
|
-
};
|
|
66
|
-
const MarkButton = ({
|
|
67
|
-
format
|
|
68
|
-
}) => {
|
|
69
|
-
return /*#__PURE__*/_jsx(Button, {
|
|
70
|
-
active: isMarkActive(editor, format),
|
|
71
|
-
format: format,
|
|
72
|
-
onMouseDown: e => {
|
|
73
|
-
e.preventDefault();
|
|
74
|
-
toggleMark(editor, format);
|
|
75
|
-
},
|
|
76
|
-
children: /*#__PURE__*/_jsx(Icon, {
|
|
77
|
-
icon: format
|
|
78
|
-
})
|
|
79
|
-
});
|
|
80
|
-
};
|
|
81
|
-
const Dropdown = ({
|
|
82
|
-
format,
|
|
83
|
-
options
|
|
84
|
-
}) => {
|
|
85
|
-
const value = activeMark(editor, format);
|
|
86
|
-
return /*#__PURE__*/_jsx(Select, {
|
|
87
|
-
value: value,
|
|
88
|
-
className: "editor-dd",
|
|
89
|
-
onChange: e => changeMarkData(e, format),
|
|
90
|
-
style: {
|
|
91
|
-
fontFamily: fontFamilyMap[value],
|
|
92
|
-
width: "200px",
|
|
93
|
-
height: "36px",
|
|
94
|
-
overflow: "hidden"
|
|
95
|
-
},
|
|
96
|
-
children: options.map((item, index) => /*#__PURE__*/_jsx(MenuItem, {
|
|
97
|
-
style: {
|
|
98
|
-
fontFamily: item.text
|
|
99
|
-
},
|
|
100
|
-
value: item.value,
|
|
101
|
-
children: item.text
|
|
102
|
-
}, index))
|
|
103
|
-
});
|
|
104
|
-
};
|
|
105
|
-
const changeMarkData = (event, format) => {
|
|
106
|
-
event.preventDefault();
|
|
107
|
-
const value = event.target.value;
|
|
108
|
-
addMarkData(editor, {
|
|
109
|
-
format,
|
|
110
|
-
value
|
|
111
|
-
});
|
|
112
|
-
};
|
|
113
48
|
return /*#__PURE__*/_jsxs("div", {
|
|
114
49
|
className: "toolbar",
|
|
115
50
|
children: [toolbarGroups.map((group, index) => /*#__PURE__*/_jsx("span", {
|
|
@@ -118,15 +53,18 @@ const Toolbar = props => {
|
|
|
118
53
|
switch (element.type) {
|
|
119
54
|
case "block":
|
|
120
55
|
return /*#__PURE__*/_jsx(BlockButton, {
|
|
121
|
-
...element
|
|
56
|
+
...element,
|
|
57
|
+
editor: editor
|
|
122
58
|
}, element.id);
|
|
123
59
|
case "mark":
|
|
124
60
|
return /*#__PURE__*/_jsx(MarkButton, {
|
|
125
|
-
...element
|
|
61
|
+
...element,
|
|
62
|
+
editor: editor
|
|
126
63
|
}, element.id);
|
|
127
64
|
case "dropdown":
|
|
128
65
|
return /*#__PURE__*/_jsx(Dropdown, {
|
|
129
|
-
...element
|
|
66
|
+
...element,
|
|
67
|
+
editor: editor
|
|
130
68
|
}, element.id);
|
|
131
69
|
case "link":
|
|
132
70
|
return /*#__PURE__*/_jsx(LinkButton, {
|
|
@@ -5,7 +5,8 @@ import withTables from "../plugins/withTable";
|
|
|
5
5
|
import withEmbeds from "../plugins/withEmbeds";
|
|
6
6
|
import withEquation from "../plugins/withEquation";
|
|
7
7
|
import withMentions from "../plugins/withMentions";
|
|
8
|
+
import withLayout from "../plugins/withLayout";
|
|
8
9
|
const withCommon = props => {
|
|
9
|
-
return withEquation(withHistory(withEmbeds(withTables(withLinks(withMentions(withReact(props)))))));
|
|
10
|
+
return withEquation(withLayout(withHistory(withEmbeds(withTables(withLinks(withMentions(withReact(props))))))));
|
|
10
11
|
};
|
|
11
12
|
export default withCommon;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { Transforms, Node, Element as SlateElement, Editor } from "slate";
|
|
2
|
+
const withLayout = editor => {
|
|
3
|
+
const {
|
|
4
|
+
normalizeNode
|
|
5
|
+
} = editor;
|
|
6
|
+
editor.normalizeNode = ([node, path]) => {
|
|
7
|
+
if (path.length === 0) {
|
|
8
|
+
if (editor.children.length <= 1 && Editor.string(editor, [0, 0]) === "") {
|
|
9
|
+
const title = {
|
|
10
|
+
type: "title",
|
|
11
|
+
children: [{
|
|
12
|
+
text: "Untitled"
|
|
13
|
+
}]
|
|
14
|
+
};
|
|
15
|
+
Transforms.insertNodes(editor, title, {
|
|
16
|
+
at: path.concat(0),
|
|
17
|
+
select: true
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
if (editor.children.length < 2) {
|
|
21
|
+
const paragraph = {
|
|
22
|
+
type: "paragraph",
|
|
23
|
+
children: [{
|
|
24
|
+
text: ""
|
|
25
|
+
}]
|
|
26
|
+
};
|
|
27
|
+
Transforms.insertNodes(editor, paragraph, {
|
|
28
|
+
at: path.concat(1)
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
for (const [child, childPath] of Node.children(editor, path)) {
|
|
32
|
+
let type = "";
|
|
33
|
+
const slateIndex = childPath[0];
|
|
34
|
+
const enforceType = type => {
|
|
35
|
+
if (SlateElement.isElement(child) && child.type !== type) {
|
|
36
|
+
const newProperties = {
|
|
37
|
+
type
|
|
38
|
+
};
|
|
39
|
+
Transforms.setNodes(editor, newProperties, {
|
|
40
|
+
at: childPath
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
switch (slateIndex) {
|
|
45
|
+
case 0:
|
|
46
|
+
type = "title";
|
|
47
|
+
enforceType(type);
|
|
48
|
+
break;
|
|
49
|
+
case 1:
|
|
50
|
+
type = "paragraph";
|
|
51
|
+
enforceType(type);
|
|
52
|
+
break;
|
|
53
|
+
default:
|
|
54
|
+
break;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return normalizeNode([node, path]);
|
|
59
|
+
};
|
|
60
|
+
return editor;
|
|
61
|
+
};
|
|
62
|
+
export default withLayout;
|
|
@@ -25,6 +25,7 @@ import ChipText from "../Elements/ChipText/ChipText";
|
|
|
25
25
|
import DrawerMenu from "../Elements/DrawerMenu/DrawerMenu";
|
|
26
26
|
import AppHeader from "../Elements/AppHeader/AppHeader";
|
|
27
27
|
import PageSettings from "../Elements/PageSettings/PageSettings";
|
|
28
|
+
import Title from "../Elements/Title/title";
|
|
28
29
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
29
30
|
const alignment = ["alignLeft", "alignRight", "alignCenter"];
|
|
30
31
|
const list_types = ["orderedList", "unorderedList"];
|
|
@@ -93,8 +94,8 @@ export const isBlockActive = (editor, format) => {
|
|
|
93
94
|
};
|
|
94
95
|
export const activeMark = (editor, format) => {
|
|
95
96
|
const defaultMarkData = {
|
|
96
|
-
color: "
|
|
97
|
-
bgColor: "
|
|
97
|
+
color: "#000000",
|
|
98
|
+
bgColor: "#FFFFFF",
|
|
98
99
|
fontSize: "normal",
|
|
99
100
|
fontFamily: "sans"
|
|
100
101
|
};
|
|
@@ -363,6 +364,10 @@ export const getBlock = props => {
|
|
|
363
364
|
return /*#__PURE__*/_jsx(PageSettings, {
|
|
364
365
|
...props
|
|
365
366
|
});
|
|
367
|
+
case "title":
|
|
368
|
+
return /*#__PURE__*/_jsx(Title, {
|
|
369
|
+
...props
|
|
370
|
+
});
|
|
366
371
|
default:
|
|
367
372
|
return /*#__PURE__*/_jsx("div", {
|
|
368
373
|
...element.attr,
|
package/package.json
CHANGED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { useEffect, useState } from "react";
|
|
2
|
-
let t = null;
|
|
3
|
-
const useTimeout = props => {
|
|
4
|
-
const {
|
|
5
|
-
timeoutInMS
|
|
6
|
-
} = props;
|
|
7
|
-
const [count, setCount] = useState(-1);
|
|
8
|
-
const onReset = () => {
|
|
9
|
-
clearTimeout(t);
|
|
10
|
-
t = setTimeout(() => {
|
|
11
|
-
setCount(count + 1);
|
|
12
|
-
}, timeoutInMS);
|
|
13
|
-
};
|
|
14
|
-
useEffect(() => {
|
|
15
|
-
if (timeoutInMS) {
|
|
16
|
-
onReset();
|
|
17
|
-
}
|
|
18
|
-
}, [timeoutInMS, count]);
|
|
19
|
-
return [count];
|
|
20
|
-
};
|
|
21
|
-
export default useTimeout;
|