@flozy/editor 1.0.5 → 1.0.7
Sign up to get free protection for your applications and to get access to all the features.
- package/dist/Editor/CollaborativeEditor.js +116 -0
- package/dist/Editor/CommonEditor.js +132 -0
- package/dist/Editor/Editor.css +115 -0
- package/dist/Editor/Elements/CodeToText/CodeToText.css +57 -0
- package/dist/Editor/Elements/CodeToText/CodeToText.js +112 -0
- package/dist/Editor/Elements/CodeToText/CodeToTextButton.js +18 -0
- package/dist/Editor/Elements/CodeToText/HtmlCode.js +54 -0
- package/dist/Editor/Elements/CodeToText/HtmlContextMenu.js +39 -0
- package/dist/Editor/Elements/Color Picker/ColorPicker.css +38 -0
- package/dist/Editor/Elements/Color Picker/ColorPicker.js +116 -0
- package/dist/Editor/Elements/Color Picker/defaultColors.js +1 -0
- package/dist/Editor/Elements/Embed/Embed.css +14 -0
- package/dist/Editor/Elements/Embed/Embed.js +94 -0
- package/dist/Editor/Elements/Embed/Image.js +70 -0
- package/dist/Editor/Elements/Embed/Video.js +62 -0
- package/dist/Editor/Elements/Equation/Equation.js +24 -0
- package/dist/Editor/Elements/Equation/EquationButton.js +66 -0
- package/dist/Editor/Elements/Equation/styles.css +4 -0
- package/dist/Editor/Elements/Grid/Grid.js +53 -0
- package/dist/Editor/Elements/Grid/GridButton.js +19 -0
- package/dist/Editor/Elements/Grid/GridItem.js +53 -0
- package/dist/Editor/Elements/ID/Id.js +56 -0
- package/dist/Editor/Elements/Link/Link.js +34 -0
- package/dist/Editor/Elements/Link/LinkButton.js +77 -0
- package/dist/Editor/Elements/Link/styles.css +20 -0
- package/dist/Editor/Elements/Mentions/Mentions.js +34 -0
- package/dist/Editor/Elements/NewLine/NewLineButton.js +22 -0
- package/dist/Editor/Elements/Table/Table.js +15 -0
- package/dist/Editor/Elements/Table/TableSelector.css +18 -0
- package/dist/Editor/Elements/Table/TableSelector.js +93 -0
- package/dist/Editor/Elements/TableContextMenu/TableContextMenu.js +91 -0
- package/dist/Editor/Elements/TableContextMenu/styles.css +18 -0
- package/dist/Editor/RemoteCursorOverlay/Overlay.js +75 -0
- package/dist/Editor/Toolbar/Toolbar.js +166 -0
- package/dist/Editor/Toolbar/styles.css +28 -0
- package/dist/Editor/Toolbar/toolbarGroups.js +131 -0
- package/dist/Editor/Toolbar/toolbarIcons/align-center.svg +1 -0
- package/dist/Editor/Toolbar/toolbarIcons/align-left.svg +1 -0
- package/dist/Editor/Toolbar/toolbarIcons/align-right.svg +1 -0
- package/dist/Editor/Toolbar/toolbarIcons/blockquote.svg +1 -0
- package/dist/Editor/Toolbar/toolbarIcons/bold.png +0 -0
- package/dist/Editor/Toolbar/toolbarIcons/fontColor.svg +4 -0
- package/dist/Editor/Toolbar/toolbarIcons/headingOne.svg +3 -0
- package/dist/Editor/Toolbar/toolbarIcons/headingTwo.svg +3 -0
- package/dist/Editor/Toolbar/toolbarIcons/italic.png +0 -0
- package/dist/Editor/Toolbar/toolbarIcons/link.svg +1 -0
- package/dist/Editor/Toolbar/toolbarIcons/orderedList.svg +1 -0
- package/dist/Editor/Toolbar/toolbarIcons/strikethrough.png +0 -0
- package/dist/Editor/Toolbar/toolbarIcons/subscript.svg +1 -0
- package/dist/Editor/Toolbar/toolbarIcons/superscript.svg +1 -0
- package/dist/Editor/Toolbar/toolbarIcons/textColor.png +0 -0
- package/dist/Editor/Toolbar/toolbarIcons/underline.png +0 -0
- package/dist/Editor/Toolbar/toolbarIcons/unlink.svg +1 -0
- package/dist/Editor/Toolbar/toolbarIcons/unorderedList.svg +1 -0
- package/dist/Editor/YjsProvider.js +9 -0
- package/dist/Editor/common/Button.js +21 -0
- package/dist/Editor/common/Icon.js +114 -0
- package/dist/Editor/common/MentionsPopup.js +54 -0
- package/dist/Editor/hooks/useMentions.js +44 -0
- package/dist/Editor/hooks/withCollaborative.js +15 -0
- package/dist/Editor/hooks/withCommon.js +11 -0
- package/dist/Editor/plugins/withEmbeds.js +29 -0
- package/dist/Editor/plugins/withEquation.js +8 -0
- package/dist/Editor/plugins/withLinks.js +8 -0
- package/dist/Editor/plugins/withMentions.js +18 -0
- package/dist/Editor/plugins/withTable.js +61 -0
- package/dist/Editor/utils/SlateUtilityFunctions.js +224 -0
- package/dist/Editor/utils/customHooks/useContextMenu.js +37 -0
- package/dist/Editor/utils/customHooks/useFormat.js +21 -0
- package/dist/Editor/utils/customHooks/usePopup.js +21 -0
- package/dist/Editor/utils/customHooks/useResize.js +47 -0
- package/dist/Editor/utils/draftToSlate.js +111 -0
- package/dist/Editor/utils/embed.js +24 -0
- package/dist/Editor/utils/equation.js +23 -0
- package/dist/Editor/utils/events.js +76 -0
- package/dist/Editor/utils/grid.js +13 -0
- package/dist/Editor/utils/gridItem.js +19 -0
- package/dist/Editor/utils/link.js +52 -0
- package/dist/Editor/utils/mentions.js +12 -0
- package/dist/Editor/utils/paragraph.js +6 -0
- package/dist/Editor/utils/serializer.js +28 -0
- package/dist/Editor/utils/table.js +129 -0
- package/dist/index.js +4 -0
- package/package.json +18 -8
@@ -0,0 +1,116 @@
|
|
1
|
+
import React, { useRef, useState } from "react";
|
2
|
+
import { MdFormatColorText, MdFormatColorFill, MdCheck } from "react-icons/md";
|
3
|
+
import "./ColorPicker.css";
|
4
|
+
import { colors } from "./defaultColors.js";
|
5
|
+
import { addMarkData, activeMark } from "../../utils/SlateUtilityFunctions.js";
|
6
|
+
import { Transforms } from "slate";
|
7
|
+
import usePopup from "../../utils/customHooks/usePopup";
|
8
|
+
import { ReactEditor } from "slate-react";
|
9
|
+
const logo = {
|
10
|
+
color: /*#__PURE__*/React.createElement(MdFormatColorText, {
|
11
|
+
size: 20
|
12
|
+
}),
|
13
|
+
bgColor: /*#__PURE__*/React.createElement(MdFormatColorFill, {
|
14
|
+
size: 20
|
15
|
+
})
|
16
|
+
};
|
17
|
+
const ColorPicker = ({
|
18
|
+
format,
|
19
|
+
editor
|
20
|
+
}) => {
|
21
|
+
const [selection, setSelection] = useState();
|
22
|
+
const [hexValue, setHexValue] = useState("");
|
23
|
+
const [validHex, setValidHex] = useState();
|
24
|
+
const colorPickerRef = useRef(null);
|
25
|
+
const [showOptions, setShowOptions] = usePopup(colorPickerRef);
|
26
|
+
const isValideHexSix = new RegExp("^#[0-9A-Za-z]{6}");
|
27
|
+
const isValideHexThree = new RegExp("^#[0-9A-Za-z]{3}");
|
28
|
+
const changeColor = e => {
|
29
|
+
const clickedColor = e.target.getAttribute("data-value");
|
30
|
+
selection && Transforms.select(editor, selection);
|
31
|
+
selection && ReactEditor.focus(editor);
|
32
|
+
addMarkData(editor, {
|
33
|
+
format,
|
34
|
+
value: clickedColor
|
35
|
+
});
|
36
|
+
setShowOptions(false);
|
37
|
+
};
|
38
|
+
const toggleOption = () => {
|
39
|
+
setSelection(editor.selection);
|
40
|
+
selection && ReactEditor.focus(editor);
|
41
|
+
setShowOptions(prev => !prev);
|
42
|
+
};
|
43
|
+
const handleFormSubmit = e => {
|
44
|
+
e.preventDefault();
|
45
|
+
if (!validHex) return;
|
46
|
+
selection && Transforms.select(editor, selection);
|
47
|
+
addMarkData(editor, {
|
48
|
+
format,
|
49
|
+
value: hexValue
|
50
|
+
});
|
51
|
+
setShowOptions(false);
|
52
|
+
setValidHex("");
|
53
|
+
setHexValue("");
|
54
|
+
selection && ReactEditor.focus(editor);
|
55
|
+
};
|
56
|
+
const handleHexChange = e => {
|
57
|
+
e.preventDefault();
|
58
|
+
const newHex = e.target.value;
|
59
|
+
setValidHex(isValideHexSix.test(newHex) || isValideHexThree.test(newHex));
|
60
|
+
setHexValue(newHex);
|
61
|
+
};
|
62
|
+
return /*#__PURE__*/React.createElement("div", {
|
63
|
+
className: "color-picker popup-wrapper",
|
64
|
+
ref: colorPickerRef
|
65
|
+
}, /*#__PURE__*/React.createElement("button", {
|
66
|
+
style: {
|
67
|
+
color: showOptions ? "black" : activeMark(editor, format),
|
68
|
+
opacity: "1"
|
69
|
+
},
|
70
|
+
className: showOptions ? "clicked" : "",
|
71
|
+
onClick: toggleOption
|
72
|
+
}, logo[format]), showOptions && /*#__PURE__*/React.createElement("div", {
|
73
|
+
className: "popup"
|
74
|
+
}, /*#__PURE__*/React.createElement("div", {
|
75
|
+
className: "color-options"
|
76
|
+
}, colors.map((color, index) => {
|
77
|
+
return /*#__PURE__*/React.createElement("div", {
|
78
|
+
key: index,
|
79
|
+
"data-value": color,
|
80
|
+
onClick: changeColor,
|
81
|
+
className: "option",
|
82
|
+
style: {
|
83
|
+
background: color
|
84
|
+
}
|
85
|
+
});
|
86
|
+
})), /*#__PURE__*/React.createElement("p", {
|
87
|
+
style: {
|
88
|
+
textAlign: "center",
|
89
|
+
opacity: "0.7",
|
90
|
+
width: "100%"
|
91
|
+
}
|
92
|
+
}, "OR"), /*#__PURE__*/React.createElement("form", {
|
93
|
+
onSubmit: handleFormSubmit
|
94
|
+
}, /*#__PURE__*/React.createElement("div", {
|
95
|
+
className: "hexPreview",
|
96
|
+
style: {
|
97
|
+
background: validHex ? hexValue : "#000000"
|
98
|
+
}
|
99
|
+
}), /*#__PURE__*/React.createElement("input", {
|
100
|
+
type: "text",
|
101
|
+
placeholder: "#000000",
|
102
|
+
value: hexValue,
|
103
|
+
onChange: handleHexChange,
|
104
|
+
style: {
|
105
|
+
border: validHex === false ? "1px solid red" : "1px solid lightgray"
|
106
|
+
}
|
107
|
+
}), /*#__PURE__*/React.createElement("button", {
|
108
|
+
style: {
|
109
|
+
color: validHex ? "green" : ""
|
110
|
+
},
|
111
|
+
type: "submit"
|
112
|
+
}, /*#__PURE__*/React.createElement(MdCheck, {
|
113
|
+
size: 20
|
114
|
+
})))));
|
115
|
+
};
|
116
|
+
export default ColorPicker;
|
@@ -0,0 +1 @@
|
|
1
|
+
export const colors = ["#000000", "#e60000", "#ff9900", "#ffff00", "#008a00", "#0066cc", "#9933ff", "#ffffff", "#facccc", "#ffebcc", "#ffffcc", "#cce8cc", "#cce0f5", "#ebd6ff", "#bbbbbb", "#f06666", "#ffc266", "#ffff66", "#66b966", "#66a3e0", "#c285ff", "#888888", "#a10000", "#b26b00", "#b2b200", "#006100", "#0047b2", "#6b24b2", "#444444", "#5c0000", "#663d00", "#666600", "#003700", "#002966", "#3d1466"];
|
@@ -0,0 +1,94 @@
|
|
1
|
+
import React, { useRef, useState } from 'react';
|
2
|
+
import Button from '../../common/Button';
|
3
|
+
import Icon from '../../common/Icon';
|
4
|
+
import { isBlockActive } from '../../utils/SlateUtilityFunctions';
|
5
|
+
import usePopup from '../../utils/customHooks/usePopup';
|
6
|
+
import { insertEmbed } from '../../utils/embed.js';
|
7
|
+
import { Transforms } from 'slate';
|
8
|
+
import { ReactEditor } from 'slate-react';
|
9
|
+
import './Embed.css';
|
10
|
+
const Embed = ({
|
11
|
+
editor,
|
12
|
+
format
|
13
|
+
}) => {
|
14
|
+
const urlInputRef = useRef();
|
15
|
+
const [showInput, setShowInput] = usePopup(urlInputRef);
|
16
|
+
const [formData, setFormData] = useState({
|
17
|
+
url: '',
|
18
|
+
alt: ''
|
19
|
+
});
|
20
|
+
const [selection, setSelection] = useState();
|
21
|
+
const handleButtonClick = e => {
|
22
|
+
e.preventDefault();
|
23
|
+
setSelection(editor.selection);
|
24
|
+
selection && ReactEditor.focus(editor);
|
25
|
+
setShowInput(prev => !prev);
|
26
|
+
};
|
27
|
+
const handleFormSubmit = e => {
|
28
|
+
e.preventDefault();
|
29
|
+
selection && Transforms.select(editor, selection);
|
30
|
+
selection && ReactEditor.focus(editor);
|
31
|
+
insertEmbed(editor, {
|
32
|
+
...formData
|
33
|
+
}, format);
|
34
|
+
setShowInput(false);
|
35
|
+
setFormData({
|
36
|
+
url: '',
|
37
|
+
alt: ''
|
38
|
+
});
|
39
|
+
};
|
40
|
+
const handleImageUpload = () => {
|
41
|
+
setShowInput(false);
|
42
|
+
};
|
43
|
+
return /*#__PURE__*/React.createElement("div", {
|
44
|
+
ref: urlInputRef,
|
45
|
+
className: "popup-wrapper"
|
46
|
+
}, /*#__PURE__*/React.createElement(Button, {
|
47
|
+
active: isBlockActive(editor, format),
|
48
|
+
style: {
|
49
|
+
border: showInput ? '1px solid lightgray' : '',
|
50
|
+
borderBottom: 'none'
|
51
|
+
},
|
52
|
+
format: format,
|
53
|
+
onClick: handleButtonClick
|
54
|
+
}, /*#__PURE__*/React.createElement(Icon, {
|
55
|
+
icon: format
|
56
|
+
})), showInput && /*#__PURE__*/React.createElement("div", {
|
57
|
+
className: "popup"
|
58
|
+
}, format === 'image' && /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", {
|
59
|
+
style: {
|
60
|
+
display: 'flex',
|
61
|
+
gap: '10px'
|
62
|
+
},
|
63
|
+
onClick: handleImageUpload
|
64
|
+
}, /*#__PURE__*/React.createElement(Icon, {
|
65
|
+
icon: "upload"
|
66
|
+
}), /*#__PURE__*/React.createElement("span", null, "Upload")), /*#__PURE__*/React.createElement("p", {
|
67
|
+
style: {
|
68
|
+
textAlign: 'center',
|
69
|
+
opacity: '0.7',
|
70
|
+
width: '100%'
|
71
|
+
}
|
72
|
+
}, "OR")), /*#__PURE__*/React.createElement("form", {
|
73
|
+
onSubmit: handleFormSubmit
|
74
|
+
}, /*#__PURE__*/React.createElement("input", {
|
75
|
+
type: "text",
|
76
|
+
placeholder: "Enter url",
|
77
|
+
value: formData.url,
|
78
|
+
onChange: e => setFormData(prev => ({
|
79
|
+
...prev,
|
80
|
+
url: e.target.value
|
81
|
+
}))
|
82
|
+
}), /*#__PURE__*/React.createElement("input", {
|
83
|
+
type: "text",
|
84
|
+
placeholder: "Enter alt",
|
85
|
+
value: formData.alt,
|
86
|
+
onChange: e => setFormData(prev => ({
|
87
|
+
...prev,
|
88
|
+
alt: e.target.value
|
89
|
+
}))
|
90
|
+
}), /*#__PURE__*/React.createElement(Button, {
|
91
|
+
type: "submit"
|
92
|
+
}, "Save"))));
|
93
|
+
};
|
94
|
+
export default Embed;
|
@@ -0,0 +1,70 @@
|
|
1
|
+
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
2
|
+
import React, { useEffect, useState } from "react";
|
3
|
+
import { useSlateStatic, useSelected, useFocused, ReactEditor } from "slate-react";
|
4
|
+
import { Node, Transforms } from "slate";
|
5
|
+
import Icon from "../../common/Icon";
|
6
|
+
import useResize from "../../utils/customHooks/useResize.js";
|
7
|
+
const Image = ({
|
8
|
+
attributes,
|
9
|
+
element,
|
10
|
+
children
|
11
|
+
}) => {
|
12
|
+
const {
|
13
|
+
url,
|
14
|
+
alt
|
15
|
+
} = element;
|
16
|
+
const editor = useSlateStatic();
|
17
|
+
const selected = useSelected();
|
18
|
+
const focused = useFocused();
|
19
|
+
const [parentDOM, setParentDOM] = useState(null);
|
20
|
+
const [size, onMouseDown, resizing, onLoad] = useResize({
|
21
|
+
parentDOM,
|
22
|
+
size: element?.size
|
23
|
+
});
|
24
|
+
const arr = Array.from(Node.elements(editor));
|
25
|
+
const ele = arr.find(([elem]) => element === elem);
|
26
|
+
useEffect(() => {
|
27
|
+
if (editor && ele[1] !== undefined) {
|
28
|
+
const dom = ReactEditor.toDOMNode(editor, Node.get(editor, ele[1]));
|
29
|
+
setParentDOM(dom);
|
30
|
+
onLoad(dom);
|
31
|
+
}
|
32
|
+
}, []);
|
33
|
+
useEffect(() => {
|
34
|
+
if (!resizing) {
|
35
|
+
Transforms.setNodes(editor, {
|
36
|
+
size: size
|
37
|
+
});
|
38
|
+
}
|
39
|
+
}, [resizing]);
|
40
|
+
return /*#__PURE__*/React.createElement("div", _extends({}, attributes, {
|
41
|
+
className: "embed",
|
42
|
+
style: {
|
43
|
+
display: "flex",
|
44
|
+
width: "100%",
|
45
|
+
maxWidth: "100%",
|
46
|
+
boxShadow: selected && focused && "0 0 3px 3px lightgray"
|
47
|
+
}
|
48
|
+
}, element.attr), /*#__PURE__*/React.createElement("div", {
|
49
|
+
contentEditable: false,
|
50
|
+
style: {
|
51
|
+
position: "relative",
|
52
|
+
width: size.widthInPercent ? `${size.widthInPercent}%` : `${size.width}px`,
|
53
|
+
height: `${size.height}px`
|
54
|
+
}
|
55
|
+
}, /*#__PURE__*/React.createElement("img", {
|
56
|
+
alt: alt,
|
57
|
+
src: url
|
58
|
+
}), selected && /*#__PURE__*/React.createElement("button", {
|
59
|
+
onPointerDown: onMouseDown,
|
60
|
+
style: {
|
61
|
+
width: "15px",
|
62
|
+
height: "15px",
|
63
|
+
opacity: 1,
|
64
|
+
background: "transparent"
|
65
|
+
}
|
66
|
+
}, /*#__PURE__*/React.createElement(Icon, {
|
67
|
+
icon: "resize"
|
68
|
+
}))), children);
|
69
|
+
};
|
70
|
+
export default Image;
|
@@ -0,0 +1,62 @@
|
|
1
|
+
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
2
|
+
import React from "react";
|
3
|
+
import { useSelected, useFocused } from "slate-react";
|
4
|
+
import Icon from "../../common/Icon";
|
5
|
+
import useResize from "../../utils/customHooks/useResize.js";
|
6
|
+
// import "./Video.css";
|
7
|
+
|
8
|
+
const Video = ({
|
9
|
+
attributes,
|
10
|
+
element,
|
11
|
+
children
|
12
|
+
}) => {
|
13
|
+
const {
|
14
|
+
url,
|
15
|
+
alt
|
16
|
+
} = element;
|
17
|
+
const [size, onMouseDown, resizing] = useResize();
|
18
|
+
const selected = useSelected();
|
19
|
+
const focused = useFocused();
|
20
|
+
return /*#__PURE__*/React.createElement("div", _extends({}, attributes, {
|
21
|
+
className: "embed",
|
22
|
+
style: {
|
23
|
+
display: "flex",
|
24
|
+
boxShadow: selected && focused && "0 0 3px 3px lightgray"
|
25
|
+
}
|
26
|
+
}, element.attr), /*#__PURE__*/React.createElement("div", {
|
27
|
+
contentEditable: false,
|
28
|
+
style: {
|
29
|
+
width: `${size.width}px`,
|
30
|
+
height: `${size.height}px`
|
31
|
+
}
|
32
|
+
},
|
33
|
+
// The iframe reloads on each re-render and hence it stutters and the document doesn't detect mouse-up event leading to unwanted behaviour
|
34
|
+
// So during resize replace the iframe with a simple div
|
35
|
+
resizing ? /*#__PURE__*/React.createElement("div", {
|
36
|
+
style: {
|
37
|
+
width: "100%",
|
38
|
+
height: "100%",
|
39
|
+
border: "2px dashed black",
|
40
|
+
display: "flex",
|
41
|
+
justifyContent: "center",
|
42
|
+
alignItems: "center"
|
43
|
+
}
|
44
|
+
}, /*#__PURE__*/React.createElement(Icon, {
|
45
|
+
icon: "videoPlayer"
|
46
|
+
})) : /*#__PURE__*/React.createElement("iframe", {
|
47
|
+
src: url,
|
48
|
+
frameBorder: "0",
|
49
|
+
title: alt
|
50
|
+
}), selected && /*#__PURE__*/React.createElement("button", {
|
51
|
+
onMouseDown: onMouseDown,
|
52
|
+
style: {
|
53
|
+
width: "15px",
|
54
|
+
height: "15px",
|
55
|
+
opacity: 1,
|
56
|
+
background: "transparent"
|
57
|
+
}
|
58
|
+
}, /*#__PURE__*/React.createElement(Icon, {
|
59
|
+
icon: "resize"
|
60
|
+
}))), children);
|
61
|
+
};
|
62
|
+
export default Video;
|
@@ -0,0 +1,24 @@
|
|
1
|
+
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
2
|
+
import React from "react";
|
3
|
+
import { InlineMath, BlockMath } from "react-katex";
|
4
|
+
import "./styles.css";
|
5
|
+
const Equation = ({
|
6
|
+
attributes,
|
7
|
+
element,
|
8
|
+
children
|
9
|
+
}) => {
|
10
|
+
const {
|
11
|
+
inline,
|
12
|
+
math
|
13
|
+
} = element;
|
14
|
+
return /*#__PURE__*/React.createElement("div", {
|
15
|
+
className: inline ? "equation-inline" : ""
|
16
|
+
}, /*#__PURE__*/React.createElement("span", _extends({}, attributes, element.attr), /*#__PURE__*/React.createElement("span", {
|
17
|
+
contentEditable: false
|
18
|
+
}, inline ? /*#__PURE__*/React.createElement(InlineMath, {
|
19
|
+
math: math
|
20
|
+
}) : /*#__PURE__*/React.createElement(BlockMath, {
|
21
|
+
math: math
|
22
|
+
})), children));
|
23
|
+
};
|
24
|
+
export default Equation;
|
@@ -0,0 +1,66 @@
|
|
1
|
+
import { useRef, useState } from 'react';
|
2
|
+
import Button from '../../common/Button';
|
3
|
+
import Icon from '../../common/Icon';
|
4
|
+
import usePopup from '../../utils/customHooks/usePopup';
|
5
|
+
import { insertEquation } from '../../utils/equation.js';
|
6
|
+
import { Transforms } from 'slate';
|
7
|
+
const EquationButton = ({
|
8
|
+
editor
|
9
|
+
}) => {
|
10
|
+
const equationInputRef = useRef(null);
|
11
|
+
const [showInput, setShowInput] = usePopup(equationInputRef);
|
12
|
+
const [math, setMath] = useState('');
|
13
|
+
const [displayInline, setDisplayInline] = useState(false);
|
14
|
+
const [selection, setSelection] = useState();
|
15
|
+
const toggleButton = () => {
|
16
|
+
setShowInput(prev => !prev);
|
17
|
+
setDisplayInline(false);
|
18
|
+
setSelection(editor.selection);
|
19
|
+
};
|
20
|
+
const handleInputChange = ({
|
21
|
+
target
|
22
|
+
}) => {
|
23
|
+
if (target.type === 'checkbox') {
|
24
|
+
setDisplayInline(prev => !prev);
|
25
|
+
} else {
|
26
|
+
setMath(target.value);
|
27
|
+
}
|
28
|
+
};
|
29
|
+
const handleAddEquation = () => {
|
30
|
+
if (!math) return;
|
31
|
+
selection && Transforms.select(editor, selection);
|
32
|
+
insertEquation(editor, math, displayInline);
|
33
|
+
console.log('btn click');
|
34
|
+
setShowInput(false);
|
35
|
+
};
|
36
|
+
return /*#__PURE__*/React.createElement("div", {
|
37
|
+
ref: equationInputRef,
|
38
|
+
className: "popup-wrapper"
|
39
|
+
}, /*#__PURE__*/React.createElement(Button, {
|
40
|
+
format: "equation",
|
41
|
+
onClick: toggleButton
|
42
|
+
}, /*#__PURE__*/React.createElement(Icon, {
|
43
|
+
icon: "equation"
|
44
|
+
})), showInput && /*#__PURE__*/React.createElement("div", {
|
45
|
+
className: "popup"
|
46
|
+
}, /*#__PURE__*/React.createElement("div", {
|
47
|
+
style: {
|
48
|
+
display: 'flex',
|
49
|
+
gap: '5px'
|
50
|
+
}
|
51
|
+
}, /*#__PURE__*/React.createElement("input", {
|
52
|
+
type: "text",
|
53
|
+
value: math,
|
54
|
+
onChange: handleInputChange,
|
55
|
+
placeholder: "Enter formula"
|
56
|
+
}), /*#__PURE__*/React.createElement("div", {
|
57
|
+
onClick: handleAddEquation
|
58
|
+
}, /*#__PURE__*/React.createElement(Icon, {
|
59
|
+
icon: "add"
|
60
|
+
}))), /*#__PURE__*/React.createElement("label", null, /*#__PURE__*/React.createElement("input", {
|
61
|
+
type: "checkbox",
|
62
|
+
checked: displayInline,
|
63
|
+
onChange: handleInputChange
|
64
|
+
}), "Inline Equation")));
|
65
|
+
};
|
66
|
+
export default EquationButton;
|
@@ -0,0 +1,53 @@
|
|
1
|
+
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
2
|
+
import React from "react";
|
3
|
+
import { Transforms, Path } from "slate";
|
4
|
+
import { useSelected, useSlateStatic } from "slate-react";
|
5
|
+
import { gridItem } from "../../utils/gridItem";
|
6
|
+
const Grid = props => {
|
7
|
+
const {
|
8
|
+
attributes,
|
9
|
+
children,
|
10
|
+
element
|
11
|
+
} = props;
|
12
|
+
const {
|
13
|
+
grid
|
14
|
+
} = element;
|
15
|
+
const editor = useSlateStatic();
|
16
|
+
const selected = useSelected();
|
17
|
+
const onAddGridItem = () => {
|
18
|
+
const currentPath = editor.selection?.anchor?.path;
|
19
|
+
const ancestorsPath = Path.ancestors(currentPath, {
|
20
|
+
reverse: true
|
21
|
+
});
|
22
|
+
const insertPath = ancestorsPath[1];
|
23
|
+
if (insertPath) {
|
24
|
+
insertPath[insertPath.length - 1] = element.children.length;
|
25
|
+
Transforms.insertNodes(editor, [{
|
26
|
+
...gridItem()
|
27
|
+
}], {
|
28
|
+
at: insertPath
|
29
|
+
});
|
30
|
+
// new line
|
31
|
+
Transforms.insertNodes(editor, [{
|
32
|
+
type: "paragraph",
|
33
|
+
children: [{
|
34
|
+
text: ""
|
35
|
+
}]
|
36
|
+
}], {
|
37
|
+
at: [editor.children.length]
|
38
|
+
});
|
39
|
+
}
|
40
|
+
};
|
41
|
+
const GridToolBar = () => {
|
42
|
+
return selected ? /*#__PURE__*/React.createElement("div", {
|
43
|
+
className: "grid-container-toolbar",
|
44
|
+
contentEditable: false
|
45
|
+
}, /*#__PURE__*/React.createElement("button", {
|
46
|
+
onClick: onAddGridItem
|
47
|
+
}, "+ Add Item")) : null;
|
48
|
+
};
|
49
|
+
return /*#__PURE__*/React.createElement("div", _extends({
|
50
|
+
className: `grid-container ${grid}`
|
51
|
+
}, attributes), /*#__PURE__*/React.createElement(GridToolBar, null), children);
|
52
|
+
};
|
53
|
+
export default Grid;
|
@@ -0,0 +1,19 @@
|
|
1
|
+
import React from "react";
|
2
|
+
import ViewComfyIcon from "@mui/icons-material/ViewComfy";
|
3
|
+
import { insertGrid } from "../../utils/grid";
|
4
|
+
const GridButton = props => {
|
5
|
+
const {
|
6
|
+
editor
|
7
|
+
} = props;
|
8
|
+
const handleInsertGrid = () => {
|
9
|
+
insertGrid(editor);
|
10
|
+
};
|
11
|
+
return /*#__PURE__*/React.createElement("button", {
|
12
|
+
onClick: handleInsertGrid,
|
13
|
+
title: "Layout",
|
14
|
+
style: {
|
15
|
+
marginLeft: "8px"
|
16
|
+
}
|
17
|
+
}, /*#__PURE__*/React.createElement(ViewComfyIcon, null));
|
18
|
+
};
|
19
|
+
export default GridButton;
|
@@ -0,0 +1,53 @@
|
|
1
|
+
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
2
|
+
import React from "react";
|
3
|
+
import { Transforms, Element } from "slate";
|
4
|
+
import { useSelected, useSlateStatic } from "slate-react";
|
5
|
+
const GridItem = props => {
|
6
|
+
const {
|
7
|
+
attributes,
|
8
|
+
children,
|
9
|
+
element
|
10
|
+
} = props;
|
11
|
+
const {
|
12
|
+
grid
|
13
|
+
} = element;
|
14
|
+
const editor = useSlateStatic();
|
15
|
+
const selected = useSelected();
|
16
|
+
const itemWidth = (grid || 6) / 12 * 100;
|
17
|
+
const onItemSizeDecrease = () => {
|
18
|
+
Transforms.setNodes(editor, {
|
19
|
+
grid: grid <= 1 ? 1 : grid - 1
|
20
|
+
}, {
|
21
|
+
match: node => {
|
22
|
+
return Element.matches(node, element);
|
23
|
+
}
|
24
|
+
});
|
25
|
+
};
|
26
|
+
const onItemSizeIncrease = () => {
|
27
|
+
Transforms.setNodes(editor, {
|
28
|
+
grid: grid >= 12 ? 12 : grid + 1
|
29
|
+
}, {
|
30
|
+
match: node => {
|
31
|
+
return Element.matches(node, element);
|
32
|
+
}
|
33
|
+
});
|
34
|
+
};
|
35
|
+
const GridItemToolbar = () => {
|
36
|
+
return selected ? /*#__PURE__*/React.createElement("div", {
|
37
|
+
contentEditable: false,
|
38
|
+
className: "grid-item-toolbar"
|
39
|
+
}, /*#__PURE__*/React.createElement("button", {
|
40
|
+
onClick: onItemSizeDecrease
|
41
|
+
}, "-"), /*#__PURE__*/React.createElement("button", {
|
42
|
+
onClick: onItemSizeIncrease
|
43
|
+
}, "+")) : null;
|
44
|
+
};
|
45
|
+
return /*#__PURE__*/React.createElement("div", _extends({
|
46
|
+
className: `grid-item xs-${grid}`
|
47
|
+
}, attributes, {
|
48
|
+
style: {
|
49
|
+
width: `${itemWidth}%`
|
50
|
+
}
|
51
|
+
}), children, /*#__PURE__*/React.createElement(GridItemToolbar, null));
|
52
|
+
};
|
53
|
+
export default GridItem;
|
@@ -0,0 +1,56 @@
|
|
1
|
+
import { Transforms } from "slate";
|
2
|
+
import React, { useRef, useState } from "react";
|
3
|
+
import Button from "../../common/Button";
|
4
|
+
import Icon from "../../common/Icon";
|
5
|
+
import usePopup from "../../utils/customHooks/usePopup";
|
6
|
+
const Id = ({
|
7
|
+
editor
|
8
|
+
}) => {
|
9
|
+
const idInputRef = useRef(null);
|
10
|
+
const [showInput, setShowInput] = usePopup(idInputRef);
|
11
|
+
const [selection, setSelection] = useState();
|
12
|
+
const [id, setId] = useState("");
|
13
|
+
const toggleId = () => {
|
14
|
+
setSelection(editor.selection);
|
15
|
+
setShowInput(prev => !prev);
|
16
|
+
};
|
17
|
+
const handleId = () => {
|
18
|
+
// selection && Transforms.select(editor,selection);
|
19
|
+
if (!selection || !id) return;
|
20
|
+
Transforms.setNodes(editor, {
|
21
|
+
attr: {
|
22
|
+
id
|
23
|
+
}
|
24
|
+
}, {
|
25
|
+
at: selection
|
26
|
+
});
|
27
|
+
setShowInput(false);
|
28
|
+
setId("");
|
29
|
+
};
|
30
|
+
return /*#__PURE__*/React.createElement("div", {
|
31
|
+
className: "popup-wrapper",
|
32
|
+
ref: idInputRef
|
33
|
+
}, /*#__PURE__*/React.createElement(Button, {
|
34
|
+
className: showInput ? "clicked" : "",
|
35
|
+
format: "add Id",
|
36
|
+
onClick: toggleId
|
37
|
+
}, /*#__PURE__*/React.createElement(Icon, {
|
38
|
+
icon: "addId"
|
39
|
+
})), showInput && /*#__PURE__*/React.createElement("div", {
|
40
|
+
className: "popup",
|
41
|
+
style: {
|
42
|
+
display: "flex",
|
43
|
+
gap: "4px"
|
44
|
+
}
|
45
|
+
}, /*#__PURE__*/React.createElement("input", {
|
46
|
+
type: "text",
|
47
|
+
placeholder: "Enter an unique ID",
|
48
|
+
value: id,
|
49
|
+
onChange: e => setId(e.target.value)
|
50
|
+
}), /*#__PURE__*/React.createElement("div", {
|
51
|
+
onClick: handleId
|
52
|
+
}, /*#__PURE__*/React.createElement(Icon, {
|
53
|
+
icon: "add"
|
54
|
+
}))));
|
55
|
+
};
|
56
|
+
export default Id;
|
@@ -0,0 +1,34 @@
|
|
1
|
+
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
2
|
+
import React from 'react';
|
3
|
+
import { useFocused, useSelected, useSlateStatic } from 'slate-react';
|
4
|
+
import { removeLink } from '../../utils/link.js';
|
5
|
+
import unlink from '../../Toolbar/toolbarIcons/unlink.svg';
|
6
|
+
import './styles.css';
|
7
|
+
const Link = ({
|
8
|
+
attributes,
|
9
|
+
element,
|
10
|
+
children
|
11
|
+
}) => {
|
12
|
+
const editor = useSlateStatic();
|
13
|
+
const selected = useSelected();
|
14
|
+
const focused = useFocused();
|
15
|
+
return /*#__PURE__*/React.createElement("div", {
|
16
|
+
className: "link"
|
17
|
+
}, /*#__PURE__*/React.createElement("a", _extends({
|
18
|
+
href: element.href
|
19
|
+
}, attributes, element.attr, {
|
20
|
+
target: element.target
|
21
|
+
}), children), selected && focused && /*#__PURE__*/React.createElement("div", {
|
22
|
+
className: "link-popup",
|
23
|
+
contentEditable: false
|
24
|
+
}, /*#__PURE__*/React.createElement("a", {
|
25
|
+
href: element.href,
|
26
|
+
target: element.target
|
27
|
+
}, element.href), /*#__PURE__*/React.createElement("button", {
|
28
|
+
onClick: () => removeLink(editor)
|
29
|
+
}, /*#__PURE__*/React.createElement("img", {
|
30
|
+
src: unlink,
|
31
|
+
alt: ""
|
32
|
+
}))));
|
33
|
+
};
|
34
|
+
export default Link;
|