@flozy/editor 2.0.6 → 2.0.8

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,6 +1,6 @@
1
1
  /* eslint-disable no-unused-vars */
2
2
  import React, { useRef, useCallback, useEffect, useMemo, useState, forwardRef, useImperativeHandle } from "react";
3
- import { createEditor, Editor, Transforms } from "slate";
3
+ import { createEditor, Transforms } from "slate";
4
4
  import { Slate, Editable, ReactEditor } from "slate-react";
5
5
  import { useDebounce } from "use-debounce";
6
6
  import { getMarked, getBlock } from "./utils/SlateUtilityFunctions";
@@ -1102,3 +1102,10 @@ blockquote {
1102
1102
  0 0 #e3aad6;
1103
1103
  }
1104
1104
  }
1105
+
1106
+ .doublequote::before {
1107
+ content: '\201C';
1108
+ }
1109
+ .doublequote::after {
1110
+ content: '\201D';
1111
+ }
@@ -323,7 +323,7 @@ const Grid = props => {
323
323
  flexWrap: {
324
324
  ...getBreakPointsValue(flexWrap || "wrap")
325
325
  },
326
- height: "fit-content"
326
+ height: "auto"
327
327
  },
328
328
  "data-path": path.join(","),
329
329
  children: children
@@ -51,7 +51,6 @@ const GridItem = props => {
51
51
  const selected = hoverPath === path.join(",");
52
52
  const [showTool] = useEditorSelection(editor);
53
53
  const isEmpty = !readOnly && isEmptyNode(editor, element?.children, path) ? "empty" : "";
54
- console.log(cellGHeight);
55
54
  const GridItemToolbar = () => {
56
55
  return selected && !showTool ? /*#__PURE__*/_jsx("div", {
57
56
  contentEditable: false,
@@ -1,19 +1,27 @@
1
1
  import React from "react";
2
2
  import Icon from "../../common/Icon";
3
3
  import Button from "../../common/Button";
4
- import { toggleBlock, isBlockActive } from "../../utils/SlateUtilityFunctions.js";
4
+ import { toggleBlock, isBlockActive, isMarkActive, toggleMark } from "../../utils/SlateUtilityFunctions.js";
5
5
  import { jsx as _jsx } from "react/jsx-runtime";
6
- const BlockButton = ({
7
- editor,
8
- format,
9
- title
10
- }) => {
6
+ const MARK_TYPES = ["doublequote"];
7
+ const BlockButton = props => {
8
+ const {
9
+ editor,
10
+ format,
11
+ title
12
+ } = props;
13
+ const isMark = MARK_TYPES?.indexOf(format) >= 0;
14
+ const isActive = isMark ? isMarkActive(editor, format) : isBlockActive(editor, format);
11
15
  return /*#__PURE__*/_jsx(Button, {
12
- active: isBlockActive(editor, format),
16
+ active: isActive,
13
17
  format: format,
14
18
  onMouseDown: e => {
15
19
  e.preventDefault();
16
- toggleBlock(editor, format);
20
+ if (isMark) {
21
+ toggleMark(editor, format);
22
+ } else {
23
+ toggleBlock(editor, format);
24
+ }
17
25
  },
18
26
  title: title,
19
27
  children: /*#__PURE__*/_jsx(Icon, {
@@ -8,6 +8,7 @@ import useDrag from "../../hooks/useDrag";
8
8
  import PopperHeader from "./PopperHeader";
9
9
  import { TableUtil } from "../../utils/table";
10
10
  import useWindowResize from "../../hooks/useWindowResize";
11
+ import useEvent from "../../hooks/useKeys";
11
12
  import { jsx as _jsx } from "react/jsx-runtime";
12
13
  import { jsxs as _jsxs } from "react/jsx-runtime";
13
14
  const PopupTool = props => {
@@ -26,6 +27,7 @@ const PopupTool = props => {
26
27
  const id = open ? "popup-edit-tool" : "";
27
28
  const table = new TableUtil(editor);
28
29
  const [size] = useWindowResize();
30
+ const [eventKey] = useEvent();
29
31
  useEffect(() => {
30
32
  if (event === "end" && anchorEl && !open) {
31
33
  // for table cell selection
@@ -37,6 +39,11 @@ const PopupTool = props => {
37
39
  setOpen(false);
38
40
  }
39
41
  }, [event, anchorEl]);
42
+ useEffect(() => {
43
+ if (eventKey) {
44
+ setOpen(false);
45
+ }
46
+ }, [eventKey]);
40
47
  useEffect(() => {
41
48
  if (!selection || !inFocus || Range.isCollapsed(selection) || Editor.string(editor, selection) === "") {
42
49
  setAnchorEl(null);
@@ -103,9 +103,9 @@ export const toolbarGroups = [[{
103
103
  group: "typography"
104
104
  }, {
105
105
  id: 14,
106
- format: "blockquote",
106
+ format: "doublequote",
107
107
  type: "block",
108
- title: "Block Quote",
108
+ title: "Double Quote",
109
109
  group: "typography"
110
110
  }], [{
111
111
  id: 15,
@@ -8,8 +8,8 @@ import { SiLatex } from "react-icons/si";
8
8
  import { RiDeleteColumn, RiDeleteRow } from "react-icons/ri";
9
9
  import { IoIosImage } from "react-icons/io";
10
10
  import { GridIcon, AccordionIcon, SignatureIcon, ButtonIcon, Carousal, FormIcon, BoldIcon, FontFamilyIcon, FontSizeIcon, ImageIcon, ItalicIcon, LinkIcon, StrikethroughIcon, TableIcon, UnderLineIcon, VideoIcon, CheckboxIcon, AppHeader, MoreHorizontal, UploadImage, DocsUpload, LeftArrow, RightArrow, CheckListButton, CheckListButtonActive, ExcelIcon, CsvIcon, DividerIcon } from "./iconslist";
11
- import ArrowRightIcon from '@mui/icons-material/ArrowRight';
12
- import ArrowDropDownIcon from '@mui/icons-material/ArrowDropDown';
11
+ import ArrowRightIcon from "@mui/icons-material/ArrowRight";
12
+ import ArrowDropDownIcon from "@mui/icons-material/ArrowDropDown";
13
13
  import { jsx as _jsx } from "react/jsx-runtime";
14
14
  import { jsxs as _jsxs } from "react/jsx-runtime";
15
15
  const iconList = {
@@ -51,6 +51,10 @@ const iconList = {
51
51
  size: 20,
52
52
  fill: "#64748B"
53
53
  }),
54
+ doublequote: /*#__PURE__*/_jsx(MdFormatQuote, {
55
+ size: 20,
56
+ fill: "#64748B"
57
+ }),
54
58
  superscript: /*#__PURE__*/_jsx(FaSuperscript, {
55
59
  size: 15,
56
60
  fill: "#64748B"
@@ -69,8 +69,9 @@ const ImageSelector = props => {
69
69
  children: /*#__PURE__*/_jsxs(Tabs, {
70
70
  sx: classes.tabs,
71
71
  onChange: handleTabChange,
72
- orientation: "horizontal",
73
72
  value: tabValue,
73
+ variant: "scrollable",
74
+ scrollButtons: "auto",
74
75
  children: [/*#__PURE__*/_jsx(Tab, {
75
76
  className: `${isActive("upload")} ${TAB_SHOW[title].indexOf("upload") === -1 ? "hidden" : ""}`,
76
77
  sx: classes.tab,
@@ -0,0 +1,107 @@
1
+ import { jsx } from "slate-hyperscript";
2
+ const ELEMENT_TAGS = {
3
+ A: el => ({
4
+ type: "link",
5
+ url: el.getAttribute("href")
6
+ }),
7
+ BLOCKQUOTE: () => ({
8
+ type: "quote"
9
+ }),
10
+ H1: () => ({
11
+ type: "headingOne"
12
+ }),
13
+ H2: () => ({
14
+ type: "headingTwo"
15
+ }),
16
+ H3: () => ({
17
+ type: "headingThree"
18
+ }),
19
+ H4: () => ({
20
+ type: "headingFour"
21
+ }),
22
+ H5: () => ({
23
+ type: "headingFive"
24
+ }),
25
+ H6: () => ({
26
+ type: "headingSix"
27
+ }),
28
+ IMG: el => ({
29
+ type: "image",
30
+ url: el.getAttribute("src")
31
+ }),
32
+ LI: () => ({
33
+ type: "list-item"
34
+ }),
35
+ UL: () => ({
36
+ type: "unorderedList"
37
+ }),
38
+ OL: () => ({
39
+ type: "orderedList"
40
+ }),
41
+ P: () => ({
42
+ type: "paragraph"
43
+ }),
44
+ PRE: () => ({
45
+ type: "code"
46
+ })
47
+ };
48
+
49
+ // COMPAT: `B` is omitted here because Google Docs uses `<b>` in weird ways.
50
+ const TEXT_TAGS = {
51
+ CODE: () => ({
52
+ code: true
53
+ }),
54
+ DEL: () => ({
55
+ strikethrough: true
56
+ }),
57
+ EM: () => ({
58
+ italic: true
59
+ }),
60
+ I: () => ({
61
+ italic: true
62
+ }),
63
+ S: () => ({
64
+ strikethrough: true
65
+ }),
66
+ STRONG: () => ({
67
+ bold: true
68
+ }),
69
+ U: () => ({
70
+ underline: true
71
+ })
72
+ };
73
+ const deserialize = el => {
74
+ if (el.nodeType === 3) {
75
+ return el.textContent;
76
+ } else if (el.nodeType !== 1) {
77
+ return null;
78
+ } else if (el.nodeName === "BR") {
79
+ return "\n";
80
+ }
81
+ const {
82
+ nodeName
83
+ } = el;
84
+ let parent = el;
85
+ if (nodeName === "PRE" && el.childNodes[0] && el.childNodes[0].nodeName === "CODE") {
86
+ parent = el.childNodes[0];
87
+ }
88
+ let children = Array.from(parent.childNodes).map(deserialize).flat();
89
+ if (children.length === 0) {
90
+ children = [{
91
+ text: ""
92
+ }];
93
+ }
94
+ if (el.nodeName === "BODY") {
95
+ return jsx("fragment", {}, children);
96
+ }
97
+ if (ELEMENT_TAGS[nodeName]) {
98
+ const attrs = ELEMENT_TAGS[nodeName](el);
99
+ return jsx("element", attrs, children);
100
+ }
101
+ if (TEXT_TAGS[nodeName]) {
102
+ const attrs = TEXT_TAGS[nodeName](el);
103
+ return children.map(child => jsx("text", attrs, child));
104
+ }
105
+ return children;
106
+ };
107
+ export default deserialize;
@@ -0,0 +1,21 @@
1
+ import { useEffect, useState } from "react";
2
+ const useEvent = () => {
3
+ const [event, setEvent] = useState("");
4
+ useEffect(() => {
5
+ addListener();
6
+ return () => {
7
+ removeListener();
8
+ };
9
+ }, []);
10
+ const onKeyUp = e => {
11
+ setEvent(e.keyCode);
12
+ };
13
+ const addListener = () => {
14
+ document.addEventListener("keyup", onKeyUp);
15
+ };
16
+ const removeListener = () => {
17
+ document.removeEventListener("keyup", onKeyUp);
18
+ };
19
+ return [event];
20
+ };
21
+ export default useEvent;
@@ -6,9 +6,8 @@ import withEmbeds from "../plugins/withEmbeds";
6
6
  import withEquation from "../plugins/withEquation";
7
7
  import withMentions from "../plugins/withMentions";
8
8
  import withLayout from "../plugins/withLayout";
9
- // import { withLinkify } from '@mercuriya/slate-linkify';
10
-
9
+ import withHtml from "../plugins/withHTML";
11
10
  const withCommon = (props, rest = {}) => {
12
- return rest.needLayout ? withEquation(withLayout(withHistory(withEmbeds(withTables(withLinks(withMentions(withReact(props)))))))) : withEquation(withHistory(withEmbeds(withTables(withLinks(withMentions(withReact(props)))))));
11
+ return rest.needLayout ? withHtml(withEquation(withLayout(withHistory(withEmbeds(withTables(withLinks(withMentions(withReact(props))))))))) : withHtml(withEquation(withHistory(withEmbeds(withTables(withLinks(withMentions(withReact(props))))))));
13
12
  };
14
13
  export default withCommon;
@@ -0,0 +1,41 @@
1
+ import { Transforms, Editor, Element } from "slate";
2
+ import deserialize from "../helper/deserialize";
3
+ const withHtml = editor => {
4
+ const {
5
+ insertData,
6
+ isInline,
7
+ isVoid
8
+ } = editor;
9
+ editor.isInline = element => {
10
+ return element.type === "link" ? true : isInline(element);
11
+ };
12
+ editor.isVoid = element => {
13
+ return element.type === "image" ? true : isVoid(element);
14
+ };
15
+ editor.insertData = data => {
16
+ const slateHTML = data?.getData("application/x-slate-fragment");
17
+ const html = data?.getData("text/html");
18
+ if (slateHTML) {
19
+ const [tableNode] = Editor.nodes(editor, {
20
+ match: n => !Editor.isEditor(n) && Element.isElement(n) && n.type === "table"
21
+ });
22
+ // do not paste table cell inside table cell
23
+ // only plain text for internal paste
24
+ if (tableNode && tableNode[0]) {
25
+ const text = data?.getData("text/plain");
26
+ Transforms.insertText(editor, text);
27
+ } else {
28
+ insertData(data);
29
+ }
30
+ } else if (html) {
31
+ const parsed = new DOMParser().parseFromString(html, "text/html");
32
+ const fragment = deserialize(parsed.body);
33
+ Transforms.insertFragment(editor, fragment);
34
+ return;
35
+ } else {
36
+ insertData(data);
37
+ }
38
+ };
39
+ return editor;
40
+ };
41
+ export default withHtml;
@@ -5,15 +5,17 @@ const withTable = editor => {
5
5
  deleteBackward,
6
6
  deleteForward
7
7
  } = editor;
8
- editor.insertData = data => {
9
- try {
10
- const text = data.getData("text/plain");
11
- Transforms.insertText(editor, text);
12
- return;
13
- } catch (err) {
14
- console.log(err);
15
- }
16
- };
8
+
9
+ // editor.insertData = (data) => {
10
+ // try {
11
+ // // const text = data.getData("text/plain");
12
+ // Transforms.insertFragment(editor, data);
13
+ // return;
14
+ // } catch (err) {
15
+ // console.log(err);
16
+ // }
17
+ // };
18
+
17
19
  editor.deleteBackward = unit => {
18
20
  const {
19
21
  selection
@@ -39,6 +39,7 @@ import { getBreakPointsValue } from "../helper/theme";
39
39
  import Variables from "../Elements/Variables/Variable";
40
40
  import insertNewLine from "./insertNewLine";
41
41
  import Divider from "../Elements/Divider/Divider";
42
+ import { getBorderColor } from "./helper";
42
43
  import { jsx as _jsx } from "react/jsx-runtime";
43
44
  const alignment = ["alignLeft", "alignRight", "alignCenter"];
44
45
  const list_types = ["orderedList", "unorderedList"];
@@ -160,6 +161,7 @@ export const activeMark = (editor, format) => {
160
161
  }
161
162
  };
162
163
  export const getMarked = (leaf, children) => {
164
+ const className = leaf?.doublequote ? "doublequote" : "";
163
165
  if (leaf.bold) {
164
166
  children = /*#__PURE__*/_jsx("strong", {
165
167
  children: children
@@ -198,7 +200,9 @@ export const getMarked = (leaf, children) => {
198
200
  children: children
199
201
  });
200
202
  }
201
- if (leaf.color) {
203
+ // cover under single span
204
+ if (leaf.color || leaf.bgColor || leaf.fontSize || leaf.fontFamily || leaf.fontWeight) {
205
+ const family = fontFamilyMap[leaf?.fontFamily];
202
206
  const textStyles = leaf?.color?.indexOf("gradient") >= 0 ? {
203
207
  background: leaf?.color?.concat("text"),
204
208
  WebkitBackgroundClip: "text",
@@ -206,45 +210,17 @@ export const getMarked = (leaf, children) => {
206
210
  } : {
207
211
  color: leaf.color
208
212
  };
209
- children = /*#__PURE__*/_jsx("span", {
210
- style: {
211
- ...textStyles
212
- },
213
- children: children
214
- });
215
- }
216
- if (leaf.bgColor) {
217
- children = /*#__PURE__*/_jsx("span", {
218
- style: {
219
- background: leaf.bgColor
220
- },
221
- children: children
222
- });
223
- }
224
- if (leaf.fontSize) {
225
213
  children = /*#__PURE__*/_jsx(Box, {
214
+ className: className,
226
215
  component: "span",
227
216
  sx: {
228
217
  fontSize: {
229
218
  lg: sizeMap[leaf.fontSize] || leaf.fontSize,
230
219
  ...getBreakPointsValue(leaf.fontSize, null, "overrideText")
231
- }
232
- },
233
- children: children
234
- });
235
- }
236
- if (leaf.fontFamily) {
237
- const family = fontFamilyMap[leaf.fontFamily];
238
- children = /*#__PURE__*/_jsx("span", {
239
- style: {
240
- fontFamily: family
241
- },
242
- children: children
243
- });
244
- }
245
- if (leaf.fontWeight) {
246
- children = /*#__PURE__*/_jsx("span", {
247
- style: {
220
+ },
221
+ background: leaf.bgColor,
222
+ ...textStyles,
223
+ fontFamily: family,
248
224
  fontWeight: leaf.fontWeight
249
225
  },
250
226
  children: children
@@ -300,7 +276,8 @@ export const getBlock = props => {
300
276
  ...attributes,
301
277
  ...element.attr,
302
278
  style: {
303
- borderColor: element?.color || "transparent",
279
+ // borderColor: element?.color || "transparent",
280
+ ...getBorderColor(element?.color || "transparent", 3),
304
281
  background: element?.bgColor || "none",
305
282
  padding: `${element?.bgColor ? "16px" : "0px"} 8px`,
306
283
  borderRadius: `${element?.color ? "0px" : "12px"} 12px 12px ${element?.color ? "0px" : "12px"}`,
@@ -1,7 +1,9 @@
1
1
  import { Transforms } from "slate";
2
2
  import insertNewLine from "./insertNewLine";
3
+ import { getSelectedText } from "./helper";
3
4
  export const insertAccordion = (editor, path) => {
4
5
  try {
6
+ const selectedText = getSelectedText(editor);
5
7
  const accordion = {
6
8
  type: "accordion",
7
9
  children: [{
@@ -9,7 +11,7 @@ export const insertAccordion = (editor, path) => {
9
11
  children: [{
10
12
  type: "paragraph",
11
13
  children: [{
12
- text: ""
14
+ text: selectedText || ""
13
15
  }]
14
16
  }]
15
17
  }, {
@@ -43,6 +43,19 @@ export const gradientBorder = color => {
43
43
  };
44
44
  }
45
45
  };
46
+ export const getBorderColor = (color, borderWidth = 3) => {
47
+ if (color?.indexOf("linear") > -1) {
48
+ return {
49
+ borderImage: `${color} ${borderWidth}`,
50
+ borderWidth: `0px 0px 0px ${borderWidth}px`,
51
+ borderStyle: "solid"
52
+ };
53
+ } else {
54
+ return {
55
+ borderColor: color || "transparent"
56
+ };
57
+ }
58
+ };
46
59
  export const absoluteLink = url => {
47
60
  try {
48
61
  if (url?.indexOf("://") === -1) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flozy/editor",
3
- "version": "2.0.6",
3
+ "version": "2.0.8",
4
4
  "description": "An Editor for flozy app brain",
5
5
  "files": [
6
6
  "dist"
@@ -41,6 +41,7 @@
41
41
  "react-slick": "^0.29.0",
42
42
  "slate": "^0.94.1",
43
43
  "slate-history": "^0.93.0",
44
+ "slate-hyperscript": "^0.100.0",
44
45
  "slate-react": "^0.98.3",
45
46
  "styled-components": "^5.3.11",
46
47
  "use-debounce": "^10.0.0",