@flozy/editor 3.5.8 → 3.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Editor/ChatEditor.js +195 -0
- package/dist/Editor/Elements/Embed/Image.js +1 -1
- package/dist/Editor/Elements/Emoji/EmojiButton.js +2 -2
- package/dist/Editor/Elements/Emoji/EmojiPicker.js +16 -0
- package/dist/Editor/Elements/Form/Form.js +24 -15
- package/dist/Editor/Elements/Form/FormElements/FormNumbers.js +19 -14
- package/dist/Editor/Toolbar/Mini/MiniToolbar.js +1 -2
- package/dist/Editor/common/StyleBuilder/fieldTypes/metaDataMapping.js +0 -1
- package/dist/Editor/utils/chatEditor/SlateUtilityFunctions.js +361 -0
- package/dist/Editor/utils/serializeToHTML.js +25 -13
- package/dist/Editor/utils/table.js +8 -4
- package/dist/index.js +5 -1
- package/package.json +1 -1
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
import React, { useCallback, useMemo, useRef, useState, useEffect, useImperativeHandle, forwardRef } from "react";
|
|
2
|
+
import { Editable, Slate } from 'slate-react';
|
|
3
|
+
import { createEditor } from 'slate';
|
|
4
|
+
import { useDebounce } from "use-debounce";
|
|
5
|
+
import withCommon from "./hooks/withCommon";
|
|
6
|
+
import { getBlock, getMarked } from "./utils/chatEditor/SlateUtilityFunctions";
|
|
7
|
+
import MiniTextFormat from "./Toolbar/PopupTool/MiniTextFormat";
|
|
8
|
+
import { commands, mentionsEvent } from "./utils/events";
|
|
9
|
+
import { insertEmoji } from "./utils/emoji";
|
|
10
|
+
import { draftToSlate } from "./utils/draftToSlate";
|
|
11
|
+
import MentionsPopup from "./common/MentionsPopup";
|
|
12
|
+
import { serializeToText } from "./utils/serializeToText";
|
|
13
|
+
import useMentions from "./hooks/useMentions";
|
|
14
|
+
import Shorthands from "./common/Shorthands";
|
|
15
|
+
import usePopupStyle from "./Toolbar/PopupTool/PopupToolStyle";
|
|
16
|
+
import { EditorProvider } from "./hooks/useMouseMove";
|
|
17
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
18
|
+
import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
19
|
+
const ChatEditor = /*#__PURE__*/forwardRef((props, ref) => {
|
|
20
|
+
const {
|
|
21
|
+
id,
|
|
22
|
+
theme,
|
|
23
|
+
content,
|
|
24
|
+
readOnly,
|
|
25
|
+
otherProps,
|
|
26
|
+
needLayout = false,
|
|
27
|
+
toolBar = true,
|
|
28
|
+
onSave,
|
|
29
|
+
onsubmit
|
|
30
|
+
} = props;
|
|
31
|
+
const classes = usePopupStyle(theme);
|
|
32
|
+
const convertedContent = draftToSlate({
|
|
33
|
+
data: content
|
|
34
|
+
});
|
|
35
|
+
const [isInteracted, setIsInteracted] = useState(false);
|
|
36
|
+
const [value, setValue] = useState(convertedContent);
|
|
37
|
+
const [loadedValue] = useState(value);
|
|
38
|
+
const [deboundedValue] = useDebounce(value, 500);
|
|
39
|
+
const editor = useMemo(() => {
|
|
40
|
+
return withCommon(createEditor(), {
|
|
41
|
+
needLayout
|
|
42
|
+
});
|
|
43
|
+
}, []);
|
|
44
|
+
const isReadOnly = readOnly === "readonly";
|
|
45
|
+
useImperativeHandle(ref, () => ({
|
|
46
|
+
emojiClick: emoji => {
|
|
47
|
+
insertEmoji(editor, emoji?.native, editor.selection);
|
|
48
|
+
}
|
|
49
|
+
}));
|
|
50
|
+
useEffect(() => {
|
|
51
|
+
setValue(draftToSlate({
|
|
52
|
+
data: content
|
|
53
|
+
}));
|
|
54
|
+
}, [id, content]);
|
|
55
|
+
useEffect(() => {
|
|
56
|
+
if (JSON.stringify(loadedValue) !== JSON.stringify(deboundedValue) && isInteracted && onSave) {
|
|
57
|
+
const {
|
|
58
|
+
value: strVal,
|
|
59
|
+
...restVal
|
|
60
|
+
} = getOnSaveData(deboundedValue);
|
|
61
|
+
onSave(strVal, restVal);
|
|
62
|
+
}
|
|
63
|
+
}, [deboundedValue]);
|
|
64
|
+
const getOnSaveData = val => {
|
|
65
|
+
const text = serializeToText(val);
|
|
66
|
+
const title = val?.find(f => f.type === "title");
|
|
67
|
+
return {
|
|
68
|
+
value: JSON.stringify(val),
|
|
69
|
+
text: text,
|
|
70
|
+
title: serializeToText(title?.children) || "Untitled"
|
|
71
|
+
};
|
|
72
|
+
};
|
|
73
|
+
const {
|
|
74
|
+
CHARACTERS = [],
|
|
75
|
+
hideTools
|
|
76
|
+
// needLayout = true,
|
|
77
|
+
} = otherProps || {};
|
|
78
|
+
const mentionsRef = useRef();
|
|
79
|
+
const customProps = {
|
|
80
|
+
...(otherProps || {}),
|
|
81
|
+
readOnly: isReadOnly,
|
|
82
|
+
editorPlaceholder: "Write Something",
|
|
83
|
+
page_id: 1
|
|
84
|
+
};
|
|
85
|
+
const [mentions, setMentions] = useMentions({
|
|
86
|
+
editor,
|
|
87
|
+
selection: editor?.selection
|
|
88
|
+
});
|
|
89
|
+
const {
|
|
90
|
+
search,
|
|
91
|
+
target,
|
|
92
|
+
index
|
|
93
|
+
} = mentions;
|
|
94
|
+
let {
|
|
95
|
+
type
|
|
96
|
+
} = mentions;
|
|
97
|
+
if (type && type === "elements" && hideTools.indexOf("slash") > -1) {
|
|
98
|
+
type = null;
|
|
99
|
+
}
|
|
100
|
+
const chars = type ? Shorthands[type]({
|
|
101
|
+
...mentions,
|
|
102
|
+
CHARACTERS,
|
|
103
|
+
hideTools: hideTools
|
|
104
|
+
}) : [];
|
|
105
|
+
const Leaf = ({
|
|
106
|
+
attributes,
|
|
107
|
+
children,
|
|
108
|
+
leaf
|
|
109
|
+
}) => {
|
|
110
|
+
children = getMarked(leaf, children);
|
|
111
|
+
return /*#__PURE__*/_jsx("span", {
|
|
112
|
+
...attributes,
|
|
113
|
+
children: children
|
|
114
|
+
});
|
|
115
|
+
};
|
|
116
|
+
const handleEditorChange = newValue => {
|
|
117
|
+
setValue(newValue);
|
|
118
|
+
if (!isInteracted) {
|
|
119
|
+
setIsInteracted(true);
|
|
120
|
+
}
|
|
121
|
+
};
|
|
122
|
+
const Element = props => {
|
|
123
|
+
return getBlock(props);
|
|
124
|
+
};
|
|
125
|
+
const renderElement = useCallback(props => {
|
|
126
|
+
return /*#__PURE__*/_jsx(Element, {
|
|
127
|
+
...props,
|
|
128
|
+
customProps: customProps
|
|
129
|
+
});
|
|
130
|
+
}, []);
|
|
131
|
+
const renderLeaf = useCallback(props => {
|
|
132
|
+
return /*#__PURE__*/_jsx(Leaf, {
|
|
133
|
+
...props,
|
|
134
|
+
customProps: customProps
|
|
135
|
+
});
|
|
136
|
+
}, []);
|
|
137
|
+
const onKeyDown = useCallback(event => {
|
|
138
|
+
const isMetaKey = event.metaKey && event.keyCode >= 65 && event.keyCode <= 90;
|
|
139
|
+
const isCtrlKey = event.ctrlKey || isMetaKey;
|
|
140
|
+
if (target && chars.length > 0 && !isCtrlKey) {
|
|
141
|
+
mentionsEvent({
|
|
142
|
+
event,
|
|
143
|
+
mentions,
|
|
144
|
+
setMentions,
|
|
145
|
+
chars,
|
|
146
|
+
target,
|
|
147
|
+
editor,
|
|
148
|
+
type,
|
|
149
|
+
mentionsRef
|
|
150
|
+
});
|
|
151
|
+
} else if (isCtrlKey) {
|
|
152
|
+
commands({
|
|
153
|
+
event,
|
|
154
|
+
editor
|
|
155
|
+
});
|
|
156
|
+
} else if (event.key === "Enter") {
|
|
157
|
+
onsubmit();
|
|
158
|
+
}
|
|
159
|
+
}, [chars, editor, target, mentions, setMentions, search, type, mentionsRef]);
|
|
160
|
+
const handleClose = () => {};
|
|
161
|
+
return /*#__PURE__*/_jsx(EditorProvider, {
|
|
162
|
+
theme: theme,
|
|
163
|
+
editor: editor,
|
|
164
|
+
children: /*#__PURE__*/_jsxs(Slate, {
|
|
165
|
+
editor: editor,
|
|
166
|
+
initialValue: value,
|
|
167
|
+
onChange: handleEditorChange,
|
|
168
|
+
children: [toolBar && /*#__PURE__*/_jsx(MiniTextFormat, {
|
|
169
|
+
classes: classes,
|
|
170
|
+
editor: editor,
|
|
171
|
+
closeMainPopup: handleClose
|
|
172
|
+
}), /*#__PURE__*/_jsx(Editable, {
|
|
173
|
+
className: "chatEditorRoot",
|
|
174
|
+
renderElement: renderElement,
|
|
175
|
+
renderLeaf: renderLeaf,
|
|
176
|
+
placeholder: "Start typing ...",
|
|
177
|
+
spellCheck: true,
|
|
178
|
+
autoFocus: true,
|
|
179
|
+
onKeyDown: onKeyDown
|
|
180
|
+
}), !readOnly ? /*#__PURE__*/_jsx(MentionsPopup, {
|
|
181
|
+
ref: mentionsRef,
|
|
182
|
+
mentions: mentions,
|
|
183
|
+
setMentions: setMentions,
|
|
184
|
+
editor: editor,
|
|
185
|
+
target: target,
|
|
186
|
+
index: index,
|
|
187
|
+
chars: chars,
|
|
188
|
+
type: type,
|
|
189
|
+
theme: theme
|
|
190
|
+
}) : null]
|
|
191
|
+
}, id)
|
|
192
|
+
});
|
|
193
|
+
});
|
|
194
|
+
ChatEditor.displayName = "ChatEditor";
|
|
195
|
+
export default ChatEditor;
|
|
@@ -6,7 +6,7 @@ import useResize from "../../utils/customHooks/useResize";
|
|
|
6
6
|
import EmbedPopup from "./EmbedPopup";
|
|
7
7
|
import { IconButton, Tooltip, Box } from "@mui/material";
|
|
8
8
|
import { GridSettingsIcon, LinkIcon } from "../../common/iconslist";
|
|
9
|
-
import { useEditorContext
|
|
9
|
+
import { useEditorContext } from "../../hooks/useMouseMove";
|
|
10
10
|
import { getTRBLBreakPoints, getBreakPointsValue } from "../../helper/theme";
|
|
11
11
|
import Icon from "../../common/Icon";
|
|
12
12
|
import frames from "./Frames";
|
|
@@ -2,10 +2,10 @@ import React, { useState, forwardRef, useImperativeHandle } from "react";
|
|
|
2
2
|
import { useSlateStatic, ReactEditor } from "slate-react";
|
|
3
3
|
import { Paper, Popover } from "@mui/material";
|
|
4
4
|
import data from "@emoji-mart/data";
|
|
5
|
-
import Picker from "@emoji-mart/react";
|
|
6
5
|
import { insertEmoji } from "../../utils/emoji";
|
|
7
6
|
import ToolbarIcon from "../../common/ToolbarIcon";
|
|
8
7
|
import Icon from "../../common/Icon";
|
|
8
|
+
import EmojiPicker from "./EmojiPicker";
|
|
9
9
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
10
10
|
import { Fragment as _Fragment } from "react/jsx-runtime";
|
|
11
11
|
import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
@@ -61,7 +61,7 @@ const EmojiButton = /*#__PURE__*/forwardRef((props, ref) => {
|
|
|
61
61
|
},
|
|
62
62
|
onClose: handleClose,
|
|
63
63
|
children: /*#__PURE__*/_jsx(Paper, {
|
|
64
|
-
children: /*#__PURE__*/_jsx(
|
|
64
|
+
children: /*#__PURE__*/_jsx(EmojiPicker, {
|
|
65
65
|
data: data,
|
|
66
66
|
onEmojiSelect: onEmojiSelect
|
|
67
67
|
})
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import data from "@emoji-mart/data";
|
|
2
|
+
import Picker from "@emoji-mart/react";
|
|
3
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
4
|
+
import { Fragment as _Fragment } from "react/jsx-runtime";
|
|
5
|
+
const EmojiPicker = props => {
|
|
6
|
+
const {
|
|
7
|
+
onEmojiSelect
|
|
8
|
+
} = props;
|
|
9
|
+
return /*#__PURE__*/_jsx(_Fragment, {
|
|
10
|
+
children: /*#__PURE__*/_jsx(Picker, {
|
|
11
|
+
data: data,
|
|
12
|
+
onEmojiSelect: onEmojiSelect
|
|
13
|
+
})
|
|
14
|
+
});
|
|
15
|
+
};
|
|
16
|
+
export default EmojiPicker;
|
|
@@ -63,9 +63,11 @@ const Form = props => {
|
|
|
63
63
|
const [showOptions, setShowOptions] = useState(false);
|
|
64
64
|
const [submittedSuccessfully, setSubmittedSuccessfully] = useState(false);
|
|
65
65
|
const [formHeight, setFormHeight] = useState();
|
|
66
|
+
const [formWidth, setFormWidth] = useState();
|
|
66
67
|
const path = ReactEditor.findPath(editor, element);
|
|
67
68
|
useEffect(() => {
|
|
68
69
|
setFormHeight(formEle?.current?.clientHeight);
|
|
70
|
+
setFormWidth(formEle?.current?.clientWidth);
|
|
69
71
|
}, []);
|
|
70
72
|
const btnBorderStyle = buttonProps?.borderColor?.indexOf("linear") >= 0 ? {
|
|
71
73
|
borderImageSource: buttonProps?.borderColor,
|
|
@@ -317,7 +319,7 @@ const Form = props => {
|
|
|
317
319
|
},
|
|
318
320
|
onMouseOver: onMouseOver,
|
|
319
321
|
onMouseLeave: onMouseLeave,
|
|
320
|
-
children: [
|
|
322
|
+
children: [/*#__PURE__*/_jsxs(Box, {
|
|
321
323
|
component: "form",
|
|
322
324
|
id: `${formName}`,
|
|
323
325
|
onSubmit: handleSubmit,
|
|
@@ -325,6 +327,7 @@ const Form = props => {
|
|
|
325
327
|
color: textColor || "#FFF",
|
|
326
328
|
borderColor: borderColor || "transparent",
|
|
327
329
|
borderWidth: borderWidth || "1px",
|
|
330
|
+
display: submittedSuccessfully ? 'none' : 'block',
|
|
328
331
|
borderRadius: {
|
|
329
332
|
...getBreakPointsValue(borderRadius || {}, null, "overrideBorderRadius", true)
|
|
330
333
|
},
|
|
@@ -412,17 +415,20 @@ const Form = props => {
|
|
|
412
415
|
}
|
|
413
416
|
})
|
|
414
417
|
})]
|
|
415
|
-
})
|
|
418
|
+
}), /*#__PURE__*/_jsx(Grid, {
|
|
416
419
|
item: true,
|
|
420
|
+
sx: {
|
|
421
|
+
display: submittedSuccessfully ? 'flex' : 'none'
|
|
422
|
+
},
|
|
417
423
|
contentEditable: false,
|
|
418
|
-
children: /*#__PURE__*/
|
|
424
|
+
children: /*#__PURE__*/_jsx(Grid, {
|
|
419
425
|
container: true,
|
|
420
426
|
alignItems: "center",
|
|
421
427
|
justifyContent: "center",
|
|
422
428
|
spacing: 2,
|
|
423
|
-
children:
|
|
429
|
+
children: /*#__PURE__*/_jsx(Grid, {
|
|
424
430
|
item: true,
|
|
425
|
-
children: /*#__PURE__*/
|
|
431
|
+
children: /*#__PURE__*/_jsxs(Typography, {
|
|
426
432
|
sx: {
|
|
427
433
|
color: textColor || "#A2A9B4",
|
|
428
434
|
borderColor: borderColor || "transparent",
|
|
@@ -436,23 +442,26 @@ const Form = props => {
|
|
|
436
442
|
...getTRBLBreakPoints(bannerSpacing)
|
|
437
443
|
},
|
|
438
444
|
minHeight: `${formHeight}px`,
|
|
445
|
+
minWidth: `${formWidth}px`,
|
|
439
446
|
display: "flex",
|
|
440
447
|
alignItems: "center",
|
|
441
448
|
justifyContent: "center",
|
|
442
449
|
textAlign: "center",
|
|
443
450
|
position: "relative"
|
|
444
451
|
},
|
|
445
|
-
children: "Form Submitted Successfully...!"
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
452
|
+
children: ["Form Submitted Successfully...!", /*#__PURE__*/_jsx("span", {
|
|
453
|
+
style: {
|
|
454
|
+
paddingLeft: "10px"
|
|
455
|
+
},
|
|
456
|
+
children: /*#__PURE__*/_jsx(IconButton, {
|
|
457
|
+
onClick: handleCloseMessage,
|
|
458
|
+
children: /*#__PURE__*/_jsx(Icon, {
|
|
459
|
+
icon: "closeIcon"
|
|
460
|
+
})
|
|
461
|
+
})
|
|
462
|
+
})]
|
|
454
463
|
})
|
|
455
|
-
})
|
|
464
|
+
})
|
|
456
465
|
})
|
|
457
466
|
}), openSetttings ? /*#__PURE__*/_jsx(FormPopup, {
|
|
458
467
|
element: element,
|
|
@@ -30,12 +30,25 @@ const FormNumbers = props => {
|
|
|
30
30
|
children: /*#__PURE__*/_jsx(Box, {
|
|
31
31
|
component: "input",
|
|
32
32
|
...rest,
|
|
33
|
-
type: "
|
|
34
|
-
|
|
35
|
-
|
|
33
|
+
type: "tel",
|
|
34
|
+
onChange: e => {
|
|
35
|
+
let value = e.target.value;
|
|
36
|
+
value = value.replace(/[^0-9+]/g, '');
|
|
37
|
+
if (value.startsWith('+')) {
|
|
38
|
+
value = value[0] + value.slice(1).replace(/\+/g, '');
|
|
39
|
+
}
|
|
40
|
+
if (value.startsWith('+')) {
|
|
41
|
+
if (value.length > 16) {
|
|
42
|
+
value = value.slice(0, 16);
|
|
43
|
+
}
|
|
44
|
+
} else {
|
|
45
|
+
if (value.length > 15) {
|
|
46
|
+
value = value.slice(0, 15);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
e.target.value = value;
|
|
50
|
+
onChange(e);
|
|
36
51
|
},
|
|
37
|
-
onChange: onChange,
|
|
38
|
-
onWheel: e => e.target.blur(),
|
|
39
52
|
sx: {
|
|
40
53
|
width: "100%",
|
|
41
54
|
border: `1px solid ${borderColor || "#FFF"}`,
|
|
@@ -50,17 +63,9 @@ const FormNumbers = props => {
|
|
|
50
63
|
},
|
|
51
64
|
borderStyle: borderStyle || "solid",
|
|
52
65
|
color: textColor || "#000",
|
|
53
|
-
background: bgColor || "transparent"
|
|
54
|
-
'&::-webkit-outer-spin-button, &::-webkit-inner-spin-button': {
|
|
55
|
-
'-webkit-appearance': 'none',
|
|
56
|
-
margin: 0
|
|
57
|
-
},
|
|
58
|
-
'&[type=number]': {
|
|
59
|
-
'-moz-appearance': 'textfield' // Hide spin buttons for Firefox
|
|
60
|
-
}
|
|
66
|
+
background: bgColor || "transparent"
|
|
61
67
|
}
|
|
62
68
|
})
|
|
63
69
|
});
|
|
64
70
|
};
|
|
65
|
-
|
|
66
71
|
export default FormNumbers;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React, { useEffect, useState } from "react";
|
|
2
2
|
import { useSlate } from "slate-react";
|
|
3
|
-
import { Box, Dialog, IconButton, Paper, Popper, Tooltip
|
|
3
|
+
import { Box, Dialog, IconButton, Paper, Popper, Tooltip } from "@mui/material";
|
|
4
4
|
import MENU_OPTIONS from "./Options/Options";
|
|
5
5
|
import TextFormat from "../PopupTool/TextFormat";
|
|
6
6
|
import AddElements from "../PopupTool/AddElements";
|
|
@@ -8,7 +8,6 @@ import AddTemplates from "../PopupTool/AddTemplates";
|
|
|
8
8
|
import miniToolbarStyles from "./Styles";
|
|
9
9
|
import usePopupStyle from "../PopupTool/PopupToolStyle";
|
|
10
10
|
import PopperHeader from "../PopupTool/PopperHeader";
|
|
11
|
-
import { getSelectedText } from "../../utils/helper";
|
|
12
11
|
import { useEditorContext } from "../../hooks/useMouseMove";
|
|
13
12
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
14
13
|
import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
@@ -0,0 +1,361 @@
|
|
|
1
|
+
import { Editor, Transforms, Element as SlateElement } from "slate";
|
|
2
|
+
import { Box } from "@mui/material";
|
|
3
|
+
import { fontFamilyMap, sizeMap } from "../font";
|
|
4
|
+
import Table from "../../Elements/Table/Table";
|
|
5
|
+
import TableRow from "../../Elements/Table/TableRow";
|
|
6
|
+
import TableCell from "../../Elements/Table/TableCell";
|
|
7
|
+
import Mentions from "../../Elements/Mentions/Mentions";
|
|
8
|
+
import CheckList from "../../Elements/List/CheckList";
|
|
9
|
+
import { isEmptyTextNode } from "../../helper";
|
|
10
|
+
import { getBreakPointsValue } from "../../helper/theme";
|
|
11
|
+
import insertNewLine from "../insertNewLine";
|
|
12
|
+
import { getBorderColor } from "../helper";
|
|
13
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
14
|
+
const alignment = ["alignLeft", "alignRight", "alignCenter"];
|
|
15
|
+
const list_types = ["orderedList", "unorderedList"];
|
|
16
|
+
const LIST_FORMAT_TYPE = {
|
|
17
|
+
orderedList: "list-item",
|
|
18
|
+
unorderedList: "list-item"
|
|
19
|
+
};
|
|
20
|
+
const NEWLINESAFTER = ["headingOne", "headingTwo", "headingThree"];
|
|
21
|
+
export const toggleBlock = (editor, format, selection = true, attr = {}) => {
|
|
22
|
+
const isActive = isBlockActive(editor, format);
|
|
23
|
+
const isList = list_types.includes(format);
|
|
24
|
+
const isIndent = alignment.includes(format);
|
|
25
|
+
const isAligned = alignment.some(alignmentType => isBlockActive(editor, alignmentType));
|
|
26
|
+
|
|
27
|
+
/*If the node is already aligned and change in indent is called we should unwrap it first and split the node to prevent
|
|
28
|
+
messy, nested DOM structure and bugs due to that.*/
|
|
29
|
+
if (isAligned && isIndent) {
|
|
30
|
+
Transforms.unwrapNodes(editor, {
|
|
31
|
+
match: n => alignment.includes(!Editor.isEditor(n) && SlateElement.isElement(n) && n.type),
|
|
32
|
+
split: true
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/* Wraping the nodes for alignment, to allow it to co-exist with other block level operations*/
|
|
37
|
+
if (isIndent) {
|
|
38
|
+
Transforms.wrapNodes(editor, {
|
|
39
|
+
type: format,
|
|
40
|
+
children: []
|
|
41
|
+
});
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
Transforms.unwrapNodes(editor, {
|
|
45
|
+
match: n => list_types.includes(!Editor.isEditor(n) && SlateElement.isElement(n) && n.type),
|
|
46
|
+
split: true
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
// inserting blocks from "/"" commands remove searched word
|
|
50
|
+
if (!selection) {
|
|
51
|
+
Transforms.insertText(editor, "");
|
|
52
|
+
}
|
|
53
|
+
Transforms.setNodes(editor, {
|
|
54
|
+
type: isActive ? "paragraph" : isList ? LIST_FORMAT_TYPE[format] : format,
|
|
55
|
+
...attr
|
|
56
|
+
});
|
|
57
|
+
if (isList && !isActive) {
|
|
58
|
+
Transforms.wrapNodes(editor, {
|
|
59
|
+
type: format,
|
|
60
|
+
children: []
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
if (NEWLINESAFTER.indexOf(format) > -1) {
|
|
64
|
+
insertNewLine(editor);
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
export const addMarkData = (editor, data) => {
|
|
68
|
+
try {
|
|
69
|
+
Editor.addMark(editor, data.format, data.value);
|
|
70
|
+
} catch (err) {
|
|
71
|
+
console.log(err);
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
export const toggleMark = (editor, format) => {
|
|
75
|
+
const isActive = isMarkActive(editor, format);
|
|
76
|
+
if (isActive) {
|
|
77
|
+
Editor.removeMark(editor, format);
|
|
78
|
+
} else {
|
|
79
|
+
Editor.addMark(editor, format, true);
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
export const isMarkActive = (editor, format) => {
|
|
83
|
+
try {
|
|
84
|
+
const marks = Editor.marks(editor);
|
|
85
|
+
return marks ? marks[format] === true : false;
|
|
86
|
+
} catch (err) {
|
|
87
|
+
console.log(err);
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
export const isBlockActive = (editor, format) => {
|
|
92
|
+
const [match] = Editor.nodes(editor, {
|
|
93
|
+
match: n => !Editor.isEditor(n) && SlateElement.isElement(n) && n.type === format
|
|
94
|
+
});
|
|
95
|
+
return !!match;
|
|
96
|
+
};
|
|
97
|
+
export const getBlockActive = (editor, format) => {
|
|
98
|
+
const [match] = Editor.nodes(editor, {
|
|
99
|
+
match: n => !Editor.isEditor(n) && SlateElement.isElement(n) && n.type === format
|
|
100
|
+
});
|
|
101
|
+
return {
|
|
102
|
+
isActive: !!match,
|
|
103
|
+
props: match && match[0]
|
|
104
|
+
};
|
|
105
|
+
};
|
|
106
|
+
export const upateBlockActive = (editor, format, attr = {}) => {
|
|
107
|
+
const [match] = Editor.nodes(editor, {
|
|
108
|
+
match: n => !Editor.isEditor(n) && SlateElement.isElement(n) && n.type === format
|
|
109
|
+
});
|
|
110
|
+
if (match && match[1] !== undefined) {
|
|
111
|
+
Transforms.setNodes(editor, attr, {
|
|
112
|
+
at: match[1]
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
export const activeMark = (editor, format) => {
|
|
117
|
+
const defaultMarkData = {
|
|
118
|
+
color: "#000000",
|
|
119
|
+
bgColor: "#FFFFFF",
|
|
120
|
+
fontSize: "normal",
|
|
121
|
+
fontFamily: "PoppinsRegular",
|
|
122
|
+
fontWeight: "normal"
|
|
123
|
+
};
|
|
124
|
+
try {
|
|
125
|
+
const marks = Editor.marks(editor);
|
|
126
|
+
const defaultValue = defaultMarkData[format];
|
|
127
|
+
return marks?.[format] ?? defaultValue;
|
|
128
|
+
} catch (err) {
|
|
129
|
+
console.log(err);
|
|
130
|
+
return null;
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
export const getMarked = (leaf, children) => {
|
|
134
|
+
const className = leaf?.doublequote ? "doublequote" : "";
|
|
135
|
+
if (leaf.bold) {
|
|
136
|
+
children = /*#__PURE__*/_jsx("strong", {
|
|
137
|
+
children: children
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
if (leaf.code) {
|
|
141
|
+
children = /*#__PURE__*/_jsx("code", {
|
|
142
|
+
children: children
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
if (leaf.italic) {
|
|
146
|
+
children = /*#__PURE__*/_jsx("em", {
|
|
147
|
+
children: children
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
if (leaf.strikethrough) {
|
|
151
|
+
children = /*#__PURE__*/_jsx("span", {
|
|
152
|
+
style: {
|
|
153
|
+
textDecoration: "line-through"
|
|
154
|
+
},
|
|
155
|
+
children: children
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
if (leaf.underline) {
|
|
159
|
+
children = /*#__PURE__*/_jsx("u", {
|
|
160
|
+
children: children
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
if (leaf.superscript) {
|
|
164
|
+
children = /*#__PURE__*/_jsx("sup", {
|
|
165
|
+
children: children
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
if (leaf.subscript) {
|
|
169
|
+
children = /*#__PURE__*/_jsx("sub", {
|
|
170
|
+
children: children
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
// cover under single span
|
|
174
|
+
if (leaf.color || leaf.bgColor || leaf.fontSize || leaf.fontFamily || leaf.fontWeight || className) {
|
|
175
|
+
const family = fontFamilyMap[leaf?.fontFamily];
|
|
176
|
+
const textStyles = leaf?.color?.indexOf("gradient") >= 0 ? {
|
|
177
|
+
background: leaf?.color?.concat("text"),
|
|
178
|
+
WebkitBackgroundClip: "text",
|
|
179
|
+
WebkitTextFillColor: "transparent"
|
|
180
|
+
} : {
|
|
181
|
+
color: leaf.color
|
|
182
|
+
};
|
|
183
|
+
children = /*#__PURE__*/_jsx("span", {
|
|
184
|
+
style: {
|
|
185
|
+
background: leaf.bgColor
|
|
186
|
+
},
|
|
187
|
+
children: /*#__PURE__*/_jsx(Box, {
|
|
188
|
+
className: className,
|
|
189
|
+
component: "span",
|
|
190
|
+
sx: {
|
|
191
|
+
fontSize: {
|
|
192
|
+
lg: sizeMap[leaf.fontSize] || leaf.fontSize,
|
|
193
|
+
...getBreakPointsValue(leaf.fontSize, null, "overrideText")
|
|
194
|
+
},
|
|
195
|
+
...textStyles,
|
|
196
|
+
fontFamily: family,
|
|
197
|
+
fontWeight: leaf.fontWeight
|
|
198
|
+
},
|
|
199
|
+
children: children
|
|
200
|
+
})
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
if (leaf.decoration === "link") {
|
|
204
|
+
children = /*#__PURE__*/_jsx("a", {
|
|
205
|
+
style: {
|
|
206
|
+
cursor: "pointer"
|
|
207
|
+
},
|
|
208
|
+
rel: "noreferrer",
|
|
209
|
+
target: "_blank",
|
|
210
|
+
href: leaf.text,
|
|
211
|
+
children: children
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
return children;
|
|
215
|
+
};
|
|
216
|
+
export const getBlock = props => {
|
|
217
|
+
const {
|
|
218
|
+
element,
|
|
219
|
+
children
|
|
220
|
+
} = props;
|
|
221
|
+
const attributes = props.attributes ?? {};
|
|
222
|
+
const isEmpty = isEmptyTextNode(element);
|
|
223
|
+
switch (element.type) {
|
|
224
|
+
case "paragraph":
|
|
225
|
+
return /*#__PURE__*/_jsx("p", {
|
|
226
|
+
...attributes,
|
|
227
|
+
...element.attr,
|
|
228
|
+
className: `content-editable ${isEmpty ? "empty" : ""}`
|
|
229
|
+
// placeholder="paragraph"
|
|
230
|
+
,
|
|
231
|
+
children: children
|
|
232
|
+
});
|
|
233
|
+
case "headingOne":
|
|
234
|
+
return /*#__PURE__*/_jsx("h1", {
|
|
235
|
+
...attributes,
|
|
236
|
+
...element.attr,
|
|
237
|
+
className: `content-editable ${isEmpty ? "empty" : ""}`
|
|
238
|
+
// placeholder="Heading 1"
|
|
239
|
+
,
|
|
240
|
+
children: children
|
|
241
|
+
});
|
|
242
|
+
case "headingTwo":
|
|
243
|
+
return /*#__PURE__*/_jsx("h2", {
|
|
244
|
+
...attributes,
|
|
245
|
+
...element.attr,
|
|
246
|
+
className: `content-editable ${isEmpty ? "empty" : ""}`
|
|
247
|
+
// placeholder="Heading 2"
|
|
248
|
+
,
|
|
249
|
+
children: children
|
|
250
|
+
});
|
|
251
|
+
case "headingThree":
|
|
252
|
+
return /*#__PURE__*/_jsx("h3", {
|
|
253
|
+
...attributes,
|
|
254
|
+
...element.attr,
|
|
255
|
+
className: `content-editable ${isEmpty ? "empty" : ""}`
|
|
256
|
+
// placeholder="Heading 3"
|
|
257
|
+
,
|
|
258
|
+
children: children
|
|
259
|
+
});
|
|
260
|
+
case "blockquote":
|
|
261
|
+
return /*#__PURE__*/_jsx("blockquote", {
|
|
262
|
+
...attributes,
|
|
263
|
+
...element.attr,
|
|
264
|
+
style: {
|
|
265
|
+
// borderColor: element?.color || "transparent",
|
|
266
|
+
...getBorderColor(element?.color || "transparent", 3),
|
|
267
|
+
background: element?.bgColor || "none",
|
|
268
|
+
padding: `${element?.bgColor ? "16px" : "0px"} 8px`,
|
|
269
|
+
borderRadius: `${element?.color ? "0px" : "12px"} 12px 12px ${element?.color ? "0px" : "12px"}`,
|
|
270
|
+
margin: `${element?.bgColor ? "16px" : "0px"} 0px`,
|
|
271
|
+
width: element?.bgColor ? "calc(100% - 16px)" : "100%",
|
|
272
|
+
borderWidth: element?.color ? "0px 0px 0px 3px" : "0px"
|
|
273
|
+
},
|
|
274
|
+
children: children
|
|
275
|
+
});
|
|
276
|
+
case "alignLeft":
|
|
277
|
+
return /*#__PURE__*/_jsx("div", {
|
|
278
|
+
...attributes,
|
|
279
|
+
...element.attr,
|
|
280
|
+
children: children
|
|
281
|
+
});
|
|
282
|
+
case "alignCenter":
|
|
283
|
+
return /*#__PURE__*/_jsx("div", {
|
|
284
|
+
style: {
|
|
285
|
+
display: "flex",
|
|
286
|
+
alignItems: "center",
|
|
287
|
+
flexDirection: "column",
|
|
288
|
+
textAlign: "center"
|
|
289
|
+
},
|
|
290
|
+
...attributes,
|
|
291
|
+
...element.attr,
|
|
292
|
+
children: children
|
|
293
|
+
});
|
|
294
|
+
case "alignRight":
|
|
295
|
+
return /*#__PURE__*/_jsx("div", {
|
|
296
|
+
style: {
|
|
297
|
+
display: "flex",
|
|
298
|
+
alignItems: "flex-end",
|
|
299
|
+
flexDirection: "column",
|
|
300
|
+
textAlign: "right"
|
|
301
|
+
},
|
|
302
|
+
...attributes,
|
|
303
|
+
...element.attr,
|
|
304
|
+
children: children
|
|
305
|
+
});
|
|
306
|
+
case "list-item":
|
|
307
|
+
const firstChildren = element.children[0] || {};
|
|
308
|
+
return /*#__PURE__*/_jsx("li", {
|
|
309
|
+
...attributes,
|
|
310
|
+
...element.attr,
|
|
311
|
+
className: `content-editable ${isEmpty ? "empty" : ""}`,
|
|
312
|
+
placeholder: "List",
|
|
313
|
+
style: {
|
|
314
|
+
color: firstChildren?.color
|
|
315
|
+
},
|
|
316
|
+
children: children
|
|
317
|
+
});
|
|
318
|
+
case "orderedList":
|
|
319
|
+
return /*#__PURE__*/_jsx("ol", {
|
|
320
|
+
type: "1",
|
|
321
|
+
...attributes,
|
|
322
|
+
children: children
|
|
323
|
+
});
|
|
324
|
+
case "unorderedList":
|
|
325
|
+
return /*#__PURE__*/_jsx("ul", {
|
|
326
|
+
...attributes,
|
|
327
|
+
children: children
|
|
328
|
+
});
|
|
329
|
+
case "check-list-item":
|
|
330
|
+
return /*#__PURE__*/_jsx(CheckList, {
|
|
331
|
+
...props,
|
|
332
|
+
isEmpty: isEmpty
|
|
333
|
+
});
|
|
334
|
+
case "table":
|
|
335
|
+
return /*#__PURE__*/_jsx(Table, {
|
|
336
|
+
...props
|
|
337
|
+
});
|
|
338
|
+
case "table-head":
|
|
339
|
+
return /*#__PURE__*/_jsx("thead", {
|
|
340
|
+
children: children
|
|
341
|
+
});
|
|
342
|
+
case "table-body":
|
|
343
|
+
return /*#__PURE__*/_jsx("tbody", {
|
|
344
|
+
children: children
|
|
345
|
+
});
|
|
346
|
+
case "table-row":
|
|
347
|
+
return /*#__PURE__*/_jsx(TableRow, {
|
|
348
|
+
...props
|
|
349
|
+
});
|
|
350
|
+
case "table-cell":
|
|
351
|
+
return /*#__PURE__*/_jsx(TableCell, {
|
|
352
|
+
...props
|
|
353
|
+
});
|
|
354
|
+
case "mention":
|
|
355
|
+
return /*#__PURE__*/_jsx(Mentions, {
|
|
356
|
+
...props
|
|
357
|
+
});
|
|
358
|
+
default:
|
|
359
|
+
return;
|
|
360
|
+
}
|
|
361
|
+
};
|
|
@@ -1,22 +1,34 @@
|
|
|
1
1
|
import { renderToString } from "react-dom/server";
|
|
2
|
-
import { getBlock } from "./SlateUtilityFunctions";
|
|
2
|
+
import { getBlock } from "./chatEditor/SlateUtilityFunctions";
|
|
3
3
|
const serializeToHTML = nodes => {
|
|
4
4
|
try {
|
|
5
|
-
const htmlString = nodes.map(
|
|
6
|
-
|
|
5
|
+
const htmlString = nodes.map(node => {
|
|
6
|
+
// Render function for each node
|
|
7
|
+
const renderNode = node => {
|
|
7
8
|
const props = {
|
|
8
|
-
element:
|
|
9
|
-
children:
|
|
9
|
+
element: node,
|
|
10
|
+
children: node.children?.map(child => {
|
|
11
|
+
// Render each child node
|
|
12
|
+
if (child.text !== undefined) {
|
|
13
|
+
// For text nodes, return the text
|
|
14
|
+
return child.text;
|
|
15
|
+
}
|
|
16
|
+
// For other nodes, render them recursively
|
|
17
|
+
return renderNode(child);
|
|
18
|
+
}) || []
|
|
10
19
|
};
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
20
|
+
return getBlock(props);
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
// Render root node to HTML string
|
|
24
|
+
const reactElement = renderNode(node);
|
|
25
|
+
return renderToString(reactElement);
|
|
26
|
+
}).join(''); // Combine all HTML strings
|
|
27
|
+
|
|
28
|
+
return htmlString;
|
|
18
29
|
} catch (err) {
|
|
19
|
-
console.
|
|
30
|
+
console.error('Error serializing to HTML:', err);
|
|
31
|
+
return '';
|
|
20
32
|
}
|
|
21
33
|
};
|
|
22
34
|
export default serializeToHTML;
|
|
@@ -320,10 +320,14 @@ export class TableUtil {
|
|
|
320
320
|
const [tableNode] = Editor.nodes(this.editor, {
|
|
321
321
|
match: n => !Editor.isEditor(n) && Element.isElement(n) && n.type === "table"
|
|
322
322
|
});
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
323
|
+
|
|
324
|
+
// const [, tableCellPath] = Editor.nodes(this.editor, {
|
|
325
|
+
// at: selection,
|
|
326
|
+
// match: (n) =>
|
|
327
|
+
// !Editor.isEditor(n) &&
|
|
328
|
+
// Element.isElement(n) &&
|
|
329
|
+
// n.type === "table-cell",
|
|
330
|
+
// });
|
|
327
331
|
const {
|
|
328
332
|
anchor,
|
|
329
333
|
focus
|
package/dist/index.js
CHANGED
|
@@ -2,7 +2,11 @@ import Collaborative from "./Editor/CollaborativeEditor";
|
|
|
2
2
|
import CommonEditor from "./Editor/CommonEditor";
|
|
3
3
|
import Mini from "./Editor/MiniEditor";
|
|
4
4
|
import EditorInFrame from "./Editor/IframeEditor";
|
|
5
|
+
import Chat from "./Editor/ChatEditor";
|
|
6
|
+
import Emoji from "./Editor/Elements/Emoji/EmojiPicker";
|
|
5
7
|
export const Editor = CommonEditor;
|
|
6
8
|
export const MiniEditor = Mini;
|
|
7
9
|
export const CollaborativeEditor = Collaborative;
|
|
8
|
-
export const IframeEditor = EditorInFrame;
|
|
10
|
+
export const IframeEditor = EditorInFrame;
|
|
11
|
+
export const ChatEditor = Chat;
|
|
12
|
+
export const EmojiPicker = Emoji;
|