@flozy/editor 4.1.1 → 4.1.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -366,9 +366,6 @@ const CommonEditor = /*#__PURE__*/forwardRef((props, ref) => {
366
366
  });
367
367
  } else if (event.key === "Enter") {
368
368
  enterEvent(event, editor, customProps?.isMobile);
369
- } else if (event.key === 'Backspace') {
370
- event.preventDefault();
371
- editor.deleteBackward();
372
369
  }
373
370
  }, [chars, editor, target, mentions, setMentions, search, type, mentionsRef]);
374
371
  const Overlay = collaborativeEditor && !isReadOnly ? RemoteCursorOverlay : React.Fragment;
@@ -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",
@@ -160,6 +160,14 @@ const useFreeGridStyles = ({
160
160
  }
161
161
  },
162
162
  "& .fgi_type_appHeader": {
163
+ maxWidth: "100%",
164
+ maxHeight: "100%",
165
+ overflow: "hidden",
166
+ display: "flex",
167
+ alignItems: "center",
168
+ "& .app-h-wrpr": {
169
+ width: "100%"
170
+ },
163
171
  "& .MuiAppBar-root": {
164
172
  zIndex: 100
165
173
  },
@@ -168,10 +176,11 @@ const useFreeGridStyles = ({
168
176
  paddingRight: "0px !important",
169
177
  "& .app-drawer-btn": {
170
178
  marginRight: "0px",
171
- width: "100%",
179
+ paddingTop: "12px",
180
+ // width: "100%",
172
181
  "& svg": {
173
- width: "100%",
174
- height: "100%"
182
+ // width: "100%",
183
+ // height: "100%",
175
184
  }
176
185
  }
177
186
  }
@@ -52,7 +52,9 @@ const MiniToolbar = props => {
52
52
  const boxRef = useRef(null); // Add ref to get the Box element
53
53
  const UPDATED_MENU_OPTIONS = MENU_OPTIONS.filter(f => (hideTools || [])?.indexOf(f.type) === -1);
54
54
  const {
55
- popupType
55
+ popupType,
56
+ selectedElement,
57
+ setSelectedElement
56
58
  } = useEditorContext();
57
59
  const canUndo = editor.history.undos.length > 0;
58
60
  const canRedo = editor.history.redos.length > 0;
@@ -75,6 +77,11 @@ const MiniToolbar = props => {
75
77
  }
76
78
  setPopper(type);
77
79
  setAnchorEl(e.currentTarget);
80
+ setSelectedElement({
81
+ ...selectedElement,
82
+ enable: 1,
83
+ selectedAction: null
84
+ });
78
85
  };
79
86
  const onClose = () => {
80
87
  setPopper(null);
@@ -116,13 +123,14 @@ const MiniToolbar = props => {
116
123
  label,
117
124
  icon: Icon
118
125
  }) => {
119
- const isDisabled = popupType === type || type === 'undo' ? !canUndo : type === 'redo' ? !canRedo : false;
126
+ const isDisabled = popupType === type || type === "undo" ? !canUndo : type === "redo" ? !canRedo : false; // for textFormat type
127
+
120
128
  return /*#__PURE__*/_jsx(Tooltip, {
121
129
  arrow: true,
122
130
  title: label,
123
131
  disableHoverListener: toolTip,
124
132
  children: /*#__PURE__*/_jsx(IconButton, {
125
- className: `${type === popper ? "active" : ""} ${type === 'undo' && !canUndo || type === 'redo' && !canRedo ? "disabled" : ""}`,
133
+ className: `${type === popper ? "active" : ""} ${type === "undo" && !canUndo || type === "redo" && !canRedo ? "disabled" : ""}`,
126
134
  onClick: handleClick(type),
127
135
  disabled: isDisabled,
128
136
  children: type === "page-settings" ? /*#__PURE__*/_jsx(PageSettingsButton, {
@@ -591,8 +591,9 @@ const usePopupStyle = theme => ({
591
591
  border: "1px solid #E4E8EB",
592
592
  maxHeight: "140px",
593
593
  background: theme?.palette?.editor?.background,
594
- overflowY: "hidden",
594
+ // overflowY: "hidden",
595
595
  padding: "6px 12px 6px 0px",
596
+ overflowY: "scroll",
596
597
  "@media only screen and (max-width: 600px)": {
597
598
  marginTop: "-40px"
598
599
  }
@@ -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
@@ -22,6 +22,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
22
22
  import { jsxs as _jsxs } from "react/jsx-runtime";
23
23
  import { Fragment as _Fragment } from "react/jsx-runtime";
24
24
  const ITEM_TYPES = ["child", "parent-container"];
25
+ const EDIT_MODES = ["text", "form"];
25
26
  let hover_on = new Set();
26
27
  const RnD = props => {
27
28
  const rndRef = useRef(null);
@@ -180,7 +181,7 @@ const RnD = props => {
180
181
  });
181
182
  setSelectedElement({
182
183
  path: str_path,
183
- enable: 2,
184
+ enable: EDIT_MODES.includes(childType) ? 2 : 1,
184
185
  cursor: "auto",
185
186
  anchorEl: rndRef?.current
186
187
  });
@@ -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.1",
3
+ "version": "4.1.3",
4
4
  "description": "An Editor for flozy app brain",
5
5
  "files": [
6
6
  "dist"