@flozy/editor 3.1.8 → 3.2.0

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.
Files changed (26) hide show
  1. package/dist/Editor/CommonEditor.js +13 -26
  2. package/dist/Editor/Editor.css +5 -0
  3. package/dist/Editor/Elements/AppHeader/AppHeader.js +33 -29
  4. package/dist/Editor/Elements/Button/EditorButton.js +32 -86
  5. package/dist/Editor/Elements/Color Picker/Styles.js +4 -1
  6. package/dist/Editor/Elements/Embed/Image.js +56 -22
  7. package/dist/Editor/Elements/Form/Form.js +1 -1
  8. package/dist/Editor/Styles/EditorStyles.js +6 -2
  9. package/dist/Editor/Toolbar/PopupTool/MiniTextFormat/SelectFontSize.js +1 -1
  10. package/dist/Editor/Toolbar/PopupTool/MiniTextFormat/index.js +1 -1
  11. package/dist/Editor/Toolbar/PopupTool/PopupToolStyle.js +43 -13
  12. package/dist/Editor/{Elements/Button/ButtonNavSettings → common/LinkSettings}/index.js +10 -36
  13. package/dist/Editor/common/StyleBuilder/embedImageStyle.js +24 -24
  14. package/dist/Editor/common/StyleBuilder/fieldTypes/index.js +0 -2
  15. package/dist/Editor/common/StyleBuilder/fieldTypes/menusArray.js +46 -3
  16. package/dist/Editor/helper/deserialize/index.js +32 -11
  17. package/dist/Editor/helper/index.js +34 -2
  18. package/dist/Editor/plugins/withTable.js +1 -1
  19. package/dist/Editor/utils/events.js +3 -1
  20. package/dist/Editor/utils/helper.js +88 -3
  21. package/dist/Editor/utils/insertAppHeader.js +14 -10
  22. package/package.json +1 -1
  23. package/dist/Editor/common/StyleBuilder/fieldTypes/borderWidth.js +0 -75
  24. /package/dist/Editor/{Elements/Button/ButtonNavSettings → common/LinkSettings}/NavComponents.js +0 -0
  25. /package/dist/Editor/{Elements/Button/ButtonNavSettings → common/LinkSettings}/navOptions.js +0 -0
  26. /package/dist/Editor/{Elements/Button/ButtonNavSettings → common/LinkSettings}/style.js +0 -0
@@ -18,6 +18,12 @@ const usePopupStyle = theme => ({
18
18
  "& .MuiPaper-root": {
19
19
  backgroundColor: theme?.palette?.editor?.background
20
20
  },
21
+ "&.textSettings": {
22
+ '@media only screen and (max-width: 600px)': {
23
+ margin: "4px !important",
24
+ marginBottom: "54px !important"
25
+ }
26
+ },
21
27
  "& .MuiTypography-root": {
22
28
  color: theme?.palette?.editor?.textColor
23
29
  },
@@ -45,6 +51,12 @@ const usePopupStyle = theme => ({
45
51
  "& button": {
46
52
  color: theme?.palette?.editor?.textColor
47
53
  }
54
+ },
55
+ "@media only screen and (max-width: 599px)": {
56
+ padding: "10px",
57
+ background: "unset",
58
+ boxShadow: "unset",
59
+ border: "none"
48
60
  }
49
61
  },
50
62
  textFormatWrapper: {
@@ -64,6 +76,9 @@ const usePopupStyle = theme => ({
64
76
  "& .ele-item-single": {
65
77
  paddingLeft: "4px",
66
78
  paddingTop: "4px"
79
+ },
80
+ "@media only screen and (max-width: 599px)": {
81
+ width: '330px'
67
82
  }
68
83
  },
69
84
  "&.templates": {
@@ -72,6 +87,9 @@ const usePopupStyle = theme => ({
72
87
  "&.fullscreen": {
73
88
  width: "100%",
74
89
  maxHeight: "fit-content"
90
+ },
91
+ "@media only screen and (max-width: 599px)": {
92
+ width: '330px'
75
93
  }
76
94
  },
77
95
  "& .headerContainer": {},
@@ -124,6 +142,9 @@ const usePopupStyle = theme => ({
124
142
  color: theme?.palette?.editor?.activeColor
125
143
  }
126
144
  }
145
+ },
146
+ "@media only screen and (max-width: 599px)": {
147
+ width: '330px'
127
148
  }
128
149
  },
129
150
  textFormatLabel: {
@@ -391,7 +412,10 @@ const usePopupStyle = theme => ({
391
412
  },
392
413
  colorPopper: {
393
414
  "& .MuiPaper-root": {
394
- backgroundColor: theme?.palette?.editor?.background
415
+ backgroundColor: theme?.palette?.editor?.background,
416
+ '@media only screen and (max-width: 600px)': {
417
+ marginTop: "-40px"
418
+ }
395
419
  }
396
420
  },
397
421
  fullViewCardMedia: {
@@ -459,7 +483,7 @@ const usePopupStyle = theme => ({
459
483
  gap: "4px"
460
484
  },
461
485
  "& .verticalLine": {
462
- borderLeft: "1px solid #E0E0E0",
486
+ borderLeft: `1px solid ${theme?.palette?.primary?.border8}`,
463
487
  minHeight: "20px",
464
488
  height: "100%"
465
489
  },
@@ -500,10 +524,14 @@ const usePopupStyle = theme => ({
500
524
  },
501
525
  customSelectPopoverWrapper: {
502
526
  "& .MuiPopover-paper": {
503
- maxHeight: '140px'
527
+ maxHeight: '140px',
528
+ background: theme?.palette?.editor?.background,
529
+ '@media only screen and (max-width: 600px)': {
530
+ marginTop: "-40px"
531
+ }
504
532
  },
505
533
  "& .customSelectOptionLabel": {
506
- color: "black",
534
+ color: theme?.palette?.editor?.textColor,
507
535
  margin: "0px",
508
536
  width: "100%",
509
537
  justifyContent: "start",
@@ -511,11 +539,13 @@ const usePopupStyle = theme => ({
511
539
  fontSize: "14px",
512
540
  lineHeight: "1.75 !important",
513
541
  fontWeight: 400,
542
+ background: theme?.palette?.editor?.background,
514
543
  "& :hover": {
515
- background: "#F0F5FA !important"
544
+ background: `${theme?.palette?.action?.selected} !important`
516
545
  },
517
546
  "&.selected": {
518
- background: "#F0F5FA !important"
547
+ color: `${theme?.palette?.primary?.main} !important`,
548
+ background: `${theme?.palette?.action?.selected} !important`
519
549
  }
520
550
  },
521
551
  "& .menuOptions": {
@@ -528,13 +558,13 @@ const usePopupStyle = theme => ({
528
558
  textTransform: "none"
529
559
  }
530
560
  },
531
- mobileMiniTextWrapper: {
532
- boxShadow: "0px 0px 10px 0px rgba(0, 0, 0, 0.16)",
533
- position: "fixed",
534
- bottom: "env(safe-area-inset-bottom)",
535
- left: 0,
536
- width: "100%"
537
- },
561
+ // mobileMiniTextWrapper: {
562
+ // boxShadow: "0px 0px 10px 0px rgba(0, 0, 0, 0.16)",
563
+ // position: "fixed",
564
+ // bottom: "env(safe-area-inset-bottom)",
565
+ // left: 0,
566
+ // width: "100%",
567
+ // },
538
568
  miniFontSizeInput: {
539
569
  "& input": {
540
570
  fontSize: "14px",
@@ -7,7 +7,7 @@ import IconButton from '@mui/material/IconButton';
7
7
  import CloseIcon from '@mui/icons-material/Close';
8
8
  import { FormControl, FormControlLabel, Grid, Radio, RadioGroup } from '@mui/material';
9
9
  import { useState } from 'react';
10
- import ButtonNavSettingsStyles from './style';
10
+ import LinkSettingsStyles from './style';
11
11
  import { getNavOptions } from './navOptions';
12
12
  import { ScrollTopBottom, SelectPage, TextInput, Trigger } from './NavComponents';
13
13
  import { jsx as _jsx } from "react/jsx-runtime";
@@ -20,49 +20,28 @@ const MAP_COMPONENT = {
20
20
  scrollTopOrBottom: ScrollTopBottom,
21
21
  page: SelectPage
22
22
  };
23
- export default function ButtonNavSettings(props) {
23
+ export default function LinkSettings(props) {
24
24
  const {
25
- open,
26
25
  handleClose,
27
26
  onSave,
28
27
  customProps,
29
- element,
30
- editor
28
+ navType
31
29
  } = props;
32
30
  const navOptions = getNavOptions(customProps.hideTools);
33
- const prevNavType = element?.buttonLink?.linkType;
34
- const classes = ButtonNavSettingsStyles();
35
- const [nav, setNav] = useState(prevNavType ? navOptions.find(n => n.value === prevNavType) : {
31
+ const classes = LinkSettingsStyles();
32
+ const [nav, setNav] = useState(navType ? navOptions.find(n => n.value === navType) : {
36
33
  label: "None",
37
34
  value: ""
38
35
  });
39
- const [navValue, setNavValue] = useState(element?.url || "");
40
- const [openInNewTab, setOpenInNewTab] = useState(element.openInNewTab || false);
41
- const {
42
- metadata
43
- } = customProps || {
44
- metadata: {}
45
- };
46
- const {
47
- buttonLink
48
- } = metadata || {
49
- actionTrigger: {}
50
- };
51
- const {
52
- actionTrigger
53
- } = buttonLink || {};
54
- const {
55
- onClick
56
- } = actionTrigger || {
57
- options: []
58
- };
36
+ const [navValue, setNavValue] = useState(props?.navValue || "");
37
+ const [openInNewTab, setOpenInNewTab] = useState(props.openInNewTab || false);
59
38
  const NavSettings = MAP_COMPONENT[nav?.value];
60
39
  const onChange = value => {
61
40
  setNavValue(value);
62
41
  };
63
42
  return /*#__PURE__*/_jsxs(Dialog, {
64
43
  onClose: handleClose,
65
- open: open,
44
+ open: true,
66
45
  sx: classes.dialogContainer,
67
46
  fullWidth: true,
68
47
  maxWidth: "sm",
@@ -106,7 +85,6 @@ export default function ButtonNavSettings(props) {
106
85
  nav: nav,
107
86
  onChange: onChange,
108
87
  value: navValue,
109
- editor: editor,
110
88
  openInNewTab: openInNewTab,
111
89
  onNewTabChange: () => setOpenInNewTab(prev => !prev),
112
90
  services: customProps.services
@@ -121,14 +99,10 @@ export default function ButtonNavSettings(props) {
121
99
  }), /*#__PURE__*/_jsx(Button, {
122
100
  onClick: () => {
123
101
  onSave({
124
- buttonLink: {
125
- linkType: nav?.value,
126
- onClick
127
- },
128
- url: navValue,
102
+ linkType: nav?.value,
103
+ navValue,
129
104
  openInNewTab
130
105
  });
131
- handleClose();
132
106
  },
133
107
  sx: classes.saveBtn,
134
108
  children: "Save"
@@ -39,17 +39,20 @@ const embedImageStyle = [{
39
39
  value: "RoundedLightB2",
40
40
  label: "Rounded Light B2 Frame"
41
41
  }]
42
- }, {
43
- label: "Add web address here",
44
- key: "webAddress",
45
- type: "text",
46
- placeholder: "https://"
47
- }, {
48
- label: "Open in new tab",
49
- key: "isNewTab",
50
- type: "selectBox",
51
- placeholder: "Open in new tab"
52
- }]
42
+ }
43
+ // {
44
+ // label: "Add web address here",
45
+ // key: "webAddress",
46
+ // type: "text",
47
+ // placeholder: "https://",
48
+ // },
49
+ // {
50
+ // label: "Open in new tab",
51
+ // key: "isNewTab",
52
+ // type: "selectBox",
53
+ // placeholder: "Open in new tab",
54
+ // },
55
+ ]
53
56
  }, {
54
57
  tab: "Banner Spacing",
55
58
  value: "bannerSpacing",
@@ -59,20 +62,21 @@ const embedImageStyle = [{
59
62
  type: "bannerSpacing"
60
63
  }]
61
64
  }, {
62
- tab: "Border Radius",
63
- value: "borderRadius",
65
+ tab: "Border",
66
+ value: "border",
64
67
  fields: [{
68
+ label: "Border Color",
69
+ key: "borderColor",
70
+ type: "color"
71
+ }, {
65
72
  label: "Border Radius",
66
73
  key: "borderRadius",
67
74
  type: "borderRadius"
68
- }]
69
- }, {
70
- tab: "Border width",
71
- value: "borderWidth",
72
- fields: [{
73
- label: "Border width",
75
+ }, {
76
+ label: "Border Width",
74
77
  key: "borderWidth",
75
- type: "borderWidth"
78
+ type: "text",
79
+ placeholder: "1px"
76
80
  }]
77
81
  }, {
78
82
  tab: "Position",
@@ -99,10 +103,6 @@ const embedImageStyle = [{
99
103
  label: "Background Color",
100
104
  key: "bgColor",
101
105
  type: "color"
102
- }, {
103
- label: "Border Color",
104
- key: "borderColor",
105
- type: "color"
106
106
  }, {
107
107
  label: "Box Shadow",
108
108
  key: "boxShadow",
@@ -15,12 +15,10 @@ import TextOptions from "./textOptions";
15
15
  import SelectBox from "./selectBox";
16
16
  import Icons from "./icons";
17
17
  import FontSize from "./fontSize";
18
- import borderWidth from "./borderWidth";
19
18
  const FieldMap = {
20
19
  text: Text,
21
20
  bannerSpacing: BannerSpacing,
22
21
  borderRadius: BorderRadius,
23
- borderWidth: borderWidth,
24
22
  color: Color,
25
23
  alignment: Alignment,
26
24
  backgroundImage: BackgroundImage,
@@ -1,6 +1,8 @@
1
- import React from "react";
1
+ import React, { useState } from "react";
2
2
  import { Button, Grid, Radio, RadioGroup, TextField, FormControl, FormLabel, FormControlLabel, Typography, Tooltip, IconButton } from "@mui/material";
3
3
  import DeleteIcon from "@mui/icons-material/Delete";
4
+ import Settings from "@mui/icons-material/Settings";
5
+ import LinkSettings from "../../LinkSettings";
4
6
  import { jsx as _jsx } from "react/jsx-runtime";
5
7
  import { jsxs as _jsxs } from "react/jsx-runtime";
6
8
  const MenusArray = props => {
@@ -8,7 +10,8 @@ const MenusArray = props => {
8
10
  value,
9
11
  data,
10
12
  elementProps,
11
- onChange
13
+ onChange,
14
+ customProps
12
15
  } = props;
13
16
  const {
14
17
  key
@@ -18,6 +21,7 @@ const MenusArray = props => {
18
21
  } = elementProps || {
19
22
  menuStyle: "stacked"
20
23
  };
24
+ const [openNav, setOpenNav] = useState(false);
21
25
  const handleChange = index => e => {
22
26
  const upValue = [...(value || [])];
23
27
  upValue[index] = {
@@ -47,6 +51,17 @@ const MenusArray = props => {
47
51
  [e.target.name]: e.target.value
48
52
  });
49
53
  };
54
+ const selectedMenu = openNav?.menu || {};
55
+ const onSave = update => {
56
+ const upValue = [...(value || [])];
57
+ upValue[openNav?.index] = {
58
+ ...(upValue[openNav?.index] || {}),
59
+ ...update
60
+ };
61
+ onChange({
62
+ [key]: upValue
63
+ });
64
+ };
50
65
  return /*#__PURE__*/_jsxs(Grid, {
51
66
  item: true,
52
67
  xs: 12,
@@ -123,6 +138,16 @@ const MenusArray = props => {
123
138
  onChange: handleChange(i),
124
139
  size: "small",
125
140
  fullWidth: true
141
+ }), /*#__PURE__*/_jsx(Tooltip, {
142
+ title: "Link Settings",
143
+ arrow: true,
144
+ children: /*#__PURE__*/_jsx(IconButton, {
145
+ onClick: () => setOpenNav({
146
+ menu: m,
147
+ index: i
148
+ }),
149
+ children: /*#__PURE__*/_jsx(Settings, {})
150
+ })
126
151
  }), /*#__PURE__*/_jsx(Tooltip, {
127
152
  title: "Delete Menu",
128
153
  arrow: true,
@@ -142,7 +167,25 @@ const MenusArray = props => {
142
167
  },
143
168
  children: "+ Add"
144
169
  })
145
- })]
170
+ }), openNav ? /*#__PURE__*/_jsx(LinkSettings, {
171
+ handleClose: () => setOpenNav(null),
172
+ onSave: ({
173
+ linkType,
174
+ navValue,
175
+ openInNewTab
176
+ }) => {
177
+ onSave({
178
+ linkType,
179
+ url: navValue,
180
+ target: openInNewTab ? "_blank" : ""
181
+ });
182
+ setOpenNav(false);
183
+ },
184
+ navType: selectedMenu?.linkType,
185
+ navValue: selectedMenu?.url,
186
+ openInNewTab: selectedMenu?.target === "_blank",
187
+ customProps: customProps
188
+ }) : null]
146
189
  });
147
190
  };
148
191
  export default MenusArray;
@@ -1,4 +1,22 @@
1
1
  import { jsx } from "slate-hyperscript";
2
+ const handleTableCell = (el, children) => {
3
+ const wrapChild = children?.map(c => {
4
+ if (typeof c === "string") {
5
+ return {
6
+ type: "paragraph",
7
+ children: [{
8
+ text: c
9
+ }],
10
+ cellBgColor: "#FFFFFF"
11
+ };
12
+ }
13
+ return c;
14
+ });
15
+ return {
16
+ type: "table-cell",
17
+ overwriteChild: wrapChild
18
+ };
19
+ };
2
20
  const ELEMENT_TAGS = {
3
21
  A: el => ({
4
22
  type: "link",
@@ -53,11 +71,15 @@ const ELEMENT_TAGS = {
53
71
  "GOOGLE-SHEETS-HTML-ORIGIN": () => ({
54
72
  type: "paragraph"
55
73
  }),
56
- TABLE: (el, bodyChildren = []) => {
74
+ TABLE: (el, children = []) => {
75
+ const bodyChild = children[0]?.children || [];
76
+ const firstRowChildren = bodyChild[0]?.children || [];
57
77
  return {
58
78
  type: "table",
59
- rows: bodyChildren?.length,
60
- columns: bodyChildren[0]?.children?.length
79
+ overwriteChild: bodyChild,
80
+ // we are not having table-body in our json format, just we are wrapping table-row's inside the table
81
+ rows: bodyChild?.length,
82
+ columns: firstRowChildren?.length
61
83
  };
62
84
  },
63
85
  THEAD: () => ({
@@ -66,15 +88,11 @@ const ELEMENT_TAGS = {
66
88
  TBODY: () => ({
67
89
  type: "table-body"
68
90
  }),
69
- TH: () => ({
70
- type: "table-cell"
71
- }),
91
+ TH: handleTableCell,
72
92
  TR: () => ({
73
93
  type: "table-row"
74
94
  }),
75
- TD: () => ({
76
- type: "table-cell"
77
- }),
95
+ TD: handleTableCell,
78
96
  COLGROUP: () => ({
79
97
  type: "paragraph"
80
98
  }),
@@ -133,8 +151,11 @@ const deserialize = el => {
133
151
  return jsx("fragment", {}, children);
134
152
  }
135
153
  if (ELEMENT_TAGS[nodeName]) {
136
- const attrs = ELEMENT_TAGS[nodeName](el, children);
137
- return jsx("element", attrs, children);
154
+ const {
155
+ overwriteChild,
156
+ ...attrs
157
+ } = ELEMENT_TAGS[nodeName](el, children);
158
+ return jsx("element", attrs, overwriteChild || children);
138
159
  }
139
160
  if (TEXT_TAGS[nodeName]) {
140
161
  const attrs = TEXT_TAGS[nodeName](el);
@@ -3,10 +3,42 @@ import { rectIntersection, closestCenter } from "@dnd-kit/core";
3
3
  import { getQueryStrings } from "../utils/SlateUtilityFunctions";
4
4
  import { Node } from "slate";
5
5
  const HIDE_PLACHOLDERS = ["grid", "grid-item", "table"];
6
+ const PREVIEW_IMAGE_HIDE_CLASS = ["grid-container-toolbar", "grid-item-toolbar", "element-toolbar", "mini-tool-wrpr-ei", "element-selector", "element-selector-ctrl"];
6
7
  export const getThumbnailImage = async (dom, options = {}) => {
7
8
  try {
8
- const canvas = await html2canvas(dom, options);
9
- return canvas.toDataURL();
9
+ const canvas = await html2canvas(dom, {
10
+ windowWidth: 1440,
11
+ windowHeight: 768,
12
+ ...options,
13
+ backgroundColor: null,
14
+ allowTaint: true,
15
+ useCORS: false,
16
+ scale: 0.5,
17
+ imageTimeout: 0,
18
+ onclone: document => {
19
+ // hide class
20
+ const sw = document.getElementById("slate-wrapper-scroll-container");
21
+ sw.style.minHeight = "2000px";
22
+ const svgFrames = document.querySelectorAll(".image-frame svg");
23
+ for (let i = 0; i < svgFrames.length; i++) {
24
+ svgFrames[i].style.width = "100%";
25
+ }
26
+ const rectFills = document.getElementsByTagName("rect");
27
+ for (let i = 0; i < rectFills.length; i++) {
28
+ const hasURL = rectFills[i]?.getAttribute("fill")?.indexOf("url") > -1;
29
+ if (hasURL) {
30
+ rectFills[i].style.fill = "#CCC";
31
+ }
32
+ }
33
+ for (let hidedeClass of PREVIEW_IMAGE_HIDE_CLASS) {
34
+ for (let element of document.getElementsByClassName(hidedeClass)) {
35
+ element.style.display = "none";
36
+ }
37
+ }
38
+ return document;
39
+ }
40
+ });
41
+ return canvas.toDataURL("image/jpeg", 0.5);
10
42
  } catch (err) {
11
43
  console.log(err);
12
44
  return null;
@@ -11,7 +11,7 @@ const withTable = editor => {
11
11
  if (arg.reverse) {
12
12
  const table = new TableUtil(editor);
13
13
  const cellsSelected = table.isCellSelected(editor.selection);
14
- if (cellsSelected) {
14
+ if (cellsSelected && cellsSelected.length > 1) {
15
15
  cellsSelected.forEach(cellPath => {
16
16
  Transforms.removeNodes(editor, {
17
17
  at: cellPath
@@ -125,7 +125,9 @@ export const escapeEvent = props => {
125
125
  const parentNodes = parentPath.filter(m => m.length).map(m => Node.get(editor, m));
126
126
  const ele = isListItem(editor);
127
127
  const eleType = ele[0]?.type;
128
- if (parentNodes.length === 2 && parentNodes[1]?.type === "list-item") {
128
+ const parentLists = parentNodes.filter(p => p.type === "orderedList" || p.type === "unorderedList");
129
+ if (parentLists?.length === 1) {
130
+ // if not in nested list
129
131
  toggleBlock(editor, "list-item", editor.selection);
130
132
  } else if (eleType === "check-list-item") {
131
133
  checkListEnterEvent(editor, eleType);
@@ -1,6 +1,7 @@
1
1
  import { Editor, Node, Transforms, Element } from "slate";
2
2
  import { ReactEditor } from "slate-react";
3
3
  import insertNewLine from "./insertNewLine";
4
+ import { getDevice } from "../helper/theme";
4
5
  export const windowVar = {};
5
6
  export const formatDate = (date, format = "MM/DD/YYYY") => {
6
7
  if (!date) return "";
@@ -100,10 +101,10 @@ export const getSelectedText = editor => {
100
101
  export const isEmptyNode = (editor, children, path) => {
101
102
  try {
102
103
  const isEmptyText = Node.string(Node.get(editor, path))?.length === 0;
103
- const emptyNode = children?.length === 1 && children[0]?.children[0]?.type === undefined && children[0]?.type === "paragraph";
104
+ const emptyNode = children?.length === 1 && children && children[0]?.children[0]?.type === undefined && children[0]?.type === "paragraph";
104
105
  return isEmptyText && emptyNode;
105
106
  } catch (err) {
106
- console.log(err);
107
+ // console.log(err);
107
108
  return "";
108
109
  }
109
110
  };
@@ -123,7 +124,7 @@ export const handleInsertLastElement = (event, editor) => {
123
124
  offset: 0
124
125
  };
125
126
  Transforms.insertNodes(editor, {
126
- text: ''
127
+ text: ""
127
128
  }, {
128
129
  at: path
129
130
  });
@@ -202,4 +203,88 @@ export const decodeAndParseBase64 = encodedString => {
202
203
  const decodedURLString = decodeURIComponent(decodedString);
203
204
  const jsonData = JSON.parse(decodedURLString);
204
205
  return jsonData;
206
+ };
207
+ export const handleLinkType = (url, linkType, readOnly, openInNewTab, onClick = () => {}) => {
208
+ const props = {};
209
+ if (!readOnly) {
210
+ return {
211
+ component: "button"
212
+ };
213
+ }
214
+ switch (linkType) {
215
+ case "webAddress":
216
+ const refUrl = url ? url.includes("http") ? url : `//${url}` : "Link";
217
+ props.component = "a";
218
+ if (refUrl !== "Link") {
219
+ props.href = refUrl;
220
+ }
221
+ if (openInNewTab) {
222
+ props.target = "_blank";
223
+ }
224
+ break;
225
+ case "actionTrigger":
226
+ if (!readOnly) {
227
+ props.component = "button";
228
+ props.onClick = () => {};
229
+ } else {
230
+ props.component = "button";
231
+ props.onClick = onClick;
232
+ }
233
+ break;
234
+ case "page":
235
+ props.component = "a";
236
+ const [page, section] = url.split("#");
237
+ const sec = section ? `#${section}` : "";
238
+ props.href = page === "home" ? sec : `/${url}`;
239
+ if (openInNewTab) {
240
+ props.target = "_blank";
241
+ }
242
+ break;
243
+ case "email":
244
+ props.component = "a";
245
+ props.href = `mailto:${url}`;
246
+ break;
247
+ case "phone":
248
+ props.component = "a";
249
+ props.href = `tel:${url}`;
250
+ break;
251
+ case "scrollTopOrBottom":
252
+ props.component = "button";
253
+ props.onClick = () => {
254
+ const scrollEle = document.getElementById("slate-wrapper-scroll-container");
255
+ if (scrollEle) {
256
+ if (url === "top") {
257
+ // top of the page
258
+ scrollEle.scrollTo(0, 0);
259
+ } else if (url === "bottom") {
260
+ // bottom of the page
261
+ scrollEle.scrollTo(0, scrollEle.scrollHeight);
262
+ }
263
+ }
264
+ };
265
+ break;
266
+ default:
267
+ return {};
268
+ }
269
+
270
+ // for iphone fix
271
+ if (props.component === "a" && props.href) {
272
+ if (getDevice(window.innerWidth) === "xs") {
273
+ props.component = "button"; // iphone is opening two tabs, on open in new tab because of a tag.
274
+ }
275
+
276
+ props.onTouchEnd = e => {
277
+ e.preventDefault();
278
+ e.stopPropagation();
279
+ if (props.target) {
280
+ window.open(props.href);
281
+ } else {
282
+ window.location.href = props.href;
283
+ }
284
+ };
285
+ props.onClick = () => {
286
+ return false;
287
+ };
288
+ }
289
+ return props;
205
290
  };