@flozy/editor 10.1.3 → 10.1.5

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.
@@ -10,7 +10,7 @@ import { draftToSlate } from "./utils/draftToSlate";
10
10
  import useMentions from "./hooks/useMentions";
11
11
  import MentionsPopup from "./common/MentionsPopup";
12
12
  import { RemoteCursorOverlay } from "./RemoteCursorOverlay/Overlay";
13
- import { mentionsEvent, commands, indentation, escapeEvent, enterEvent, upDownArrowKeyEvents } from "./utils/events";
13
+ import { mentionsEvent, commands, indentation, escapeEvent, enterEvent, upDownArrowKeyEvents, handleAccordionOnBackspace } from "./utils/events";
14
14
  import withCommon from "./hooks/withCommon";
15
15
  import DialogWrapper from "./DialogWrapper";
16
16
  import { serializeToText } from "./utils/serializeToText";
@@ -451,6 +451,10 @@ const CommonEditor = /*#__PURE__*/forwardRef((props, ref) => {
451
451
  } else if (event.key === "ArrowDown" && otherProps?.tagName !== "Pages") {
452
452
  upDownArrowKeyEvents(event, editor);
453
453
  } else if (event.key === "Backspace") {
454
+ const isAccordion = handleAccordionOnBackspace(event, editor);
455
+ if (isAccordion) {
456
+ return;
457
+ }
454
458
  const isNodeRestricted = isRestrictedNode(event, editor);
455
459
  if (isNodeRestricted) {
456
460
  return;
@@ -426,6 +426,32 @@ blockquote {
426
426
 
427
427
  .upload-sign-img-wrapper {
428
428
  text-align: center;
429
+ position: relative;
430
+ }
431
+
432
+ .upload-sign-img {
433
+ max-width: 100%;
434
+ }
435
+
436
+ .remove-sign-img-btn {
437
+ padding: 8px 12px;
438
+ background-color: #ffffff68;
439
+ cursor: pointer;
440
+ width: fit-content;
441
+ border-radius: 8px;
442
+ position: absolute;
443
+ left: 50%;
444
+ top: 50%;
445
+ transform: translate(-50%, -50%);
446
+ display: none;
447
+ }
448
+
449
+ .remove-sign-img-btn:hover {
450
+ background-color: #ffffffa0;
451
+ }
452
+
453
+ .upload-sign-img-wrapper:hover .remove-sign-img-btn {
454
+ display: block;
429
455
  }
430
456
 
431
457
  .signature-tab img {
@@ -8,6 +8,7 @@ import { GridSettingsIcon } from "../../common/iconslist";
8
8
  import Icon from "../../common/Icon";
9
9
  import { useEditorContext, useEditorSelection } from "../../hooks/useMouseMove";
10
10
  import useCommonStyle from "../../commonStyle";
11
+ import { getBorderColor } from "../../helper";
11
12
  import { jsx as _jsx } from "react/jsx-runtime";
12
13
  import { jsxs as _jsxs } from "react/jsx-runtime";
13
14
  const accordionBtnStyleKeys = {
@@ -78,8 +79,10 @@ const Accordion = props => {
78
79
  const path = ReactEditor.findPath(editor, element);
79
80
  const {
80
81
  textColor,
81
- bgColor
82
+ bgColor,
83
+ borderColor
82
84
  } = element;
85
+ const borderStyle = getBorderColor(borderColor);
83
86
  const {
84
87
  theme
85
88
  } = useEditorContext();
@@ -168,7 +171,8 @@ const Accordion = props => {
168
171
  children: [/*#__PURE__*/_jsxs("div", {
169
172
  className: "accordion-title",
170
173
  style: {
171
- background: bgColor
174
+ background: bgColor,
175
+ ...borderStyle
172
176
  },
173
177
  onClick: onToggle,
174
178
  children: [/*#__PURE__*/_jsx(Box, {
@@ -38,7 +38,8 @@ const CarouselItem = props => {
38
38
  className: "element-toolbar hr",
39
39
  style: {
40
40
  top: "0px",
41
- left: "0px"
41
+ left: "0px",
42
+ width: "fit-content"
42
43
  },
43
44
  contentEditable: false,
44
45
  children: /*#__PURE__*/_jsx(Tooltip, {
@@ -1,6 +1,6 @@
1
1
  /* eslint-disable no-unused-vars */
2
2
  import React, { useState } from "react";
3
- import { Transforms, Path, Node } from "slate";
3
+ import { Transforms, Path, Node, Editor, Element } from "slate";
4
4
  import { useSlateStatic, ReactEditor } from "slate-react";
5
5
  import { IconButton, Tooltip, Grid as GridContainer, useTheme } from "@mui/material";
6
6
  import ArrowUpwardIcon from "@mui/icons-material/ArrowUpward";
@@ -206,7 +206,19 @@ const Grid = props => {
206
206
  };
207
207
  const onAddSection = () => () => {
208
208
  try {
209
- const duplicateGrid = JSON.parse(JSON.stringify(element));
209
+ let duplicateGrid = JSON.parse(JSON.stringify(element));
210
+ const carousel = Editor.above(editor, {
211
+ at: path,
212
+ match: n => !Editor.isEditor(n) && Element.isElement(n) && n.type === "carousel-item"
213
+ });
214
+ if (carousel) {
215
+ const [carouselNode, carouselItemPath] = carousel || [];
216
+ const duplicatecCarousel = JSON.parse(JSON.stringify(carouselNode));
217
+ Transforms.insertNodes(editor, duplicatecCarousel, {
218
+ at: Path.next(carouselItemPath)
219
+ });
220
+ return;
221
+ }
210
222
  insertGrid(editor, duplicateGrid, [path[0] + 1, 0]);
211
223
  } catch (err) {
212
224
  console.log(err);
@@ -46,11 +46,12 @@
46
46
 
47
47
  .upload-input-wrapper {
48
48
  width: 100%;
49
+ height: 100%;
49
50
  position: relative;
50
51
  }
51
52
  .upload-input-wrapper input {
52
53
  width: 100%;
53
- height: 100px;
54
+ height: 100%;
54
55
  opacity: 0;
55
56
  z-index: 1;
56
57
  position: relative;
@@ -1,6 +1,7 @@
1
1
  import React, { useRef, useState } from "react";
2
2
  import SignatureCanvas from "react-signature-canvas";
3
- import { Grid, useMediaQuery } from "@mui/material";
3
+ import { Grid, IconButton, useMediaQuery } from "@mui/material";
4
+ import { ResetIcon } from "../../../common/iconListV2";
4
5
  import { jsx as _jsx } from "react/jsx-runtime";
5
6
  import { jsxs as _jsxs } from "react/jsx-runtime";
6
7
  const DrawSignature = props => {
@@ -24,6 +25,13 @@ const DrawSignature = props => {
24
25
  signature: result?.imageURL || strImage
25
26
  });
26
27
  };
28
+ const onClear = () => {
29
+ canvasRef.clear();
30
+ setUploading(false);
31
+ onDataChange({
32
+ signature: ""
33
+ });
34
+ };
27
35
  const isMobile = useMediaQuery("(max-width:599px)");
28
36
  const signatureCanvasStyle = isMobile ? {
29
37
  width: "260px",
@@ -31,14 +39,15 @@ const DrawSignature = props => {
31
39
  } : {};
32
40
  return /*#__PURE__*/_jsxs(Grid, {
33
41
  container: true,
34
- children: [uploading ? "Uploading..." : "", /*#__PURE__*/_jsx(Grid, {
42
+ children: [uploading ? "Uploading..." : "", /*#__PURE__*/_jsxs(Grid, {
35
43
  item: true,
36
44
  xs: 12,
37
45
  style: {
38
46
  width: "100%",
39
- height: "209px"
47
+ height: "209px",
48
+ position: "relative"
40
49
  },
41
- children: /*#__PURE__*/_jsx(SignatureCanvas, {
50
+ children: [/*#__PURE__*/_jsx(SignatureCanvas, {
42
51
  canvasProps: {
43
52
  className: "signature-canvas",
44
53
  ...signatureCanvasStyle
@@ -47,7 +56,11 @@ const DrawSignature = props => {
47
56
  ref: ref => canvasRef = ref,
48
57
  maxWidth: brush.size || 2,
49
58
  penColor: brush?.color || "#000"
50
- })
59
+ }), /*#__PURE__*/_jsx(IconButton, {
60
+ className: "clear-canvas",
61
+ onClick: onClear,
62
+ children: /*#__PURE__*/_jsx(ResetIcon, {})
63
+ })]
51
64
  })]
52
65
  });
53
66
  };
@@ -30,15 +30,28 @@ const UploadSignature = props => {
30
30
  signature: result?.imageURL || strImage
31
31
  });
32
32
  };
33
+ const onRemove = () => {
34
+ setBase64(null);
35
+ setUploading(false);
36
+ onUploadDone({
37
+ signature: ""
38
+ });
39
+ };
33
40
  return /*#__PURE__*/_jsxs("div", {
34
41
  className: "signature-tab2",
35
- children: [uploading ? "Uploading..." : "", base64 ? /*#__PURE__*/_jsx("div", {
42
+ children: [uploading ? "Uploading..." : "", base64 ? /*#__PURE__*/_jsxs("div", {
36
43
  className: "upload-sign-img-wrapper",
37
- children: /*#__PURE__*/_jsx("img", {
44
+ children: [/*#__PURE__*/_jsx("img", {
38
45
  className: "upload-sign-img",
39
46
  src: base64,
40
47
  alt: "Signature"
41
- })
48
+ }), /*#__PURE__*/_jsx(Typography, {
49
+ variant: "body2",
50
+ gutterBottom: true,
51
+ className: "remove-sign-img-btn",
52
+ onClick: onRemove,
53
+ children: "Remove"
54
+ })]
42
55
  }) : /*#__PURE__*/_jsxs("div", {
43
56
  className: "upload-input-wrapper",
44
57
  children: [/*#__PURE__*/_jsx("input", {
@@ -44,7 +44,6 @@ function DragButton({
44
44
  const dragProps = {
45
45
  ...dndProps,
46
46
  id: dndProps?.id + dragType,
47
- disabled: isMobile,
48
47
  data: {
49
48
  ...dndProps.data,
50
49
  dragType
@@ -13,9 +13,13 @@ function Draggable(props) {
13
13
  } = props?.data || {};
14
14
  const style = transform ? {
15
15
  transform: dragType === "row" ? `translate3d(0, ${transform.y}px, 0)` : `translate3d(${transform.x}px, 0, 0)`
16
- } : undefined;
16
+ } : {};
17
17
  return /*#__PURE__*/_jsx(Box, {
18
- style: style,
18
+ style: {
19
+ ...style,
20
+ touchAction: "none" // Disables scrolling while dragging. Necessary for proper mobile drag functionality.
21
+ },
22
+
19
23
  ref: setNodeRef,
20
24
  ...listeners,
21
25
  ...attributes,
@@ -86,6 +86,13 @@ const TableStyles = theme => {
86
86
  background: "#2563EB"
87
87
  }
88
88
  },
89
+ mobileCellResizer: {
90
+ position: "absolute",
91
+ right: "-10px",
92
+ top: "-10px",
93
+ zIndex: 4000,
94
+ padding: "2px"
95
+ },
89
96
  mobileToolDrawer: {
90
97
  "& .customSelectContainer": {
91
98
  border: "none !important",
@@ -1,6 +1,6 @@
1
1
  import React, { useState, useEffect, useMemo } from "react";
2
2
  import { Editor, Path, Transforms } from "slate";
3
- import { Box } from "@mui/material";
3
+ import { Box, IconButton } from "@mui/material";
4
4
  import { useSlateStatic, ReactEditor } from "slate-react";
5
5
  import useTableResize from "../../utils/customHooks/useTableResize";
6
6
  import { TableUtil } from "../../utils/table";
@@ -12,6 +12,7 @@ import TablePopup from "./TablePopup";
12
12
  import { Droppable } from "./Droppable";
13
13
  import { useDndContext } from "@dnd-kit/core";
14
14
  import { getNodeWithType } from "../../utils/helper";
15
+ import { ResizeIcon } from "../../common/iconListV2";
15
16
  import { isEmptyTextNode } from "../../helper";
16
17
  import SimpleText from "../SimpleText";
17
18
  import { jsx as _jsx } from "react/jsx-runtime";
@@ -41,16 +42,32 @@ const Resizer = ({
41
42
  onMouseDown,
42
43
  height
43
44
  }) => {
45
+ const eventProps = {
46
+ onPointerDown: onMouseDown
47
+ };
44
48
  return /*#__PURE__*/_jsx(_Fragment, {
45
49
  children: /*#__PURE__*/_jsx(Box, {
46
50
  component: "div",
47
51
  className: "cell-resizer",
48
52
  contentEditable: false,
49
- onPointerDown: onMouseDown,
50
53
  sx: classes.cellResizer,
51
54
  style: {
52
55
  height: `${height}px`
53
- }
56
+ },
57
+ ...eventProps
58
+ })
59
+ });
60
+ };
61
+ const MobileResizer = ({
62
+ classes,
63
+ onMouseDown
64
+ }) => {
65
+ return /*#__PURE__*/_jsx(_Fragment, {
66
+ children: /*#__PURE__*/_jsx(IconButton, {
67
+ contentEditable: false,
68
+ sx: classes.mobileCellResizer,
69
+ onTouchStart: onMouseDown,
70
+ children: /*#__PURE__*/_jsx(ResizeIcon, {})
54
71
  })
55
72
  });
56
73
  };
@@ -115,7 +132,8 @@ const TableCell = props => {
115
132
  size: element?.size,
116
133
  minMaxProps: {
117
134
  minWidth: 30
118
- }
135
+ },
136
+ isMobile
119
137
  });
120
138
  const [tableSize, setTableSize] = useState({});
121
139
  const [openSettings, setOpenSettings] = useState(false);
@@ -420,6 +438,7 @@ const TableCell = props => {
420
438
  resetSelection
421
439
  };
422
440
  const showRowDragBtn = (showRowDrag || isRowDragging) && containerEle?.scrollLeft <= 0;
441
+ const TableResizer = isMobile && hoverCol === column ? MobileResizer : Resizer;
423
442
  return /*#__PURE__*/_jsxs(_Fragment, {
424
443
  children: [/*#__PURE__*/_jsxs("td", {
425
444
  ...element.attr,
@@ -454,7 +473,7 @@ const TableCell = props => {
454
473
  padding: "8px"
455
474
  },
456
475
  children: children
457
- }), isHeader && !readOnly && tableSize?.height && !showTool ? /*#__PURE__*/_jsx(Resizer, {
476
+ }), isHeader && !readOnly && tableSize?.height && !showTool ? /*#__PURE__*/_jsx(TableResizer, {
458
477
  classes: classes,
459
478
  onMouseDown: onMouseDown,
460
479
  height: tableDOM?.getBoundingClientRect()?.height
@@ -322,7 +322,7 @@ function TextSize(props) {
322
322
  // to avoid default normal size
323
323
  if (size?.device === "lg") {
324
324
  upData = BREAKPOINTS_DEVICES.reduce((a, b) => {
325
- a[b] = `${newVal}px`;
325
+ a[b] = upData[b] || `${newVal}px`;
326
326
  return a;
327
327
  }, {});
328
328
  }
@@ -13,7 +13,7 @@ const Signature = props => {
13
13
  const pPath = path?.split("|")?.map(m => parseInt(m));
14
14
  const element_path = [...pPath, 0];
15
15
  const onSave = (data = {}) => {
16
- onClear();
16
+ onClear(element_path);
17
17
  Transforms.insertNodes(editor, [{
18
18
  type: "sign",
19
19
  signature: null,
@@ -35,9 +35,10 @@ const Signature = props => {
35
35
  at: parentPath
36
36
  });
37
37
  };
38
- const onClear = () => {
38
+ const onClear = path => {
39
+ const parentPath = path || Path.parent(element_path);
39
40
  Transforms.removeNodes(editor, {
40
- at: element_path
41
+ at: parentPath
41
42
  });
42
43
  };
43
44
  return /*#__PURE__*/_jsx(_Fragment, {
@@ -295,7 +295,7 @@ export const calculateProps = (curPath, dom, domClass, allData, parentDom, isBox
295
295
  const itemsData = [];
296
296
  const items = dom.querySelectorAll(domClass);
297
297
  const nextItemPathLength = curPath?.split("|").length + 2;
298
- let sectionHeight = 12;
298
+ // let sectionHeight = 12;
299
299
  for (let i = 0; i < items.length; i++) {
300
300
  const itemRect = items[i]?.getBoundingClientRect();
301
301
  if (items[i]?.classList.contains("type_box")) {
@@ -315,9 +315,10 @@ export const calculateProps = (curPath, dom, domClass, allData, parentDom, isBox
315
315
  gridArea: calculateGridArea(y)
316
316
  }
317
317
  });
318
- sectionHeight += itemRect?.height;
318
+ // sectionHeight += itemRect?.height;
319
319
  }
320
320
  }
321
+
321
322
  if (dom?.classList.contains("type_box") && parentDom) {
322
323
  const parentDomRect = parentDom?.getBoundingClientRect();
323
324
  const isAppHeader = isBoxHeader || dom?.classList.contains("appHeaderBox");
@@ -962,6 +962,41 @@ export function DragIcon() {
962
962
  })]
963
963
  });
964
964
  }
965
+ export function ResizeIcon() {
966
+ return /*#__PURE__*/_jsxs("svg", {
967
+ width: "16",
968
+ height: "16",
969
+ viewBox: "0 0 16 16",
970
+ fill: "none",
971
+ xmlns: "http://www.w3.org/2000/svg",
972
+ children: [/*#__PURE__*/_jsx("rect", {
973
+ width: "16",
974
+ height: "16",
975
+ rx: "8",
976
+ fill: "#F8FAFC"
977
+ }), /*#__PURE__*/_jsx("rect", {
978
+ x: "0.5",
979
+ y: "0.5",
980
+ width: "15",
981
+ height: "15",
982
+ rx: "7.5",
983
+ stroke: "#2563EB",
984
+ strokeOpacity: "0.32"
985
+ }), /*#__PURE__*/_jsx("path", {
986
+ d: "M5.76758 6.44141L3.99981 8.20917L5.76758 9.97694",
987
+ stroke: "#94A3B8",
988
+ strokeWidth: "0.8",
989
+ strokeLinecap: "round",
990
+ strokeLinejoin: "round"
991
+ }), /*#__PURE__*/_jsx("path", {
992
+ d: "M10.2324 6.44141L12.0002 8.20917L10.2324 9.97694",
993
+ stroke: "#94A3B8",
994
+ strokeWidth: "0.8",
995
+ strokeLinecap: "round",
996
+ strokeLinejoin: "round"
997
+ })]
998
+ });
999
+ }
965
1000
  export function LeftAlignTextFormat() {
966
1001
  return /*#__PURE__*/_jsxs("svg", {
967
1002
  width: "19",
@@ -1467,6 +1502,26 @@ export function PenIcon() {
1467
1502
  })]
1468
1503
  });
1469
1504
  }
1505
+ export function ResetIcon() {
1506
+ return /*#__PURE__*/_jsxs("svg", {
1507
+ width: "24",
1508
+ height: "24",
1509
+ viewBox: "0 0 24 24",
1510
+ fill: "none",
1511
+ xmlns: "http://www.w3.org/2000/svg",
1512
+ children: [/*#__PURE__*/_jsx("circle", {
1513
+ cx: "11.646",
1514
+ cy: "11.6452",
1515
+ r: "11.5",
1516
+ transform: "rotate(-89.2717 11.646 11.6452)",
1517
+ fill: "#2563EB",
1518
+ fillOpacity: "0.16"
1519
+ }), /*#__PURE__*/_jsx("path", {
1520
+ d: "M18.2814 11.8168V11.8168C18.2813 11.8313 18.2987 11.8387 18.3091 11.8287L19.2379 10.9273C19.6367 10.5404 20.247 10.5482 20.6358 10.9451C21.0245 11.342 21.0168 11.9495 20.6181 12.3364L17.9434 14.9012C17.5478 15.2806 16.9205 15.2708 16.5369 14.8792L13.9636 12.2519C13.7692 12.0534 13.674 11.7974 13.677 11.5622C13.6802 11.3075 13.7819 11.054 13.981 10.8801C14.3797 10.4932 14.9901 10.501 15.3788 10.8979L16.2708 11.8085C16.286 11.824 16.3124 11.8135 16.3126 11.7917V11.7917C16.351 8.77391 13.9017 6.27324 10.8698 6.2347C7.83784 6.19615 5.32577 8.63374 5.28741 11.6516C5.24904 14.6694 7.69833 17.1701 10.7303 17.2086C11.2815 17.2156 11.7092 17.6522 11.7022 18.2009C11.6952 18.7496 11.2566 19.1752 10.7054 19.1682C6.5709 19.1157 3.2663 15.7418 3.31861 11.6265C3.37093 7.51133 6.76023 4.22251 10.8947 4.27507C15.0095 4.32738 18.3338 7.70154 18.2814 11.8168Z",
1521
+ fill: "#2563EB"
1522
+ })]
1523
+ });
1524
+ }
1470
1525
  export function SaveTemplIcon() {
1471
1526
  return /*#__PURE__*/_jsxs("svg", {
1472
1527
  width: "18",
@@ -59,10 +59,6 @@ const useCommonStyle = theme => ({
59
59
  marginBottom: "7px",
60
60
  marginTop: "4px"
61
61
  },
62
- "& p": {
63
- marginBottom: "7px",
64
- marginTop: "4px"
65
- },
66
62
  "& .muiIconsListParent": {
67
63
  "& svg": {
68
64
  color: `${theme?.palette?.editor?.svgTextAlignStrokeColor} !important`
@@ -295,6 +291,12 @@ const useCommonStyle = theme => ({
295
291
  "& .signature-canvas": {
296
292
  backgroundColor: `${theme?.palette?.editor?.inputFieldBgColor} !important`
297
293
  },
294
+ "& .clear-canvas": {
295
+ position: "absolute",
296
+ top: 6,
297
+ right: 6,
298
+ color: theme?.palette?.editor?.closeButtonSvgStroke
299
+ },
298
300
  "& label": {
299
301
  color: theme?.palette?.editor?.textColor
300
302
  },
@@ -401,4 +401,8 @@ export const clearSelectionOnly = editor => {
401
401
  } catch (err) {
402
402
  console.log(err);
403
403
  }
404
+ };
405
+ export const isMobileWindow = () => {
406
+ const isMobile = window.matchMedia("(max-width: 899px)")?.matches || false;
407
+ return isMobile;
404
408
  };
@@ -190,16 +190,17 @@ export const TableProvider = ({
190
190
  // selectFirstCell(tablePath, editor, updateTableSelection);
191
191
  // }, []);
192
192
 
193
+ const onClickAway = () => {
194
+ setTableSelection(getDefaultTableSelection());
195
+ setHoverPath(null);
196
+ };
193
197
  return /*#__PURE__*/_jsx(TableContext.Provider, {
194
198
  value: values,
195
199
  children: /*#__PURE__*/_jsxs(DndContext, {
196
200
  sensors: sensors,
197
201
  onDragEnd: data => handleDragEnd(data, editor, resetAll),
198
202
  children: [/*#__PURE__*/_jsx(ClickAwayListener, {
199
- onClickAway: () => {
200
- setTableSelection(getDefaultTableSelection());
201
- setHoverPath(null);
202
- },
203
+ onClickAway: onClickAway,
203
204
  children: /*#__PURE__*/_jsx("div", {
204
205
  children: children
205
206
  })
@@ -1,5 +1,5 @@
1
1
  import React, { useRef, useState } from "react";
2
- import { Accordion, AccordionDetails, AccordionSummary, Button, Fade, Grid, IconButton, Popper, Typography, styled } from "@mui/material";
2
+ import { Accordion, AccordionDetails, AccordionSummary, Button, Fade, Grid, IconButton, Popper, Typography, styled, useTheme } from "@mui/material";
3
3
 
4
4
  // Style
5
5
  import Style from "./style";
@@ -7,7 +7,7 @@ import { PenIcon } from "../icons";
7
7
  import StyleBuilder from "../../common/StyleBuilder";
8
8
  import { fontOptions } from "../../utils/font";
9
9
  import { useEditorTheme } from "../../hooks/useEditorTheme";
10
- import { getBreakPointsValue, getElementProperty, getTRBLBreakPoints } from "../../helper/theme";
10
+ import { getBreakPointsValue, getElementProperty, getTRBLBreakPoints, groupByBreakpoint } from "../../helper/theme";
11
11
  import { KeyboardArrowDownRounded } from "@mui/icons-material";
12
12
  import { jsx as _jsx } from "react/jsx-runtime";
13
13
  import { jsxs as _jsxs } from "react/jsx-runtime";
@@ -80,18 +80,24 @@ const buttonStyle = [{
80
80
  type: "color"
81
81
  }]
82
82
  }];
83
- function getBtnSxProps(buttonStyle = {}) {
84
- const newStyle = {
83
+ function getBtnSxProps(buttonStyle = {}, theme) {
84
+ let newStyle = {
85
85
  ...buttonStyle
86
86
  };
87
87
  if (newStyle?.bannerSpacing) {
88
88
  newStyle.padding = newStyle?.bannerSpacing;
89
89
  }
90
- newStyle.borderRadius = {
91
- ...getBreakPointsValue(newStyle?.borderRadius || {}, null, "overrideBorderRadius", true)
92
- };
93
- newStyle.padding = {
94
- ...getTRBLBreakPoints(newStyle?.bannerSpacing || {})
90
+ const btnSp = groupByBreakpoint({
91
+ borderRadius: {
92
+ ...getBreakPointsValue(newStyle?.borderRadius || {}, null, "overrideBorderRadius", true)
93
+ },
94
+ padding: {
95
+ ...getTRBLBreakPoints(newStyle?.bannerSpacing)
96
+ }
97
+ }, theme);
98
+ newStyle = {
99
+ ...newStyle,
100
+ ...btnSp
95
101
  };
96
102
  delete newStyle?.bannerSpacing;
97
103
  if (newStyle?.hover) {
@@ -192,6 +198,7 @@ const Buttons = props => {
192
198
  type
193
199
  } = props;
194
200
  const [anchorEl, setAnchorEl] = useState();
201
+ const theme = useTheme();
195
202
  const {
196
203
  selectedTheme,
197
204
  updateTheme
@@ -199,6 +206,7 @@ const Buttons = props => {
199
206
  const {
200
207
  button
201
208
  } = selectedTheme?.elementProps || {};
209
+ console.log("getBtnSxProps(button, theme)", getBtnSxProps(button, theme));
202
210
  const buttonEl = useRef();
203
211
  const elementProps = convertThemeToElementProps(button, buttonEl);
204
212
 
@@ -224,19 +232,13 @@ const Buttons = props => {
224
232
  onClick: e => setAnchorEl(e.currentTarget),
225
233
  children: [/*#__PURE__*/_jsxs(Grid, {
226
234
  item: true,
227
- style: {
228
- maxWidth: "calc(100% - 50px)",
229
- overflowX: "auto"
230
- },
235
+ size: 12,
231
236
  children: [/*#__PURE__*/_jsx(Typography, {
232
237
  variant: "body1",
233
238
  className: "fw-600 fs-14",
234
- style: {
235
- marginBottom: "10px"
236
- },
237
239
  children: "Theme Button"
238
240
  }), /*#__PURE__*/_jsx(Button, {
239
- sx: getBtnSxProps(button),
241
+ sx: getBtnSxProps(button, theme),
240
242
  ref: buttonEl,
241
243
  children: "Button"
242
244
  })]
@@ -1,6 +1,13 @@
1
1
  import { Transforms } from "slate";
2
2
  import insertNewLine from "./insertNewLine";
3
3
  import { getSelectedText } from "./helper";
4
+ import { isMobileWindow } from "../helper";
5
+ const focusAccordion = (editor, upPath) => {
6
+ Transforms.select(editor, {
7
+ path: upPath,
8
+ offset: 0
9
+ });
10
+ };
4
11
  export const insertAccordion = (editor, path) => {
5
12
  try {
6
13
  const selectedText = getSelectedText(editor);
@@ -36,11 +43,14 @@ export const insertAccordion = (editor, path) => {
36
43
  // get title index
37
44
  const summaryIndex = upPath.length - 3;
38
45
  upPath[summaryIndex] = upPath[summaryIndex] === 0 ? 0 : upPath[summaryIndex] - 1;
46
+
39
47
  // select accordion title by default
40
- Transforms.select(editor, {
41
- path: upPath,
42
- offset: 0
43
- });
48
+ if (isMobileWindow()) {
49
+ // timeout to resolve focus issue in mobile
50
+ setTimeout(() => focusAccordion(editor, upPath), 0);
51
+ } else {
52
+ focusAccordion(editor, upPath);
53
+ }
44
54
  insertNewLine(editor);
45
55
  } catch (err) {
46
56
  console.log(err);
@@ -1,9 +1,10 @@
1
- import { useState } from "react";
1
+ import { useRef, useState } from "react";
2
2
  const useTableResize = ({
3
3
  parentDOM,
4
4
  size: defaultSize,
5
5
  onDone,
6
- minMaxProps = {}
6
+ minMaxProps = {},
7
+ isMobile
7
8
  }) => {
8
9
  const {
9
10
  width
@@ -18,6 +19,10 @@ const useTableResize = ({
18
19
  });
19
20
  const [resizing, setResizing] = useState(false);
20
21
  const [isDone, setIsDone] = useState(0);
22
+ const lastTouch = useRef({
23
+ x: 0,
24
+ y: 0
25
+ });
21
26
  const onLoad = defaultSize => {
22
27
  setSize({
23
28
  widthInPercent: 100,
@@ -25,29 +30,64 @@ const useTableResize = ({
25
30
  ...defaultSize
26
31
  });
27
32
  };
33
+ const handleEventListeners = type => {
34
+ const listener = type === "add" ? document.addEventListener : document.removeEventListener;
35
+ const onMoveListener = isMobile ? "touchmove" : "pointermove";
36
+ const onEndListener = isMobile ? "touchend" : "pointerup";
37
+ listener(onMoveListener, onMouseMove);
38
+ listener(onEndListener, onMouseUp);
39
+ };
40
+ const updateLastTouch = ({
41
+ clientX,
42
+ clientY
43
+ }) => {
44
+ lastTouch.current.x = clientX;
45
+ lastTouch.current.y = clientY;
46
+ };
28
47
  const onMouseDown = e => {
29
- e.preventDefault();
30
- document.addEventListener("pointermove", onMouseMove);
31
- document.addEventListener("pointerup", onMouseUp);
48
+ if (isMobile) {
49
+ updateLastTouch(e.touches[0]);
50
+ } else {
51
+ e.preventDefault();
52
+ }
53
+ handleEventListeners("add");
32
54
  setResizing(true);
33
55
  setIsDone(0);
34
56
  };
35
57
  const onMouseUp = () => {
36
- document.removeEventListener("pointermove", onMouseMove);
37
- document.removeEventListener("pointerup", onMouseUp);
58
+ handleEventListeners("remove");
38
59
  setResizing(false);
39
60
  setIsDone(1);
40
61
  };
41
62
  const onMouseMove = e => {
63
+ let {
64
+ movementX,
65
+ movementY
66
+ } = e || {};
67
+ if (e.type === "touchmove") {
68
+ // for mobile
69
+ const {
70
+ x,
71
+ y
72
+ } = lastTouch.current || {};
73
+ const touches = e.touches[0];
74
+ const {
75
+ clientX,
76
+ clientY
77
+ } = touches;
78
+ movementX = clientX - x;
79
+ movementY = clientY - y;
80
+ updateLastTouch(touches);
81
+ }
42
82
  const {
43
83
  minWidth
44
84
  } = minMaxProps || {};
45
85
  setSize(currentSize => {
46
86
  const width = currentSize?.width || parentDOM?.clientWidth;
47
- const calcWidth = width + e.movementX;
87
+ const calcWidth = width + movementX;
48
88
  return {
49
89
  width: minWidth && calcWidth < minWidth ? minWidth : calcWidth,
50
- height: currentSize.height + e.movementY,
90
+ height: currentSize.height + movementY,
51
91
  widthInPercent: calcWidth / width * 100
52
92
  };
53
93
  });
@@ -1,10 +1,11 @@
1
- import { Editor, Transforms, Element, Node, Path, Range } from "slate";
1
+ import { Editor, Transforms, Element, Node, Path, Range, Point } from "slate";
2
2
  import { toggleBlock } from "./SlateUtilityFunctions";
3
3
  import insertNewLine from "./insertNewLine";
4
4
  import { insertAccordion } from "./accordion";
5
- import { isListItem } from "./helper";
5
+ import { getNodeWithType, isListItem } from "./helper";
6
6
  import RnDCtrlCmds from "./RnD/RnDCtrlCmds";
7
7
  import EDITORCMDS from "../common/EditorCmds";
8
+ import { ReactEditor } from "slate-react";
8
9
  const HOTKEYS = {
9
10
  b: "bold",
10
11
  i: "italic",
@@ -183,6 +184,20 @@ const checkListEnterEvent = (editor, type) => {
183
184
  insertNewLine(editor);
184
185
  }
185
186
  };
187
+ const removeAccordion = (editor, accordionPath) => {
188
+ Transforms.removeNodes(editor, {
189
+ at: accordionPath
190
+ });
191
+ Transforms.insertNodes(editor, {
192
+ type: "paragraph",
193
+ children: [{
194
+ text: ""
195
+ }]
196
+ }, {
197
+ at: accordionPath,
198
+ select: true
199
+ });
200
+ };
186
201
  export const enterEvent = (e, editor, isMobile) => {
187
202
  try {
188
203
  const ele = isListItem(editor);
@@ -225,9 +240,7 @@ export const enterEvent = (e, editor, isMobile) => {
225
240
  e.preventDefault();
226
241
  if (!text) {
227
242
  const accordionIndex = ele[1].slice(0, Math.max(ele[1].length - 1));
228
- Transforms.removeNodes(editor, {
229
- at: accordionIndex
230
- });
243
+ removeAccordion(editor, accordionIndex);
231
244
  } else {
232
245
  const nextPath = Path.next(Path.parent(ele[1]));
233
246
  insertAccordion(editor, nextPath);
@@ -329,6 +342,37 @@ export const enterEvent = (e, editor, isMobile) => {
329
342
  console.log(err);
330
343
  }
331
344
  };
345
+ export const handleAccordionOnBackspace = (e, editor) => {
346
+ try {
347
+ let isAccordion = false;
348
+ const [accordionDetails] = getNodeWithType(editor, "accordion-details");
349
+ const [accordionDetailsNode] = accordionDetails || [];
350
+ if (accordionDetailsNode) {
351
+ const dom = ReactEditor.toDOMNode(editor, accordionDetailsNode);
352
+ if (dom?.parentElement) {
353
+ dom.parentElement.style.display = "block";
354
+ }
355
+ }
356
+ const [accordionSummary] = getNodeWithType(editor, "accordion-summary");
357
+ const [accordionTitle, accordionTitlePath] = accordionSummary || [];
358
+ if (accordionTitle) {
359
+ // no selection
360
+ if (Range.isCollapsed(editor.selection)) {
361
+ const start = Editor.start(editor, accordionTitlePath);
362
+ const isCursorAtStart = Point.equals(editor.selection.focus, start);
363
+ if (isCursorAtStart) {
364
+ e.preventDefault();
365
+ const parentPath = Path.parent(accordionTitlePath);
366
+ removeAccordion(editor, parentPath);
367
+ isAccordion = true;
368
+ }
369
+ }
370
+ }
371
+ return isAccordion;
372
+ } catch (err) {
373
+ console.log(err);
374
+ }
375
+ };
332
376
  export const upDownArrowKeyEvents = (e, editor) => {
333
377
  try {
334
378
  const {
@@ -348,7 +392,7 @@ export const upDownArrowKeyEvents = (e, editor) => {
348
392
  }
349
393
  Transforms.move(editor, {
350
394
  distance: 0,
351
- unit: 'offset',
395
+ unit: "offset",
352
396
  reverse: false
353
397
  });
354
398
  Transforms.select(editor, {
@@ -3,6 +3,7 @@ import { ReactEditor } from "slate-react";
3
3
  import insertNewLine from "./insertNewLine";
4
4
  import { getDevice } from "../helper/theme";
5
5
  import { activeMark, getSelectedElementStyle } from "./SlateUtilityFunctions";
6
+ import { getCurrentElementText } from "../plugins/withHTML";
6
7
  export const windowVar = {};
7
8
  let ST_TIMEOUT = null;
8
9
  const BLOCKS = ["grid", "dataView"];
@@ -858,6 +859,24 @@ export const hideSlateSelection = () => {
858
859
  const root = document.documentElement;
859
860
  root.style.setProperty("--slate-highlight-bg", "none");
860
861
  };
862
+ export const insertSlashNode = (editor, insertNode) => {
863
+ try {
864
+ // Delete the currently selected text
865
+ editor.deleteFragment();
866
+ const currentText = getCurrentElementText(editor);
867
+ const currentPath = editor?.selection?.anchor?.path;
868
+ let insertAt = currentPath;
869
+ if (currentText?.trim()) {
870
+ const parentPath = Path.parent(currentPath);
871
+ insertAt = Path.next(parentPath);
872
+ }
873
+ Transforms.insertNodes(editor, insertNode, {
874
+ at: insertAt
875
+ });
876
+ } catch (err) {
877
+ console.log(err);
878
+ }
879
+ };
861
880
  export const isEverythingSelected = editor => {
862
881
  const {
863
882
  selection
@@ -1,9 +1,5 @@
1
- import { Path, Transforms } from "slate";
2
- import insertNewLine from "./insertNewLine";
3
- import { getCurrentElementText } from "../plugins/withHTML";
1
+ import { insertSlashNode } from "./helper";
4
2
  export const insertSignature = editor => {
5
- const hasText = getCurrentElementText(editor);
6
- const insertPath = hasText ? Path.next(Path.parent(editor?.selection.focus.path)) : editor.selection.anchor.path;
7
3
  const signature = {
8
4
  type: "signature",
9
5
  alignment: "center",
@@ -17,8 +13,5 @@ export const insertSignature = editor => {
17
13
  text: " "
18
14
  }]
19
15
  };
20
- Transforms.insertNodes(editor, signature, {
21
- at: insertPath
22
- });
23
- insertNewLine(editor);
16
+ insertSlashNode(editor, signature);
24
17
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flozy/editor",
3
- "version": "10.1.3",
3
+ "version": "10.1.5",
4
4
  "description": "An Editor for flozy app brain",
5
5
  "files": [
6
6
  "dist"