@flozy/editor 1.2.3 → 1.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.
@@ -12,10 +12,10 @@ import { RemoteCursorOverlay } from "./RemoteCursorOverlay/Overlay";
12
12
  import { mentionsEvent, commands } from "./utils/events";
13
13
  import withCommon from "./hooks/withCommon";
14
14
  import DialogWrapper from "./DialogWrapper";
15
- import useTimeout from "./hooks/useTimeout";
16
15
  import "./Editor.css";
17
16
  import { serialize } from "./utils/serializer";
18
17
  import { getThumbnailImage } from "./helper";
18
+ import PopupTool from "./Toolbar/PopupTool";
19
19
  import { jsx as _jsx } from "react/jsx-runtime";
20
20
  import { jsxs as _jsxs } from "react/jsx-runtime";
21
21
  const PREVIEW_IMAGE_HIDE_CLASS = ["grid-container-toolbar", "grid-item-toolbar", "element-toolbar"];
@@ -40,18 +40,16 @@ const CommonEditor = /*#__PURE__*/forwardRef((props, ref) => {
40
40
  onSave,
41
41
  editor: collaborativeEditor,
42
42
  readOnly,
43
- otherProps,
44
- timeoutInMS = 1000
43
+ otherProps
45
44
  } = props;
46
45
  const editorWrapper = useRef();
47
46
  const convertedContent = draftToSlate({
48
47
  data: content
49
48
  });
50
49
  const [value, setValue] = useState(convertedContent);
50
+ const [loadedValue] = useState(value);
51
+ const [isInteracted, setIsInteracted] = useState(false);
51
52
  const [deboundedValue] = useDebounce(value, 500);
52
- const [count] = useTimeout({
53
- timeoutInMS: timeoutInMS
54
- });
55
53
  const editor = useMemo(() => {
56
54
  if (collaborativeEditor) return collaborativeEditor;
57
55
  return withCommon(createEditor());
@@ -76,13 +74,13 @@ const CommonEditor = /*#__PURE__*/forwardRef((props, ref) => {
76
74
  }));
77
75
  }, [id, content]);
78
76
  useEffect(() => {
79
- if (count > 0) {
80
- if (editorWrapper && editorWrapper?.current) {
81
- const text = serialize(deboundedValue);
82
- onSave(JSON.stringify(deboundedValue), {
83
- text: text
84
- });
85
- }
77
+ if (editorWrapper && editorWrapper?.current && loadedValue !== deboundedValue && isInteracted) {
78
+ const text = serialize(deboundedValue);
79
+ const title = deboundedValue?.find(f => f.type === "title");
80
+ onSave(JSON.stringify(deboundedValue), {
81
+ text: text,
82
+ title: serialize(title?.children) || "Untitled"
83
+ });
86
84
  }
87
85
  }, [deboundedValue]);
88
86
  const getPreviewImage = async (needBackground = false, options = {}) => {
@@ -144,6 +142,9 @@ const CommonEditor = /*#__PURE__*/forwardRef((props, ref) => {
144
142
  const chars = CHARACTERS.filter(c => c.toLowerCase().startsWith(search?.toLowerCase())).slice(0, 10);
145
143
  const handleEditorChange = newValue => {
146
144
  setValue(newValue);
145
+ if (!isInteracted) {
146
+ setIsInteracted(true);
147
+ }
147
148
  };
148
149
  const customProps = {
149
150
  ...(otherProps || {})
@@ -215,7 +216,7 @@ const CommonEditor = /*#__PURE__*/forwardRef((props, ref) => {
215
216
  paddingTop: `${bannerSpacing?.top}px`,
216
217
  paddingBottom: `${bannerSpacing?.bottom}px`
217
218
  },
218
- children: [/*#__PURE__*/_jsx(Editable, {
219
+ children: [/*#__PURE__*/_jsx(PopupTool, {}), /*#__PURE__*/_jsx(Editable, {
219
220
  className: "innert-editor-textbox",
220
221
  readOnly: isReadOnly,
221
222
  placeholder: "Write something",
@@ -1,9 +1,5 @@
1
1
  @import url('https://fonts.googleapis.com/css2?family=Inter:wght@100;200;300;400;500;600;700;800;900&display=swap');
2
2
 
3
- * {
4
- font-family: 'Inter', sans-serif;
5
- }
6
-
7
3
  .ml-1 {
8
4
  margin-left: 10px;
9
5
  }
@@ -437,4 +433,8 @@ html{
437
433
 
438
434
  .toolbar svg {
439
435
  /* fill: 'red' */
436
+ }
437
+
438
+ .MuiIconButton-root.btnActive {
439
+ background-color: #ccc;
440
440
  }
@@ -1,31 +1,23 @@
1
1
  import React, { useRef, useState } from "react";
2
- import { MdFormatColorText, MdFormatColorFill } from "react-icons/md";
3
- import "./ColorPicker.css";
2
+ import { ReactEditor } from "slate-react";
3
+ import Button from "../../common/Button";
4
4
  import { colors } from "./defaultColors";
5
5
  import { addMarkData, activeMark } from "../../utils/SlateUtilityFunctions";
6
6
  import { Transforms } from "slate";
7
7
  import usePopup from "../../utils/customHooks/usePopup";
8
- import { ReactEditor } from "slate-react";
8
+ import { logo } from "./LogoIcon";
9
+ import "./ColorPicker.css";
9
10
  import { jsx as _jsx } from "react/jsx-runtime";
10
11
  import { jsxs as _jsxs } from "react/jsx-runtime";
11
12
  import { Fragment as _Fragment } from "react/jsx-runtime";
12
- const logo = {
13
- color: /*#__PURE__*/_jsx(MdFormatColorText, {
14
- size: 17,
15
- style: {
16
- fill: '#64748B'
17
- }
18
- }),
19
- bgColor: /*#__PURE__*/_jsx(MdFormatColorFill, {
20
- size: 17,
21
- style: {
22
- fill: '#64748B'
23
- }
24
- })
13
+ const DEFAULT_COLOR = {
14
+ color: "#000000",
15
+ bgcolor: "#FFFFFF"
25
16
  };
26
17
  const ColorPicker = ({
27
18
  format,
28
- editor
19
+ editor,
20
+ showHex
29
21
  }) => {
30
22
  const [selection, setSelection] = useState();
31
23
  const [hexValue, setHexValue] = useState("");
@@ -68,17 +60,27 @@ const ColorPicker = ({
68
60
  setValidHex(isValideHexSix.test(newHex) || isValideHexThree.test(newHex));
69
61
  setHexValue(newHex);
70
62
  };
63
+ const activeColor = showOptions ? DEFAULT_COLOR[format] : activeMark(editor, format);
71
64
  return /*#__PURE__*/_jsxs("div", {
72
65
  className: "color-picker popup-wrapper1 color-picker-dialog",
73
66
  ref: colorPickerRef,
74
- children: [/*#__PURE__*/_jsx("button", {
67
+ style: {
68
+ display: "flex",
69
+ alignItems: "center"
70
+ },
71
+ children: [showHex ? /*#__PURE__*/_jsx("div", {
72
+ style: {
73
+ display: "flex"
74
+ },
75
+ children: activeColor
76
+ }) : null, /*#__PURE__*/_jsx(Button, {
75
77
  style: {
76
- color: showOptions ? "black" : activeMark(editor, format),
78
+ color: activeColor,
77
79
  opacity: "1"
78
80
  },
79
81
  className: showOptions ? "clicked" : "",
80
82
  onClick: toggleOption,
81
- children: logo[format]
83
+ children: logo[format](activeColor)
82
84
  }), showOptions && /*#__PURE__*/_jsxs(_Fragment, {
83
85
  children: [/*#__PURE__*/_jsx("div", {
84
86
  className: "backdrop",
@@ -125,7 +127,7 @@ const ColorPicker = ({
125
127
  className: "colorSaveBtn",
126
128
  style: {
127
129
  background: validHex ? "#2563EB" : "#64748B",
128
- color: '#fff'
130
+ color: "#fff"
129
131
  },
130
132
  type: "submit",
131
133
  children: "Save"
@@ -0,0 +1,59 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { jsxs as _jsxs } from "react/jsx-runtime";
3
+ export const logo = {
4
+ color: color => /*#__PURE__*/_jsx("svg", {
5
+ xmlns: "http://www.w3.org/2000/svg",
6
+ fill: "#000000",
7
+ height: "20px",
8
+ width: "20px",
9
+ version: "1.1",
10
+ id: "Icons",
11
+ viewBox: "0 0 32 32",
12
+ children: /*#__PURE__*/_jsxs("g", {
13
+ children: [/*#__PURE__*/_jsx("path", {
14
+ d: "M29,27H3c-0.6,0-1,0.4-1,1s0.4,1,1,1h26c0.6,0,1-0.4,1-1S29.6,27,29,27z",
15
+ fill: color || "#000"
16
+ }), /*#__PURE__*/_jsx("path", {
17
+ d: "M5,24h4c0.6,0,1-0.4,1-1s-0.4-1-1-1H8.6l1.9-4h11.1l1.9,4H23c-0.6,0-1,0.4-1,1s0.4,1,1,1h4c0.6,0,1-0.4,1-1s-0.4-1-1-1 h-1.4L16.9,3.6C16.7,3.2,16.4,3,16,3s-0.7,0.2-0.9,0.6L6.4,22H5c-0.6,0-1,0.4-1,1S4.4,24,5,24z M16,6.3l4.6,9.7h-9.2L16,6.3z"
18
+ })]
19
+ })
20
+ }),
21
+ bgColor: color => /*#__PURE__*/_jsxs("svg", {
22
+ xmlns: "http://www.w3.org/2000/svg",
23
+ width: "24px",
24
+ height: "24px",
25
+ viewBox: "0 0 50 50",
26
+ fill: "none",
27
+ children: [/*#__PURE__*/_jsx("rect", {
28
+ width: "48",
29
+ height: "48",
30
+ fill: "white",
31
+ fillOpacity: "0.01"
32
+ }), /*#__PURE__*/_jsx("path", {
33
+ fillRule: "evenodd",
34
+ clipRule: "evenodd",
35
+ d: "M37 37C39.2091 37 41 35.2091 41 33C41 31.5272 39.6667 29.5272 37 27C34.3333 29.5272 33 31.5272 33 33C33 35.2091 34.7909 37 37 37Z",
36
+ fill: "#000000"
37
+ }), /*#__PURE__*/_jsx("path", {
38
+ d: "M20.8535 5.50439L24.389 9.03993",
39
+ stroke: "#000000",
40
+ strokeWidth: "4",
41
+ strokeLinecap: "round"
42
+ }), /*#__PURE__*/_jsx("path", {
43
+ d: "M23.6818 8.33281L8.12549 23.8892L19.4392 35.2029L34.9955 19.6465L23.6818 8.33281Z",
44
+ stroke: "#000000",
45
+ strokeWidth: "4",
46
+ strokeLinejoin: "round"
47
+ }), /*#__PURE__*/_jsx("path", {
48
+ d: "M12 20.0732L28.961 25.6496",
49
+ stroke: "#000000",
50
+ strokeWidth: "4",
51
+ strokeLinecap: "round"
52
+ }), /*#__PURE__*/_jsx("path", {
53
+ d: "M4 43H44",
54
+ stroke: color || "#FFF",
55
+ strokeWidth: "4",
56
+ strokeLinecap: "round"
57
+ })]
58
+ })
59
+ };
@@ -0,0 +1,16 @@
1
+ import React from "react";
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ const Title = props => {
4
+ const {
5
+ attributes,
6
+ children
7
+ } = props;
8
+ return /*#__PURE__*/_jsx("div", {
9
+ ...attributes,
10
+ style: {
11
+ fontWeight: "bold"
12
+ },
13
+ children: children
14
+ });
15
+ };
16
+ export default Title;
@@ -0,0 +1,22 @@
1
+ import React from "react";
2
+ import Icon from "../../common/Icon";
3
+ import Button from "../../common/Button";
4
+ import { toggleBlock, isBlockActive } from "../../utils/SlateUtilityFunctions.js";
5
+ import { jsx as _jsx } from "react/jsx-runtime";
6
+ const BlockButton = ({
7
+ editor,
8
+ format
9
+ }) => {
10
+ return /*#__PURE__*/_jsx(Button, {
11
+ active: isBlockActive(editor, format),
12
+ format: format,
13
+ onMouseDown: e => {
14
+ e.preventDefault();
15
+ toggleBlock(editor, format);
16
+ },
17
+ children: /*#__PURE__*/_jsx(Icon, {
18
+ icon: format
19
+ })
20
+ });
21
+ };
22
+ export default BlockButton;
@@ -0,0 +1,40 @@
1
+ import React from "react";
2
+ import { Select, MenuItem } from "@mui/material";
3
+ import { addMarkData, activeMark } from "../../utils/SlateUtilityFunctions.js";
4
+ import { fontFamilyMap } from "../../utils/font";
5
+ import { jsx as _jsx } from "react/jsx-runtime";
6
+ const Dropdown = ({
7
+ editor,
8
+ format,
9
+ options
10
+ }) => {
11
+ const value = activeMark(editor, format);
12
+ const changeMarkData = (event, format) => {
13
+ event.preventDefault();
14
+ const value = event.target.value;
15
+ addMarkData(editor, {
16
+ format,
17
+ value
18
+ });
19
+ };
20
+ return /*#__PURE__*/_jsx(Select, {
21
+ value: value,
22
+ className: "editor-dd",
23
+ onChange: e => changeMarkData(e, format),
24
+ style: {
25
+ fontFamily: fontFamilyMap[value],
26
+ width: "100%",
27
+ height: "36px",
28
+ overflow: "hidden",
29
+ borderRadius: "10px"
30
+ },
31
+ children: options.map((item, index) => /*#__PURE__*/_jsx(MenuItem, {
32
+ style: {
33
+ fontFamily: item.text
34
+ },
35
+ value: item.value,
36
+ children: item.text
37
+ }, index))
38
+ });
39
+ };
40
+ export default Dropdown;
@@ -0,0 +1,22 @@
1
+ import React from "react";
2
+ import Icon from "../../common/Icon";
3
+ import Button from "../../common/Button";
4
+ import { toggleMark, isMarkActive } from "../../utils/SlateUtilityFunctions.js";
5
+ import { jsx as _jsx } from "react/jsx-runtime";
6
+ const MarkButton = ({
7
+ editor,
8
+ format
9
+ }) => {
10
+ return /*#__PURE__*/_jsx(Button, {
11
+ active: isMarkActive(editor, format),
12
+ format: format,
13
+ onMouseDown: e => {
14
+ e.preventDefault();
15
+ toggleMark(editor, format);
16
+ },
17
+ children: /*#__PURE__*/_jsx(Icon, {
18
+ icon: format
19
+ })
20
+ });
21
+ };
22
+ export default MarkButton;
@@ -0,0 +1,4 @@
1
+ import BlockButton from "./BlockButton";
2
+ import Dropdown from "./Dropdown";
3
+ import MarkButton from "./MarkButton";
4
+ export { BlockButton, Dropdown, MarkButton };
@@ -0,0 +1,34 @@
1
+ const usePopupStyle = () => ({
2
+ popupWrapper: {
3
+ boxShadow: "0px 4px 10px 0px rgba(0, 0, 0, 0.16)"
4
+ },
5
+ textFormatWrapper: {
6
+ padding: "0px 24px 24px 24px",
7
+ width: "350px"
8
+ },
9
+ textFormatLabel: {
10
+ display: "flex",
11
+ alignItems: "center",
12
+ fontWeight: 600,
13
+ fontSize: "14px",
14
+ lineHeight: "25px",
15
+ marginTop: "8px",
16
+ marginBottom: "8px",
17
+ color: "rgba(169, 169, 169, 1)"
18
+ },
19
+ textFormatField: {
20
+ marginBottom: "8px"
21
+ },
22
+ textFormatFieldBorder: {
23
+ display: "flex",
24
+ alignItems: "center",
25
+ marginBottom: "8px",
26
+ border: "1px solid rgba(169, 169, 169, 1)",
27
+ padding: "0px 8px",
28
+ borderRadius: "10px"
29
+ },
30
+ textFormatCG: {
31
+ marginBottom: "8px"
32
+ }
33
+ });
34
+ export default usePopupStyle;
@@ -0,0 +1,81 @@
1
+ import React from "react";
2
+ import { Grid } from "@mui/material";
3
+ import toolbarGroups from "../toolbarGroups";
4
+ import { Dropdown, MarkButton } from "../FormatTools";
5
+ import ColorPicker from "../../Elements/Color Picker/ColorPicker";
6
+ import { activeMark } from "../../utils/SlateUtilityFunctions";
7
+ import { jsx as _jsx } from "react/jsx-runtime";
8
+ import { jsxs as _jsxs } from "react/jsx-runtime";
9
+ const allTools = toolbarGroups.flat();
10
+ const TextFormat = props => {
11
+ const {
12
+ classes,
13
+ editor
14
+ } = props;
15
+ const fontFamily = allTools.find(f => f.format === "fontFamily");
16
+ const fontStyle = allTools.filter(f => f.type === "mark");
17
+ return /*#__PURE__*/_jsxs(Grid, {
18
+ container: true,
19
+ sx: classes.textFormatWrapper,
20
+ children: [/*#__PURE__*/_jsx(Grid, {
21
+ item: true,
22
+ xs: 12,
23
+ sx: classes.textFormatLabel,
24
+ children: "TEXT COLOR"
25
+ }), /*#__PURE__*/_jsx(Grid, {
26
+ item: true,
27
+ xs: 12,
28
+ sx: classes.textFormatFieldBorder,
29
+ children: /*#__PURE__*/_jsx(ColorPicker, {
30
+ format: "color",
31
+ activeMark: activeMark,
32
+ editor: editor,
33
+ showHex: true
34
+ })
35
+ }), /*#__PURE__*/_jsx(Grid, {
36
+ item: true,
37
+ xs: 12,
38
+ sx: classes.textFormatLabel,
39
+ children: "BACKGROUND COLOR"
40
+ }), /*#__PURE__*/_jsx(Grid, {
41
+ item: true,
42
+ xs: 12,
43
+ sx: classes.textFormatFieldBorder,
44
+ children: /*#__PURE__*/_jsx(ColorPicker, {
45
+ format: "bgColor",
46
+ activeMark: activeMark,
47
+ editor: editor,
48
+ showHex: true
49
+ })
50
+ }), /*#__PURE__*/_jsx(Grid, {
51
+ item: true,
52
+ xs: 12,
53
+ sx: classes.textFormatLabel,
54
+ children: "FONT FAMILY"
55
+ }), /*#__PURE__*/_jsx(Grid, {
56
+ item: true,
57
+ xs: 12,
58
+ sx: classes.textFormatField,
59
+ children: /*#__PURE__*/_jsx(Dropdown, {
60
+ ...fontFamily,
61
+ editor: editor
62
+ })
63
+ }), /*#__PURE__*/_jsx(Grid, {
64
+ item: true,
65
+ xs: 12,
66
+ sx: classes.textFormatLabel,
67
+ children: "FONT STYLE"
68
+ }), /*#__PURE__*/_jsx(Grid, {
69
+ item: true,
70
+ xs: 12,
71
+ sx: classes.textFormatCG,
72
+ children: fontStyle?.map((m, i) => {
73
+ return /*#__PURE__*/_jsx(MarkButton, {
74
+ editor: editor,
75
+ ...m
76
+ }, `pptool_mark_${i}_${m.id}`);
77
+ })
78
+ })]
79
+ });
80
+ };
81
+ export default TextFormat;
@@ -0,0 +1,69 @@
1
+ import React, { useEffect, useState } from "react";
2
+ import { Popper, Fade, Paper, IconButton } from "@mui/material";
3
+ import CloseIcon from "@mui/icons-material/Close";
4
+ import { Editor, Range } from "slate";
5
+ import { useSlate, useFocused } from "slate-react";
6
+ import TextFormat from "./TextFormat";
7
+ import usePopupStyle from "./PopupToolStyle";
8
+ import { jsx as _jsx } from "react/jsx-runtime";
9
+ import { jsxs as _jsxs } from "react/jsx-runtime";
10
+ const PopupTool = () => {
11
+ const classes = usePopupStyle();
12
+ const [anchorEl, setAnchorEl] = useState(null);
13
+ const editor = useSlate();
14
+ const inFocus = useFocused();
15
+ const {
16
+ selection
17
+ } = editor;
18
+ const open = Boolean(anchorEl);
19
+ const id = open ? "popup-edit-tool" : "";
20
+ useEffect(() => {
21
+ if (!selection || !inFocus || Range.isCollapsed(selection) || Editor.string(editor, selection) === "") {
22
+ setAnchorEl(null);
23
+ } else {
24
+ const domSelection = window.getSelection();
25
+ const domRange = domSelection.getRangeAt(0);
26
+ const rect = domRange.getBoundingClientRect();
27
+ setAnchorEl({
28
+ clientWidth: rect.width,
29
+ clientHeight: rect.height,
30
+ getBoundingClientRect: () => rect
31
+ });
32
+ }
33
+ }, [selection]);
34
+ const handleClose = () => {
35
+ setAnchorEl(null);
36
+ };
37
+ return /*#__PURE__*/_jsx(Popper, {
38
+ id: id,
39
+ open: open,
40
+ disablePortal: false,
41
+ anchorEl: anchorEl,
42
+ transition: true,
43
+ placement: "bottom-start",
44
+ onMouseDown: e => e.preventDefault(),
45
+ sx: classes.popupWrapper,
46
+ children: ({
47
+ TransitionProps
48
+ }) => /*#__PURE__*/_jsx(Fade, {
49
+ ...TransitionProps,
50
+ timeout: 350,
51
+ children: /*#__PURE__*/_jsxs(Paper, {
52
+ children: [/*#__PURE__*/_jsx("div", {
53
+ style: {
54
+ display: "flex",
55
+ justifyContent: "end"
56
+ },
57
+ children: /*#__PURE__*/_jsx(IconButton, {
58
+ onClick: handleClose,
59
+ children: /*#__PURE__*/_jsx(CloseIcon, {})
60
+ })
61
+ }), /*#__PURE__*/_jsx(TextFormat, {
62
+ editor: editor,
63
+ classes: classes
64
+ })]
65
+ })
66
+ })
67
+ });
68
+ };
69
+ export default PopupTool;
@@ -1,13 +1,9 @@
1
1
  import React, { useEffect, useState } from "react";
2
- import { Select, MenuItem } from "@mui/material";
3
2
  import { useSlate } from "slate-react";
4
- import Button from "../common/Button";
5
- import Icon from "../common/Icon";
6
- import { toggleBlock, toggleMark, isMarkActive, addMarkData, isBlockActive, activeMark } from "../utils/SlateUtilityFunctions.js";
7
- import { fontFamilyMap } from "../utils/font";
3
+ import { isBlockActive, activeMark } from "../utils/SlateUtilityFunctions.js";
8
4
  import useFormat from "../utils/customHooks/useFormat.js";
9
5
  import defaultToolbarGroups from "./toolbarGroups.js";
10
- import "./styles.css";
6
+ import { BlockButton, MarkButton, Dropdown } from "./FormatTools";
11
7
  import ColorPicker from "../Elements/Color Picker/ColorPicker";
12
8
  import LinkButton from "../Elements/Link/LinkButton";
13
9
  import Embed from "../Elements/Embed/Embed";
@@ -26,6 +22,7 @@ import CarouselButton from "../Elements/Carousel/CarouselButton";
26
22
  import ChipTextButton from "../Elements/ChipText/ChipTextButton";
27
23
  import DrawerMenuButton from "../Elements/DrawerMenu/DrawerMenuButton";
28
24
  import AppHeaderButton from "../Elements/AppHeader/AppHeaderButton";
25
+ import "./styles.css";
29
26
  import { jsx as _jsx } from "react/jsx-runtime";
30
27
  import { jsxs as _jsxs } from "react/jsx-runtime";
31
28
  const Toolbar = props => {
@@ -48,68 +45,6 @@ const Toolbar = props => {
48
45
  setToolbarGroups(filteredGroups);
49
46
  // eslint-disable-next-line react-hooks/exhaustive-deps
50
47
  }, [isTable]);
51
- const BlockButton = ({
52
- format
53
- }) => {
54
- return /*#__PURE__*/_jsx(Button, {
55
- active: isBlockActive(editor, format),
56
- format: format,
57
- onMouseDown: e => {
58
- e.preventDefault();
59
- toggleBlock(editor, format);
60
- },
61
- children: /*#__PURE__*/_jsx(Icon, {
62
- icon: format
63
- })
64
- });
65
- };
66
- const MarkButton = ({
67
- format
68
- }) => {
69
- return /*#__PURE__*/_jsx(Button, {
70
- active: isMarkActive(editor, format),
71
- format: format,
72
- onMouseDown: e => {
73
- e.preventDefault();
74
- toggleMark(editor, format);
75
- },
76
- children: /*#__PURE__*/_jsx(Icon, {
77
- icon: format
78
- })
79
- });
80
- };
81
- const Dropdown = ({
82
- format,
83
- options
84
- }) => {
85
- const value = activeMark(editor, format);
86
- return /*#__PURE__*/_jsx(Select, {
87
- value: value,
88
- className: "editor-dd",
89
- onChange: e => changeMarkData(e, format),
90
- style: {
91
- fontFamily: fontFamilyMap[value],
92
- width: "200px",
93
- height: "36px",
94
- overflow: "hidden"
95
- },
96
- children: options.map((item, index) => /*#__PURE__*/_jsx(MenuItem, {
97
- style: {
98
- fontFamily: item.text
99
- },
100
- value: item.value,
101
- children: item.text
102
- }, index))
103
- });
104
- };
105
- const changeMarkData = (event, format) => {
106
- event.preventDefault();
107
- const value = event.target.value;
108
- addMarkData(editor, {
109
- format,
110
- value
111
- });
112
- };
113
48
  return /*#__PURE__*/_jsxs("div", {
114
49
  className: "toolbar",
115
50
  children: [toolbarGroups.map((group, index) => /*#__PURE__*/_jsx("span", {
@@ -118,15 +53,18 @@ const Toolbar = props => {
118
53
  switch (element.type) {
119
54
  case "block":
120
55
  return /*#__PURE__*/_jsx(BlockButton, {
121
- ...element
56
+ ...element,
57
+ editor: editor
122
58
  }, element.id);
123
59
  case "mark":
124
60
  return /*#__PURE__*/_jsx(MarkButton, {
125
- ...element
61
+ ...element,
62
+ editor: editor
126
63
  }, element.id);
127
64
  case "dropdown":
128
65
  return /*#__PURE__*/_jsx(Dropdown, {
129
- ...element
66
+ ...element,
67
+ editor: editor
130
68
  }, element.id);
131
69
  case "link":
132
70
  return /*#__PURE__*/_jsx(LinkButton, {
@@ -5,7 +5,8 @@ import withTables from "../plugins/withTable";
5
5
  import withEmbeds from "../plugins/withEmbeds";
6
6
  import withEquation from "../plugins/withEquation";
7
7
  import withMentions from "../plugins/withMentions";
8
+ import withLayout from "../plugins/withLayout";
8
9
  const withCommon = props => {
9
- return withEquation(withHistory(withEmbeds(withTables(withLinks(withMentions(withReact(props)))))));
10
+ return withEquation(withLayout(withHistory(withEmbeds(withTables(withLinks(withMentions(withReact(props))))))));
10
11
  };
11
12
  export default withCommon;
@@ -0,0 +1,62 @@
1
+ import { Transforms, Node, Element as SlateElement, Editor } from "slate";
2
+ const withLayout = editor => {
3
+ const {
4
+ normalizeNode
5
+ } = editor;
6
+ editor.normalizeNode = ([node, path]) => {
7
+ if (path.length === 0) {
8
+ if (editor.children.length <= 1 && Editor.string(editor, [0, 0]) === "") {
9
+ const title = {
10
+ type: "title",
11
+ children: [{
12
+ text: "Untitled"
13
+ }]
14
+ };
15
+ Transforms.insertNodes(editor, title, {
16
+ at: path.concat(0),
17
+ select: true
18
+ });
19
+ }
20
+ if (editor.children.length < 2) {
21
+ const paragraph = {
22
+ type: "paragraph",
23
+ children: [{
24
+ text: ""
25
+ }]
26
+ };
27
+ Transforms.insertNodes(editor, paragraph, {
28
+ at: path.concat(1)
29
+ });
30
+ }
31
+ for (const [child, childPath] of Node.children(editor, path)) {
32
+ let type = "";
33
+ const slateIndex = childPath[0];
34
+ const enforceType = type => {
35
+ if (SlateElement.isElement(child) && child.type !== type) {
36
+ const newProperties = {
37
+ type
38
+ };
39
+ Transforms.setNodes(editor, newProperties, {
40
+ at: childPath
41
+ });
42
+ }
43
+ };
44
+ switch (slateIndex) {
45
+ case 0:
46
+ type = "title";
47
+ enforceType(type);
48
+ break;
49
+ case 1:
50
+ type = "paragraph";
51
+ enforceType(type);
52
+ break;
53
+ default:
54
+ break;
55
+ }
56
+ }
57
+ }
58
+ return normalizeNode([node, path]);
59
+ };
60
+ return editor;
61
+ };
62
+ export default withLayout;
@@ -25,6 +25,7 @@ import ChipText from "../Elements/ChipText/ChipText";
25
25
  import DrawerMenu from "../Elements/DrawerMenu/DrawerMenu";
26
26
  import AppHeader from "../Elements/AppHeader/AppHeader";
27
27
  import PageSettings from "../Elements/PageSettings/PageSettings";
28
+ import Title from "../Elements/Title/title";
28
29
  import { jsx as _jsx } from "react/jsx-runtime";
29
30
  const alignment = ["alignLeft", "alignRight", "alignCenter"];
30
31
  const list_types = ["orderedList", "unorderedList"];
@@ -93,8 +94,8 @@ export const isBlockActive = (editor, format) => {
93
94
  };
94
95
  export const activeMark = (editor, format) => {
95
96
  const defaultMarkData = {
96
- color: "black",
97
- bgColor: "black",
97
+ color: "#000000",
98
+ bgColor: "#FFFFFF",
98
99
  fontSize: "normal",
99
100
  fontFamily: "sans"
100
101
  };
@@ -363,6 +364,10 @@ export const getBlock = props => {
363
364
  return /*#__PURE__*/_jsx(PageSettings, {
364
365
  ...props
365
366
  });
367
+ case "title":
368
+ return /*#__PURE__*/_jsx(Title, {
369
+ ...props
370
+ });
366
371
  default:
367
372
  return /*#__PURE__*/_jsx("div", {
368
373
  ...element.attr,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flozy/editor",
3
- "version": "1.2.3",
3
+ "version": "1.2.4",
4
4
  "description": "An Editor for flozy app brain",
5
5
  "files": [
6
6
  "dist"
@@ -1,21 +0,0 @@
1
- import { useEffect, useState } from "react";
2
- let t = null;
3
- const useTimeout = props => {
4
- const {
5
- timeoutInMS
6
- } = props;
7
- const [count, setCount] = useState(-1);
8
- const onReset = () => {
9
- clearTimeout(t);
10
- t = setTimeout(() => {
11
- setCount(count + 1);
12
- }, timeoutInMS);
13
- };
14
- useEffect(() => {
15
- if (timeoutInMS) {
16
- onReset();
17
- }
18
- }, [timeoutInMS, count]);
19
- return [count];
20
- };
21
- export default useTimeout;