@flozy/editor 1.7.1 → 1.7.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -2,7 +2,6 @@
2
2
  import React, { useRef, useCallback, useEffect, useMemo, useState, forwardRef, useImperativeHandle } from "react";
3
3
  import { createEditor, Transforms } from "slate";
4
4
  import { Slate, Editable, ReactEditor } from "slate-react";
5
- import { DndContext, DragOverlay } from "@dnd-kit/core";
6
5
  import { useDebounce } from "use-debounce";
7
6
  import { getMarked, getBlock } from "./utils/SlateUtilityFunctions";
8
7
  import CodeToText from "./Elements/CodeToText/CodeToText";
@@ -13,9 +12,9 @@ import { RemoteCursorOverlay } from "./RemoteCursorOverlay/Overlay";
13
12
  import { mentionsEvent, commands, indentation, escapeEvent } from "./utils/events";
14
13
  import withCommon from "./hooks/withCommon";
15
14
  import DialogWrapper from "./DialogWrapper";
16
- import { serialize } from "./utils/serializer";
15
+ import { serializeToText } from "./utils/serializeToText";
17
16
  import { getPageSettings } from "./utils/pageSettings";
18
- import { customCollisionDetectionAlgorithm, getThumbnailImage } from "./helper";
17
+ import { getThumbnailImage } from "./helper";
19
18
  import PopupTool from "./Toolbar/PopupTool";
20
19
  import "./font.css";
21
20
  import "./Editor.css";
@@ -25,8 +24,9 @@ import MiniToolbar from "./Toolbar/Mini/MiniToolbar";
25
24
  import { EditorProvider } from "./hooks/useMouseMove";
26
25
  import TopBanner from "./Elements/TopBanner/TopBanner";
27
26
  import editorStyles from "./Styles/EditorStyles";
27
+ import DragHandle from "./common/DnD/DragHandle";
28
+ import DragAndDrop from "./common/DnD";
28
29
  import "animate.css";
29
- import Section from "./Elements/Section";
30
30
  import { jsx as _jsx } from "react/jsx-runtime";
31
31
  import { jsxs as _jsxs } from "react/jsx-runtime";
32
32
  const PREVIEW_IMAGE_HIDE_CLASS = ["grid-container-toolbar", "grid-item-toolbar", "element-toolbar"];
@@ -135,12 +135,12 @@ const CommonEditor = /*#__PURE__*/forwardRef((props, ref) => {
135
135
  }
136
136
  }, [deboundedValue]);
137
137
  const getOnSaveData = val => {
138
- const text = serialize(val);
138
+ const text = serializeToText(val);
139
139
  const title = val?.find(f => f.type === "title");
140
140
  return {
141
141
  value: JSON.stringify(val),
142
142
  text: text,
143
- title: serialize(title?.children) || "Untitled"
143
+ title: serializeToText(title?.children) || "Untitled"
144
144
  };
145
145
  };
146
146
  const getPreviewImage = async (needBackground = false, options = {}) => {
@@ -299,61 +299,6 @@ const CommonEditor = /*#__PURE__*/forwardRef((props, ref) => {
299
299
  });
300
300
  }
301
301
  }, [chars, editor, target, mentions, setMentions, search, type, mentionsRef]);
302
- const handleDragStart = e => {
303
- try {
304
- const {
305
- active: {
306
- data: {
307
- current: {
308
- element
309
- }
310
- }
311
- }
312
- } = e;
313
- const dragEle = ReactEditor.toDOMNode(editor, element);
314
- const {
315
- width,
316
- height
317
- } = dragEle.getBoundingClientRect();
318
- setDrag({
319
- style: {
320
- width,
321
- height
322
- },
323
- dom: dragEle.outerHTML
324
- });
325
- } catch (err) {
326
- console.log(err);
327
- }
328
- };
329
- const handleDragEnd = e => {
330
- try {
331
- const {
332
- active: {
333
- data: {
334
- current: {
335
- element,
336
- onDragEnd
337
- }
338
- }
339
- },
340
- over: {
341
- data: {
342
- current: {
343
- onDrop
344
- }
345
- }
346
- }
347
- } = e;
348
- onDrop(JSON.stringify(element));
349
- setTimeout(() => {
350
- onDragEnd();
351
- }, 100);
352
- setDrag(null);
353
- } catch (err) {
354
- console.log(err);
355
- }
356
- };
357
302
  const Overlay = collaborativeEditor && !isReadOnly ? RemoteCursorOverlay : React.Fragment;
358
303
  const dotBg = needDotsBG ? {
359
304
  background: "white",
@@ -389,11 +334,8 @@ const CommonEditor = /*#__PURE__*/forwardRef((props, ref) => {
389
334
  editor: editor,
390
335
  initialValue: value,
391
336
  onChange: handleEditorChange,
392
- children: [/*#__PURE__*/_jsxs(DndContext, {
393
- collisionDetection: customCollisionDetectionAlgorithm,
394
- onDragStart: handleDragStart,
395
- onDragEnd: handleDragEnd,
396
- children: [/*#__PURE__*/_jsx(Overlay, {
337
+ children: [/*#__PURE__*/_jsx(DragAndDrop, {
338
+ children: /*#__PURE__*/_jsx(Overlay, {
397
339
  children: /*#__PURE__*/_jsx(Box, {
398
340
  className: `${hasTopBanner() ? "has-topbanner" : ""}`,
399
341
  sx: classes.slateWrapper,
@@ -448,19 +390,7 @@ const CommonEditor = /*#__PURE__*/forwardRef((props, ref) => {
448
390
  }) : null]
449
391
  })
450
392
  })
451
- }), /*#__PURE__*/_jsx(DragOverlay, {
452
- className: "drag-overlay",
453
- style: {
454
- ...(drag?.style || {})
455
- },
456
- children: drag ? /*#__PURE__*/_jsx(Item, {
457
- children: /*#__PURE__*/_jsx("div", {
458
- dangerouslySetInnerHTML: {
459
- __html: drag?.dom
460
- }
461
- })
462
- }) : null
463
- })]
393
+ })
464
394
  }), htmlAction.showInput && /*#__PURE__*/_jsx(CodeToText, {
465
395
  ...htmlAction,
466
396
  handleCodeToText: handleCodeToText
@@ -413,6 +413,14 @@ blockquote {
413
413
  width: auto !important;
414
414
  }
415
415
 
416
+ .MuiButton-root.primaryBtn.disabled,
417
+ .MuiButton-root.secondaryBtn.disabled {
418
+ background: #eee !important;
419
+ color: #ccc !important;
420
+ border: 1px solid #ccc !important;
421
+
422
+ }
423
+
416
424
  .MuiButton-root.secondaryBtn {
417
425
  background: #ffffff;
418
426
  border: 1px solid #2563eb !important;
@@ -823,6 +831,9 @@ blockquote {
823
831
  width: 200px;
824
832
  cursor: pointer;
825
833
  color:#464646;
834
+ background-color: #FFF;
835
+ padding: 4px 6px;
836
+ border-radius: 12px;
826
837
  span {
827
838
  text-transform: capitalize;
828
839
  }
@@ -8,6 +8,7 @@ import OpenInNewIcon from "@mui/icons-material/OpenInNew";
8
8
  import DeleteIcon from "@mui/icons-material/Delete";
9
9
  import ButtonPopup from "./ButtonPopup";
10
10
  import { actionButtonRedirect } from "../../service/actionTrigger";
11
+ import { WorkflowIcon } from "../../common/iconslist";
11
12
  import { jsx as _jsx } from "react/jsx-runtime";
12
13
  import { jsxs as _jsxs } from "react/jsx-runtime";
13
14
  const EditorButton = props => {
@@ -47,6 +48,7 @@ const EditorButton = props => {
47
48
  linkType,
48
49
  redirectOnURLResult
49
50
  } = buttonLink || {};
51
+ const isTrigger = linkType === "actionTrigger";
50
52
  const {
51
53
  topLeft,
52
54
  topRight,
@@ -62,7 +64,7 @@ const EditorButton = props => {
62
64
  const BtnIcon = buttonIcon ? fIcons[buttonIcon] : null;
63
65
  const onClick = async e => {
64
66
  if (readOnly) {
65
- if (linkType === "actionTrigger") {
67
+ if (isTrigger) {
66
68
  if (metadata?.buttonLink?.handler) {
67
69
  metadata.buttonLink.handler("click");
68
70
  } else if (redirectOnURLResult) {
@@ -162,7 +164,6 @@ const EditorButton = props => {
162
164
  sx: {
163
165
  background: bgColor || "rgb(30, 75, 122)",
164
166
  borderBlockStyle: "solid",
165
- // ...borderStyleColor,
166
167
  borderColor: borderColor || "transparent",
167
168
  borderWidth: borderWidth || "1px",
168
169
  borderRadius: `${topLeft}px ${topRight}px ${bottomLeft}px ${bottomRight}px`,
@@ -199,7 +200,10 @@ const EditorButton = props => {
199
200
  paddingLeft: "4px",
200
201
  paddingRight: "4px"
201
202
  }
202
- }), /*#__PURE__*/_jsx(Toolbar, {})]
203
+ }), !readOnly && isTrigger ? /*#__PURE__*/_jsx(IconButton, {
204
+ className: "workflow-icon-btn",
205
+ children: /*#__PURE__*/_jsx(WorkflowIcon, {})
206
+ }) : null, /*#__PURE__*/_jsx(Toolbar, {})]
203
207
  })
204
208
  }), /*#__PURE__*/_jsx("div", {
205
209
  contentEditable: false,
@@ -51,14 +51,14 @@ const Carousel = props => {
51
51
  }
52
52
  }, [edit]);
53
53
  const onAddSlide = () => {
54
- const insertPath = [path[0], children.length];
55
- if (insertPath[0] !== undefined) {
56
- insertPath[insertPath.length - 1] = element.children.length;
54
+ try {
57
55
  Transforms.insertNodes(editor, [{
58
56
  ...carouselItem()
59
57
  }], {
60
- at: insertPath
58
+ at: [...path, children.length]
61
59
  });
60
+ } catch (err) {
61
+ console.log(err);
62
62
  }
63
63
  };
64
64
  const onEdit = () => {
@@ -148,6 +148,7 @@ const Image = ({
148
148
  },
149
149
  ...element.attr,
150
150
  "data-path": path.join(","),
151
+ contentEditable: false,
151
152
  children: [openSetttings ? /*#__PURE__*/_jsx(EmbedPopup, {
152
153
  element: element,
153
154
  onSave: onSave,
@@ -188,7 +189,10 @@ const Image = ({
188
189
  className: "resize-br visible-on-hover",
189
190
  children: /*#__PURE__*/_jsx(AspectRatioIcon, {})
190
191
  })]
191
- }), children]
192
+ }), /*#__PURE__*/_jsx("span", {
193
+ contentEditable: false,
194
+ children: children
195
+ })]
192
196
  });
193
197
  };
194
198
  export default Image;
@@ -4,8 +4,7 @@ import { useSlateStatic, ReactEditor } from "slate-react";
4
4
  import { IconButton, Tooltip, Grid, Menu, MenuItem, CircularProgress } from "@mui/material";
5
5
  import DeleteIcon from "@mui/icons-material/Delete";
6
6
  import BackupIcon from "@mui/icons-material/Backup";
7
- import { GridSettingsIcon, GridAddSectionIcon } from "../../common/iconslist";
8
- import SendTimeExtensionIcon from '@mui/icons-material/SendTimeExtension';
7
+ import { GridSettingsIcon, GridAddSectionIcon, WorkflowIcon } from "../../common/iconslist";
9
8
  import FormPopup from "./FormPopup";
10
9
  import ButtonPopup from "../Button/ButtonPopup";
11
10
  import { formField } from "../../utils/formfield";
@@ -222,8 +221,9 @@ const Form = props => {
222
221
  title: "Workflow",
223
222
  arrow: true,
224
223
  children: /*#__PURE__*/_jsx(IconButton, {
224
+ className: "svg-big-btn",
225
225
  onClick: onWorkflow,
226
- children: /*#__PURE__*/_jsx(SendTimeExtensionIcon, {})
226
+ children: /*#__PURE__*/_jsx(WorkflowIcon, {})
227
227
  })
228
228
  })]
229
229
  });
@@ -1,7 +1,7 @@
1
1
  import React from "react";
2
2
  import { Grid, Radio, RadioGroup, Typography, FormControlLabel, Select, MenuItem, FormControl, TextField } from "@mui/material";
3
3
  import FormStyles from "./Styles";
4
- import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown';
4
+ import KeyboardArrowDownIcon from "@mui/icons-material/KeyboardArrowDown";
5
5
  import UserInputs from "./UserInputs";
6
6
  import { jsx as _jsx } from "react/jsx-runtime";
7
7
  import { jsxs as _jsxs } from "react/jsx-runtime";
@@ -61,26 +61,26 @@ const FormWorkflow = props => {
61
61
  value: schedule,
62
62
  defaultValue: 1,
63
63
  children: [/*#__PURE__*/_jsx(FormControlLabel, {
64
- value: 'immediately',
64
+ value: "immediately",
65
65
  label: "Immediately",
66
66
  onChange: () => {
67
- setSchedule('immediately');
67
+ setSchedule("immediately");
68
68
  },
69
69
  control: /*#__PURE__*/_jsx(Radio, {
70
70
  size: "small"
71
71
  })
72
72
  }), /*#__PURE__*/_jsx(FormControlLabel, {
73
- value: 'after',
73
+ value: "after",
74
74
  label: "After",
75
75
  onChange: () => {
76
- setSchedule('after');
76
+ setSchedule("after");
77
77
  },
78
78
  control: /*#__PURE__*/_jsx(Radio, {
79
79
  size: "small"
80
80
  })
81
81
  })]
82
82
  })
83
- }), schedule === 'after' && /*#__PURE__*/_jsx(Grid, {
83
+ }), schedule === "after" && /*#__PURE__*/_jsx(Grid, {
84
84
  item: true,
85
85
  children: /*#__PURE__*/_jsxs(Grid, {
86
86
  container: true,
@@ -113,19 +113,19 @@ const FormWorkflow = props => {
113
113
  sx: classes.select,
114
114
  IconComponent: KeyboardArrowDownIcon,
115
115
  style: {
116
- minWidth: '160px'
116
+ minWidth: "160px"
117
117
  },
118
118
  children: [/*#__PURE__*/_jsx(MenuItem, {
119
119
  sx: classes.selectList,
120
- value: 'min',
120
+ value: "min",
121
121
  children: "Minutes"
122
122
  }), /*#__PURE__*/_jsx(MenuItem, {
123
123
  sx: classes.selectList,
124
- value: 'hr',
124
+ value: "hr",
125
125
  children: "Hours"
126
126
  }), /*#__PURE__*/_jsx(MenuItem, {
127
127
  sx: classes.selectList,
128
- value: 'day',
128
+ value: "day",
129
129
  children: "Day"
130
130
  })]
131
131
  })
@@ -149,11 +149,11 @@ const FormWorkflow = props => {
149
149
  maxRows: 5,
150
150
  sx: {
151
151
  "& fieldset": {
152
- border: '1px solid #6F6F6F33',
152
+ border: "1px solid #6F6F6F33",
153
153
  borderRadius: "8px"
154
154
  },
155
155
  "& textarea": {
156
- fontSize: '16px',
156
+ fontSize: "16px",
157
157
  fontWeight: 500
158
158
  },
159
159
  "& textarea:focus-visible": {
@@ -13,7 +13,8 @@ const FormStyles = () => ({
13
13
  border: "none",
14
14
  width: "100%",
15
15
  maxWidth: "100%",
16
- outline: "none"
16
+ outline: "none",
17
+ padding: "12px"
17
18
  },
18
19
  "& textarea:focus-visible": {
19
20
  outline: "none",
@@ -1,11 +1,11 @@
1
1
  import React, { useEffect, useState } from "react";
2
2
  import { Button, Dialog, DialogActions, DialogContent, DialogTitle, IconButton } from "@mui/material";
3
- import ArrowBackIcon from '@mui/icons-material/ArrowBack';
3
+ import ArrowBackIcon from "@mui/icons-material/ArrowBack";
4
4
  import FormStyles from "./Styles";
5
5
  import FormWorkflow from "./FormWorkflow";
6
6
 
7
7
  //Constants
8
- import { minutes, hours, days } from './constant';
8
+ import { minutes, hours, days } from "./constant";
9
9
  import ListWorkflow from "./ListWorkflow";
10
10
  import { PlusIcon } from "../../../common/iconslist";
11
11
  import { jsx as _jsx } from "react/jsx-runtime";
@@ -23,12 +23,12 @@ const Workflow = props => {
23
23
  const classes = FormStyles();
24
24
  const [workflowList, setWorkflowList] = useState([]);
25
25
  const [formData, setFormData] = useState(false);
26
- const [schedule, setSchedule] = useState('immediately');
27
- const [scheduleEvery, setScheduleEvery] = useState('min');
28
- const currentInstant = scheduleEvery === 'min' ? minutes : scheduleEvery === 'hr' ? hours : scheduleEvery === 'day' ? days : [];
26
+ const [schedule, setSchedule] = useState("immediately");
27
+ const [scheduleEvery, setScheduleEvery] = useState("min");
28
+ const currentInstant = scheduleEvery === "min" ? minutes : scheduleEvery === "hr" ? hours : scheduleEvery === "day" ? days : [];
29
29
  const [scheduleOn, setScheduleOn] = useState(currentInstant[0]);
30
- const [subject, setSubject] = useState('');
31
- const [bodyData, setBodyData] = useState('');
30
+ const [subject, setSubject] = useState("Welcome to Flozy!");
31
+ const [bodyData, setBodyData] = useState("Hey %field_name% \n\nThanks for attending the event called %Event Name% at %Event Time% on %Event Time%.");
32
32
  const [flowEdited, setFlowEdited] = useState({
33
33
  isEdited: false,
34
34
  listIndex: null
@@ -44,16 +44,16 @@ const Workflow = props => {
44
44
  };
45
45
  const onFormBack = () => {
46
46
  setFormData(false);
47
- setBodyData('');
48
- setSubject('');
49
- setSchedule('immediately');
47
+ setBodyData("");
48
+ setSubject("");
49
+ setSchedule("immediately");
50
50
  };
51
51
  const saveFormWorkflow = () => {
52
52
  let workflowData = [...workflowList];
53
53
  let data = {
54
54
  schedule_type: schedule,
55
- schedule_every: schedule === 'after' ? scheduleEvery : 0,
56
- schedule_on: schedule === 'after' ? scheduleOn : 0,
55
+ schedule_every: schedule === "after" ? scheduleEvery : 0,
56
+ schedule_on: schedule === "after" ? scheduleOn : 0,
57
57
  subject_data: subject,
58
58
  body_data: bodyData
59
59
  };
@@ -67,9 +67,9 @@ const Workflow = props => {
67
67
  };
68
68
  onSave(saveData);
69
69
  setFormData(false);
70
- setBodyData('');
71
- setSubject('');
72
- setSchedule('immediately');
70
+ setBodyData("");
71
+ setSubject("");
72
+ setSchedule("immediately");
73
73
  setFlowEdited({
74
74
  isEdited: false,
75
75
  listIndex: null
@@ -117,26 +117,25 @@ const Workflow = props => {
117
117
  children: [/*#__PURE__*/_jsxs(DialogTitle, {
118
118
  sx: classes.popupTitle,
119
119
  style: {
120
- padding: formData ? '16px 12px' : '16px 24px',
120
+ padding: formData ? "16px 12px" : "16px 24px",
121
121
  justifyContent: !formData ? "space-between" : ""
122
122
  },
123
123
  children: [formData && /*#__PURE__*/_jsx(IconButton, {
124
124
  onClick: onFormBack,
125
125
  children: /*#__PURE__*/_jsx(ArrowBackIcon, {})
126
- }), "Follow-Up Email", !formData && workflowList?.length > 0 && /*#__PURE__*/_jsx(Button, {
126
+ }), "Follow-Up Email", !formData && workflowList?.length > 0 && /*#__PURE__*/_jsxs(Button, {
127
127
  variant: "outlined",
128
128
  sx: {
129
- textTransform: 'none',
130
- background: '#EBF1F9',
131
- padding: '7px 15px'
129
+ textTransform: "none",
130
+ background: "#EBF1F9",
131
+ padding: "7px 15px"
132
132
  },
133
133
  onClick: handleAddFormWorkflow,
134
134
  size: "small",
135
135
  startIcon: /*#__PURE__*/_jsx(PlusIcon, {}),
136
- children: " New Email"
136
+ children: [" ", "New Email"]
137
137
  })]
138
138
  }), /*#__PURE__*/_jsxs(DialogContent, {
139
- dividers: true,
140
139
  children: [!formData && workflowList?.length > 0 && /*#__PURE__*/_jsx(ListWorkflow, {
141
140
  workflow: workflowList,
142
141
  handleEditFormWorkflow: handleEditFormWorkflow,
@@ -161,15 +160,14 @@ const Workflow = props => {
161
160
  }), /*#__PURE__*/_jsxs(DialogActions, {
162
161
  sx: classes.dialogFooter,
163
162
  children: [/*#__PURE__*/_jsx(Button, {
164
- color: "primary",
163
+ className: "secondaryBtn",
165
164
  sx: classes.closeBtn,
166
- variant: "outlined",
167
165
  onClick: closeWorkflow,
168
166
  size: "small",
169
167
  children: "Close"
170
168
  }), (formData || workflowList?.length === 0) && /*#__PURE__*/_jsx(Button, {
169
+ className: "primaryBtn",
171
170
  sx: classes.saveBtn,
172
- variant: "contained",
173
171
  onClick: saveFormWorkflow,
174
172
  size: "small",
175
173
  children: "Save"
@@ -150,6 +150,9 @@ const GridItem = props => {
150
150
  children: [!readOnly && /*#__PURE__*/_jsxs("div", {
151
151
  className: `element-selector ${selected ? "selected" : ""}`,
152
152
  contentEditable: false,
153
+ style: {
154
+ zIndex: 1000
155
+ },
153
156
  children: [/*#__PURE__*/_jsx("div", {
154
157
  className: "element-selector-dots tl",
155
158
  children: " "
@@ -26,7 +26,9 @@ const SignaturePopup = props => {
26
26
  const [open, setOpen] = useState(false);
27
27
  const [tab, setTab] = useState(0);
28
28
  const SeletectedTab = SignatureOptions[tab];
29
- const [signedData, setSignedData] = useState({});
29
+ const [signedData, setSignedData] = useState({
30
+ signedOn: new Date()
31
+ });
30
32
  const [brush, setBrush] = useState({
31
33
  size: 1,
32
34
  color: "#000000"
@@ -250,12 +252,14 @@ const SignaturePopup = props => {
250
252
  children: /*#__PURE__*/_jsx(DatePicker, {
251
253
  showIcon: true,
252
254
  id: "signedOn",
255
+ name: "signedOn",
253
256
  selected: signedData?.signedOn ? new Date(signedData?.signedOn) : new Date(),
257
+ value: signedData?.signedOn || "",
254
258
  dateFormat: "MM/dd/yyyy",
255
259
  onChange: date => {
256
260
  setSignedData({
257
261
  ...signedData,
258
- signedOn: new Date(date).toISOString().split("T")[0]
262
+ signedOn: date ? new Date(date).toISOString().split("T")[0] : ""
259
263
  });
260
264
  }
261
265
  })
@@ -342,7 +346,8 @@ const SignaturePopup = props => {
342
346
  children: "Delete"
343
347
  }) : null, /*#__PURE__*/_jsx(Button, {
344
348
  onClick: handleSave,
345
- className: "primaryBtn",
349
+ className: `primaryBtn ${!signedData?.signature ? "disabled" : ""}`,
350
+ disabled: !signedData?.signature,
346
351
  children: "Save"
347
352
  })]
348
353
  })]
@@ -1,6 +1,6 @@
1
1
  import React from "react";
2
2
  import { useSlateStatic, useSelected, ReactEditor } from "slate-react";
3
- import { Node } from "slate";
3
+ import { Node, Editor } from "slate";
4
4
  import { Box } from "@mui/material";
5
5
  import { jsx as _jsx } from "react/jsx-runtime";
6
6
  import { jsxs as _jsxs } from "react/jsx-runtime";
@@ -47,7 +47,8 @@ const SimpleText = props => {
47
47
  customProps
48
48
  } = props;
49
49
  const {
50
- readOnly
50
+ readOnly,
51
+ editorPlaceholder
51
52
  } = customProps;
52
53
  const classes = SimpleTextStyle();
53
54
  const editor = useSlateStatic();
@@ -55,20 +56,24 @@ const SimpleText = props => {
55
56
  const path = ReactEditor.findPath(editor, element);
56
57
  const noContent = Node.string(Node.get(editor, path)).length === 0 && path.length === 1;
57
58
  const emptyEditor = editor.children.length === 1 && path[0] === 0 && path.length === 1 && !selected;
59
+ const isMoreText = (editor.selection ? Editor.string(editor, editor.selection) : "")?.trim()?.length === 0;
58
60
  return /*#__PURE__*/_jsxs(Box, {
59
61
  ...element.attr,
60
62
  ...attributes,
61
63
  className: `simple-text`,
62
64
  sx: classes.root,
63
- children: [children, selected && noContent && !readOnly ? /*#__PURE__*/_jsxs("span", {
65
+ children: [children, isMoreText && selected && noContent && !readOnly ? /*#__PURE__*/_jsxs("span", {
64
66
  className: "placeholder-simple-text",
65
67
  children: ["Type ", /*#__PURE__*/_jsx("span", {
66
68
  className: "bg-pad-sl",
67
69
  children: "/"
68
70
  }), " for browse elements"]
69
- }) : null, emptyEditor && !readOnly ? /*#__PURE__*/_jsx("span", {
71
+ }) : null, isMoreText && emptyEditor && !readOnly ? /*#__PURE__*/_jsx("span", {
70
72
  className: "placeholder-simple-text",
71
73
  children: "Write Something..."
74
+ }) : null, editorPlaceholder && !selected ? /*#__PURE__*/_jsx("span", {
75
+ className: "placeholder-simple-text",
76
+ children: editorPlaceholder
72
77
  }) : null]
73
78
  });
74
79
  };
@@ -0,0 +1,118 @@
1
+ import React, { useCallback, useMemo, useRef, useState } from "react";
2
+ import { createEditor } from 'slate';
3
+ import { Slate, Editable, withReact } from "slate-react";
4
+ import { getBlock, getMarked } from "./utils/SlateUtilityFunctions";
5
+ import { commands, mentionsEvent } from "./utils/events";
6
+ import useMentions from "./hooks/useMentions";
7
+ import Shorthands from "./common/Shorthands";
8
+ // import withCommon from "./hooks/withCommon";
9
+ import { jsx as _jsx } from "react/jsx-runtime";
10
+ const initialValue = [{
11
+ type: 'paragraph',
12
+ children: [{
13
+ text: ''
14
+ }]
15
+ }];
16
+ const MiniEditor = props => {
17
+ const {
18
+ id,
19
+ // content,
20
+ // onSave,
21
+ // editor: collaborativeEditor,
22
+ readOnly,
23
+ miniEditorPlaceholder,
24
+ otherProps
25
+ } = props;
26
+ const {
27
+ CHARACTERS = []
28
+ // needLayout = true,
29
+ } = otherProps || {};
30
+ const mentionsRef = useRef();
31
+ const [editor] = useState(() => withReact(createEditor()));
32
+
33
+ // const editor = useMemo(() => {
34
+ // if (collaborativeEditor) return collaborativeEditor;
35
+ // return withCommon(createEditor(), { needLayout });
36
+ // }, [collaborativeEditor]);
37
+
38
+ const isReadOnly = readOnly === "readonly";
39
+ const customProps = {
40
+ ...(otherProps || {}),
41
+ readOnly: isReadOnly,
42
+ editorPlaceholder: miniEditorPlaceholder,
43
+ page_id: id
44
+ };
45
+ const [mentions, setMentions] = useMentions({
46
+ editor,
47
+ selection: editor?.selection
48
+ });
49
+ const {
50
+ search,
51
+ target,
52
+ index,
53
+ type
54
+ } = mentions;
55
+ console.log("🚀 ~ MiniEditor ~ mentions:", mentions);
56
+ const chars = type ? Shorthands[type]({
57
+ ...mentions,
58
+ CHARACTERS
59
+ }) : [];
60
+ const Leaf = ({
61
+ attributes,
62
+ children,
63
+ leaf
64
+ }) => {
65
+ children = getMarked(leaf, children);
66
+ return /*#__PURE__*/_jsx("span", {
67
+ ...attributes,
68
+ children: children
69
+ });
70
+ };
71
+ const Element = props => {
72
+ return getBlock(props);
73
+ };
74
+ const renderLeaf = useCallback(props => {
75
+ return /*#__PURE__*/_jsx(Leaf, {
76
+ ...props,
77
+ customProps: customProps
78
+ });
79
+ }, []);
80
+ const onKeyDown = useCallback(event => {
81
+ const isMetaKey = event.metaKey && event.keyCode >= 65 && event.keyCode <= 90;
82
+ const isCtrlKey = event.ctrlKey || isMetaKey;
83
+ if (target && chars.length > 0 && !isCtrlKey) {
84
+ mentionsEvent({
85
+ event,
86
+ mentions,
87
+ setMentions,
88
+ chars,
89
+ target,
90
+ editor,
91
+ type,
92
+ mentionsRef
93
+ });
94
+ } else if (isCtrlKey) {
95
+ commands({
96
+ event,
97
+ editor
98
+ });
99
+ }
100
+ }, [chars, editor, target, mentions, setMentions, search, type, mentionsRef]);
101
+ const renderElement = useCallback(props => {
102
+ return /*#__PURE__*/_jsx(Element, {
103
+ ...props,
104
+ customProps: customProps
105
+ });
106
+ }, []);
107
+ return /*#__PURE__*/_jsx(Slate, {
108
+ editor: editor,
109
+ initialValue: initialValue,
110
+ children: /*#__PURE__*/_jsx(Editable, {
111
+ renderElement: renderElement,
112
+ renderLeaf: renderLeaf,
113
+ onKeyDown: onKeyDown
114
+ })
115
+ });
116
+ };
117
+ MiniEditor.displayName = "MiniEditor";
118
+ export default MiniEditor;
@@ -62,6 +62,26 @@ const editorStyles = ({
62
62
  },
63
63
  "& .accordion-summary-collapse-btn": {
64
64
  padding: "4px"
65
+ },
66
+ "& .workflow-icon-btn": {
67
+ pointerEvents: "none",
68
+ position: "absolute",
69
+ right: "-9px",
70
+ top: "-9px",
71
+ border: "2px solid #f3b814",
72
+ padding: "0px",
73
+ background: "#FFF",
74
+ "& svg": {
75
+ width: "18px",
76
+ height: "18px"
77
+ }
78
+ },
79
+ "& .svg-big-btn": {
80
+ padding: "2px !important",
81
+ "& svg": {
82
+ width: "24px !important",
83
+ height: "24px !important"
84
+ }
65
85
  }
66
86
  }
67
87
  });
@@ -50,7 +50,7 @@ const TextFormat = props => {
50
50
  };
51
51
  const handlePageWidth = width => () => {
52
52
  updatePageSettings(editor, {
53
- ...pageProps,
53
+ ...(pageProps || {}),
54
54
  pageWidth: width
55
55
  });
56
56
  };
@@ -0,0 +1,99 @@
1
+ import React, { useEffect, useState } from "react";
2
+ import { ReactEditor, useSlateStatic } from "slate-react";
3
+ import { Box } from "@mui/material";
4
+ import Draggable from "./Draggable";
5
+ import Droppable from "./Droppable";
6
+ import { useEditorContext } from "../../hooks/useMouseMove";
7
+ import { Transforms } from "slate";
8
+ import { jsx as _jsx } from "react/jsx-runtime";
9
+ import { jsxs as _jsxs } from "react/jsx-runtime";
10
+ const DRAGGABLE_TYPES = ["paragraph"];
11
+ const DragHandleStyle = () => ({
12
+ root: {
13
+ position: "relative",
14
+ paddingLeft: "20px",
15
+ "&:hover": {
16
+ "& > .dh-para:first-child": {
17
+ opacity: 1
18
+ }
19
+ },
20
+ "&.dragging": {
21
+ backgroundColor: "#def4ff"
22
+ }
23
+ },
24
+ dragHandle: {
25
+ opacity: 0,
26
+ content: '" "',
27
+ position: "absolute",
28
+ top: 0,
29
+ left: 0,
30
+ borderRadius: "4px",
31
+ padding: "0px",
32
+ width: "18px",
33
+ background: "transparent",
34
+ border: 0,
35
+ display: "flex",
36
+ alignItems: "center",
37
+ justifyContent: "center",
38
+ cursor: "grab",
39
+ "& svg": {
40
+ fill: "#ccc",
41
+ width: "20px"
42
+ },
43
+ "&:hover": {
44
+ opacity: 1,
45
+ background: "#eee"
46
+ },
47
+ "&.active": {
48
+ opacity: 1,
49
+ cursor: "grabbing"
50
+ }
51
+ },
52
+ dropArea: {
53
+ height: "2px"
54
+ }
55
+ });
56
+ const DragHandle = props => {
57
+ const classes = DragHandleStyle();
58
+ const editor = useSlateStatic();
59
+ const [dragging, setDragging] = useState(false);
60
+ const {
61
+ attributes,
62
+ element,
63
+ children
64
+ } = props;
65
+ const path = ReactEditor.findPath(editor, element);
66
+ const canDraggable = DRAGGABLE_TYPES.indexOf(element?.type) > -1;
67
+ const {
68
+ drop
69
+ } = useEditorContext();
70
+ const id = `${element.type}_${[...path].join("|")}`;
71
+ const {
72
+ moved
73
+ } = element;
74
+ useEffect(() => {
75
+ if (moved) {
76
+ Transforms.removeNodes(editor, {
77
+ at: path
78
+ });
79
+ }
80
+ }, [moved]);
81
+ const handleOnDrag = isDragging => {
82
+ setDragging(isDragging);
83
+ };
84
+ return canDraggable ? /*#__PURE__*/_jsxs(Box, {
85
+ ...attributes,
86
+ component: "div",
87
+ className: `${dragging ? "dragging" : ""}`,
88
+ sx: classes.root,
89
+ children: [/*#__PURE__*/_jsx(Droppable, {
90
+ id: id,
91
+ classes: classes
92
+ }), children, /*#__PURE__*/_jsx(Draggable, {
93
+ id: id,
94
+ classes: classes,
95
+ onDrag: handleOnDrag
96
+ })]
97
+ }, `${id}_${drop}`) : children;
98
+ };
99
+ export default DragHandle;
@@ -0,0 +1,41 @@
1
+ import React, { useEffect } from "react";
2
+ import { useDraggable } from "@dnd-kit/core";
3
+ import { Box } from "@mui/material";
4
+ import DragIndicatorIcon from "@mui/icons-material/DragIndicator";
5
+ import { jsx as _jsx } from "react/jsx-runtime";
6
+ const Draggable = props => {
7
+ const {
8
+ id,
9
+ classes,
10
+ onDrag
11
+ } = props;
12
+ const {
13
+ attributes: dragAttributes,
14
+ listeners,
15
+ setNodeRef,
16
+ isDragging,
17
+ transform
18
+ } = useDraggable({
19
+ id: id
20
+ });
21
+ useEffect(() => {
22
+ if (onDrag) {
23
+ onDrag(isDragging);
24
+ }
25
+ }, [isDragging]);
26
+ const dragStyle = transform ? {
27
+ transform: `translate3d(${transform.x}px, ${transform.y}px, 0)`
28
+ } : undefined;
29
+ return /*#__PURE__*/_jsx(Box, {
30
+ ref: setNodeRef,
31
+ ...listeners,
32
+ ...dragAttributes,
33
+ component: "button",
34
+ className: `dh-para ${isDragging ? "active" : ""}`,
35
+ contentEditable: false,
36
+ style: dragStyle,
37
+ sx: classes.dragHandle,
38
+ children: /*#__PURE__*/_jsx(DragIndicatorIcon, {})
39
+ });
40
+ };
41
+ export default Draggable;
@@ -0,0 +1,28 @@
1
+ import React from "react";
2
+ import { useDroppable } from "@dnd-kit/core";
3
+ import { Box } from "@mui/material";
4
+ import { jsx as _jsx } from "react/jsx-runtime";
5
+ const Droppable = props => {
6
+ const {
7
+ id,
8
+ classes
9
+ } = props;
10
+ const {
11
+ isOver,
12
+ setNodeRef
13
+ } = useDroppable({
14
+ id: id
15
+ });
16
+ const dropStyle = {
17
+ backgroundColor: isOver ? "green" : undefined
18
+ };
19
+ return /*#__PURE__*/_jsx(Box, {
20
+ ref: setNodeRef,
21
+ component: "div",
22
+ className: `droppable-para`,
23
+ contentEditable: false,
24
+ style: dropStyle,
25
+ sx: classes.dropArea
26
+ });
27
+ };
28
+ export default Droppable;
@@ -0,0 +1,48 @@
1
+ import React from "react";
2
+ import { Transforms, Node } from "slate";
3
+ import { useSlateStatic } from "slate-react";
4
+ import { DndContext } from "@dnd-kit/core";
5
+ import { customCollisionDetectionAlgorithm } from "../../helper";
6
+ import { jsx as _jsx } from "react/jsx-runtime";
7
+ const DragAndDrop = ({
8
+ children
9
+ }) => {
10
+ const editor = useSlateStatic();
11
+ const handleDragStart = e => {
12
+ try {
13
+ // console.log(e);
14
+ } catch (err) {
15
+ console.log(err);
16
+ }
17
+ };
18
+ const handleDragEnd = e => {
19
+ try {
20
+ const {
21
+ active,
22
+ over
23
+ } = e;
24
+ const fromPath = active.id.split("_")[1].split("|");
25
+ const toPath = over.id.split("_")[1].split("|");
26
+ const toCloneNode = JSON.stringify(Node.get(editor, fromPath));
27
+ // set moved node delete
28
+ Transforms.setNodes(editor, {
29
+ moved: true
30
+ }, {
31
+ at: [...fromPath]
32
+ });
33
+ // clone node in the moved path
34
+ Transforms.insertNodes(editor, JSON.parse(toCloneNode), {
35
+ at: [...toPath]
36
+ });
37
+ } catch (err) {
38
+ console.log(err);
39
+ }
40
+ };
41
+ return /*#__PURE__*/_jsx(DndContext, {
42
+ collisionDetection: customCollisionDetectionAlgorithm,
43
+ onDragStart: handleDragStart,
44
+ onDragEnd: handleDragEnd,
45
+ children: children
46
+ });
47
+ };
48
+ export default DragAndDrop;
@@ -1529,4 +1529,20 @@ export const UploadImage = () => /*#__PURE__*/_jsx("svg", {
1529
1529
  fill: "#64748B",
1530
1530
  stroke: "#64748B"
1531
1531
  })
1532
- });
1532
+ });
1533
+ export const WorkflowIcon = () => {
1534
+ return /*#__PURE__*/_jsxs("svg", {
1535
+ xmlns: "http://www.w3.org/2000/svg",
1536
+ fill: "#000000",
1537
+ width: "800px",
1538
+ height: "800px",
1539
+ viewBox: "0 0 32 32",
1540
+ version: "1.1",
1541
+ children: [/*#__PURE__*/_jsx("title", {
1542
+ children: "lightning-bolt"
1543
+ }), /*#__PURE__*/_jsx("path", {
1544
+ d: "M23.5 13.187h-7.5v-12.187l-7.5 17.813h7.5v12.187l7.5-17.813z",
1545
+ fill: "#f3b814"
1546
+ })]
1547
+ });
1548
+ };
@@ -6,7 +6,11 @@ export const EditorProvider = ({
6
6
  }) => {
7
7
  const [event] = useMouseMove();
8
8
  const [previous, setPrevious] = useState("");
9
+ const [drop, setDrop] = useState(0);
9
10
  const path = event?.target?.getAttribute("data-path");
11
+ const onDrop = () => {
12
+ setDrop(drop + 1);
13
+ };
10
14
  const value = useMemo(() => {
11
15
  if (path) {
12
16
  setPrevious(path);
@@ -20,7 +24,11 @@ export const EditorProvider = ({
20
24
  }
21
25
  }, [path]);
22
26
  return /*#__PURE__*/_jsx(EditorContext.Provider, {
23
- value: value,
27
+ value: {
28
+ ...(value || {}),
29
+ onDrop: onDrop,
30
+ drop
31
+ },
24
32
  children: children
25
33
  });
26
34
  };
@@ -1,4 +1,5 @@
1
1
  export const formatDate = (date, format = "MM/DD/YYYY") => {
2
+ if (!date) return "";
2
3
  var d = new Date(date),
3
4
  month = "" + (d.getMonth() + 1),
4
5
  day = "" + d.getDate(),
@@ -35,8 +35,8 @@ export const insertPageSettings = (editor, pageProps = {}) => {
35
35
  Transforms.insertNodes(editor, [{
36
36
  type: "page-settings",
37
37
  pageProps: {
38
- ...pageProps,
39
- pageWidth: "fixed"
38
+ pageWidth: "fixed",
39
+ ...pageProps
40
40
  },
41
41
  children: [{
42
42
  text: ""
@@ -0,0 +1,5 @@
1
+ import { Node } from "slate";
2
+ const serializeToHTML = nodes => {
3
+ return nodes.map(n => Node.string(n)).join("\n");
4
+ };
5
+ export default serializeToHTML;
@@ -1,4 +1,4 @@
1
- export const serialize = node => {
1
+ export const serializeToText = node => {
2
2
  try {
3
3
  if (!node?.type && node?.text) {
4
4
  return node?.text;
@@ -6,8 +6,8 @@ export const serialize = node => {
6
6
  let n = Array.isArray(node) ? node : node?.children;
7
7
  n = n && Array.isArray(n) ? n : n ? [n] : [];
8
8
  let block = n.map(m => {
9
- return serialize(m);
10
- }).join(' ');
9
+ return serializeToText(m);
10
+ }).join(" ");
11
11
  return block;
12
12
  } catch (err) {
13
13
  console.log(err);
package/dist/index.js CHANGED
@@ -1,4 +1,6 @@
1
1
  import Collaborative from "./Editor/CollaborativeEditor";
2
2
  import CommonEditor from "./Editor/CommonEditor";
3
+ import Mini from "./Editor/MiniEditor";
3
4
  export const Editor = CommonEditor;
5
+ export const MiniEditor = Mini;
4
6
  export const CollaborativeEditor = Collaborative;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flozy/editor",
3
- "version": "1.7.1",
3
+ "version": "1.7.2",
4
4
  "description": "An Editor for flozy app brain",
5
5
  "files": [
6
6
  "dist"
@@ -1,42 +0,0 @@
1
- import React from "react";
2
- import { Box } from "@mui/material";
3
- import { ReactEditor, useSlateStatic } from "slate-react";
4
- import { jsx as _jsx } from "react/jsx-runtime";
5
- const SectionStyle = () => ({
6
- root: {
7
- position: "relative",
8
- padding: "0px",
9
- display: "flex",
10
- alignItems: "center",
11
- justifyContent: "center",
12
- width: "100%",
13
- "&.root-1": {
14
- "& .section-inner-ed.root-1": {
15
- width: "80%",
16
- maxWidth: "1440px"
17
- }
18
- }
19
- }
20
- });
21
- const Section = props => {
22
- const {
23
- element
24
- } = props;
25
- const editor = useSlateStatic();
26
- const path = ReactEditor.findPath(editor, element);
27
- console.log(path);
28
- const classes = SectionStyle();
29
- const {
30
- children
31
- } = props;
32
- return /*#__PURE__*/_jsx(Box, {
33
- component: "div",
34
- className: `root-${path.length}`,
35
- sx: classes.root,
36
- children: /*#__PURE__*/_jsx("div", {
37
- className: `section-inner-ed root-${path.length}`,
38
- children: children
39
- })
40
- });
41
- };
42
- export default Section;