@flozy/editor 4.2.2 → 4.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 +5 -1
- package/dist/Editor/Elements/Embed/Image.js +9 -11
- package/dist/Editor/Elements/Embed/Video.js +73 -53
- package/dist/Editor/Elements/Form/Form.js +2 -0
- package/dist/Editor/Elements/FreeGrid/FreeGrid.js +5 -5
- package/dist/Editor/Elements/Table/TableRow.js +1 -1
- package/dist/Editor/common/Shorthands/mentions.js +1 -1
- package/dist/Editor/plugins/withHTML.js +26 -3
- package/dist/Editor/utils/chatEditor/SlateUtilityFunctions.js +0 -23
- package/dist/Editor/utils/events.js +37 -0
- package/package.json +1 -1
|
@@ -10,7 +10,7 @@ import { draftToSlate } from "./utils/draftToSlate";
|
|
|
10
10
|
import useMentions from "./hooks/useMentions";
|
|
11
11
|
import MentionsPopup from "./common/MentionsPopup";
|
|
12
12
|
import { RemoteCursorOverlay } from "./RemoteCursorOverlay/Overlay";
|
|
13
|
-
import { mentionsEvent, commands, indentation, escapeEvent, enterEvent } from "./utils/events";
|
|
13
|
+
import { mentionsEvent, commands, indentation, escapeEvent, enterEvent, upArrowEvent, downArrowEvent } from "./utils/events";
|
|
14
14
|
import withCommon from "./hooks/withCommon";
|
|
15
15
|
import DialogWrapper from "./DialogWrapper";
|
|
16
16
|
import { serializeToText } from "./utils/serializeToText";
|
|
@@ -379,6 +379,10 @@ const CommonEditor = /*#__PURE__*/forwardRef((props, ref) => {
|
|
|
379
379
|
});
|
|
380
380
|
}
|
|
381
381
|
}
|
|
382
|
+
} else if (event.key === "ArrowUp" && otherProps?.tagName !== "Pages") {
|
|
383
|
+
upArrowEvent(event, editor);
|
|
384
|
+
} else if (event.key === "ArrowDown" && otherProps?.tagName !== "Pages") {
|
|
385
|
+
downArrowEvent(event, editor);
|
|
382
386
|
}
|
|
383
387
|
}, [chars, editor, target, mentions, setMentions, search, type, mentionsRef]);
|
|
384
388
|
const Overlay = collaborativeEditor && !isReadOnly ? RemoteCursorOverlay : React.Fragment;
|
|
@@ -47,14 +47,7 @@ const ToolBar = ({
|
|
|
47
47
|
})]
|
|
48
48
|
}) : null;
|
|
49
49
|
};
|
|
50
|
-
const ImageContent =
|
|
51
|
-
readOnly,
|
|
52
|
-
setOpenSettings,
|
|
53
|
-
element,
|
|
54
|
-
handleImageClick,
|
|
55
|
-
onTouchEnd,
|
|
56
|
-
path
|
|
57
|
-
}) => {
|
|
50
|
+
const ImageContent = props => {
|
|
58
51
|
const {
|
|
59
52
|
alt,
|
|
60
53
|
url,
|
|
@@ -64,8 +57,13 @@ const ImageContent = ({
|
|
|
64
57
|
boxShadow,
|
|
65
58
|
frame = null,
|
|
66
59
|
objectFit,
|
|
67
|
-
webAddress
|
|
68
|
-
|
|
60
|
+
webAddress,
|
|
61
|
+
readOnly,
|
|
62
|
+
setOpenSettings,
|
|
63
|
+
handleImageClick,
|
|
64
|
+
onTouchEnd,
|
|
65
|
+
path
|
|
66
|
+
} = props;
|
|
69
67
|
const theme = useTheme();
|
|
70
68
|
return !url && !readOnly ? /*#__PURE__*/_jsxs(Box, {
|
|
71
69
|
component: "button",
|
|
@@ -278,9 +276,9 @@ const Image = ({
|
|
|
278
276
|
onSettings: onSettings,
|
|
279
277
|
setOpenNav: setOpenNav
|
|
280
278
|
}), /*#__PURE__*/_jsx(ImageContent, {
|
|
279
|
+
...element,
|
|
281
280
|
readOnly: readOnly,
|
|
282
281
|
setOpenSettings: setOpenSettings,
|
|
283
|
-
element: element,
|
|
284
282
|
handleImageClick: handleImageClick,
|
|
285
283
|
onTouchEnd: onTouchEnd,
|
|
286
284
|
path: path
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { useState, useEffect } from "react";
|
|
1
|
+
import React, { useState, useEffect, useCallback } from "react";
|
|
2
2
|
import { useSlateStatic, ReactEditor } from "slate-react";
|
|
3
3
|
import { Node, Transforms } from "slate";
|
|
4
4
|
import { IconButton, Tooltip, Box, useTheme } from "@mui/material";
|
|
@@ -13,6 +13,66 @@ import { getEmbedURL } from "../../helper";
|
|
|
13
13
|
import { getBreakPointsValue, getTRBLBreakPoints, groupByBreakpoint } from "../../helper/theme";
|
|
14
14
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
15
15
|
import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
16
|
+
const VideoContent = props => {
|
|
17
|
+
const {
|
|
18
|
+
resizing,
|
|
19
|
+
borderColor,
|
|
20
|
+
borderWidth,
|
|
21
|
+
borderStyle,
|
|
22
|
+
bgColor,
|
|
23
|
+
embedURL,
|
|
24
|
+
alt,
|
|
25
|
+
videoSX
|
|
26
|
+
} = props;
|
|
27
|
+
return resizing ? /*#__PURE__*/_jsx("div", {
|
|
28
|
+
style: {
|
|
29
|
+
width: "100%",
|
|
30
|
+
height: "100%",
|
|
31
|
+
border: "2px dashed black",
|
|
32
|
+
display: "flex",
|
|
33
|
+
justifyContent: "center",
|
|
34
|
+
alignItems: "center"
|
|
35
|
+
},
|
|
36
|
+
children: /*#__PURE__*/_jsx(Icon, {
|
|
37
|
+
icon: "videoPlayer"
|
|
38
|
+
})
|
|
39
|
+
}) : /*#__PURE__*/_jsx(Box, {
|
|
40
|
+
component: "iframe",
|
|
41
|
+
className: "embedd-iframe",
|
|
42
|
+
sx: {
|
|
43
|
+
border: "none",
|
|
44
|
+
position: "absolute",
|
|
45
|
+
width: "100%",
|
|
46
|
+
height: "100%",
|
|
47
|
+
maxWidth: "100%",
|
|
48
|
+
left: "0px",
|
|
49
|
+
...(gradientBorder(borderColor) || {}),
|
|
50
|
+
borderWidth: borderWidth || "1px",
|
|
51
|
+
borderStyle: borderStyle || "solid",
|
|
52
|
+
background: bgColor || "transparent",
|
|
53
|
+
...videoSX
|
|
54
|
+
},
|
|
55
|
+
src: embedURL,
|
|
56
|
+
title: alt
|
|
57
|
+
});
|
|
58
|
+
};
|
|
59
|
+
const VideoPlaceholder = props => {
|
|
60
|
+
const {
|
|
61
|
+
url,
|
|
62
|
+
readOnly,
|
|
63
|
+
onSettings
|
|
64
|
+
} = props;
|
|
65
|
+
return !url && !readOnly ? /*#__PURE__*/_jsxs(Box, {
|
|
66
|
+
component: "button",
|
|
67
|
+
className: "element-empty-btn",
|
|
68
|
+
onClick: onSettings,
|
|
69
|
+
children: [/*#__PURE__*/_jsx(Icon, {
|
|
70
|
+
icon: "video"
|
|
71
|
+
}), "Embed Video or Other"]
|
|
72
|
+
}) : /*#__PURE__*/_jsx(VideoContent, {
|
|
73
|
+
...props
|
|
74
|
+
});
|
|
75
|
+
};
|
|
16
76
|
const Video = ({
|
|
17
77
|
attributes,
|
|
18
78
|
element,
|
|
@@ -21,17 +81,12 @@ const Video = ({
|
|
|
21
81
|
}) => {
|
|
22
82
|
const theme = useTheme();
|
|
23
83
|
const {
|
|
24
|
-
alt,
|
|
25
84
|
alignment,
|
|
26
85
|
borderRadius,
|
|
27
|
-
borderWidth,
|
|
28
|
-
borderColor,
|
|
29
|
-
borderStyle,
|
|
30
86
|
url,
|
|
31
87
|
xsHidden,
|
|
32
88
|
width: oldWidth,
|
|
33
|
-
bannerSpacing
|
|
34
|
-
bgColor
|
|
89
|
+
bannerSpacing
|
|
35
90
|
} = element;
|
|
36
91
|
const editor = useSlateStatic();
|
|
37
92
|
const [openSetttings, setOpenSettings] = useState(false);
|
|
@@ -124,8 +179,8 @@ const Video = ({
|
|
|
124
179
|
const getWidth = () => {
|
|
125
180
|
if (resizing) {
|
|
126
181
|
return {
|
|
127
|
-
width: `${size.width}px
|
|
128
|
-
height: url ? `${size.height}px` : "auto"
|
|
182
|
+
width: size.width ? `${size.width}px` : "100%",
|
|
183
|
+
height: url ? `${size.height || 300}px` : "auto"
|
|
129
184
|
};
|
|
130
185
|
} else {
|
|
131
186
|
return {
|
|
@@ -149,49 +204,6 @@ const Video = ({
|
|
|
149
204
|
...getTRBLBreakPoints(bannerSpacing)
|
|
150
205
|
}
|
|
151
206
|
}, theme);
|
|
152
|
-
const VideoContent = () => {
|
|
153
|
-
return resizing ? /*#__PURE__*/_jsx("div", {
|
|
154
|
-
style: {
|
|
155
|
-
width: "100%",
|
|
156
|
-
height: "100%",
|
|
157
|
-
border: "2px dashed black",
|
|
158
|
-
display: "flex",
|
|
159
|
-
justifyContent: "center",
|
|
160
|
-
alignItems: "center"
|
|
161
|
-
},
|
|
162
|
-
children: /*#__PURE__*/_jsx(Icon, {
|
|
163
|
-
icon: "videoPlayer"
|
|
164
|
-
})
|
|
165
|
-
}) : /*#__PURE__*/_jsx(Box, {
|
|
166
|
-
component: "iframe",
|
|
167
|
-
className: "embedd-iframe",
|
|
168
|
-
sx: {
|
|
169
|
-
border: "none",
|
|
170
|
-
position: "absolute",
|
|
171
|
-
width: "100%",
|
|
172
|
-
height: "100%",
|
|
173
|
-
maxWidth: "100%",
|
|
174
|
-
left: "0px",
|
|
175
|
-
...(gradientBorder(borderColor) || {}),
|
|
176
|
-
borderWidth: borderWidth || "1px",
|
|
177
|
-
borderStyle: borderStyle || "solid",
|
|
178
|
-
background: bgColor || "transparent",
|
|
179
|
-
...videoSX
|
|
180
|
-
},
|
|
181
|
-
src: embedURL,
|
|
182
|
-
title: alt
|
|
183
|
-
});
|
|
184
|
-
};
|
|
185
|
-
const VideoPlaceholder = () => {
|
|
186
|
-
return !url && !readOnly ? /*#__PURE__*/_jsxs(Box, {
|
|
187
|
-
component: "button",
|
|
188
|
-
className: "element-empty-btn",
|
|
189
|
-
onClick: onSettings,
|
|
190
|
-
children: [/*#__PURE__*/_jsx(Icon, {
|
|
191
|
-
icon: "video"
|
|
192
|
-
}), "Embed Video or Other"]
|
|
193
|
-
}) : /*#__PURE__*/_jsx(VideoContent, {});
|
|
194
|
-
};
|
|
195
207
|
return /*#__PURE__*/_jsxs(Box, {
|
|
196
208
|
...attributes,
|
|
197
209
|
className: "embed has-hover video dpath",
|
|
@@ -224,7 +236,15 @@ const Video = ({
|
|
|
224
236
|
...getWidth(),
|
|
225
237
|
maxWidth: "100%"
|
|
226
238
|
},
|
|
227
|
-
children: [!readOnly && url && /*#__PURE__*/_jsx(ToolBar, {}), /*#__PURE__*/_jsx(VideoPlaceholder, {
|
|
239
|
+
children: [!readOnly && url && /*#__PURE__*/_jsx(ToolBar, {}), /*#__PURE__*/_jsx(VideoPlaceholder, {
|
|
240
|
+
...element,
|
|
241
|
+
embedURL: embedURL,
|
|
242
|
+
onSettings: onSettings,
|
|
243
|
+
videoSX: videoSX,
|
|
244
|
+
url: url,
|
|
245
|
+
readOnly: readOnly,
|
|
246
|
+
resizing: resizing
|
|
247
|
+
}), !readOnly && url ? /*#__PURE__*/_jsx(IconButton, {
|
|
228
248
|
onPointerDown: onMouseDown,
|
|
229
249
|
style: {
|
|
230
250
|
background: "#FFF"
|
|
@@ -401,6 +401,7 @@ const Form = props => {
|
|
|
401
401
|
component: "button",
|
|
402
402
|
onClick: onSubmitClick,
|
|
403
403
|
disabled: loading,
|
|
404
|
+
contentEditable: false,
|
|
404
405
|
sx: {
|
|
405
406
|
background: buttonProps?.bgColor || "rgb(30, 75, 122)",
|
|
406
407
|
borderWidth: "1px",
|
|
@@ -495,6 +496,7 @@ const Form = props => {
|
|
|
495
496
|
open: anchorEl !== null,
|
|
496
497
|
anchorEl: anchorEl,
|
|
497
498
|
onClose: handleClose,
|
|
499
|
+
contentEditable: false,
|
|
498
500
|
children: [/*#__PURE__*/_jsx(MenuItem, {
|
|
499
501
|
onClick: onMenuClick("edit"),
|
|
500
502
|
children: /*#__PURE__*/_jsx(Tooltip, {
|
|
@@ -465,15 +465,15 @@ const FreeGrid = props => {
|
|
|
465
465
|
className: "freegrid-container freegrid-container-parent",
|
|
466
466
|
sx: {
|
|
467
467
|
...classes.root,
|
|
468
|
-
...freegridSX
|
|
468
|
+
...freegridSX,
|
|
469
|
+
background: sectionBgColor,
|
|
470
|
+
backgroundImage: sectionBackgroundImage ? `url('${sectionBackgroundImage}')` : "",
|
|
471
|
+
backgroundSize: "cover"
|
|
469
472
|
},
|
|
470
473
|
"data-path": path.join("|"),
|
|
471
474
|
style: {
|
|
472
475
|
"--cols": `100%`,
|
|
473
|
-
"--rows": `repeat(${repeatTimes}, ${ROW_HEIGHT}px)
|
|
474
|
-
background: sectionBgColor,
|
|
475
|
-
backgroundImage: sectionBackgroundImage ? `url('${sectionBackgroundImage}')` : "",
|
|
476
|
-
backgroundSize: "cover"
|
|
476
|
+
"--rows": `repeat(${repeatTimes}, ${ROW_HEIGHT}px)`
|
|
477
477
|
},
|
|
478
478
|
children: [children, !readOnly ? /*#__PURE__*/_jsx("span", {
|
|
479
479
|
placeholder: `Section (${sectionName || "Welcome"})`,
|
|
@@ -3,6 +3,6 @@ const mentions = props => {
|
|
|
3
3
|
CHARACTERS,
|
|
4
4
|
search
|
|
5
5
|
} = props;
|
|
6
|
-
return CHARACTERS.filter(c => c
|
|
6
|
+
return CHARACTERS.filter(c => c?.name?.toLowerCase()?.startsWith(search?.toLowerCase())).slice(0, 10);
|
|
7
7
|
};
|
|
8
8
|
export default mentions;
|
|
@@ -101,9 +101,6 @@ const withHtml = editor => {
|
|
|
101
101
|
return element.type === "image" ? true : isVoid(element);
|
|
102
102
|
};
|
|
103
103
|
editor.insertData = data => {
|
|
104
|
-
if (editor.isChatEditor) {
|
|
105
|
-
return;
|
|
106
|
-
}
|
|
107
104
|
const slateHTML = data?.getData("application/x-slate-fragment");
|
|
108
105
|
const html = data?.getData("text/html");
|
|
109
106
|
const currentEl = getCurrentElement(editor);
|
|
@@ -117,6 +114,23 @@ const withHtml = editor => {
|
|
|
117
114
|
const defaultInsert = loopChildren(decoded, true);
|
|
118
115
|
if (defaultInsert) {
|
|
119
116
|
insertData(data);
|
|
117
|
+
// } else if (editor.isChatEditor) {
|
|
118
|
+
// // Only convert table to paragraphs if in chat editor mode
|
|
119
|
+
// const paragraphs = decoded.map(row =>
|
|
120
|
+
// row.children.map(cell =>
|
|
121
|
+
// cell.children.map(paragraph =>
|
|
122
|
+
// paragraph.children.map(textNode => textNode.text).join('')
|
|
123
|
+
// ).join(' ')
|
|
124
|
+
// ).join(' ')
|
|
125
|
+
// ).join('\n'); // Joining with a newline for separate paragraphs
|
|
126
|
+
|
|
127
|
+
// // Insert text as paragraphs
|
|
128
|
+
// const textNodes = paragraphs.split('\n').map(text => ({
|
|
129
|
+
// type: 'paragraph',
|
|
130
|
+
// children: [{ text }]
|
|
131
|
+
// }));
|
|
132
|
+
|
|
133
|
+
// Transforms.insertNodes(editor, textNodes);
|
|
120
134
|
} else {
|
|
121
135
|
// do not paste table, grid inside table cell
|
|
122
136
|
// only plain text for internal paste
|
|
@@ -141,6 +155,15 @@ const withHtml = editor => {
|
|
|
141
155
|
}
|
|
142
156
|
const fragment = deserialize(parsed.body);
|
|
143
157
|
const formattedFragment = formatFragment[eltype] ? formatFragment[eltype](fragment) : fragment;
|
|
158
|
+
let is_img_table = false;
|
|
159
|
+
formattedFragment.map(f => {
|
|
160
|
+
if (f.type === 'image' || f.type === 'table') {
|
|
161
|
+
is_img_table = true;
|
|
162
|
+
}
|
|
163
|
+
});
|
|
164
|
+
if (editor.isChatEditor && is_img_table) {
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
144
167
|
handleInsert(editor, () => Transforms.insertFragment(editor, formattedFragment), formattedFragment);
|
|
145
168
|
return;
|
|
146
169
|
} else {
|
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
import { Editor, Transforms, Element as SlateElement } from "slate";
|
|
2
2
|
import { Box } from "@mui/material";
|
|
3
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
4
|
import Mentions from "../../Elements/Mentions/Mentions";
|
|
8
5
|
import CheckList from "../../Elements/List/CheckList";
|
|
9
6
|
import { isEmptyTextNode } from "../../helper";
|
|
@@ -340,26 +337,6 @@ export const getBlock = props => {
|
|
|
340
337
|
...props,
|
|
341
338
|
isEmpty: isEmpty
|
|
342
339
|
});
|
|
343
|
-
case "table":
|
|
344
|
-
return /*#__PURE__*/_jsx(Table, {
|
|
345
|
-
...props
|
|
346
|
-
});
|
|
347
|
-
case "table-head":
|
|
348
|
-
return /*#__PURE__*/_jsx("thead", {
|
|
349
|
-
children: children
|
|
350
|
-
});
|
|
351
|
-
case "table-body":
|
|
352
|
-
return /*#__PURE__*/_jsx("tbody", {
|
|
353
|
-
children: children
|
|
354
|
-
});
|
|
355
|
-
case "table-row":
|
|
356
|
-
return /*#__PURE__*/_jsx(TableRow, {
|
|
357
|
-
...props
|
|
358
|
-
});
|
|
359
|
-
case "table-cell":
|
|
360
|
-
return /*#__PURE__*/_jsx(TableCell, {
|
|
361
|
-
...props
|
|
362
|
-
});
|
|
363
340
|
case "mention":
|
|
364
341
|
return /*#__PURE__*/_jsx(Mentions, {
|
|
365
342
|
...props
|
|
@@ -5,6 +5,7 @@ import { insertAccordion } from "./accordion";
|
|
|
5
5
|
import { isListItem } from "./helper";
|
|
6
6
|
import RnDCtrlCmds from "./RnD/RnDCtrlCmds";
|
|
7
7
|
import EDITORCMDS from "../common/EditorCmds";
|
|
8
|
+
import { ReactEditor } from "slate-react";
|
|
8
9
|
const HOTKEYS = {
|
|
9
10
|
b: "bold",
|
|
10
11
|
i: "italic",
|
|
@@ -284,4 +285,40 @@ export const enterEvent = (e, editor, isMobile) => {
|
|
|
284
285
|
} catch (err) {
|
|
285
286
|
console.log(err);
|
|
286
287
|
}
|
|
288
|
+
};
|
|
289
|
+
export const upArrowEvent = (e, editor) => {
|
|
290
|
+
try {
|
|
291
|
+
const {
|
|
292
|
+
selection
|
|
293
|
+
} = editor;
|
|
294
|
+
if (!selection) return;
|
|
295
|
+
const prevNodePath = Editor.before(editor, selection, {
|
|
296
|
+
unit: "line"
|
|
297
|
+
});
|
|
298
|
+
if (prevNodePath) {
|
|
299
|
+
e.preventDefault();
|
|
300
|
+
Transforms.select(editor, prevNodePath);
|
|
301
|
+
ReactEditor.focus(editor);
|
|
302
|
+
}
|
|
303
|
+
} catch (err) {
|
|
304
|
+
console.log(err);
|
|
305
|
+
}
|
|
306
|
+
};
|
|
307
|
+
export const downArrowEvent = (e, editor) => {
|
|
308
|
+
try {
|
|
309
|
+
const {
|
|
310
|
+
selection
|
|
311
|
+
} = editor;
|
|
312
|
+
if (!selection) return;
|
|
313
|
+
const nextNodePath = Editor.after(editor, selection, {
|
|
314
|
+
unit: "line"
|
|
315
|
+
});
|
|
316
|
+
if (nextNodePath) {
|
|
317
|
+
e.preventDefault();
|
|
318
|
+
Transforms.select(editor, nextNodePath);
|
|
319
|
+
ReactEditor.focus(editor);
|
|
320
|
+
}
|
|
321
|
+
} catch (err) {
|
|
322
|
+
console.log(err);
|
|
323
|
+
}
|
|
287
324
|
};
|