@flozy/editor 4.1.2 → 4.1.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -426,16 +426,21 @@ const CommonEditor = /*#__PURE__*/forwardRef((props, ref) => {
426
426
  };
427
427
  const handleCursorScroll = container => {
428
428
  try {
429
- const cursorPosition = window.getSelection()?.getRangeAt(0).getBoundingClientRect();
430
- const containerBottom = container.getBoundingClientRect().bottom;
431
- if (cursorPosition?.bottom > containerBottom - 250) {
432
- container.scrollBy({
433
- top: 200,
434
- behavior: "smooth"
435
- });
429
+ const selection = window?.getSelection();
430
+ if (selection && selection.rangeCount > 0) {
431
+ const cursorPosition = selection.getRangeAt(0)?.getBoundingClientRect();
432
+ const containerBottom = container?.getBoundingClientRect()?.bottom;
433
+ if (cursorPosition && cursorPosition.bottom > containerBottom - 250) {
434
+ container?.scrollBy({
435
+ top: 200,
436
+ behavior: "smooth"
437
+ });
438
+ }
439
+ } else {
440
+ console.warn('No valid selection range found');
436
441
  }
437
442
  } catch (err) {
438
- console.log(err);
443
+ console.log('handleCursorScroll', err);
439
444
  }
440
445
  };
441
446
  return /*#__PURE__*/_jsx(EditorProvider, {
@@ -401,6 +401,18 @@ blockquote {
401
401
  position: relative;
402
402
  }
403
403
 
404
+ .editor-btn-wrapper .moreBtnShow {
405
+ opacity: 0;
406
+ }
407
+
408
+ .editor-btn-wrapper:hover .moreBtnShow {
409
+ opacity: 1;
410
+ }
411
+
412
+ .editor-btn-wrapper .activeBtnShow {
413
+ opacity: 1;
414
+ }
415
+
404
416
  .editor-btn {
405
417
  opacity: 1;
406
418
  }
@@ -199,6 +199,7 @@ function AppHeader(props) {
199
199
  }, theme);
200
200
  return /*#__PURE__*/_jsxs(_Fragment, {
201
201
  children: [/*#__PURE__*/_jsxs(Box, {
202
+ className: "app-h-wrpr",
202
203
  sx: {
203
204
  display: "flex",
204
205
  position: "relative"
@@ -3,15 +3,14 @@ import { Transforms } from "slate";
3
3
  import { ReactEditor, useSlateStatic } from "slate-react";
4
4
  import { IconButton, Tooltip, Box, useTheme } from "@mui/material";
5
5
  import MUIIcon from "../../common/StyleBuilder/fieldTypes/loadIcon";
6
- import SettingsIcon from "@mui/icons-material/Settings";
7
- import OpenInNewIcon from "@mui/icons-material/OpenInNew";
8
- import LinkIcon from "@mui/icons-material/Link";
9
6
  import ButtonPopup from "./ButtonPopup";
10
7
  import { actionButtonRedirect } from "../../service/actionTrigger";
11
8
  import { WorkflowIcon } from "../../common/iconslist";
12
9
  import { getTRBLBreakPoints, getBreakPointsValue, groupByBreakpoint } from "../../helper/theme";
13
10
  import { handleLinkType, windowVar } from "../../utils/helper";
14
11
  import LinkSettings from "../../common/LinkSettings";
12
+ import Icon from "../../common/Icon";
13
+ import { useEditorContext } from "../../hooks/useMouseMove";
15
14
  import { jsx as _jsx } from "react/jsx-runtime";
16
15
  import { jsxs as _jsxs } from "react/jsx-runtime";
17
16
  const EditorButton = props => {
@@ -30,6 +29,7 @@ const EditorButton = props => {
30
29
  const path = ReactEditor.findPath(editor, element);
31
30
  const [edit, setEdit] = useState(false);
32
31
  const [openNav, setOpenNav] = useState(false);
32
+ const [openMoreOptions, setOpenMoreOptions] = useState(false);
33
33
  const {
34
34
  label,
35
35
  bgColor,
@@ -106,7 +106,7 @@ const EditorButton = props => {
106
106
  className: "element-toolbar hr",
107
107
  style: {
108
108
  width: "max-content",
109
- top: "-12px",
109
+ top: "-33px",
110
110
  alignItems: "center",
111
111
  cursor: "pointer"
112
112
  },
@@ -115,14 +115,18 @@ const EditorButton = props => {
115
115
  arrow: true,
116
116
  children: /*#__PURE__*/_jsx(IconButton, {
117
117
  onClick: onMenuClick("edit"),
118
- children: /*#__PURE__*/_jsx(SettingsIcon, {})
118
+ children: /*#__PURE__*/_jsx(Icon, {
119
+ icon: "pagesSettings"
120
+ })
119
121
  })
120
122
  }), /*#__PURE__*/_jsx(Tooltip, {
121
123
  title: "Nav Settings",
122
124
  arrow: true,
123
125
  children: /*#__PURE__*/_jsx(IconButton, {
124
126
  onClick: onMenuClick("nav"),
125
- children: /*#__PURE__*/_jsx(LinkIcon, {})
127
+ children: /*#__PURE__*/_jsx(Icon, {
128
+ icon: "link"
129
+ })
126
130
  })
127
131
  }), hideOpenLink ? null : /*#__PURE__*/_jsx(Tooltip, {
128
132
  title: "Open Link",
@@ -130,11 +134,15 @@ const EditorButton = props => {
130
134
  children: /*#__PURE__*/_jsx(Box, {
131
135
  sx: {
132
136
  display: "inline-flex",
133
- color: "rgba(0, 0, 0, 0.54)"
137
+ color: "rgba(0, 0, 0, 0.54)",
138
+ borderRadius: '50% !important',
139
+ border: 'none !important'
134
140
  },
135
141
  ...btnProps,
136
142
  target: openInNewTab ? "_blank" : "_self",
137
- children: /*#__PURE__*/_jsx(OpenInNewIcon, {})
143
+ children: /*#__PURE__*/_jsx(Icon, {
144
+ icon: "openLinkIcon"
145
+ })
138
146
  })
139
147
  })]
140
148
  }) : null;
@@ -169,11 +177,19 @@ const EditorButton = props => {
169
177
  lg: "inline-block"
170
178
  }
171
179
  }, theme);
180
+ const handleMoreBtn = () => {
181
+ setOpenMoreOptions(!openMoreOptions);
182
+ };
172
183
  return /*#__PURE__*/_jsxs("div", {
173
184
  className: `editor-btn-wrapper`,
174
185
  ...attributes,
175
186
  style: {
176
- textAlign: tAlign
187
+ textAlign: tAlign,
188
+ "&:hover": {
189
+ "& .moreBtnShow": {
190
+ opacity: 1
191
+ }
192
+ }
177
193
  },
178
194
  contentEditable: false,
179
195
  children: [/*#__PURE__*/_jsx(Box, {
@@ -182,13 +198,25 @@ const EditorButton = props => {
182
198
  sx: {
183
199
  ...pSp,
184
200
  "& .element-toolbar": {
185
- display: "none"
186
- },
187
- "&:hover": {
188
- "& .element-toolbar": {
189
- display: "flex"
201
+ display: openMoreOptions ? "flex" : "none",
202
+ alignItems: "center",
203
+ "&:hover": {
204
+ display: openMoreOptions ? "flex" : "none",
205
+ "& .moreBtnShow": {
206
+ opacity: 1
207
+ }
208
+ },
209
+ "& svg": {
210
+ "& path": {
211
+ stroke: theme.palette.text.primary
212
+ }
213
+ },
214
+ "& button": {
215
+ borderRadius: "50%",
216
+ border: "none"
190
217
  }
191
- }
218
+ },
219
+ position: "relative"
192
220
  },
193
221
  children: /*#__PURE__*/_jsxs("span", {
194
222
  style: {
@@ -237,6 +265,20 @@ const EditorButton = props => {
237
265
  paddingRight: "4px"
238
266
  },
239
267
  props: customProps
268
+ }), !readOnly && /*#__PURE__*/_jsx(IconButton, {
269
+ className: `moreBtnShow ${openMoreOptions && "activeBtnShow"}`,
270
+ sx: {
271
+ position: "absolute",
272
+ right: '-42px',
273
+ stroke: '#fff',
274
+ "& path": {
275
+ fill: openMoreOptions ? theme.palette.text.blueText : ""
276
+ }
277
+ },
278
+ onClick: handleMoreBtn,
279
+ children: /*#__PURE__*/_jsx(Icon, {
280
+ icon: "moreVertical"
281
+ })
240
282
  })]
241
283
  }), !readOnly && isTrigger ? /*#__PURE__*/_jsx(IconButton, {
242
284
  className: "workflow-icon-btn",
@@ -1,12 +1,12 @@
1
1
  import { useEffect, useRef, useState } from "react";
2
- import useDragDom from "../../../hooks/useDragDom";
3
2
  import { IconButton, Popper } from "@mui/material";
4
3
  import Box from "@mui/material/Box";
5
4
  import ContinuousSlider from "./Slider";
6
- import frames from ".";
7
5
  import { useEditorContext } from "../../../hooks/useMouseMove";
8
6
  import { CloseIcon } from "../../../common/iconslist";
7
+ import useDragDom from "../../../hooks/useDragDom";
9
8
  import FramesStyles from "./Styles";
9
+ import frames from ".";
10
10
  import { jsx as _jsx } from "react/jsx-runtime";
11
11
  import { jsxs as _jsxs } from "react/jsx-runtime";
12
12
  import { Fragment as _Fragment } from "react/jsx-runtime";
@@ -48,18 +48,28 @@ const ImageFrame = props => {
48
48
  const SVGFrame = frame ? frames[frame] : null;
49
49
  const {
50
50
  selectedPath,
51
- setSelectedPath
52
- } = useEditorContext();
53
- const open = selectedPath === id && Boolean(anchorEl);
54
- const {
55
- theme
51
+ setSelectedPath,
52
+ selectedElement,
53
+ theme,
54
+ setSelectedElement
56
55
  } = useEditorContext();
56
+ const freeGridItemPath = `${selectedElement?.path?.split("|")?.join(",")},0`;
57
+ const isFreegridSelection = freeGridItemPath === id;
58
+ const open = (selectedPath === id || isFreegridSelection) && Boolean(anchorEl);
57
59
  const classes = FramesStyles(theme);
58
60
  useEffect(() => {
59
61
  if (imageRef?.current && !readOnly) {
60
62
  setDOM(dom);
61
63
  }
62
64
  }, [imageRef]);
65
+ useEffect(() => {
66
+ if (svgRef?.current && selectedElement?.selectedAction === "imageFrame") {
67
+ const imageFrameDom = document.getElementById(`opt_ref_${selectedElement?.path}`);
68
+ setAnchorEl(imageFrameDom);
69
+ } else {
70
+ setAnchorEl(null);
71
+ }
72
+ }, [isFreegridSelection, svgRef?.current, selectedElement?.selectedAction]);
63
73
  useEffect(() => {
64
74
  if (event === "end" && !readOnly) {
65
75
  onChange({
@@ -97,6 +107,11 @@ const ImageFrame = props => {
97
107
  const handleClose = () => {
98
108
  setAnchorEl(null);
99
109
  setSelectedPath(null);
110
+ setSelectedElement({
111
+ ...selectedElement,
112
+ enable: 1,
113
+ selectedAction: null
114
+ });
100
115
  };
101
116
  return /*#__PURE__*/_jsxs(_Fragment, {
102
117
  children: [/*#__PURE__*/_jsx(SVGFrame, {
@@ -118,8 +133,8 @@ const ImageFrame = props => {
118
133
  sx: {
119
134
  zIndex: 100
120
135
  },
121
- placement: "top",
122
- disablePortal: true,
136
+ placement: isFreegridSelection ? "bottom" : "top",
137
+ disablePortal: false,
123
138
  children: /*#__PURE__*/_jsxs(Box, {
124
139
  sx: classes?.sliderContainer,
125
140
  children: [/*#__PURE__*/_jsx(ContinuousSlider, {
@@ -295,6 +295,7 @@ const Image = ({
295
295
  id: path.join(","),
296
296
  onChange: onPosChange,
297
297
  readOnly: readOnly,
298
+ editor: editor,
298
299
  handleImageClick: handleImageClick
299
300
  })
300
301
  }) : null, selected && !readOnly && /*#__PURE__*/_jsx(IconButton, {
@@ -1,7 +1,7 @@
1
1
  const commonOptions = ["drag", "edit", "settings", "saveAsTemplate", "close"];
2
2
  const textOptions = ["edit", "settings", "link", "saveAsTemplate", "close"];
3
3
  const buttonOptions = ["settings", "link", "saveAsTemplate", "close"];
4
- const imageOptions = ["settings", "link", "saveAsTemplate", "close"];
4
+ const imageOptions = ["settings", "link", "imageFrame", "saveAsTemplate", "close"];
5
5
  const boxOptions = ["settings", "link", "saveAsTemplate", "close"];
6
6
  const appHeaderOptions = ["settings", "saveAsTemplate", "close"];
7
7
  const tableOptions = ["drag", "edit", "settings", "saveAsTemplate", "close"];
@@ -96,6 +96,11 @@ const useFreeGridStyles = ({
96
96
  "& .default-toolbar": {
97
97
  display: "block"
98
98
  }
99
+ },
100
+ "& .fgi_type_image": {
101
+ "& .visible-on-hover": {
102
+ display: "none !important"
103
+ }
99
104
  }
100
105
  },
101
106
  /** for element items */
@@ -163,6 +168,11 @@ const useFreeGridStyles = ({
163
168
  maxWidth: "100%",
164
169
  maxHeight: "100%",
165
170
  overflow: "hidden",
171
+ display: "flex",
172
+ alignItems: "center",
173
+ "& .app-h-wrpr": {
174
+ width: "100%"
175
+ },
166
176
  "& .MuiAppBar-root": {
167
177
  zIndex: 100
168
178
  },
@@ -0,0 +1,31 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { jsxs as _jsxs } from "react/jsx-runtime";
3
+ const OpenLinkIcon = props => {
4
+ return /*#__PURE__*/_jsxs("svg", {
5
+ width: "14",
6
+ height: "14",
7
+ viewBox: "0 0 14 14",
8
+ fill: "none",
9
+ xmlns: "http://www.w3.org/2000/svg",
10
+ children: [/*#__PURE__*/_jsx("path", {
11
+ d: "M7.58325 6.41615L12.3666 1.63281",
12
+ stroke: "#0F172A",
13
+ strokeWidth: "1.5",
14
+ strokeLinecap: "round",
15
+ strokeLinejoin: "round"
16
+ }), /*#__PURE__*/_jsx("path", {
17
+ d: "M12.8334 3.96602V1.16602H10.0334",
18
+ stroke: "#0F172A",
19
+ strokeWidth: "1.5",
20
+ strokeLinecap: "round",
21
+ strokeLinejoin: "round"
22
+ }), /*#__PURE__*/_jsx("path", {
23
+ d: "M6.41675 1.16602H5.25008C2.33341 1.16602 1.16675 2.33268 1.16675 5.24935V8.74935C1.16675 11.666 2.33341 12.8327 5.25008 12.8327H8.75008C11.6667 12.8327 12.8334 11.666 12.8334 8.74935V7.58268",
24
+ stroke: "#0F172A",
25
+ strokeWidth: "1.5",
26
+ strokeLinecap: "round",
27
+ strokeLinejoin: "round"
28
+ })]
29
+ });
30
+ };
31
+ export default OpenLinkIcon;
@@ -1,6 +1,7 @@
1
1
  import { useEffect } from "react";
2
2
  import WebFont from "webfontloader";
3
3
  import { useEditorContext } from "../../hooks/useMouseMove";
4
+ const defaultFonts = ['PoppinsRegular', 'PoppinsBold', 'Helvetica', 'Georgia', 'Times New Roman', 'Monaco', 'Courier New', 'Qwitcher Grypen', 'EB Garamond', 'Anton', 'DM Serif Text', 'Libre Baskerville', 'Montserrat', 'Open Sans', 'Public Sans', 'Raleway', 'Space Mono', 'Bulgarian Garamond', 'Impact', 'Redacted Script', 'Great Vibes', 'Zeyada', 'Allura', 'Pinyon Script', 'Herr Von Muellerhoff', 'Dawning of a New Day', 'Coming Soon', 'Dancing Script', 'Engagement', 'Gaegu', 'Ingrid Darling', 'Kite One', 'La Belle Aurore', 'Mea Culpa', 'Meddon', 'Merriweather', 'The Girl Next Door'];
4
5
  const FontLoader = props => {
5
6
  const {
6
7
  otherProps,
@@ -9,8 +10,9 @@ const FontLoader = props => {
9
10
  const {
10
11
  setFontFamilies
11
12
  } = useEditorContext();
12
- const loadFontsInBatches = (families, batchSize = 5) => {
13
+ const loadFontsInBatches = (families, batchSize = 5, maxRetries = 3) => {
13
14
  let currentIndex = 0;
15
+ let retryCount = 0;
14
16
  function loadNextBatch() {
15
17
  if (currentIndex >= families.length) {
16
18
  console.log('All fonts have been loaded');
@@ -25,10 +27,22 @@ const FontLoader = props => {
25
27
  active: () => {
26
28
  console.log(`Fonts loaded successfully: ${batch}`);
27
29
  currentIndex += batchSize;
30
+ retryCount = 0; // Reset retry count for the next batch
28
31
  loadNextBatch();
29
32
  },
30
33
  inactive: () => {
31
34
  console.log(`Font loading failed for: ${batch}`);
35
+ if (retryCount < maxRetries) {
36
+ retryCount++;
37
+ console.log(`Retrying batch (${retryCount}/${maxRetries})...`);
38
+ // Retry loading the same batch
39
+ loadNextBatch();
40
+ } else {
41
+ console.log(`Max retries reached for batch: ${batch}. Moving to the next batch.`);
42
+ currentIndex += batchSize;
43
+ retryCount = 0; // Reset retry count for the next batch
44
+ loadNextBatch();
45
+ }
32
46
  }
33
47
  });
34
48
  }
@@ -38,15 +52,16 @@ const FontLoader = props => {
38
52
  return fontFamily.replace(/\\/g, '').replace(/['"]/g, '');
39
53
  };
40
54
  useEffect(() => {
41
- let families = [];
55
+ let families = ["PoppinsRegular"];
42
56
  if (!readOnly) {
43
57
  otherProps.services("listGoogleFont", []).then(data => {
44
- families = data?.data.map(sanitizeFontFamily);
58
+ families = [...defaultFonts, ...(data?.data || ['PoppinsRegular'])];
59
+ const filteredfamilies = families.filter(font => !font.includes("Material"));
45
60
  setFontFamilies({
46
61
  id: 1,
47
62
  format: "fontFamily",
48
63
  type: "fontfamilydropdown",
49
- options: families || []
64
+ options: filteredfamilies || []
50
65
  });
51
66
  loadFontsInBatches(families);
52
67
  }).catch(err => {
@@ -62,7 +77,7 @@ const FontLoader = props => {
62
77
  families = Array.from(fontSet);
63
78
  loadFontsInBatches(families);
64
79
  }
65
- }, []);
80
+ }, [readOnly, otherProps, setFontFamilies]);
66
81
  return null;
67
82
  };
68
83
  export default FontLoader;
@@ -13,12 +13,14 @@ import ArrowDropDownIcon from "@mui/icons-material/ArrowDropDown";
13
13
  import EmailRoundedIcon from "@mui/icons-material/EmailRounded";
14
14
  import InfoOutlinedIcon from "@mui/icons-material/InfoOutlined";
15
15
  import { AccordionTextFormatIcon, BoldTextFormatIcon, BulletedListTextFormatIcon, ButtonElementIcon, CarouselElementIcon, CheckListTextFormatIcon, ColorBoxElementIcon, DividerElementIcon, DocUploadElementIcon, EmbedElementIcon, EmojiElementIcon, FormElementIcon, GridElementIcon, ImageElementIcon, ItalicTextFormatIcon, LinkIconV2, OrderedListTextFormatIcon, SignatureElementIcon, TableElementIcon, TopBannerElementIcon, UnderlineTextFormatIcon, VideoElementIcon } from "./iconListV2";
16
+ import MoreVertRoundedIcon from '@mui/icons-material/MoreVertRounded';
16
17
  import SettingsIcon from "../assets/svg/SettingsIcon";
17
18
  import UndoIcon from "../assets/svg/UndoIcon";
18
19
  import RedoIcon from "../assets/svg/RedoIcon";
19
20
  import TextIcon from "../assets/svg/TextIcon";
20
21
  import AddElementIcon from "../assets/svg/AddElementIcon";
21
22
  import AddTemplateIcon from "../assets/svg/AddTemplateIcon";
23
+ import OpenLinkIcon from "../assets/svg/OpenLinkIcon";
22
24
  import { jsx as _jsx } from "react/jsx-runtime";
23
25
  import { jsxs as _jsxs } from "react/jsx-runtime";
24
26
  const iconList = {
@@ -207,6 +209,7 @@ const iconList = {
207
209
  },
208
210
  size: 20
209
211
  }),
212
+ moreVertical: /*#__PURE__*/_jsx(MoreVertRoundedIcon, {}),
210
213
  leftArrow: /*#__PURE__*/_jsx(LeftArrow, {}),
211
214
  rightArrow: /*#__PURE__*/_jsx(RightArrow, {}),
212
215
  checkListButton: /*#__PURE__*/_jsx(CheckListButton, {}),
@@ -266,7 +269,8 @@ const iconList = {
266
269
  redoIcon: /*#__PURE__*/_jsx(RedoIcon, {}),
267
270
  textIcon: /*#__PURE__*/_jsx(TextIcon, {}),
268
271
  addElement: /*#__PURE__*/_jsx(AddElementIcon, {}),
269
- addTemplate: /*#__PURE__*/_jsx(AddTemplateIcon, {})
272
+ addTemplate: /*#__PURE__*/_jsx(AddTemplateIcon, {}),
273
+ openLinkIcon: /*#__PURE__*/_jsx(OpenLinkIcon, {})
270
274
  };
271
275
  export const icons = {
272
276
  ...iconList
@@ -11,6 +11,7 @@ import ArrowDownwardIcon from "@mui/icons-material/ArrowDownward";
11
11
  import SaveIcon from "@mui/icons-material/Save";
12
12
  import LinkIcon from "./Icons/LinkIcon";
13
13
  import CodeIcon from "@mui/icons-material/Code";
14
+ import FilterFramesIcon from "@mui/icons-material/FilterFrames";
14
15
  import { GridAddSectionIcon, WorkflowIcon } from "../../iconslist";
15
16
  const Actions = {
16
17
  ai: {
@@ -104,6 +105,12 @@ const Actions = {
104
105
  Button: IconButton,
105
106
  Icon: SaveIcon,
106
107
  title: "Save As Template"
108
+ },
109
+ imageFrame: {
110
+ type: "imageFrame",
111
+ Button: IconButton,
112
+ Icon: FilterFramesIcon,
113
+ title: "Image Frame Settings"
107
114
  }
108
115
  };
109
116
  export default Actions;
@@ -236,6 +236,14 @@ const RnD = props => {
236
236
  selectedActionPath: path
237
237
  });
238
238
  break;
239
+ case "imageFrame":
240
+ setSelectedElement({
241
+ ...selectedElementProps,
242
+ enable: 2,
243
+ selectedAction: actionType,
244
+ selectedActionPath: path
245
+ });
246
+ break;
239
247
  case "saveAsTemplate":
240
248
  const curPath = type === "parent" ? Path.parent(path) : path;
241
249
  const currentNode = Node.get(editor, curPath);
@@ -13,6 +13,7 @@ const appHeaderStyle = [{
13
13
  key: "titleFontFamily",
14
14
  type: "textOptions",
15
15
  options: fontOptions,
16
+ webFont: true,
16
17
  width: 7,
17
18
  renderOption: option => {
18
19
  return /*#__PURE__*/_jsx("span", {
@@ -80,7 +80,9 @@ export const commands = props => {
80
80
  RnDCtrlCmds[event.key](event, {
81
81
  editor
82
82
  });
83
- } else if (EDITORCMDS[event.key]) {
83
+ }
84
+ // for select all
85
+ if (EDITORCMDS[event.key]) {
84
86
  EDITORCMDS[event.key](event, {
85
87
  editor,
86
88
  needLayout
@@ -236,9 +238,9 @@ export const enterEvent = (e, editor, isMobile) => {
236
238
  if (isAtEnd) {
237
239
  e.preventDefault();
238
240
  Transforms.insertNodes(editor, {
239
- type: 'paragraph',
241
+ type: "paragraph",
240
242
  children: [{
241
- text: ''
243
+ text: ""
242
244
  }]
243
245
  });
244
246
  const newLocation = Editor.after(editor, selection);
@@ -249,7 +251,7 @@ export const enterEvent = (e, editor, isMobile) => {
249
251
  e.preventDefault();
250
252
  Transforms.splitNodes(editor);
251
253
  Transforms.setNodes(editor, {
252
- type: 'paragraph'
254
+ type: "paragraph"
253
255
  }, {
254
256
  at: Editor.after(editor, selection)
255
257
  });
@@ -260,9 +262,9 @@ export const enterEvent = (e, editor, isMobile) => {
260
262
  } else if (isAtStart) {
261
263
  e.preventDefault();
262
264
  Transforms.insertNodes(editor, {
263
- type: 'paragraph',
265
+ type: "paragraph",
264
266
  children: [{
265
- text: ''
267
+ text: ""
266
268
  }]
267
269
  }, {
268
270
  at: Editor.before(editor, selection)
@@ -115,6 +115,10 @@ export const handleInsertLastElement = (event, editor) => {
115
115
  return;
116
116
  }
117
117
  const lastElement = editor.children[editor.children?.length - 1];
118
+ const isFreeGrid = lastElement?.type === "freegrid" || lastElement?.children[0]?.type === "freegrid";
119
+ if (isFreeGrid) {
120
+ return;
121
+ }
118
122
  const isLastElementEmpty = lastElement.type === "paragraph" && !lastElement.children[0]?.text && !lastElement.children?.some(c => c.type === "grid");
119
123
  if (!ReactEditor.isFocused(editor)) {
120
124
  if (isLastElementEmpty) {
@@ -20,7 +20,7 @@ export const getPageSettings = editor => {
20
20
  const [pageSettingsNode] = Editor.nodes(editor, {
21
21
  at: [],
22
22
  match: n => {
23
- return !Editor.isEditor(n) && Element.isElement(n) && n.type === "page-settings";
23
+ return n.type === "page-settings";
24
24
  }
25
25
  });
26
26
  if (pageSettingsNode && pageSettingsNode[0] && pageSettingsNode[1]) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flozy/editor",
3
- "version": "4.1.2",
3
+ "version": "4.1.4",
4
4
  "description": "An Editor for flozy app brain",
5
5
  "files": [
6
6
  "dist"