@flozy/editor 11.0.1 → 11.0.2

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.
@@ -22,7 +22,7 @@ import { DEFAULT_TABLE_NODE } from "../../utils/table";
22
22
  import itemOptions from "./Options/sectionItemOptions";
23
23
  import { getBreakPointsValue, groupByBreakpoint } from "../../helper/theme";
24
24
  import { useDebouncedCallback } from "use-debounce";
25
- import { getNewElementXsValues } from "./helper";
25
+ import { getElementValues } from "./helper";
26
26
  import updateFormName from "../../utils/updateFormName";
27
27
  import { jsx as _jsx } from "react/jsx-runtime";
28
28
  import { jsxs as _jsxs } from "react/jsx-runtime";
@@ -185,9 +185,9 @@ const FreeGrid = props => {
185
185
  const isEmpty = isEmptySection();
186
186
  const insertAt = isEmpty ? [...path, 0] : [...path, childrenCountRef.current];
187
187
  const {
188
- xsVal,
189
- sectionHeightXs
190
- } = getNewElementXsValues(type, element?.children);
188
+ elValues,
189
+ sectionVal
190
+ } = getElementValues(type, element?.children, breakpoint);
191
191
  const id = crypto?.randomUUID();
192
192
  switch (type) {
193
193
  case "addText":
@@ -200,13 +200,7 @@ const FreeGrid = props => {
200
200
  text: "Text"
201
201
  }]
202
202
  }],
203
- gridArea: "3 / 1 / 4 / 2",
204
- left: 50,
205
- marginTop: 0,
206
- top: 0,
207
- width: 170,
208
- height: 30,
209
- ...(xsVal || {})
203
+ ...(elValues || {})
210
204
  }], {
211
205
  at: [...insertAt]
212
206
  });
@@ -227,13 +221,7 @@ const FreeGrid = props => {
227
221
  textAlign: "center",
228
222
  label: "Get Started"
229
223
  }],
230
- gridArea: "3 / 1 / 4 / 2",
231
- left: 50,
232
- marginTop: 0,
233
- top: 0,
234
- width: 143,
235
- height: 50,
236
- ...(xsVal || {})
224
+ ...(elValues || {})
237
225
  }], {
238
226
  at: [...insertAt]
239
227
  });
@@ -253,15 +241,7 @@ const FreeGrid = props => {
253
241
  date: ""
254
242
  }
255
243
  }],
256
- gridArea: "3 / 1 / 4 / 2",
257
- left: 50,
258
- marginTop: 0,
259
- top: 0,
260
- width: 217,
261
- height: 173,
262
- // width_xs: 217,
263
- // height_xs: 173,
264
- ...(xsVal || {})
244
+ ...(elValues || {})
265
245
  }], {
266
246
  at: [...insertAt]
267
247
  });
@@ -281,13 +261,7 @@ const FreeGrid = props => {
281
261
  fromFreeGrid: true,
282
262
  uniqueId: id
283
263
  }],
284
- gridArea: "3 / 1 / 4 / 2",
285
- left: 50,
286
- marginTop: 0,
287
- top: 0,
288
- width: 650,
289
- height: 80,
290
- ...(xsVal || {})
264
+ ...(elValues || {})
291
265
  }], {
292
266
  at: [...insertAt]
293
267
  });
@@ -297,13 +271,9 @@ const FreeGrid = props => {
297
271
  ...insertFreeGridItem("video", createEmbedNode("video", {
298
272
  url: "",
299
273
  alt: "",
300
- images: [],
301
- fromFreeGrid: true,
302
- uniqueId: id
274
+ images: []
303
275
  }), {
304
- height: 370,
305
- width: 650,
306
- ...(xsVal || {})
276
+ ...(elValues || {})
307
277
  })
308
278
  }], {
309
279
  at: [...insertAt]
@@ -314,9 +284,7 @@ const FreeGrid = props => {
314
284
  ...insertFreeGridItem("table", {
315
285
  ...DEFAULT_TABLE_NODE()
316
286
  }, {
317
- height: 150,
318
- width: 400,
319
- ...(xsVal || {})
287
+ ...(elValues || {})
320
288
  })
321
289
  }], {
322
290
  at: [...insertAt]
@@ -335,13 +303,7 @@ const FreeGrid = props => {
335
303
  isEncoded: true,
336
304
  isSanitized: true
337
305
  }],
338
- gridArea: "3 / 1 / 4 / 2",
339
- left: 50,
340
- marginTop: 0,
341
- top: 0,
342
- width: 400,
343
- height: 300,
344
- ...(xsVal || {})
306
+ ...(elValues || {})
345
307
  }], {
346
308
  at: [...insertAt]
347
309
  });
@@ -354,7 +316,7 @@ const FreeGrid = props => {
354
316
  text: ""
355
317
  }]
356
318
  }, {
357
- ...(xsVal || {})
319
+ ...(elValues || {})
358
320
  }, "freegridBox")
359
321
  }], {
360
322
  at: [...insertAt]
@@ -365,9 +327,7 @@ const FreeGrid = props => {
365
327
  ...insertFreeGridItem("form", {
366
328
  ...FORM_NODE()
367
329
  }, {
368
- height: 92,
369
- width: 400,
370
- ...(xsVal || {})
330
+ ...(elValues || {})
371
331
  })
372
332
  }], {
373
333
  at: [...insertAt]
@@ -380,9 +340,7 @@ const FreeGrid = props => {
380
340
  menus: null
381
341
  })
382
342
  }, {
383
- height: 60,
384
- width: 400,
385
- ...(xsVal || {})
343
+ ...(elValues || {})
386
344
  })
387
345
  }], {
388
346
  at: [...insertAt]
@@ -398,28 +356,21 @@ const FreeGrid = props => {
398
356
  text: ""
399
357
  }]
400
358
  }],
401
- gridArea: "3 / 1 / 4 / 2",
402
- left: 50,
403
- marginTop: 0,
404
- top: 0,
405
- width: 170,
406
- height: 30,
407
- ...(xsVal || {})
359
+ ...(elValues || {})
408
360
  }], {
409
361
  at: [...insertAt]
410
362
  });
411
363
  break;
412
364
  default:
413
365
  }
414
- if (xsVal) {
415
- setSelectedElement({});
416
- Transforms.setNodes(editor, {
417
- height_xs: sectionHeightXs,
418
- updated_at: new Date().getTime()
419
- }, {
420
- at: path
421
- });
422
- }
366
+ setSelectedElement({});
367
+ // increase the section height if new element is inserted based on auto align
368
+ Transforms.setNodes(editor, {
369
+ ...sectionVal,
370
+ updated_at: new Date().getTime()
371
+ }, {
372
+ at: path
373
+ });
423
374
  count.current = count.current + 1;
424
375
 
425
376
  // focus on newly added element
@@ -525,7 +476,7 @@ const FreeGrid = props => {
525
476
  style: {
526
477
  position: "relative",
527
478
  "--height": `${height}px`,
528
- display: 'block' //for test purpose
479
+ display: "block" //for test purpose
529
480
  },
530
481
 
531
482
  dataSets: {
@@ -197,7 +197,8 @@ const FreeGridBox = props => {
197
197
  "data-margin-top-xs": marginTop_xs,
198
198
  "data-height-xs": height_xs,
199
199
  "data-width-xs": width_xs,
200
- "data-left-xs": left_xs
200
+ "data-left-xs": left_xs,
201
+ "data-width-lg": width
201
202
  },
202
203
  gridArea: gridArea,
203
204
  onChange: onChange,
@@ -296,7 +296,8 @@ const FreeGridItem = props => {
296
296
  "data-margin-top-xs": marginTop_xs,
297
297
  "data-height-xs": height_xs,
298
298
  "data-width-xs": width_xs,
299
- "data-left-xs": left_xs
299
+ "data-left-xs": left_xs,
300
+ "data-width-lg": width
300
301
  },
301
302
  defaultStyle: {
302
303
  height: `${height}px`,
@@ -21,55 +21,100 @@ const commonXsValues = {
21
21
  width_xs: 272,
22
22
  xs_updatedOn: new Date().getTime()
23
23
  };
24
- const elementXsValues = {
24
+ const elementValues = {
25
25
  [ELEMENT_CASE.ADD_TEXT]: {
26
- ...commonXsValues,
27
- height_xs: 50
26
+ gridArea: "3 / 1 / 4 / 2",
27
+ left: 50,
28
+ marginTop: 0,
29
+ top: 0,
30
+ width: 170,
31
+ height: 30,
32
+ height_xs: 50,
33
+ ...commonXsValues
28
34
  },
29
35
  [ELEMENT_CASE.ADD_BUTTON]: {
30
- ...commonXsValues,
31
- height_xs: 50
36
+ gridArea: "3 / 1 / 4 / 2",
37
+ left: 50,
38
+ marginTop: 0,
39
+ top: 0,
40
+ width: 143,
41
+ height: 50,
42
+ height_xs: 50,
43
+ ...commonXsValues
32
44
  },
33
45
  [ELEMENT_CASE.ADD_SIGNATURE]: {
34
- ...commonXsValues,
35
- height_xs: 173
46
+ left: 50,
47
+ marginTop: 0,
48
+ top: 0,
49
+ width: 217,
50
+ height: 173,
51
+ height_xs: 173,
52
+ ...commonXsValues
36
53
  },
37
54
  [ELEMENT_CASE.ADD_IMAGE]: {
38
- ...commonXsValues,
39
- height_xs: 80
55
+ gridArea: "3 / 1 / 4 / 2",
56
+ left: 50,
57
+ marginTop: 0,
58
+ top: 0,
59
+ width: 170,
60
+ height: 80,
61
+ height_xs: 80,
62
+ ...commonXsValues
40
63
  },
41
64
  [ELEMENT_CASE.ADD_VIDEO]: {
42
- ...commonXsValues,
43
- height_xs: 300
65
+ height: 370,
66
+ width: 650,
67
+ height_xs: 300,
68
+ ...commonXsValues
44
69
  },
45
70
  [ELEMENT_CASE.ADD_TABLE]: {
46
- ...commonXsValues,
47
- height_xs: 165
71
+ height: 150,
72
+ width: 400,
73
+ height_xs: 165,
74
+ ...commonXsValues
48
75
  },
49
76
  [ELEMENT_CASE.ADD_CODE]: {
50
- ...commonXsValues,
51
- height: 300
77
+ gridArea: "3 / 1 / 4 / 2",
78
+ left: 50,
79
+ marginTop: 0,
80
+ top: 0,
81
+ width: 400,
82
+ height: 300,
83
+ ...commonXsValues
52
84
  },
53
85
  [ELEMENT_CASE.ADD_BOX]: {
54
- ...commonXsValues,
55
- height_xs: 300
86
+ height_xs: 300,
87
+ ...commonXsValues
56
88
  },
57
89
  [ELEMENT_CASE.ADD_FORM]: {
58
- ...commonXsValues,
59
- height_xs: 80
90
+ height: 92,
91
+ width: 400,
92
+ height_xs: 80,
93
+ ...commonXsValues
60
94
  },
61
95
  [ELEMENT_CASE.ADD_APP_HEADER]: {
62
- ...commonXsValues,
63
- height_xs: 80
96
+ height: 60,
97
+ width: 400,
98
+ height_xs: 80,
99
+ ...commonXsValues
64
100
  },
65
101
  [ELEMENT_CASE.ADD_DIVIDER]: {
66
- ...commonXsValues,
67
- height_xs: 24
102
+ gridArea: "3 / 1 / 4 / 2",
103
+ left: 50,
104
+ marginTop: 0,
105
+ top: 0,
106
+ width: 170,
107
+ height: 30,
108
+ height_xs: 24,
109
+ ...commonXsValues
68
110
  }
69
111
  };
70
112
  export const findMaxYValue = (sectionItems, breakpoint) => {
71
113
  let maxY = 0;
72
114
  sectionItems.forEach(item => {
115
+ if (!item?.type) {
116
+ return;
117
+ }
73
118
  const isHidden = breakpoint === "xs" && item.children.some(c => c.xsHidden);
74
119
  if (item?.type && RND_ITEMS.includes(item.type) && !isHidden) {
75
120
  const {
@@ -94,22 +139,56 @@ export const convertToGridArea = y => {
94
139
  marginTop
95
140
  };
96
141
  };
97
- export const getNewElementXsValues = (type, sectionItems) => {
98
- const values = elementXsValues[type] || {};
99
- const y = sectionItems?.length ? findMaxYValue(sectionItems) : 0;
142
+ const BUFFER_MARGIN_TOP = 12;
143
+ const getInsertValues = (sectionItems, breakpoint, elValues) => {
144
+ const y_xs = sectionItems?.length ? findMaxYValue(sectionItems, breakpoint) : 0;
100
145
  const {
101
146
  gridArea,
102
147
  marginTop
103
- } = convertToGridArea(y);
104
- const BUFFER_MARGIN_TOP = 12;
105
- const xsVal = {
106
- ...values,
107
- gridArea_xs: gridArea,
108
- marginTop_xs: marginTop + BUFFER_MARGIN_TOP
148
+ } = convertToGridArea(y_xs);
149
+ const appendBp = breakpoint === "lg" ? "" : "_xs";
150
+ const insertPos = {
151
+ [`gridArea${appendBp}`]: gridArea,
152
+ [`marginTop${appendBp}`]: marginTop + BUFFER_MARGIN_TOP
153
+ };
154
+ const sectionHeight = y_xs + elValues[`height${appendBp}`] + BUFFER_MARGIN_TOP + 12;
155
+ return {
156
+ insertPos,
157
+ sectionHeight
109
158
  };
110
- const sectionHeightXs = y + values?.height_xs + BUFFER_MARGIN_TOP + 12;
159
+ };
160
+ export const getElementValues = (type, sectionItems, breakpoint) => {
161
+ const elValues = elementValues[type] || {};
162
+ let elInsertPos = {};
163
+ let sectionVal = {};
164
+
165
+ // insert element on xs
166
+ const {
167
+ insertPos: insertPos_xs,
168
+ sectionHeight: sectionHeight_xs
169
+ } = getInsertValues(sectionItems, "xs", elValues);
170
+ elInsertPos = {
171
+ ...insertPos_xs
172
+ };
173
+ sectionVal.height_xs = sectionHeight_xs;
174
+
175
+ // if user in xs, auto-align lg
176
+ if (breakpoint === "xs") {
177
+ const {
178
+ insertPos: insertPos_lg,
179
+ sectionHeight
180
+ } = getInsertValues(sectionItems, "lg", elValues);
181
+ elInsertPos = {
182
+ ...elInsertPos,
183
+ ...insertPos_lg
184
+ };
185
+ sectionVal.height = sectionHeight;
186
+ }
111
187
  return {
112
- xsVal,
113
- sectionHeightXs
188
+ elValues: {
189
+ ...elValues,
190
+ ...elInsertPos
191
+ },
192
+ sectionVal
114
193
  };
115
194
  };
@@ -9,7 +9,7 @@ import { useEditorContext } from "../../hooks/useMouseMove";
9
9
  import usePopupStyles from "../PopupTool/PopupToolStyle";
10
10
  import useEditorScroll from "../../hooks/useEditorScroll";
11
11
  import { isCarouselSelected } from "../../helper";
12
- import { hideSlateSelection, viewSlateSelection } from "../../utils/helper";
12
+ import { viewSlateSelection } from "../../utils/helper";
13
13
  import { jsx as _jsx } from "react/jsx-runtime";
14
14
  const isSlateDOM = event => {
15
15
  return event.target.getAttribute("data-slate-string") === "true";
@@ -95,7 +95,7 @@ const PopupTool = props => {
95
95
  const isFreeGridEnabled = enable === 1 && isFreeGridElement;
96
96
  if (!selection || Range.isCollapsed(selection) || Editor.string(editor, selection) === "" || isFreeGridEnabled) {
97
97
  setAnchorEl(null);
98
- hideSlateSelection(); // removes slate selection background, when there is no selection
98
+ // hideSlateSelection(); // removes slate selection background, when there is no selection
99
99
  } else {
100
100
  updateAnchorEl();
101
101
  viewSlateSelection();
@@ -243,6 +243,13 @@ export function onDropItem(props, parentClass) {
243
243
  const isBoxHeader = currentNode?.childType === "appHeader" && moveTo?.length > 2;
244
244
  if (isBoxHeader) {
245
245
  // will handle on <BoxHeaderAutoAlignment />
246
+ } else if (moveTo?.length === 2 && autoAlign) {
247
+ // auto align in mobile
248
+ Transforms.setNodes(editor, {
249
+ xs_updatedOn: new Date().getTime()
250
+ }, {
251
+ at: moveTo
252
+ });
246
253
  } else if (autoAlign) {
247
254
  Transforms.setNodes(editor, {
248
255
  autoAlign: true,
@@ -47,7 +47,8 @@ function VirtualTextElement(props) {
47
47
  dataSets,
48
48
  getCurrentEle,
49
49
  path,
50
- editor
50
+ editor,
51
+ breakpoint
51
52
  } = props;
52
53
  const currElement = getCurrentEle();
53
54
  const textRef = useRef(null);
@@ -61,7 +62,7 @@ function VirtualTextElement(props) {
61
62
  const currentText = currElement?.innerText;
62
63
  const prevText = prevTextRef?.current;
63
64
  if (currentText && currentText !== prevText) {
64
- updateTextHeight(editor, path, height, "xs");
65
+ updateTextHeight(editor, path, height, breakpoint);
65
66
  }
66
67
  prevTextRef.current = currentText;
67
68
  }
@@ -77,11 +78,12 @@ function VirtualTextElement(props) {
77
78
  }
78
79
  observer.disconnect();
79
80
  };
80
- }, [currElement?.innerText]);
81
+ }, [currElement?.innerText, breakpoint]);
82
+ const fontSize = `var(--fontSize_${breakpoint}) !important`;
81
83
  return /*#__PURE__*/_jsx(Box, {
82
84
  style: {
83
85
  position: "fixed",
84
- width: dataSets["data-width-xs"],
86
+ width: dataSets[`data-width-${breakpoint}`],
85
87
  minHeight: "fit-content",
86
88
  visibility: "hidden",
87
89
  pointerEvents: "none",
@@ -91,9 +93,9 @@ function VirtualTextElement(props) {
91
93
  ref: textRef,
92
94
  sx: {
93
95
  "& .leaf-item": {
94
- fontSize: "var(--fontSize_xs) !important",
96
+ fontSize: fontSize,
95
97
  "& span": {
96
- fontSize: "var(--fontSize_xs) !important"
98
+ fontSize: fontSize
97
99
  }
98
100
  },
99
101
  "& .editor-blocker": {
@@ -46,6 +46,21 @@ function getTextElementHeight(textElement) {
46
46
  }
47
47
  return totalHeight;
48
48
  }
49
+ function textAutoAlign(editor, path, getCurrentEle, delta, breakpoint, onLoad) {
50
+ const currElement = getCurrentEle();
51
+ const textElement = currElement?.querySelector(".fgi_type_text");
52
+ const clientHeight = getTextElementHeight(textElement);
53
+ const {
54
+ height
55
+ } = delta || {};
56
+ const heightDiff = Math.abs(clientHeight - height);
57
+ const autoAlign = onLoad ? clientHeight > height : heightDiff >= 5;
58
+ if (clientHeight && height && autoAlign) {
59
+ updateTextHeight(editor, path, clientHeight, breakpoint);
60
+ const parentSectionPath = path.slice(0, 2);
61
+ reRenderChildNodes(editor, parentSectionPath);
62
+ }
63
+ }
49
64
  const ITEM_TYPES = ["child", "parent-container"];
50
65
  const EDIT_MODES = ["text", "form", "table"];
51
66
  const DISABLE_RESIZING = {
@@ -151,6 +166,7 @@ const RnD = props => {
151
166
  translation
152
167
  } = customProps;
153
168
  const timerId = useRef(0);
169
+ const isFirstRender = useRef(true);
154
170
  useEffect(() => {
155
171
  if (ITEM_TYPES.includes(type)) {
156
172
  if (enable === 1) {
@@ -160,24 +176,19 @@ const RnD = props => {
160
176
  setAbsPosition({});
161
177
  }
162
178
  }
163
- const currElement = getCurrentEle();
164
- const textElement = currElement?.querySelector(".fgi_type_text");
165
- if (breakpoint && textElement && childType === "text" && !enable) {
166
- timerId.current = setTimeout(() => {
167
- // const { clientHeight } = textElement;
168
- const clientHeight = getTextElementHeight(textElement);
169
- const {
170
- height
171
- } = delta || {};
172
- const heightDiff = Math.abs(clientHeight - height);
173
- if (clientHeight && height && heightDiff >= 5) {
174
- updateTextHeight(editor, path, clientHeight, breakpoint);
175
- const parentSectionPath = path.slice(0, 2);
176
- reRenderChildNodes(editor, parentSectionPath);
177
- }
178
- }, 200);
179
+ if (childType === "text" && !enable && !readOnly) {
180
+ if (isFirstRender.current) {
181
+ isFirstRender.current = false;
182
+ timerId.current = setTimeout(() => {
183
+ // auto align on load
184
+ textAutoAlign(editor, path, getCurrentEle, delta, breakpoint, true);
185
+ }, 200);
186
+ } else {
187
+ // auto align when the text is changed
188
+ textAutoAlign(editor, path, getCurrentEle, delta, breakpoint);
189
+ }
179
190
  }
180
- return () => clearTimeout(timerId.current);
191
+ return () => clearTimeout(timerId?.current);
181
192
  }, [enable]);
182
193
  const getCurrentEle = () => {
183
194
  return positionRef.current?.resizableElement?.current;
@@ -726,11 +737,12 @@ const RnD = props => {
726
737
  handleClose: handleClose,
727
738
  theme: theme,
728
739
  translation: translation
729
- }), childType === "text" && breakpoint === "lg" && !readOnly && enable ? /*#__PURE__*/_jsx(VirtualTextElement, {
740
+ }), childType === "text" && !readOnly && enable ? /*#__PURE__*/_jsx(VirtualTextElement, {
730
741
  editor: editor,
731
742
  dataSets: dataSets,
732
743
  getCurrentEle: getCurrentEle,
733
- path: path
744
+ path: path,
745
+ breakpoint: breakpoint === "xs" ? "lg" : "xs" // auto-align for this passed breakpoint
734
746
  }) : null, type === "parent" && breakpoint === "xs" && !readOnly && autoAlign ? /*#__PURE__*/_jsx(ForceAutoAlignment, {
735
747
  updated_at: updated_at,
736
748
  path: str_path,
@@ -401,7 +401,8 @@ export const getMarked = (leaf, children, theme) => {
401
401
  WebkitTextFillColor: "unset !important"
402
402
  },
403
403
  style: {
404
- "--fontSize_xs": leaf?.fontSize?.xs || "auto"
404
+ "--fontSize_xs": leaf?.fontSize?.xs || "auto",
405
+ "--fontSize_lg": leaf?.fontSize?.lg || "auto"
405
406
  },
406
407
  children: children
407
408
  })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flozy/editor",
3
- "version": "11.0.1",
3
+ "version": "11.0.2",
4
4
  "description": "An Editor for flozy app brain",
5
5
  "files": [
6
6
  "dist"