@flozy/editor 5.8.8 → 5.9.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.
Files changed (34) hide show
  1. package/dist/Editor/CommonEditor.js +17 -13
  2. package/dist/Editor/Editor.css +29 -14
  3. package/dist/Editor/Elements/Button/EditorButton.js +2 -1
  4. package/dist/Editor/Elements/DataView/Layouts/DataTypes/Components/Select.js +8 -12
  5. package/dist/Editor/Elements/Grid/GridItem.js +1 -2
  6. package/dist/Editor/Elements/Link/Link.js +70 -43
  7. package/dist/Editor/Elements/SimpleText/index.js +7 -12
  8. package/dist/Editor/Elements/SimpleText/style.js +2 -2
  9. package/dist/Editor/Elements/Title/title.js +13 -1
  10. package/dist/Editor/Elements/Variables/Style.js +28 -2
  11. package/dist/Editor/Elements/Variables/VariableButton.js +17 -4
  12. package/dist/Editor/Toolbar/PopupTool/PopupToolStyle.js +5 -0
  13. package/dist/Editor/Toolbar/PopupTool/index.js +28 -31
  14. package/dist/Editor/common/FontLoader/FontList.js +3 -11
  15. package/dist/Editor/common/FontLoader/FontLoader.js +24 -7
  16. package/dist/Editor/common/RnD/ElementSettings/Settings/FormSettings.js +1 -0
  17. package/dist/Editor/common/RnD/SwitchViewport/SwitchViewport.js +8 -2
  18. package/dist/Editor/common/Section/index.js +60 -89
  19. package/dist/Editor/common/StyleBuilder/fieldTypes/backgroundImage.js +5 -0
  20. package/dist/Editor/common/StyleBuilder/fieldTypes/card.js +10 -2
  21. package/dist/Editor/common/Uploader.js +8 -0
  22. package/dist/Editor/common/iconslist.js +1 -2
  23. package/dist/Editor/commonStyle.js +55 -59
  24. package/dist/Editor/helper/deserialize/index.js +18 -5
  25. package/dist/Editor/helper/index.js +2 -2
  26. package/dist/Editor/helper/markdown.js +45 -0
  27. package/dist/Editor/hooks/useEditorScroll.js +1 -1
  28. package/dist/Editor/plugins/withHTML.js +8 -1
  29. package/dist/Editor/plugins/withLayout.js +1 -1
  30. package/dist/Editor/utils/SlateUtilityFunctions.js +36 -0
  31. package/dist/Editor/utils/button.js +4 -4
  32. package/dist/Editor/utils/draftToSlate.js +3 -2
  33. package/dist/Editor/utils/helper.js +20 -20
  34. package/package.json +3 -2
@@ -90,9 +90,18 @@ const ELEMENT_TAGS = {
90
90
  type: "image",
91
91
  url: el.getAttribute("src")
92
92
  }),
93
- LI: () => ({
94
- type: "list-item"
95
- }),
93
+ LI: el => {
94
+ const checkListItem = el.querySelector(".check-list-item");
95
+ if (checkListItem) {
96
+ return {
97
+ type: "check-list-item",
98
+ checked: checkListItem?.dataset?.checked === "true"
99
+ };
100
+ }
101
+ return {
102
+ type: "list-item"
103
+ };
104
+ },
96
105
  UL: () => ({
97
106
  type: "unorderedList"
98
107
  }),
@@ -109,7 +118,7 @@ const ELEMENT_TAGS = {
109
118
  "GOOGLE-SHEETS-HTML-ORIGIN": paragraphType,
110
119
  TABLE: (el, children = []) => {
111
120
  try {
112
- const bodyChild = children || [];
121
+ const bodyChild = (children || [])?.filter(f => f !== null);
113
122
  const firstRowChildren = bodyChild[0]?.children || [];
114
123
  return {
115
124
  type: "table",
@@ -129,7 +138,11 @@ const ELEMENT_TAGS = {
129
138
  }),
130
139
  TD: handleTableCell,
131
140
  COLGROUP: paragraphType,
132
- COL: paragraphType
141
+ COL: paragraphType,
142
+ HR: () => ({
143
+ type: "divider",
144
+ borderColor: "#CCC"
145
+ })
133
146
  };
134
147
 
135
148
  // COMPAT: `B` is omitted here because Google Docs uses `<b>` in weird ways.
@@ -337,14 +337,14 @@ export const isCarouselSelected = editor => {
337
337
  return false;
338
338
  }
339
339
  const [nodeEntry] = Editor.nodes(editor, {
340
- match: n => !Editor.isEditor(n) && Element.isElement(n) && n.type === 'carousel'
340
+ match: n => !Editor.isEditor(n) && Element.isElement(n) && n.type === "carousel"
341
341
  });
342
342
  if (!nodeEntry) {
343
343
  return false;
344
344
  }
345
345
  const [node] = nodeEntry;
346
346
  const carouselDom = ReactEditor.toDOMNode(editor, node);
347
- const isEdit = carouselDom.classList.contains('carousel_slider_edit');
347
+ const isEdit = carouselDom.classList.contains("carousel_slider_edit");
348
348
  return !isEdit;
349
349
  } catch (err) {
350
350
  console.log(err);
@@ -0,0 +1,45 @@
1
+ import MarkdownIt from "markdown-it";
2
+ const md = new MarkdownIt();
3
+ function markdownItCheckbox(md) {
4
+ md.core.ruler.push("checkbox_lists", function (state) {
5
+ const tokens = state.tokens;
6
+ for (let i = 0; i < tokens.length; i++) {
7
+ const token = tokens[i];
8
+ if (token.type === "inline" && token.content) {
9
+ const taskListRegex = /^\s*(-\s*)?\[\s*([xX\s]?)\s*\]\s+(.*)/;
10
+ const match = taskListRegex.exec(token.content);
11
+ if (match) {
12
+ token.attrJoin("class", "check-list-item");
13
+ const isChecked = match[2].toLowerCase() === "x"; // Check if checked
14
+ const content = match[3].trim(); // Extract text after checkbox
15
+
16
+ // Create new tokens for the task list item
17
+ const listItemOpenToken = new state.Token("html_inline", "", 0);
18
+ listItemOpenToken.content = `<li class="check-list-item" data-checked="${isChecked}">`;
19
+ const checkboxToken = new state.Token("html_inline", "", 0);
20
+ checkboxToken.content = `<span class='check-list-item' data-checked="${isChecked}" />`;
21
+ const textToken = new state.Token("text", "", 0);
22
+ textToken.content = content;
23
+ const listItemCloseToken = new state.Token("html_inline", "", 0);
24
+ listItemCloseToken.content = `</li>`;
25
+
26
+ // Replace the original token with the new tokens
27
+ tokens.splice(i, 1, checkboxToken, textToken);
28
+ }
29
+ }
30
+ }
31
+ });
32
+ }
33
+
34
+ // init plugin
35
+ md.use(markdownItCheckbox);
36
+ function convertMDToHTML(data) {
37
+ try {
38
+ const html = md.render(data);
39
+ return html;
40
+ } catch (err) {
41
+ console.log(err);
42
+ return data;
43
+ }
44
+ }
45
+ export default convertMDToHTML;
@@ -5,7 +5,7 @@ function useEditorScroll(editorWrapper = {
5
5
  useEffect(() => {
6
6
  const handleScroll = () => {
7
7
  if (editorWrapper.current) {
8
- callback();
8
+ callback("scroll");
9
9
  }
10
10
  };
11
11
  const currentEditorWrapper = editorWrapper.current;
@@ -1,6 +1,7 @@
1
1
  import { Transforms, Editor, Element, Node, Path } from "slate";
2
2
  import deserialize from "../helper/deserialize";
3
3
  import { decodeAndParseBase64 } from "../utils/helper";
4
+ import convertMDToHTML from "../helper/markdown";
4
5
  const avoidDefaultInsert = ["table", "grid"];
5
6
  const NON_TEXT_TAGS = ["ol", "ul", "img", "table", "video", "a", "button", "GOOGLE-SHEETS-HTML-ORIGIN"];
6
7
  const ALLOWED_TEXT_NODES = ["paragraph", "title", "headingOne", "headingTwo", "headingThree"];
@@ -274,9 +275,15 @@ const withHtml = editor => {
274
275
  Transforms.insertFragment(editor, formattedFragment);
275
276
  return;
276
277
  } else {
277
- insertData(data);
278
+ const html = convertMDToHTML(data.getData("text/plain"));
279
+ let parsed = new DOMParser().parseFromString(html, "text/html");
280
+ parsed = parseCopiedHTML(html);
281
+ const fragment = deserialize(parsed.body);
282
+ Transforms.insertFragment(editor, fragment);
283
+ // insertData(data);
278
284
  }
279
285
  };
286
+
280
287
  return editor;
281
288
  };
282
289
  export default withHtml;
@@ -39,7 +39,7 @@ const withLayout = editor => {
39
39
  const title = {
40
40
  type: "title",
41
41
  children: [{
42
- text: "Untitled"
42
+ text: ""
43
43
  }]
44
44
  };
45
45
  Transforms.insertNodes(editor, title, {
@@ -301,6 +301,30 @@ export const getBlock = props => {
301
301
  placeholder: "Heading 3",
302
302
  children: children
303
303
  });
304
+ case "headingFour":
305
+ return /*#__PURE__*/_jsx("h4", {
306
+ ...attributes,
307
+ ...element.attr,
308
+ className: `edt-headings content-editable ${isEmpty ? "empty" : ""}`,
309
+ placeholder: "Heading 4",
310
+ children: children
311
+ });
312
+ case "headingFive":
313
+ return /*#__PURE__*/_jsx("h5", {
314
+ ...attributes,
315
+ ...element.attr,
316
+ className: `edt-headings content-editable ${isEmpty ? "empty" : ""}`,
317
+ placeholder: "Heading 5",
318
+ children: children
319
+ });
320
+ case "headingSix":
321
+ return /*#__PURE__*/_jsx("h6", {
322
+ ...attributes,
323
+ ...element.attr,
324
+ className: `edt-headings content-editable ${isEmpty ? "empty" : ""}`,
325
+ placeholder: "Heading 6",
326
+ children: children
327
+ });
304
328
  case "blockquote":
305
329
  return /*#__PURE__*/_jsx("blockquote", {
306
330
  ...attributes,
@@ -588,7 +612,19 @@ export const getBlock = props => {
588
612
  return /*#__PURE__*/_jsx(ColumnView, {
589
613
  ...props
590
614
  });
615
+ case "code":
616
+ return /*#__PURE__*/_jsx("code", {
617
+ ...attributes,
618
+ ...element.attr,
619
+ className: "markcode",
620
+ children: children
621
+ });
591
622
  default:
623
+ // return (
624
+ // <span {...attributes} {...element.attr}>
625
+ // {children}
626
+ // </span>
627
+ // );
592
628
  return /*#__PURE__*/_jsx(SimpleText, {
593
629
  ...props,
594
630
  isEmpty: isEmpty
@@ -20,10 +20,10 @@ export const insertButton = editor => {
20
20
  bottomRight: 30
21
21
  },
22
22
  bannerSpacing: {
23
- left: 16,
24
- top: 8,
25
- right: 16,
26
- bottom: 8
23
+ left: 24,
24
+ top: 10,
25
+ right: 24,
26
+ bottom: 10
27
27
  },
28
28
  ...(windowVar.lastButtonProps || {})
29
29
  };
@@ -82,7 +82,8 @@ const splitInlineStyleRanges = (text, inlineStyleRanges, data) => {
82
82
  };
83
83
  export const draftToSlate = props => {
84
84
  const {
85
- data
85
+ data,
86
+ needLayout
86
87
  } = props;
87
88
  if (data?.blocks && data?.blocks?.length > 0) {
88
89
  const converted = data?.blocks?.reduce((a, b) => {
@@ -104,7 +105,7 @@ export const draftToSlate = props => {
104
105
  return data;
105
106
  } else {
106
107
  return [{
107
- type: "paragraph",
108
+ type: needLayout ? "title" : "paragraph",
108
109
  children: [{
109
110
  text: ""
110
111
  }]
@@ -625,6 +625,10 @@ export const isRestrictedNode = (event, editor) => {
625
625
  return isNodeRestricted;
626
626
  }
627
627
  };
628
+ export function capitalizeFirstLetter(str) {
629
+ if (!str) return str;
630
+ return str.charAt(0).toUpperCase() + str.slice(1);
631
+ }
628
632
  export const insertLineBreakAtEndOfPath = (editor, path) => {
629
633
  try {
630
634
  const [node, nodePath] = Editor.node(editor, path); // Get the node at the specified path
@@ -643,6 +647,13 @@ export const insertLineBreakAtEndOfPath = (editor, path) => {
643
647
  console.log(err);
644
648
  }
645
649
  };
650
+ export function isHavingSelection(editor) {
651
+ try {
652
+ return editor?.selection && !Range.isCollapsed(editor.selection);
653
+ } catch (err) {
654
+ console.log(err);
655
+ }
656
+ }
646
657
  const omitNodes = ["site-settings", "page-settings"];
647
658
  export function getInitialValue(value = [], readOnly) {
648
659
  if (readOnly === "readonly" && value?.length) {
@@ -673,20 +684,17 @@ export function getInitialValue(value = [], readOnly) {
673
684
  }
674
685
  return value;
675
686
  }
676
- export function capitalizeFirstLetter(str) {
677
- if (!str) return str;
678
- return str.charAt(0).toUpperCase() + str.slice(1);
679
- }
680
- export function isHavingSelection(editor) {
681
- try {
682
- return editor?.selection && !Range.isCollapsed(editor.selection);
683
- } catch (err) {
684
- console.log(err);
685
- }
686
- }
687
687
  export function getSelectedCls(defaultCls = "", selected, selectedClsName = "selected") {
688
688
  return `${defaultCls} ${selected ? selectedClsName : ""}`;
689
689
  }
690
+ export function handleNegativeInteger(val) {
691
+ return val < 0 ? 0 : val;
692
+ }
693
+ export const containsSurrogatePair = text => {
694
+ // Match surrogate pairs (high and low surrogate)
695
+ const surrogatePairRegex = /[\uD800-\uDBFF][\uDC00-\uDFFF]/;
696
+ return surrogatePairRegex.test(text);
697
+ };
690
698
  export const getNodeWithType = (editor, nodeType = "", otherOptions) => {
691
699
  try {
692
700
  const options = {
@@ -700,11 +708,6 @@ export const getNodeWithType = (editor, nodeType = "", otherOptions) => {
700
708
  return [];
701
709
  }
702
710
  };
703
- export const containsSurrogatePair = text => {
704
- // Match surrogate pairs (high and low surrogate)
705
- const surrogatePairRegex = /[\uD800-\uDBFF][\uDC00-\uDFFF]/;
706
- return surrogatePairRegex.test(text);
707
- };
708
711
  export const getSlateDom = (editor, range) => {
709
712
  try {
710
713
  const slateDom = ReactEditor.toDOMRange(editor, range);
@@ -753,7 +756,4 @@ export const viewSlateSelection = () => {
753
756
  export const hideSlateSelection = () => {
754
757
  const root = document.documentElement;
755
758
  root.style.setProperty("--slate-highlight-bg", "none");
756
- };
757
- export function handleNegativeInteger(val) {
758
- return val < 0 ? 0 : val;
759
- }
759
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flozy/editor",
3
- "version": "5.8.8",
3
+ "version": "5.9.0",
4
4
  "description": "An Editor for flozy app brain",
5
5
  "files": [
6
6
  "dist"
@@ -30,6 +30,7 @@
30
30
  "husky": "^8.0.3",
31
31
  "interweave": "^13.1.0",
32
32
  "lint-staged": "^13.2.3",
33
+ "markdown-it": "^14.1.0",
33
34
  "prettier": "^3.0.1",
34
35
  "react-best-gradient-color-picker": "^2.2.23",
35
36
  "react-datepicker": "^4.18.0",
@@ -68,7 +69,7 @@
68
69
  "storybook": "storybook dev -p 6006",
69
70
  "build-storybook": "NODE_OPTIONS='--max_old_space_size=4096' storybook build",
70
71
  "publish:npm": "rm -rf dist && mkdir dist && babel src/components -d dist --copy-files",
71
- "publish:local": "rm -rf /Users/agmac30/Documents/CODE_BASE/flozy/client/node_modules/@flozy/editor/dist && babel src/components -d /Users/agmac30/Documents/CODE_BASE/flozy/client/node_modules/@flozy/editor/dist --copy-files"
72
+ "publish:local": "rm -rf /Users/agmac03/flozy/client/node_modules/@flozy/editor/dist && babel src/components -d /Users/agmac03/flozy/client/node_modules/@flozy/editor/dist --copy-files"
72
73
  },
73
74
  "eslintConfig": {
74
75
  "extends": [