@flozy/editor 10.7.6 → 10.7.7

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.
@@ -1,12 +1,12 @@
1
1
  import React, { useState } from "react";
2
2
  import { Transforms } from "slate";
3
- import { useSelected, useSlateStatic, ReactEditor } from "slate-react";
3
+ import { useSlateStatic, ReactEditor } from "slate-react";
4
4
  import AccordionBtnPopup from "./AccordionBtnPopup";
5
5
  import { IconButton, Tooltip, Box } from "@mui/material";
6
6
  import DeleteIcon from "@mui/icons-material/Delete";
7
7
  import { GridSettingsIcon } from "../../common/iconslist";
8
8
  import Icon from "../../common/Icon";
9
- import { useEditorContext, useEditorSelection } from "../../hooks/useMouseMove";
9
+ import { useEditorContext } from "../../hooks/useMouseMove";
10
10
  import useCommonStyle from "../../commonStyle";
11
11
  import { getBorderColor, getTextColor } from "../../helper";
12
12
  import { getBreakPointsValue, getTRBLBreakPoints } from "../../helper/theme";
@@ -75,8 +75,6 @@ const Accordion = props => {
75
75
  const [toggle, setToggle] = useState(false);
76
76
  const [openSetttings, setOpenSettings] = useState(false);
77
77
  const editor = useSlateStatic();
78
- const [showTool] = useEditorSelection(editor);
79
- const selected = useSelected();
80
78
  const path = ReactEditor.findPath(editor, element);
81
79
  const {
82
80
  textColor,
@@ -120,7 +118,7 @@ const Accordion = props => {
120
118
  Transforms.deselect(editor);
121
119
  };
122
120
  const ToolBar = () => {
123
- return selected && !showTool ? /*#__PURE__*/_jsxs("div", {
121
+ return toggle ? /*#__PURE__*/_jsxs("div", {
124
122
  className: "element-toolbar hr",
125
123
  contentEditable: false,
126
124
  style: {
@@ -1,5 +1,5 @@
1
1
  import React from "react";
2
- import { insertAccordion } from "../../utils/accordion";
2
+ import { insertAccordion, toggleAccordion } from "../../utils/accordion";
3
3
  import ToolbarIcon from "../../common/ToolbarIcon";
4
4
  import Icon from "../../common/Icon";
5
5
  import { jsx as _jsx } from "react/jsx-runtime";
@@ -7,13 +7,22 @@ const AccordionButton = props => {
7
7
  const {
8
8
  editor,
9
9
  icoBtnType,
10
- customProps
10
+ customProps,
11
+ commonProps
11
12
  } = props;
12
13
  const {
13
14
  translation
14
15
  } = customProps;
16
+ const {
17
+ listType
18
+ } = commonProps || {};
19
+ const isAccordion = listType === "accordion-summary";
15
20
  const handleInsertAccordion = () => {
16
- insertAccordion(editor);
21
+ if (isAccordion) {
22
+ toggleAccordion(editor);
23
+ } else {
24
+ insertAccordion(editor);
25
+ }
17
26
  };
18
27
  return /*#__PURE__*/_jsx(ToolbarIcon, {
19
28
  icon: /*#__PURE__*/_jsx(Icon, {
@@ -18,10 +18,6 @@ const AttachmentsButton = props => {
18
18
  const {
19
19
  translation
20
20
  } = customProps;
21
- const [uploadStatus, setUploadStatus] = useState({
22
- isUploading: false,
23
- uploadPercentage: 0
24
- });
25
21
  const handleClick = () => {
26
22
  SetOpen(true);
27
23
  };
@@ -51,8 +47,7 @@ const AttachmentsButton = props => {
51
47
  onClose: handleClose,
52
48
  customProps: customProps,
53
49
  onSelectImage: onSelectImage,
54
- title: "Document",
55
- setUploadStatus: setUploadStatus
50
+ title: "Document"
56
51
  })]
57
52
  });
58
53
  };
@@ -15,10 +15,6 @@ export const TopBannerToolbar = props => {
15
15
  editor
16
16
  } = props;
17
17
  const [open, setOpen] = useState(false);
18
- const [uploadStatus, setUploadStatus] = useState({
19
- isUploading: false,
20
- uploadPercentage: 0
21
- });
22
18
  const handleClick = type => () => {
23
19
  switch (type) {
24
20
  case "change":
@@ -32,8 +28,9 @@ export const TopBannerToolbar = props => {
32
28
  }
33
29
  };
34
30
  const onSelectImage = img => {
31
+ const embedURL = typeof img === "string" ? img : img?.embedURL ? img?.embedURL : null;
35
32
  updateTopBanner(editor, {
36
- url: img
33
+ url: embedURL
37
34
  });
38
35
  handleClose();
39
36
  };
@@ -61,7 +58,7 @@ export const TopBannerToolbar = props => {
61
58
  onClose: handleClose,
62
59
  customProps: customProps,
63
60
  onSelectImage: onSelectImage,
64
- setUploadStatus: setUploadStatus
61
+ disableProgress: true
65
62
  })]
66
63
  });
67
64
  };
@@ -16,14 +16,11 @@ const TopBannerButton = props => {
16
16
  const {
17
17
  translation
18
18
  } = customProps;
19
- const [uploadStatus, setUploadStatus] = useState({
20
- isUploading: false,
21
- uploadPercentage: 0
22
- });
23
19
  const onSelectImage = url => {
24
- if (url) {
20
+ const embedURL = typeof url === "string" ? url : url?.embedURL ? url?.embedURL : null;
21
+ if (embedURL) {
25
22
  insertTopBanner(editor, {
26
- url: url?.embedURL
23
+ url: embedURL
27
24
  });
28
25
  }
29
26
  setOpen(false);
@@ -47,7 +44,6 @@ const TopBannerButton = props => {
47
44
  onClose: handleClose,
48
45
  customProps: customProps,
49
46
  onSelectImage: onSelectImage,
50
- setUploadStatus: setUploadStatus,
51
47
  disableProgress: true
52
48
  })]
53
49
  });
@@ -2,7 +2,7 @@ import { useMemo } from "react";
2
2
  import { isBlockActive, toggleBlock } from "../../../utils/SlateUtilityFunctions";
3
3
  import CustomSelectTool from "./CustomSelectTool";
4
4
  import Icon from "../../../common/Icon";
5
- import { insertAccordion } from "../../../utils/accordion";
5
+ import { insertAccordion, toggleAccordion } from "../../../utils/accordion";
6
6
  import { jsx as _jsx } from "react/jsx-runtime";
7
7
  import { jsxs as _jsxs } from "react/jsx-runtime";
8
8
  function Label({
@@ -99,7 +99,11 @@ function SelectList({
99
99
  if (option.type === "block") {
100
100
  toggleBlock(editor, format);
101
101
  } else if (option.type === "accordion") {
102
- insertAccordion(editor);
102
+ if (listType === "accordion-summary") {
103
+ toggleAccordion(editor);
104
+ } else {
105
+ insertAccordion(editor);
106
+ }
103
107
  }
104
108
  closeMainPopup();
105
109
  };
@@ -56,13 +56,7 @@ const TextFormat = props => {
56
56
  const fontStyle = allTools.filter(f => f.type === "mark" && f.format !== "strikethrough" && f.format !== "superscript" && f.format !== "subscript");
57
57
  const fontAlign = allTools.filter(f => f.format?.indexOf("align") >= 0);
58
58
  const link = allTools.find(f => f.format?.indexOf("link") >= 0);
59
- const lists = allTools.filter(f => {
60
- let listTool = f.group?.indexOf("list") >= 0;
61
- if (listTool) {
62
- const hide = f.hideFor?.includes(listType);
63
- return !hide;
64
- }
65
- });
59
+ const lists = allTools.filter(f => f.group?.includes("list") && !f.hideFor?.includes(listType));
66
60
  const {
67
61
  isActive: isBlockQuoteActive,
68
62
  props: bqProps
@@ -399,7 +393,8 @@ const TextFormat = props => {
399
393
  return /*#__PURE__*/_jsx(Comp, {
400
394
  editor: editor,
401
395
  ...m,
402
- customProps: customProps
396
+ customProps: customProps,
397
+ commonProps: commonProps
403
398
  }, `pptool_block_${i}_${m.id}`);
404
399
  })
405
400
  })]
@@ -100,6 +100,7 @@ const FontLoader = props => {
100
100
  });
101
101
  let families = Array.from(fontSet);
102
102
  families = correctFontArray(families.join(", "));
103
+ // eslint-disable-next-line no-useless-escape
103
104
  families = families?.map(font => font?.replace(/\"/g, ""));
104
105
  families = families?.map(font => font?.replace(", sans-serif", ""));
105
106
  families = families?.filter(font => googleFontList?.includes(font));
@@ -32,7 +32,7 @@ const ImageSelector = props => {
32
32
  open,
33
33
  onSelectImage,
34
34
  customProps,
35
- setUploadStatus,
35
+ setUploadStatus = () => {},
36
36
  disableProgress
37
37
  } = props;
38
38
  const {
@@ -3,6 +3,7 @@ import { Editor, Transforms } from "slate";
3
3
  import TextFormat from "../../../../Toolbar/PopupTool/TextFormat";
4
4
  import usePopupStyle from "../../../../Toolbar/PopupTool/PopupToolStyle";
5
5
  import { ReactEditor } from "slate-react";
6
+ import { getListType } from "../../../../utils/SlateUtilityFunctions";
6
7
  import { jsx as _jsx } from "react/jsx-runtime";
7
8
  const TextSettings = props => {
8
9
  const {
@@ -15,6 +16,10 @@ const TextSettings = props => {
15
16
  const item_path = path.split("|").map(m => parseInt(m));
16
17
  const element_path = [...item_path, 0];
17
18
  const classes = usePopupStyle(theme);
19
+ const listType = getListType(editor);
20
+ const commonProps = {
21
+ listType
22
+ };
18
23
  useEffect(() => {
19
24
  try {
20
25
  ReactEditor.focus(editor);
@@ -29,7 +34,8 @@ const TextSettings = props => {
29
34
  classes: classes,
30
35
  editor: editor,
31
36
  customProps: customProps,
32
- closeMainPopup: onClose
37
+ closeMainPopup: onClose,
38
+ commonProps: commonProps
33
39
  });
34
40
  };
35
41
  export default TextSettings;
@@ -28,10 +28,6 @@ const BackgroundImage = props => {
28
28
  } = useEditorContext();
29
29
  const classes = UploadStyles(theme);
30
30
  const disableProgress = title === "Page Settings" || elementProps?.type === "freegridBox" || elementProps?.type === "freegrid";
31
- const [uploadStatus, setUploadStatus] = useState({
32
- isUploading: false,
33
- uploadPercentage: 0
34
- });
35
31
  const onRemoveBG = () => {
36
32
  setBase64(null);
37
33
  onChange({
@@ -117,8 +113,7 @@ const BackgroundImage = props => {
117
113
  customProps: customProps,
118
114
  onSelectImage: onSelectImage,
119
115
  title: getTitle(),
120
- disableProgress: disableProgress,
121
- setUploadStatus: setUploadStatus
116
+ disableProgress: disableProgress
122
117
  })]
123
118
  });
124
119
  };
@@ -1,4 +1,6 @@
1
1
  import { Transforms, Path, Node } from "slate";
2
+ import { isListItem } from "../utils/helper";
3
+ import { customizeEnterEvent } from "../utils/events";
2
4
  const AvoidCopying = ["headingOne", "headingTwo", "headingThree", "headingFour", "headingFive", "headingSix", "paragraphOne", "paragraphTwo", "paragraphThree", "blockquote"];
3
5
  const BlockTypes = ["grid"];
4
6
  const withEmbeds = editor => {
@@ -53,6 +55,15 @@ const withEmbeds = editor => {
53
55
  };
54
56
  editor.insertBreak = (...args) => {
55
57
  try {
58
+ const ele = isListItem(editor);
59
+ if (ele && ele[0]) {
60
+ const {
61
+ breakNext
62
+ } = customizeEnterEvent(editor, ele);
63
+ if (breakNext) {
64
+ return;
65
+ }
66
+ }
56
67
  const parentPath = Path.parent(editor.selection.focus.path);
57
68
  const parentNode = Node.get(editor, parentPath);
58
69
  if (editor.isVoid(parentNode)) {
@@ -221,8 +221,9 @@ export const getListType = editor => {
221
221
  if (accordionSummary) {
222
222
  return "accordion-summary";
223
223
  }
224
+ const listItems = ["list-item", "check-list-item"];
224
225
  const [listItem] = Editor.nodes(editor, {
225
- match: n => !Editor.isEditor(n) && SlateElement.isElement(n) && n.type === "list-item"
226
+ match: n => !Editor.isEditor(n) && SlateElement.isElement(n) && listItems.includes(n.type)
226
227
  });
227
228
  if (listItem) {
228
229
  return "list-item";
@@ -1,7 +1,5 @@
1
1
  import { Editor, Element, Path, Transforms } from "slate";
2
- import insertNewLine from "./insertNewLine";
3
2
  import { ALLOWED_TEXT_NODES, getNode, getNodeText, getNodeWithType } from "./helper";
4
- import { isMobileWindow } from "../helper";
5
3
  import { removeAccordion } from "./events";
6
4
  import { ReactEditor } from "slate-react";
7
5
  const focusAccordion = (editor, upPath) => {
@@ -9,6 +7,7 @@ const focusAccordion = (editor, upPath) => {
9
7
  path: upPath,
10
8
  offset: 0
11
9
  });
10
+ ReactEditor.focus(editor);
12
11
  };
13
12
  const getAccordionNode = summaryNode => {
14
13
  return {
@@ -75,13 +74,7 @@ export const insertAccordion = (editor, path) => {
75
74
  accordionPath = lastNodePath;
76
75
  }
77
76
  const focusPath = [...accordionPath, 0, 0, 0];
78
- if (isMobileWindow()) {
79
- // timeout to resolve focus issue in mobile
80
- setTimeout(() => focusAccordion(editor, focusPath), 0);
81
- } else {
82
- focusAccordion(editor, focusPath);
83
- }
84
- insertNewLine(editor);
77
+ focusAccordion(editor, focusPath);
85
78
  } catch (err) {
86
79
  console.log(err);
87
80
  }
@@ -161,4 +154,11 @@ export const onDeleteBackwardAccordion = editor => {
161
154
  } catch (err) {
162
155
  console.log(err);
163
156
  }
157
+ };
158
+ export const toggleAccordion = editor => {
159
+ const parentAccordion = Editor.above(editor, {
160
+ match: node => Element.isElement(node) && node.type === "accordion"
161
+ });
162
+ const [, accordionPath] = parentAccordion;
163
+ removeAccordion(editor, accordionPath);
164
164
  };
@@ -197,9 +197,102 @@ export const removeAccordion = (editor, accordionPath) => {
197
197
  select: true
198
198
  });
199
199
  };
200
+ export const customizeEnterEvent = (editor, ele, e) => {
201
+ const {
202
+ type
203
+ } = ele[0];
204
+ const path = ele[1];
205
+ const text = Node.string(ele[0]);
206
+ let breakNext = false;
207
+ switch (type) {
208
+ case "list-item":
209
+ if (!text) {
210
+ e?.preventDefault();
211
+ escapeEvent({
212
+ editor
213
+ });
214
+ }
215
+ break;
216
+ case "check-list-item":
217
+ const selectionPath = editor?.selection?.anchor?.path;
218
+ const currEle = Node.parent(editor, selectionPath);
219
+ const currEleText = Node.string(currEle);
220
+ if (!currEleText) {
221
+ e?.preventDefault();
222
+ checkListEnterEvent(editor, type);
223
+ }
224
+ break;
225
+ case "accordion-summary":
226
+ e?.preventDefault();
227
+ breakNext = true;
228
+ if (!text) {
229
+ const accordionIndex = ele[1].slice(0, Math.max(ele[1].length - 1));
230
+ removeAccordion(editor, accordionIndex);
231
+ } else {
232
+ const nextPath = Path.next(Path.parent(ele[1]));
233
+ insertAccordion(editor, nextPath);
234
+ }
235
+ break;
236
+ case "headingOne":
237
+ case "headingTwo":
238
+ case "headingThree":
239
+ const {
240
+ selection
241
+ } = editor;
242
+ if (selection && Range.isCollapsed(selection)) {
243
+ const isAtEnd = Editor.isEnd(editor, selection.anchor, path);
244
+ const isAtStart = Editor.isStart(editor, selection.anchor, path);
245
+ if (isAtEnd) {
246
+ e?.preventDefault();
247
+ Transforms.insertNodes(editor, {
248
+ type: "paragraph",
249
+ children: [{
250
+ text: ""
251
+ }]
252
+ });
253
+ const newLocation = Editor.after(editor, selection);
254
+ if (newLocation) {
255
+ Transforms.select(editor, newLocation);
256
+ }
257
+ } else if (!isAtStart) {
258
+ e?.preventDefault();
259
+ Transforms.splitNodes(editor);
260
+ Transforms.setNodes(editor, {
261
+ type: "paragraph"
262
+ }, {
263
+ at: Editor.after(editor, selection)
264
+ });
265
+ const newLocation = Editor.after(editor, selection);
266
+ if (newLocation) {
267
+ Transforms.select(editor, newLocation);
268
+ }
269
+ } else if (isAtStart) {
270
+ e?.preventDefault();
271
+ Transforms.insertNodes(editor, {
272
+ type: "paragraph",
273
+ children: [{
274
+ text: ""
275
+ }]
276
+ }, {
277
+ at: Editor.before(editor, selection)
278
+ });
279
+ Transforms.select(editor, Editor.before(editor, selection));
280
+ const newLocation = Editor.before(editor, selection);
281
+ if (newLocation) {
282
+ Transforms.select(editor, newLocation);
283
+ }
284
+ }
285
+ return;
286
+ }
287
+ break;
288
+ default:
289
+ }
290
+ return {
291
+ breakNext
292
+ };
293
+ };
200
294
  export const enterEvent = (e, editor, isMobile) => {
201
295
  try {
202
- const ele = isListItem(editor);
203
296
  // on shift enter break line in same node
204
297
  if (e.shiftKey && !isMobile) {
205
298
  e.preventDefault();
@@ -211,94 +304,6 @@ export const enterEvent = (e, editor, isMobile) => {
211
304
  } else {
212
305
  Transforms.insertText(editor, "\n");
213
306
  }
214
- } else if (ele && ele[0]) {
215
- const {
216
- type
217
- } = ele[0];
218
- const path = ele[1];
219
- const text = Node.string(ele[0]);
220
- switch (type) {
221
- case "list-item":
222
- if (!text) {
223
- e.preventDefault();
224
- escapeEvent({
225
- editor
226
- });
227
- }
228
- break;
229
- case "check-list-item":
230
- const selectionPath = editor?.selection?.anchor?.path;
231
- const currEle = Node.parent(editor, selectionPath);
232
- const currEleText = Node.string(currEle);
233
- if (!currEleText) {
234
- e.preventDefault();
235
- checkListEnterEvent(editor, type);
236
- }
237
- break;
238
- case "accordion-summary":
239
- e.preventDefault();
240
- if (!text) {
241
- const accordionIndex = ele[1].slice(0, Math.max(ele[1].length - 1));
242
- removeAccordion(editor, accordionIndex);
243
- } else {
244
- const nextPath = Path.next(Path.parent(ele[1]));
245
- insertAccordion(editor, nextPath);
246
- }
247
- break;
248
- case "headingOne":
249
- case "headingTwo":
250
- case "headingThree":
251
- const {
252
- selection
253
- } = editor;
254
- if (selection && Range.isCollapsed(selection)) {
255
- const isAtEnd = Editor.isEnd(editor, selection.anchor, path);
256
- const isAtStart = Editor.isStart(editor, selection.anchor, path);
257
- if (isAtEnd) {
258
- e.preventDefault();
259
- Transforms.insertNodes(editor, {
260
- type: "paragraph",
261
- children: [{
262
- text: ""
263
- }]
264
- });
265
- const newLocation = Editor.after(editor, selection);
266
- if (newLocation) {
267
- Transforms.select(editor, newLocation);
268
- }
269
- } else if (!isAtStart) {
270
- e.preventDefault();
271
- Transforms.splitNodes(editor);
272
- Transforms.setNodes(editor, {
273
- type: "paragraph"
274
- }, {
275
- at: Editor.after(editor, selection)
276
- });
277
- const newLocation = Editor.after(editor, selection);
278
- if (newLocation) {
279
- Transforms.select(editor, newLocation);
280
- }
281
- } else if (isAtStart) {
282
- e.preventDefault();
283
- Transforms.insertNodes(editor, {
284
- type: "paragraph",
285
- children: [{
286
- text: ""
287
- }]
288
- }, {
289
- at: Editor.before(editor, selection)
290
- });
291
- Transforms.select(editor, Editor.before(editor, selection));
292
- const newLocation = Editor.before(editor, selection);
293
- if (newLocation) {
294
- Transforms.select(editor, newLocation);
295
- }
296
- }
297
- return;
298
- }
299
- break;
300
- default:
301
- }
302
307
  }
303
308
  // Handle blockquote splitting
304
309
  if (!e.shiftKey) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flozy/editor",
3
- "version": "10.7.6",
3
+ "version": "10.7.7",
4
4
  "description": "An Editor for flozy app brain",
5
5
  "files": [
6
6
  "dist"