@flozy/editor 5.1.7 → 5.1.9

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.
@@ -111,7 +111,7 @@ const Divider = props => {
111
111
  contentEditable: false,
112
112
  style: {
113
113
  zIndex: 1000,
114
- left: "50%"
114
+ left: "0%"
115
115
  },
116
116
  children: /*#__PURE__*/_jsx(DividerToolbar, {
117
117
  selected: selected,
@@ -4,7 +4,7 @@ import { Node, Transforms, Editor } from "slate";
4
4
  import AspectRatioIcon from "@mui/icons-material/AspectRatio";
5
5
  import useResize from "../../utils/customHooks/useResize";
6
6
  import EmbedPopup from "./EmbedPopup";
7
- import { IconButton, Tooltip, Box, useTheme } from "@mui/material";
7
+ import { IconButton, Tooltip, Box, useTheme, Popper } from "@mui/material";
8
8
  import { GridSettingsIcon, LinkIcon } from "../../common/iconslist";
9
9
  import { useEditorContext } from "../../hooks/useMouseMove";
10
10
  import { getTRBLBreakPoints, getBreakPointsValue, groupByBreakpoint } from "../../helper/theme";
@@ -19,15 +19,15 @@ import { jsxs as _jsxs } from "react/jsx-runtime";
19
19
  const ToolBar = ({
20
20
  isEmpty,
21
21
  onSettings,
22
- setOpenNav
22
+ setOpenNav,
23
+ topM
23
24
  }) => {
24
25
  return !isEmpty ? /*#__PURE__*/_jsxs("div", {
25
26
  className: "element-toolbar visible-on-hover",
26
27
  contentEditable: false,
27
28
  style: {
28
- top: "0px",
29
- right: "0px",
30
- left: "auto",
29
+ top: "-5px",
30
+ left: topM ? "35px" : "0px",
31
31
  margin: "0px"
32
32
  },
33
33
  children: [/*#__PURE__*/_jsx(Tooltip, {
@@ -155,7 +155,10 @@ const Image = props => {
155
155
  }, {
156
156
  at: path
157
157
  });
158
- }
158
+ },
159
+ MW: 32,
160
+ MH: 32,
161
+ MP: 2
159
162
  });
160
163
  const arr = Array.from(Node.elements(editor));
161
164
  const ele = arr.find(([elem]) => element === elem);
@@ -277,7 +280,8 @@ const Image = props => {
277
280
  children: [!readOnly && /*#__PURE__*/_jsx(ToolBar, {
278
281
  isEmpty: isEmpty,
279
282
  onSettings: onSettings,
280
- setOpenNav: setOpenNav
283
+ setOpenNav: setOpenNav,
284
+ topM: size.width < 100
281
285
  }), /*#__PURE__*/_jsx(ImageContent, {
282
286
  ...element,
283
287
  readOnly: readOnly,
@@ -52,6 +52,7 @@ const GridItemToolbar = props => {
52
52
  sx: classes.popTools,
53
53
  className: "gi-tool-pp",
54
54
  disablePortal: true,
55
+ contentEditable: false,
55
56
  children: [/*#__PURE__*/_jsx(Tooltip, {
56
57
  title: "Column Settings",
57
58
  arrow: true,
@@ -354,12 +355,14 @@ const GridItem = props => {
354
355
  onMouseDown: onMouseDown,
355
356
  height: "auto"
356
357
  }) : null, /*#__PURE__*/_jsxs(Dialog, {
358
+ sx: classes.dialog,
357
359
  open: Boolean(alert),
358
360
  onClose: handleClose,
359
361
  children: [/*#__PURE__*/_jsx(DialogContent, {
360
362
  children: alert
361
363
  }), /*#__PURE__*/_jsx(DialogActions, {
362
364
  children: /*#__PURE__*/_jsx(Button, {
365
+ variant: "contained",
363
366
  onClick: handleClose,
364
367
  children: "Close"
365
368
  })
@@ -106,6 +106,12 @@ const GridStyles = (theme, appTheme) => ({
106
106
  }
107
107
  }
108
108
  }
109
+ },
110
+ dialog: {
111
+ "& .MuiPaper-root": {
112
+ background: appTheme?.palette?.editor?.background,
113
+ color: appTheme?.palette?.editor?.textColor
114
+ }
109
115
  }
110
116
  });
111
117
  export default GridStyles;
@@ -1,70 +1,88 @@
1
- const TableStyles = theme => ({
2
- tableToolBar: {
3
- position: "absolute",
4
- top: "-24px",
5
- left: 0,
6
- transition: "all 0.3s",
7
- "& button": {
8
- backgroundColor: theme?.palette?.editor?.background,
9
- border: "1px solid rgba(37, 99, 235, 0.32)",
10
- boxShadow: "0px 0px 10px 0px rgba(0, 0, 0, 0.16)",
11
- borderRadius: "50%",
12
- padding: "4px",
13
- margin: "2px",
14
- "&:hover": {
15
- backgroundColor: theme?.palette?.editor?.background
1
+ const TableStyles = theme => {
2
+ const {
3
+ background,
4
+ closeButtonSvgStroke,
5
+ activeColor,
6
+ signaturePopUpTabButtonSelectedBg,
7
+ signaturePopUpTabButtonSelectedSvg
8
+ } = theme?.palette?.editor || {};
9
+ return {
10
+ tableToolBar: {
11
+ position: "absolute",
12
+ top: "-24px",
13
+ left: 0,
14
+ transition: "all 0.3s",
15
+ "& button": {
16
+ backgroundColor: background,
17
+ border: "1px solid rgba(37, 99, 235, 0.32)",
18
+ boxShadow: "0px 0px 10px 0px rgba(0, 0, 0, 0.16)",
19
+ borderRadius: "50%",
20
+ padding: "4px",
21
+ margin: "2px",
22
+ "&:hover": {
23
+ backgroundColor: background
24
+ },
25
+ "& svg": {
26
+ width: "18px",
27
+ height: "18px",
28
+ "& path": {
29
+ stroke: closeButtonSvgStroke
30
+ }
31
+ },
32
+ "&.selected": {
33
+ outline: `1.5px solid ${activeColor || "#2563EB"}`,
34
+ background: signaturePopUpTabButtonSelectedBg,
35
+ "& svg": {
36
+ "& path": {
37
+ stroke: signaturePopUpTabButtonSelectedSvg
38
+ }
39
+ }
40
+ }
16
41
  },
17
- "& svg": {
18
- width: "18px",
19
- height: "18px",
20
- "& path": {
21
- stroke: theme?.palette?.editor?.closeButtonSvgStroke
42
+ "&.active": {
43
+ width: "auto",
44
+ "& .toggle": {
45
+ rotate: "180deg"
46
+ }
47
+ },
48
+ "& .toolbtn": {
49
+ "& svg": {
50
+ stroke: "rgb(100, 116, 139)"
22
51
  }
23
52
  }
24
53
  },
25
- "&.active": {
26
- width: "auto",
27
- "& .toggle": {
28
- rotate: "180deg"
29
- }
30
- },
31
- "& .toolbtn": {
32
- "& svg": {
33
- stroke: "rgb(100, 116, 139)"
54
+ table: {
55
+ "& td": {
56
+ padding: "8px 8px"
57
+ },
58
+ "& .selection-area-tc": {
59
+ position: "absolute",
60
+ width: "100%",
61
+ height: "100%",
62
+ top: 0,
63
+ left: 0,
64
+ outline: "1px solid #2563EB",
65
+ pointerEvents: "none"
66
+ },
67
+ "& .hide-drag-btn-wrapper": {
68
+ "& .row-drag-btn": {
69
+ display: "none"
70
+ }
34
71
  }
35
- }
36
- },
37
- table: {
38
- "& td": {
39
- padding: "8px 8px"
40
72
  },
41
- "& .selection-area-tc": {
73
+ cellResizer: {
42
74
  position: "absolute",
43
- width: "100%",
44
- height: "100%",
75
+ cursor: "col-resize",
76
+ right: "-2px",
45
77
  top: 0,
46
- left: 0,
47
- outline: "1px solid #2563EB",
48
- pointerEvents: "none"
49
- },
50
- "& .hide-drag-btn-wrapper": {
51
- "& .row-drag-btn": {
52
- display: "none"
78
+ background: "transparent",
79
+ width: "3px",
80
+ borderRadius: "0px",
81
+ zIndex: 1,
82
+ "&:hover": {
83
+ background: "#2563EB"
53
84
  }
54
85
  }
55
- },
56
- cellResizer: {
57
- position: "absolute",
58
- cursor: "col-resize",
59
- right: "-2px",
60
- top: 0,
61
- background: "transparent",
62
- width: "3px",
63
- borderRadius: "0px",
64
- zIndex: 1,
65
- "&:hover": {
66
- background: "#2563EB"
67
- }
68
- }
69
- });
86
+ };
87
+ };
70
88
  export default TableStyles;
@@ -1,17 +1,18 @@
1
1
  import React, { useEffect, useRef, useState } from "react";
2
2
  import { Editor, Transforms } from "slate";
3
3
  import { ReactEditor, useSelected, useSlateStatic } from "slate-react";
4
- import { Box, IconButton, Tooltip, Table as TableComp, TableBody, useTheme, Popper, Fade } from "@mui/material";
4
+ import { Box, IconButton, Tooltip, Table as TableComp, TableBody, useTheme, Popper, Fade, ClickAwayListener } from "@mui/material";
5
5
  import { TableUtil } from "../../utils/table";
6
6
  import TablePopup from "./TablePopup";
7
7
  import { useEditorContext, useEditorSelection } from "../../hooks/useMouseMove";
8
8
  import TableStyles from "./Styles";
9
9
  import "./table.css";
10
10
  import { groupByBreakpoint } from "../../helper/theme";
11
- import useTable, { TableProvider } from "../../hooks/useTable";
11
+ import useTable, { TableProvider, getDefaultTableSelection } from "../../hooks/useTable";
12
12
  import AddRowCol from "./AddRowCol";
13
13
  import TableTool from "./TableTool";
14
14
  import { MoreIcon, SettingsIcon } from "../../assets/svg/TableIcons";
15
+ import { getSelectedCls } from "../../utils/helper";
15
16
  import { jsx as _jsx } from "react/jsx-runtime";
16
17
  import { jsxs as _jsxs } from "react/jsx-runtime";
17
18
  const hideRowDragBtns = (hide, dragRowBtnCls) => {
@@ -20,6 +21,40 @@ const hideRowDragBtns = (hide, dragRowBtnCls) => {
20
21
  rowDragBtns?.forEach(btn => btn.style.display = hide);
21
22
  }
22
23
  };
24
+ const MoreTableSettings = props => {
25
+ const {
26
+ exandTools,
27
+ handleAction,
28
+ editorTheme,
29
+ setExpandTools
30
+ } = props;
31
+ const {
32
+ updateTableSelection
33
+ } = useTable();
34
+ return /*#__PURE__*/_jsx(Popper, {
35
+ open: Boolean(exandTools),
36
+ anchorEl: exandTools,
37
+ contentEditable: false,
38
+ sx: {
39
+ zIndex: 2000
40
+ },
41
+ placement: "bottom-start",
42
+ children: /*#__PURE__*/_jsx(ClickAwayListener, {
43
+ onClickAway: () => setExpandTools(false),
44
+ children: /*#__PURE__*/_jsx("div", {
45
+ children: /*#__PURE__*/_jsx(TableTool, {
46
+ theme: editorTheme,
47
+ handleToolAction: (type, option) => {
48
+ handleAction(type, option);
49
+ if (type === "duplicate") {
50
+ updateTableSelection(getDefaultTableSelection());
51
+ }
52
+ }
53
+ })
54
+ })
55
+ })
56
+ });
57
+ };
23
58
  const ToolBar = props => {
24
59
  const {
25
60
  selected,
@@ -27,7 +62,8 @@ const ToolBar = props => {
27
62
  classes,
28
63
  handleExpand,
29
64
  handleAction,
30
- exandTools
65
+ exandTools,
66
+ openSetttings
31
67
  } = props;
32
68
  const {
33
69
  getSelectedCells
@@ -43,7 +79,7 @@ const ToolBar = props => {
43
79
  arrow: true,
44
80
  onClick: () => handleAction("settings"),
45
81
  children: /*#__PURE__*/_jsx(IconButton, {
46
- className: "toolbtn toggle",
82
+ className: getSelectedCls("toolbtn toggle", openSetttings),
47
83
  children: /*#__PURE__*/_jsx(SettingsIcon, {})
48
84
  })
49
85
  }), /*#__PURE__*/_jsx(Tooltip, {
@@ -51,7 +87,7 @@ const ToolBar = props => {
51
87
  arrow: true,
52
88
  onClick: handleExpand,
53
89
  children: /*#__PURE__*/_jsx(IconButton, {
54
- className: "toolbtn toggle",
90
+ className: getSelectedCls("toolbtn toggle", exandTools),
55
91
  children: /*#__PURE__*/_jsx(MoreIcon, {})
56
92
  })
57
93
  })]
@@ -100,6 +136,7 @@ const Table = props => {
100
136
  break;
101
137
  case "duplicate":
102
138
  table.duplicateTable();
139
+ setExpandTools(false);
103
140
  break;
104
141
  case "settings":
105
142
  if (tableProps) {
@@ -198,7 +235,8 @@ const Table = props => {
198
235
  otherProps: {
199
236
  dragRowBtnCls,
200
237
  tablePath: path,
201
- openSetttings
238
+ openSetttings,
239
+ exandTools
202
240
  },
203
241
  children: [/*#__PURE__*/_jsxs("div", {
204
242
  style: {
@@ -249,28 +287,13 @@ const Table = props => {
249
287
  classes: classes,
250
288
  handleExpand: handleExpand,
251
289
  handleAction: handleAction,
252
- exandTools: exandTools
253
- }), /*#__PURE__*/_jsx(Popper, {
254
- open: Boolean(exandTools),
255
- anchorEl: exandTools,
256
- transition: true,
257
- contentEditable: false,
258
- sx: {
259
- zIndex: 2000
260
- },
261
- placement: "bottom-start",
262
- children: ({
263
- TransitionProps
264
- }) => /*#__PURE__*/_jsx(Fade, {
265
- ...TransitionProps,
266
- timeout: 350,
267
- children: /*#__PURE__*/_jsx("div", {
268
- children: /*#__PURE__*/_jsx(TableTool, {
269
- theme: editorTheme,
270
- handleToolAction: handleAction
271
- })
272
- })
273
- })
290
+ exandTools: exandTools,
291
+ openSetttings: openSetttings
292
+ }), /*#__PURE__*/_jsx(MoreTableSettings, {
293
+ exandTools: exandTools,
294
+ handleAction: handleAction,
295
+ editorTheme: editorTheme,
296
+ setExpandTools: setExpandTools
274
297
  }), openSetttings ? /*#__PURE__*/_jsx(TablePopup, {
275
298
  element: tableProps?.styleProps || {},
276
299
  onSave: onSave,
@@ -87,7 +87,10 @@ const TableCell = props => {
87
87
  const isHeader = path.length >= 2 ? path[path.length - 2] === 0 : false;
88
88
  const [size, onMouseDown, resizing, onLoad] = useTableResize({
89
89
  parentDOM,
90
- size: element?.size
90
+ size: element?.size,
91
+ minMaxProps: {
92
+ minWidth: 30
93
+ }
91
94
  });
92
95
  const [tableSize, setTableSize] = useState({});
93
96
  const [openSettings, setOpenSettings] = useState(false);
@@ -8,6 +8,19 @@ import { serializeToText } from "../utils/serializeToText";
8
8
  import { createCopiedTableStructure, getRectangleBounds, tableNodeToDom } from "../Elements/Table/tableHelper";
9
9
  import { jsx as _jsx } from "react/jsx-runtime";
10
10
  import { jsxs as _jsxs } from "react/jsx-runtime";
11
+ const selectFirstCell = (tablePath, editor, updateTableSelection) => {
12
+ const firstCell = [...tablePath, 0, 0];
13
+ const end = Editor.end(editor, firstCell);
14
+ Transforms.select(editor, {
15
+ anchor: end,
16
+ focus: end
17
+ });
18
+ updateTableSelection({
19
+ startCellPath: firstCell,
20
+ endCellPath: [],
21
+ isDragging: false
22
+ });
23
+ };
11
24
  const handleDragEnd = (dragData, editor, resetAll) => {
12
25
  const {
13
26
  active,
@@ -65,7 +78,7 @@ export const TableProvider = ({
65
78
  otherProps = {}
66
79
  }) => {
67
80
  const {
68
- openSetttings
81
+ tablePath
69
82
  } = otherProps;
70
83
  const [hoverPath, setHoverPath] = useState(null);
71
84
  const [tableSelection, setTableSelection] = useState(getDefaultTableSelection());
@@ -105,7 +118,8 @@ export const TableProvider = ({
105
118
  tableSelection,
106
119
  tableResizing,
107
120
  setTableResizing,
108
- otherProps
121
+ otherProps,
122
+ resetAll
109
123
  };
110
124
  }, [hoverPath, editor?.selection, tableSelection, tableResizing]);
111
125
  useEffect(() => {
@@ -171,10 +185,8 @@ export const TableProvider = ({
171
185
  };
172
186
  }, [tableSelection, editor, tableSelection]);
173
187
  useEffect(() => {
174
- if (!openSetttings) {
175
- resetAll();
176
- }
177
- }, [openSetttings]);
188
+ selectFirstCell(tablePath, editor, updateTableSelection);
189
+ }, []);
178
190
  return /*#__PURE__*/_jsx(TableContext.Provider, {
179
191
  value: values,
180
192
  children: /*#__PURE__*/_jsxs(DndContext, {
@@ -2,6 +2,7 @@ import { Transforms, Editor, Element, Node, Path } from "slate";
2
2
  import deserialize from "../helper/deserialize";
3
3
  import { decodeAndParseBase64 } from "../utils/helper";
4
4
  const avoidDefaultInsert = ["table", "grid"];
5
+ const LIST_TAGS = ["ol", "ul", "img", "table"];
5
6
  const loopChildren = (children = [], defaultInsert) => {
6
7
  if (!children?.length) {
7
8
  return defaultInsert;
@@ -120,12 +121,21 @@ const withHtml = editor => {
120
121
  const slateHTML = data?.getData("application/x-slate-fragment");
121
122
  const html = data?.getData("text/html");
122
123
  const currentEl = getCurrentElement(editor);
123
- let eltype = currentEl?.type;
124
+ const eltype = currentEl?.type;
125
+ const isTitlePath = editor?.selection?.anchor?.path[0] === 0;
124
126
  if (slateHTML && !formatFragment[eltype]) {
125
127
  const [tableCellNode] = Editor.nodes(editor, {
126
128
  match: n => !Editor.isEditor(n) && Element.isElement(n) && n.type === "table-cell"
127
129
  });
128
130
  const decoded = decodeAndParseBase64(slateHTML);
131
+ if (decoded && decoded[0] && decoded[0]?.type !== "paragraph" && isTitlePath) {
132
+ decoded.unshift({
133
+ type: "title",
134
+ children: [{
135
+ text: ""
136
+ }]
137
+ });
138
+ }
129
139
  if (tableCellNode) {
130
140
  const tableCellChild = getTableCellChild(decoded);
131
141
  if (tableCellChild?.length) {
@@ -170,10 +180,40 @@ const withHtml = editor => {
170
180
  Transforms.insertText(editor, text);
171
181
  }
172
182
  } else {
173
- handleInsert(editor, () => insertData(data), decoded);
183
+ handleInsert(editor, () => {
184
+ if (isTitlePath) {
185
+ Transforms.insertNodes(editor, [{
186
+ type: "title",
187
+ children: [{
188
+ text: ""
189
+ }]
190
+ }], {
191
+ at: [0]
192
+ });
193
+ insertData(data);
194
+ }
195
+ }, decoded);
174
196
  }
175
197
  } else if (html) {
176
198
  const parsed = new DOMParser().parseFromString(html, "text/html");
199
+ const rootElement = parsed.body || parsed.documentElement;
200
+ const isList = LIST_TAGS.includes(rootElement.firstChild.tagName.toLowerCase());
201
+
202
+ // if selection is in title add the empty paragraph
203
+ if (isTitlePath && isList) {
204
+ // Check if the first child exists and is not a paragraph
205
+ if (!rootElement.firstChild || rootElement.firstChild.tagName.toLowerCase() !== "p") {
206
+ // Create a new empty paragraph element
207
+ const emptyParagraph = parsed.createElement("p");
208
+
209
+ // Insert the empty paragraph at the beginning
210
+ if (rootElement.firstChild) {
211
+ rootElement.insertBefore(emptyParagraph, rootElement.firstChild);
212
+ } else {
213
+ rootElement.appendChild(emptyParagraph);
214
+ }
215
+ }
216
+ }
177
217
  const isGoogleSheet = parsed.body.querySelector("google-sheets-html-origin");
178
218
  if (isGoogleSheet) {
179
219
  if (editor.isChatEditor) {
@@ -4,7 +4,10 @@ const useResize = ({
4
4
  parentDOM,
5
5
  size: allSize,
6
6
  isGrid,
7
- onChange
7
+ onChange,
8
+ MH,
9
+ MW,
10
+ MP
8
11
  }) => {
9
12
  const device = getDevice(window.innerWidth);
10
13
  const defaultSize = getBreakPointsValue(allSize);
@@ -52,9 +55,9 @@ const useResize = ({
52
55
  const cWP = calcWidth / width * 100;
53
56
  const calcHeight = (parseInt(currentSize.height) || height) + e.movementY;
54
57
  const calc = {
55
- width: Math.max(calcWidth, 140),
56
- height: Math.max(calcHeight, 50),
57
- widthInPercent: cWP > 100 ? 100 : Math.max(cWP, 15)
58
+ width: Math.max(calcWidth, MW || 140),
59
+ height: Math.max(calcHeight, MH || 50),
60
+ widthInPercent: cWP > 100 ? 100 : Math.max(cWP, MP || 15)
58
61
  };
59
62
  latest = calc;
60
63
  return calc;
@@ -2,7 +2,8 @@ import { useState } from "react";
2
2
  const useTableResize = ({
3
3
  parentDOM,
4
4
  size: defaultSize,
5
- onDone
5
+ onDone,
6
+ minMaxProps = {}
6
7
  }) => {
7
8
  const {
8
9
  width
@@ -38,10 +39,13 @@ const useTableResize = ({
38
39
  setIsDone(1);
39
40
  };
40
41
  const onMouseMove = e => {
42
+ const {
43
+ minWidth
44
+ } = minMaxProps || {};
41
45
  setSize(currentSize => {
42
46
  const calcWidth = currentSize?.width + e.movementX;
43
47
  return {
44
- width: calcWidth,
48
+ width: minWidth && calcWidth < minWidth ? minWidth : calcWidth,
45
49
  height: currentSize.height + e.movementY,
46
50
  widthInPercent: calcWidth / width * 100
47
51
  };
@@ -676,4 +676,7 @@ export function getInitialValue(value = [], readOnly) {
676
676
  return newValue;
677
677
  }
678
678
  return value;
679
+ }
680
+ export function getSelectedCls(defaultCls = "", selected, selectedClsName = "selected") {
681
+ return `${defaultCls} ${selected ? selectedClsName : ""}`;
679
682
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flozy/editor",
3
- "version": "5.1.7",
3
+ "version": "5.1.9",
4
4
  "description": "An Editor for flozy app brain",
5
5
  "files": [
6
6
  "dist"