@flozy/editor 3.1.0 → 3.1.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.
- package/dist/Editor/CommonEditor.js +1 -1
- package/dist/Editor/Editor.css +4 -0
- package/dist/Editor/Elements/Button/ButtonNavSettings/NavComponents.js +219 -0
- package/dist/Editor/Elements/Button/ButtonNavSettings/index.js +138 -0
- package/dist/Editor/Elements/Button/ButtonNavSettings/navOptions.js +32 -0
- package/dist/Editor/Elements/Button/ButtonNavSettings/style.js +55 -0
- package/dist/Editor/Elements/Button/EditorButton.js +115 -30
- package/dist/Editor/Elements/Form/Form.js +6 -2
- package/dist/Editor/Toolbar/Mini/Options/Options.js +1 -1
- package/dist/Editor/Toolbar/PopupTool/MiniTextFormat/SelectFontSize.js +10 -8
- package/dist/Editor/common/Section/index.js +2 -1
- package/dist/Editor/common/StyleBuilder/buttonStyle.js +13 -9
- package/dist/Editor/plugins/withHTML.js +25 -4
- package/dist/Editor/plugins/withTable.js +26 -1
- package/dist/Editor/service/formSubmit.js +1 -1
- package/dist/Editor/utils/grid.js +2 -4
- package/dist/Editor/utils/helper.js +53 -0
- package/dist/Editor/utils/table.js +4 -8
- package/package.json +1 -1
|
@@ -408,7 +408,7 @@ const CommonEditor = /*#__PURE__*/forwardRef((props, ref) => {
|
|
|
408
408
|
children: [/*#__PURE__*/_jsx(DragAndDrop, {
|
|
409
409
|
children: /*#__PURE__*/_jsx(Overlay, {
|
|
410
410
|
children: /*#__PURE__*/_jsx(Box, {
|
|
411
|
-
className: `${hasTopBanner() ? "has-topbanner" : ""} ${!pageColor ? "no-color" : ""} ${isScrolling ? "" : "hideScroll"} scrollable-content`,
|
|
411
|
+
className: `${hasTopBanner() ? "has-topbanner" : ""} ${!pageColor ? "no-color" : ""} ${isScrolling ? "" : "hideScroll"} scrollable-content scrollSmooth`,
|
|
412
412
|
sx: classes.slateWrapper,
|
|
413
413
|
id: "slate-wrapper-scroll-container",
|
|
414
414
|
style: editorWrapperStyle,
|
package/dist/Editor/Editor.css
CHANGED
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
import { Autocomplete, Checkbox, FormControlLabel, MenuItem, Select, TextField, Typography, createFilterOptions } from "@mui/material";
|
|
2
|
+
import { useEffect, useMemo, useState } from "react";
|
|
3
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
4
|
+
import { Fragment as _Fragment } from "react/jsx-runtime";
|
|
5
|
+
import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
6
|
+
const OpenInNewTab = props => {
|
|
7
|
+
const {
|
|
8
|
+
nav,
|
|
9
|
+
openInNewTab,
|
|
10
|
+
onNewTabChange
|
|
11
|
+
} = props;
|
|
12
|
+
return nav?.showOpenInNewTab ? /*#__PURE__*/_jsx(FormControlLabel, {
|
|
13
|
+
className: "ccheckbox-primary",
|
|
14
|
+
control: /*#__PURE__*/_jsx(Checkbox, {
|
|
15
|
+
checked: openInNewTab,
|
|
16
|
+
onChange: onNewTabChange
|
|
17
|
+
}),
|
|
18
|
+
label: /*#__PURE__*/_jsx(Typography, {
|
|
19
|
+
variant: "body2",
|
|
20
|
+
children: "Open in new tab"
|
|
21
|
+
})
|
|
22
|
+
}) : null;
|
|
23
|
+
};
|
|
24
|
+
export const TextInput = props => {
|
|
25
|
+
return /*#__PURE__*/_jsxs(_Fragment, {
|
|
26
|
+
children: [/*#__PURE__*/_jsx(TextField, {
|
|
27
|
+
fullWidth: true,
|
|
28
|
+
size: "small",
|
|
29
|
+
...props,
|
|
30
|
+
onChange: e => {
|
|
31
|
+
props.onChange(e.target.value);
|
|
32
|
+
}
|
|
33
|
+
}), /*#__PURE__*/_jsx(OpenInNewTab, {
|
|
34
|
+
...props
|
|
35
|
+
})]
|
|
36
|
+
});
|
|
37
|
+
};
|
|
38
|
+
export const SelectPage = props => {
|
|
39
|
+
const {
|
|
40
|
+
value,
|
|
41
|
+
onChange,
|
|
42
|
+
services
|
|
43
|
+
} = props;
|
|
44
|
+
const [pages, setPages] = useState([]);
|
|
45
|
+
const getPages = async () => {
|
|
46
|
+
const result = await services("getPages", {});
|
|
47
|
+
const refactor = result?.data?.map(r => {
|
|
48
|
+
const {
|
|
49
|
+
title,
|
|
50
|
+
url_name,
|
|
51
|
+
...rest
|
|
52
|
+
} = r;
|
|
53
|
+
return {
|
|
54
|
+
label: title,
|
|
55
|
+
value: url_name,
|
|
56
|
+
...rest
|
|
57
|
+
};
|
|
58
|
+
});
|
|
59
|
+
setPages(refactor);
|
|
60
|
+
};
|
|
61
|
+
useEffect(() => {
|
|
62
|
+
getPages();
|
|
63
|
+
}, []);
|
|
64
|
+
const [page, section] = useMemo(() => {
|
|
65
|
+
if (value) {
|
|
66
|
+
const [page, section] = value.split("#");
|
|
67
|
+
const selectedPage = pages.find(p => p.value === page) || {
|
|
68
|
+
label: page,
|
|
69
|
+
value: page
|
|
70
|
+
};
|
|
71
|
+
const selectedSection = pages.find(p => p.value === section) || {
|
|
72
|
+
label: section,
|
|
73
|
+
value: section
|
|
74
|
+
};
|
|
75
|
+
return [selectedPage, selectedSection];
|
|
76
|
+
}
|
|
77
|
+
return [];
|
|
78
|
+
}, [value, pages]);
|
|
79
|
+
return /*#__PURE__*/_jsxs("div", {
|
|
80
|
+
children: [/*#__PURE__*/_jsx(FreeSoloCreateOption, {
|
|
81
|
+
label: page?.label,
|
|
82
|
+
setValue: val => onChange(val?.value),
|
|
83
|
+
placeholder: "Select Page",
|
|
84
|
+
options: pages
|
|
85
|
+
}), /*#__PURE__*/_jsx(FreeSoloCreateOption, {
|
|
86
|
+
label: section?.label,
|
|
87
|
+
setValue: val => {
|
|
88
|
+
let url = page?.value;
|
|
89
|
+
if (val?.value) {
|
|
90
|
+
url += `#${val?.value}`;
|
|
91
|
+
}
|
|
92
|
+
onChange(url);
|
|
93
|
+
},
|
|
94
|
+
placeholder: "Select Section or anchor",
|
|
95
|
+
options: page?.sections?.map(p => ({
|
|
96
|
+
label: p,
|
|
97
|
+
value: p
|
|
98
|
+
}))
|
|
99
|
+
}), /*#__PURE__*/_jsx(OpenInNewTab, {
|
|
100
|
+
...props
|
|
101
|
+
})]
|
|
102
|
+
});
|
|
103
|
+
};
|
|
104
|
+
export const Trigger = props => {
|
|
105
|
+
return /*#__PURE__*/_jsx(Typography, {
|
|
106
|
+
variant: "h6",
|
|
107
|
+
gutterBottom: true,
|
|
108
|
+
children: "Choosing this will trigger the next step"
|
|
109
|
+
});
|
|
110
|
+
};
|
|
111
|
+
const scrollToOptions = [{
|
|
112
|
+
label: "Top",
|
|
113
|
+
value: "top"
|
|
114
|
+
}, {
|
|
115
|
+
label: "Bottom",
|
|
116
|
+
value: "bottom"
|
|
117
|
+
}];
|
|
118
|
+
export const ScrollTopBottom = props => {
|
|
119
|
+
const {
|
|
120
|
+
value,
|
|
121
|
+
onChange
|
|
122
|
+
} = props;
|
|
123
|
+
return /*#__PURE__*/_jsxs(_Fragment, {
|
|
124
|
+
children: [/*#__PURE__*/_jsx(Typography, {
|
|
125
|
+
variant: "body2",
|
|
126
|
+
sx: {
|
|
127
|
+
paddingBottom: "4px"
|
|
128
|
+
},
|
|
129
|
+
children: "Choose Top/Bottom of page"
|
|
130
|
+
}), /*#__PURE__*/_jsx(Select, {
|
|
131
|
+
size: "small",
|
|
132
|
+
fullWidth: true,
|
|
133
|
+
value: value,
|
|
134
|
+
onChange: e => onChange(e.target.value),
|
|
135
|
+
children: scrollToOptions.map((option, i) => {
|
|
136
|
+
return /*#__PURE__*/_jsx(MenuItem, {
|
|
137
|
+
value: option.value,
|
|
138
|
+
children: /*#__PURE__*/_jsx(Typography, {
|
|
139
|
+
variant: "body2",
|
|
140
|
+
children: option.label
|
|
141
|
+
})
|
|
142
|
+
}, i);
|
|
143
|
+
})
|
|
144
|
+
})]
|
|
145
|
+
});
|
|
146
|
+
};
|
|
147
|
+
const filter = createFilterOptions();
|
|
148
|
+
export function FreeSoloCreateOption({
|
|
149
|
+
label,
|
|
150
|
+
setValue,
|
|
151
|
+
options = [],
|
|
152
|
+
placeholder = ""
|
|
153
|
+
}) {
|
|
154
|
+
return /*#__PURE__*/_jsx(Autocomplete, {
|
|
155
|
+
freeSolo: true,
|
|
156
|
+
options: options,
|
|
157
|
+
value: label || "",
|
|
158
|
+
renderInput: params => /*#__PURE__*/_jsx(TextField, {
|
|
159
|
+
...params,
|
|
160
|
+
label: placeholder
|
|
161
|
+
}),
|
|
162
|
+
renderOption: (props, option) => /*#__PURE__*/_jsx("li", {
|
|
163
|
+
...props,
|
|
164
|
+
children: option.label
|
|
165
|
+
}),
|
|
166
|
+
onChange: (event, newValue) => {
|
|
167
|
+
if (typeof newValue === 'string') {
|
|
168
|
+
setValue({
|
|
169
|
+
value: newValue
|
|
170
|
+
});
|
|
171
|
+
} else if (newValue && newValue.inputValue) {
|
|
172
|
+
const {
|
|
173
|
+
inputValue
|
|
174
|
+
} = newValue;
|
|
175
|
+
|
|
176
|
+
// Create a new value from the user input
|
|
177
|
+
setValue({
|
|
178
|
+
label: inputValue,
|
|
179
|
+
value: inputValue
|
|
180
|
+
});
|
|
181
|
+
} else {
|
|
182
|
+
setValue(newValue);
|
|
183
|
+
}
|
|
184
|
+
},
|
|
185
|
+
filterOptions: (options, params) => {
|
|
186
|
+
const filtered = filter(options, params);
|
|
187
|
+
const {
|
|
188
|
+
inputValue
|
|
189
|
+
} = params;
|
|
190
|
+
// Suggest the creation of a new value
|
|
191
|
+
const isExisting = options.some(option => inputValue === option.label);
|
|
192
|
+
if (inputValue !== '' && !isExisting) {
|
|
193
|
+
filtered.push({
|
|
194
|
+
inputValue,
|
|
195
|
+
label: `Add "${inputValue}"`
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
return filtered;
|
|
199
|
+
},
|
|
200
|
+
selectOnFocus: true,
|
|
201
|
+
clearOnBlur: true,
|
|
202
|
+
handleHomeEndKeys: true,
|
|
203
|
+
getOptionLabel: option => {
|
|
204
|
+
// Value selected with enter, right from the input
|
|
205
|
+
if (typeof option === 'string') {
|
|
206
|
+
return option;
|
|
207
|
+
}
|
|
208
|
+
// Add "xxx" option created dynamically
|
|
209
|
+
if (option.inputValue) {
|
|
210
|
+
return option.inputValue;
|
|
211
|
+
}
|
|
212
|
+
// Regular option
|
|
213
|
+
return option.value;
|
|
214
|
+
},
|
|
215
|
+
sx: {
|
|
216
|
+
marginTop: "10px"
|
|
217
|
+
}
|
|
218
|
+
});
|
|
219
|
+
}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import Button from '@mui/material/Button';
|
|
2
|
+
import Dialog from '@mui/material/Dialog';
|
|
3
|
+
import DialogTitle from '@mui/material/DialogTitle';
|
|
4
|
+
import DialogContent from '@mui/material/DialogContent';
|
|
5
|
+
import DialogActions from '@mui/material/DialogActions';
|
|
6
|
+
import IconButton from '@mui/material/IconButton';
|
|
7
|
+
import CloseIcon from '@mui/icons-material/Close';
|
|
8
|
+
import { FormControl, FormControlLabel, Grid, Radio, RadioGroup } from '@mui/material';
|
|
9
|
+
import { useState } from 'react';
|
|
10
|
+
import ButtonNavSettingsStyles from './style';
|
|
11
|
+
import { getNavOptions } from './navOptions';
|
|
12
|
+
import { ScrollTopBottom, SelectPage, TextInput, Trigger } from './NavComponents';
|
|
13
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
14
|
+
import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
15
|
+
const MAP_COMPONENT = {
|
|
16
|
+
webAddress: TextInput,
|
|
17
|
+
email: TextInput,
|
|
18
|
+
phone: TextInput,
|
|
19
|
+
actionTrigger: Trigger,
|
|
20
|
+
scrollTopOrBottom: ScrollTopBottom,
|
|
21
|
+
page: SelectPage
|
|
22
|
+
};
|
|
23
|
+
export default function ButtonNavSettings(props) {
|
|
24
|
+
const {
|
|
25
|
+
open,
|
|
26
|
+
handleClose,
|
|
27
|
+
onSave,
|
|
28
|
+
customProps,
|
|
29
|
+
element,
|
|
30
|
+
editor
|
|
31
|
+
} = props;
|
|
32
|
+
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) : {
|
|
36
|
+
label: "None",
|
|
37
|
+
value: ""
|
|
38
|
+
});
|
|
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
|
+
};
|
|
59
|
+
const NavSettings = MAP_COMPONENT[nav?.value];
|
|
60
|
+
const onChange = value => {
|
|
61
|
+
setNavValue(value);
|
|
62
|
+
};
|
|
63
|
+
return /*#__PURE__*/_jsxs(Dialog, {
|
|
64
|
+
onClose: handleClose,
|
|
65
|
+
open: open,
|
|
66
|
+
sx: classes.dialogContainer,
|
|
67
|
+
fullWidth: true,
|
|
68
|
+
maxWidth: "sm",
|
|
69
|
+
children: [/*#__PURE__*/_jsx(DialogTitle, {
|
|
70
|
+
children: "What do you want to link to?"
|
|
71
|
+
}), /*#__PURE__*/_jsx(IconButton, {
|
|
72
|
+
"aria-label": "close",
|
|
73
|
+
onClick: handleClose,
|
|
74
|
+
sx: classes.closeIcon,
|
|
75
|
+
children: /*#__PURE__*/_jsx(CloseIcon, {})
|
|
76
|
+
}), /*#__PURE__*/_jsx(DialogContent, {
|
|
77
|
+
dividers: true,
|
|
78
|
+
children: /*#__PURE__*/_jsxs(Grid, {
|
|
79
|
+
container: true,
|
|
80
|
+
spacing: 2,
|
|
81
|
+
children: [/*#__PURE__*/_jsx(Grid, {
|
|
82
|
+
item: true,
|
|
83
|
+
xs: 6,
|
|
84
|
+
sx: classes.gridDivider,
|
|
85
|
+
children: /*#__PURE__*/_jsx(FormControl, {
|
|
86
|
+
children: /*#__PURE__*/_jsx(RadioGroup, {
|
|
87
|
+
value: nav?.value,
|
|
88
|
+
children: navOptions?.map((navOption, i) => {
|
|
89
|
+
return /*#__PURE__*/_jsx(FormControlLabel, {
|
|
90
|
+
value: navOption.value,
|
|
91
|
+
control: /*#__PURE__*/_jsx(Radio, {}),
|
|
92
|
+
label: navOption.label,
|
|
93
|
+
onChange: () => {
|
|
94
|
+
setNav(navOption);
|
|
95
|
+
setNavValue("");
|
|
96
|
+
}
|
|
97
|
+
}, i);
|
|
98
|
+
})
|
|
99
|
+
})
|
|
100
|
+
})
|
|
101
|
+
}), /*#__PURE__*/_jsx(Grid, {
|
|
102
|
+
item: true,
|
|
103
|
+
xs: 6,
|
|
104
|
+
children: NavSettings && /*#__PURE__*/_jsx(NavSettings, {
|
|
105
|
+
placeholder: nav?.placeholder,
|
|
106
|
+
nav: nav,
|
|
107
|
+
onChange: onChange,
|
|
108
|
+
value: navValue,
|
|
109
|
+
editor: editor,
|
|
110
|
+
openInNewTab: openInNewTab,
|
|
111
|
+
onNewTabChange: () => setOpenInNewTab(prev => !prev),
|
|
112
|
+
services: customProps.services
|
|
113
|
+
})
|
|
114
|
+
})]
|
|
115
|
+
})
|
|
116
|
+
}), /*#__PURE__*/_jsxs(DialogActions, {
|
|
117
|
+
children: [/*#__PURE__*/_jsx(Button, {
|
|
118
|
+
onClick: handleClose,
|
|
119
|
+
sx: classes.closeBtn,
|
|
120
|
+
children: "Cancel"
|
|
121
|
+
}), /*#__PURE__*/_jsx(Button, {
|
|
122
|
+
onClick: () => {
|
|
123
|
+
onSave({
|
|
124
|
+
buttonLink: {
|
|
125
|
+
linkType: nav?.value,
|
|
126
|
+
onClick
|
|
127
|
+
},
|
|
128
|
+
url: navValue,
|
|
129
|
+
openInNewTab
|
|
130
|
+
});
|
|
131
|
+
handleClose();
|
|
132
|
+
},
|
|
133
|
+
sx: classes.saveBtn,
|
|
134
|
+
children: "Save"
|
|
135
|
+
})]
|
|
136
|
+
})]
|
|
137
|
+
});
|
|
138
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export const getNavOptions = (hideTools = []) => {
|
|
2
|
+
let navOptions = [{
|
|
3
|
+
label: "None",
|
|
4
|
+
value: ""
|
|
5
|
+
}, {
|
|
6
|
+
label: "Trigger",
|
|
7
|
+
value: "actionTrigger"
|
|
8
|
+
}, {
|
|
9
|
+
label: "Web Address",
|
|
10
|
+
value: "webAddress",
|
|
11
|
+
placeholder: "https://",
|
|
12
|
+
showOpenInNewTab: true
|
|
13
|
+
}, {
|
|
14
|
+
label: "Select Page and Section",
|
|
15
|
+
value: "page",
|
|
16
|
+
placeholder: "Select Page and Section",
|
|
17
|
+
showOpenInNewTab: true
|
|
18
|
+
}, {
|
|
19
|
+
label: "Top/Bottom of page",
|
|
20
|
+
value: "scrollTopOrBottom"
|
|
21
|
+
}, {
|
|
22
|
+
label: "Email",
|
|
23
|
+
value: "email",
|
|
24
|
+
placeholder: "email"
|
|
25
|
+
}, {
|
|
26
|
+
label: "Phone number",
|
|
27
|
+
value: "phone",
|
|
28
|
+
placeholder: "phone"
|
|
29
|
+
}];
|
|
30
|
+
navOptions = navOptions.filter(n => !hideTools.includes(n.value));
|
|
31
|
+
return navOptions;
|
|
32
|
+
};
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
const ButtonNavSettingsStyles = () => ({
|
|
2
|
+
dialogContainer: {
|
|
3
|
+
'& .MuiDialogContent-root': {
|
|
4
|
+
padding: "0px 20px"
|
|
5
|
+
},
|
|
6
|
+
'& .MuiDialogActions-root': {
|
|
7
|
+
padding: "10px"
|
|
8
|
+
},
|
|
9
|
+
'& .MuiTypography-h6': {
|
|
10
|
+
fontWeight: 600,
|
|
11
|
+
fontSize: "16px",
|
|
12
|
+
paddingRight: "20px"
|
|
13
|
+
},
|
|
14
|
+
"& .MuiGrid-container": {
|
|
15
|
+
marginTop: '0px'
|
|
16
|
+
},
|
|
17
|
+
"& .MuiGrid-item": {
|
|
18
|
+
padding: "14px"
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
saveBtn: {
|
|
22
|
+
color: '#fff',
|
|
23
|
+
background: "#2563EB",
|
|
24
|
+
fontSize: "14px",
|
|
25
|
+
fontWeight: 500,
|
|
26
|
+
padding: "4px 24px",
|
|
27
|
+
textTransform: "none",
|
|
28
|
+
"&:hover": {
|
|
29
|
+
color: '#fff',
|
|
30
|
+
background: "#2563EB"
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
closeBtn: {
|
|
34
|
+
backgroundColor: "#F4F6F9",
|
|
35
|
+
color: "#64748B",
|
|
36
|
+
fontSize: "14px",
|
|
37
|
+
fontWeight: 500,
|
|
38
|
+
padding: "4px 22px",
|
|
39
|
+
textTransform: "none",
|
|
40
|
+
border: "1px solid #D8DDE1",
|
|
41
|
+
"&:hover": {
|
|
42
|
+
border: "1px solid #64748B"
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
closeIcon: {
|
|
46
|
+
position: 'absolute',
|
|
47
|
+
right: 8,
|
|
48
|
+
top: 8,
|
|
49
|
+
color: theme => theme.palette.grey[500]
|
|
50
|
+
},
|
|
51
|
+
gridDivider: {
|
|
52
|
+
borderRight: "1px solid rgba(0, 0, 0, 0.12)"
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
export default ButtonNavSettingsStyles;
|
|
@@ -5,11 +5,13 @@ import { IconButton, Tooltip, Box } from "@mui/material";
|
|
|
5
5
|
import * as fIcons from "@mui/icons-material";
|
|
6
6
|
import SettingsIcon from "@mui/icons-material/Settings";
|
|
7
7
|
import OpenInNewIcon from "@mui/icons-material/OpenInNew";
|
|
8
|
+
import LinkIcon from "@mui/icons-material/Link";
|
|
8
9
|
import ButtonPopup from "./ButtonPopup";
|
|
9
10
|
import { actionButtonRedirect } from "../../service/actionTrigger";
|
|
10
11
|
import { WorkflowIcon } from "../../common/iconslist";
|
|
11
12
|
import { getTRBLBreakPoints, getBreakPointsValue } from "../../helper/theme";
|
|
12
13
|
import { windowVar } from "../../utils/helper";
|
|
14
|
+
import ButtonNavSettings from "./ButtonNavSettings";
|
|
13
15
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
14
16
|
import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
15
17
|
const EditorButton = props => {
|
|
@@ -26,6 +28,7 @@ const EditorButton = props => {
|
|
|
26
28
|
const editor = useSlateStatic();
|
|
27
29
|
const path = ReactEditor.findPath(editor, element);
|
|
28
30
|
const [edit, setEdit] = useState(false);
|
|
31
|
+
const [openNav, setOpenNav] = useState(false);
|
|
29
32
|
const {
|
|
30
33
|
label,
|
|
31
34
|
bgColor,
|
|
@@ -45,7 +48,8 @@ const EditorButton = props => {
|
|
|
45
48
|
borderWidth,
|
|
46
49
|
borderColor,
|
|
47
50
|
alignment,
|
|
48
|
-
xsHidden
|
|
51
|
+
xsHidden,
|
|
52
|
+
openInNewTab
|
|
49
53
|
} = element;
|
|
50
54
|
const {
|
|
51
55
|
linkType,
|
|
@@ -54,33 +58,90 @@ const EditorButton = props => {
|
|
|
54
58
|
const isTrigger = linkType === "actionTrigger";
|
|
55
59
|
const BtnIcon = buttonIcon ? fIcons[buttonIcon] : null;
|
|
56
60
|
windowVar.lastButtonProps = element;
|
|
57
|
-
const
|
|
58
|
-
if (
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
61
|
+
const handleTrigger = async () => {
|
|
62
|
+
if (metadata?.buttonLink?.handler) {
|
|
63
|
+
metadata.buttonLink.handler("click");
|
|
64
|
+
} else if (redirectOnURLResult) {
|
|
65
|
+
// call api and redirect based on api result
|
|
66
|
+
const apiResult = await actionButtonRedirect({}, {
|
|
67
|
+
url: buttonLink?.url
|
|
68
|
+
});
|
|
69
|
+
window.open(apiResult, "_blank").focus();
|
|
70
|
+
} else {
|
|
71
|
+
const refUrl = buttonLink?.url ? buttonLink?.url.includes("http") ? buttonLink?.url : `//${buttonLink?.url}` : "Link";
|
|
72
|
+
window.open(refUrl, "_blank").focus();
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
const handleLinkType = (readOnly, openInNewTab) => {
|
|
76
|
+
const props = {};
|
|
77
|
+
if (!readOnly) {
|
|
78
|
+
return {
|
|
79
|
+
component: "button"
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
switch (linkType) {
|
|
83
|
+
case "webAddress":
|
|
84
|
+
const refUrl = url ? url.includes("http") ? url : `//${url}` : "Link";
|
|
85
|
+
props.component = "a";
|
|
86
|
+
if (refUrl !== "Link") {
|
|
87
|
+
props.href = refUrl;
|
|
88
|
+
}
|
|
89
|
+
if (openInNewTab) {
|
|
90
|
+
props.target = "_blank";
|
|
91
|
+
}
|
|
92
|
+
break;
|
|
93
|
+
case "actionTrigger":
|
|
94
|
+
if (readOnly) {
|
|
95
|
+
const {
|
|
96
|
+
url
|
|
97
|
+
} = buttonLink || {};
|
|
98
|
+
const refUrl = url ? url.includes("http") ? url : `//${url}` : "Link";
|
|
99
|
+
props.component = "a";
|
|
100
|
+
if (refUrl !== "Link") {
|
|
101
|
+
props.href = refUrl;
|
|
102
|
+
}
|
|
68
103
|
} else {
|
|
69
|
-
|
|
70
|
-
|
|
104
|
+
props.component = "button";
|
|
105
|
+
props.onClick = handleTrigger;
|
|
71
106
|
}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
107
|
+
break;
|
|
108
|
+
case "page":
|
|
109
|
+
props.component = "a";
|
|
110
|
+
const [page, section] = url.split("#");
|
|
111
|
+
props.href = page === "home" ? `#${section}` : `/${url}`;
|
|
112
|
+
if (openInNewTab) {
|
|
113
|
+
props.target = "_blank";
|
|
114
|
+
}
|
|
115
|
+
break;
|
|
116
|
+
case "email":
|
|
117
|
+
props.component = "a";
|
|
118
|
+
props.href = `mailto:${url}`;
|
|
119
|
+
break;
|
|
120
|
+
case "phone":
|
|
121
|
+
props.component = "a";
|
|
122
|
+
props.href = `tel:${url}`;
|
|
123
|
+
break;
|
|
124
|
+
case "scrollTopOrBottom":
|
|
125
|
+
props.component = "button";
|
|
126
|
+
props.onClick = () => {
|
|
127
|
+
const scrollEle = document.getElementById("slate-wrapper-scroll-container");
|
|
128
|
+
if (scrollEle) {
|
|
129
|
+
if (url === "top") {
|
|
130
|
+
// top of the page
|
|
131
|
+
scrollEle.scrollTo(0, 0);
|
|
132
|
+
} else if (url === "bottom") {
|
|
133
|
+
// bottom of the page
|
|
134
|
+
scrollEle.scrollTo(0, scrollEle.scrollHeight);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
break;
|
|
76
139
|
}
|
|
140
|
+
return props;
|
|
77
141
|
};
|
|
142
|
+
const buttonProps = handleLinkType(readOnly, openInNewTab);
|
|
78
143
|
const onMenuClick = val => () => {
|
|
79
144
|
switch (val) {
|
|
80
|
-
case "open":
|
|
81
|
-
const refUrl = url ? url.includes("http") ? url : `//${url}` : "Link";
|
|
82
|
-
window.open(refUrl, "_blank").focus();
|
|
83
|
-
return;
|
|
84
145
|
case "edit":
|
|
85
146
|
setEdit(true);
|
|
86
147
|
return;
|
|
@@ -89,16 +150,22 @@ const EditorButton = props => {
|
|
|
89
150
|
at: [...path]
|
|
90
151
|
});
|
|
91
152
|
return;
|
|
153
|
+
case "nav":
|
|
154
|
+
setOpenNav(true);
|
|
155
|
+
return;
|
|
92
156
|
default:
|
|
93
157
|
return;
|
|
94
158
|
}
|
|
95
159
|
};
|
|
96
160
|
const Toolbar = () => {
|
|
161
|
+
const btnProps = handleLinkType(true, true);
|
|
97
162
|
return !readOnly ? /*#__PURE__*/_jsxs("div", {
|
|
98
163
|
className: "element-toolbar hr",
|
|
99
164
|
style: {
|
|
100
165
|
width: "max-content",
|
|
101
|
-
top: "-38px"
|
|
166
|
+
top: "-38px",
|
|
167
|
+
alignItems: "center",
|
|
168
|
+
cursor: "pointer"
|
|
102
169
|
},
|
|
103
170
|
children: [/*#__PURE__*/_jsx(Tooltip, {
|
|
104
171
|
title: "Settings",
|
|
@@ -108,10 +175,21 @@ const EditorButton = props => {
|
|
|
108
175
|
children: /*#__PURE__*/_jsx(SettingsIcon, {})
|
|
109
176
|
})
|
|
110
177
|
}), /*#__PURE__*/_jsx(Tooltip, {
|
|
111
|
-
title: "
|
|
178
|
+
title: "Nav Settings",
|
|
112
179
|
arrow: true,
|
|
113
180
|
children: /*#__PURE__*/_jsx(IconButton, {
|
|
114
|
-
onClick: onMenuClick("
|
|
181
|
+
onClick: onMenuClick("nav"),
|
|
182
|
+
children: /*#__PURE__*/_jsx(LinkIcon, {})
|
|
183
|
+
})
|
|
184
|
+
}), linkType === "page" ? null : /*#__PURE__*/_jsx(Tooltip, {
|
|
185
|
+
title: "Open Link",
|
|
186
|
+
arrow: true,
|
|
187
|
+
children: /*#__PURE__*/_jsx(Box, {
|
|
188
|
+
sx: {
|
|
189
|
+
display: "inline-flex",
|
|
190
|
+
color: "rgba(0, 0, 0, 0.54)"
|
|
191
|
+
},
|
|
192
|
+
...btnProps,
|
|
115
193
|
children: /*#__PURE__*/_jsx(OpenInNewIcon, {})
|
|
116
194
|
})
|
|
117
195
|
})]
|
|
@@ -152,7 +230,7 @@ const EditorButton = props => {
|
|
|
152
230
|
},
|
|
153
231
|
"&:hover": {
|
|
154
232
|
"& .element-toolbar": {
|
|
155
|
-
display: "
|
|
233
|
+
display: "flex"
|
|
156
234
|
}
|
|
157
235
|
}
|
|
158
236
|
},
|
|
@@ -161,8 +239,8 @@ const EditorButton = props => {
|
|
|
161
239
|
position: "relative"
|
|
162
240
|
},
|
|
163
241
|
children: [/*#__PURE__*/_jsxs(Box, {
|
|
164
|
-
component: "button",
|
|
165
242
|
sx: {
|
|
243
|
+
textDecoration: "none",
|
|
166
244
|
background: bgColor || "rgb(30, 75, 122)",
|
|
167
245
|
borderBlockStyle: "solid",
|
|
168
246
|
borderColor: borderColor || "transparent",
|
|
@@ -187,11 +265,11 @@ const EditorButton = props => {
|
|
|
187
265
|
color: `${textColorHover || textColor || "#FFFFFF"}`,
|
|
188
266
|
background: bgColorHover || bgColor || "rgb(30, 75, 122)",
|
|
189
267
|
"& .element-toolbar": {
|
|
190
|
-
display: "
|
|
268
|
+
display: "flex"
|
|
191
269
|
}
|
|
192
270
|
}
|
|
193
271
|
},
|
|
194
|
-
|
|
272
|
+
...buttonProps,
|
|
195
273
|
children: [BtnIcon && iconPosition === "start" && /*#__PURE__*/_jsx(BtnIcon, {
|
|
196
274
|
style: {
|
|
197
275
|
paddingLeft: "4px",
|
|
@@ -220,7 +298,14 @@ const EditorButton = props => {
|
|
|
220
298
|
onClose: onClose,
|
|
221
299
|
onDelete: onMenuClick("delete"),
|
|
222
300
|
customProps: customProps
|
|
223
|
-
})
|
|
301
|
+
}), openNav ? /*#__PURE__*/_jsx(ButtonNavSettings, {
|
|
302
|
+
open: openNav,
|
|
303
|
+
handleClose: () => setOpenNav(false),
|
|
304
|
+
onSave: onSave,
|
|
305
|
+
customProps: customProps,
|
|
306
|
+
element: element,
|
|
307
|
+
editor: editor
|
|
308
|
+
}) : null]
|
|
224
309
|
});
|
|
225
310
|
};
|
|
226
311
|
export default EditorButton;
|
|
@@ -24,7 +24,8 @@ const Form = props => {
|
|
|
24
24
|
} = props;
|
|
25
25
|
const {
|
|
26
26
|
readOnly,
|
|
27
|
-
page_id
|
|
27
|
+
page_id,
|
|
28
|
+
onFormSubmit
|
|
28
29
|
} = customProps;
|
|
29
30
|
const {
|
|
30
31
|
buttonProps,
|
|
@@ -116,7 +117,10 @@ const Form = props => {
|
|
|
116
117
|
if (isValidForm) {
|
|
117
118
|
alert(isValidForm[0]);
|
|
118
119
|
} else {
|
|
119
|
-
await formSubmit(params, customProps);
|
|
120
|
+
const formRes = await formSubmit(params, customProps);
|
|
121
|
+
if (formRes) {
|
|
122
|
+
onFormSubmit(formRes);
|
|
123
|
+
}
|
|
120
124
|
}
|
|
121
125
|
setLoading(false);
|
|
122
126
|
}
|
|
@@ -5,7 +5,6 @@ import DownArrowIcon from "../../../assets/svg/DownArrowIcon";
|
|
|
5
5
|
import useWindowResize from "../../../hooks/useWindowResize";
|
|
6
6
|
import { BREAKPOINTS_DEVICES, getBreakPointsValue } from "../../../helper/theme";
|
|
7
7
|
import { headingMap, sizeMap } from "../../../utils/font";
|
|
8
|
-
import { useDebounce } from "use-debounce";
|
|
9
8
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
10
9
|
import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
11
10
|
const fontSizeOptions = [16, 18, 20, 22, 26, 32, 36, 40, 48, 64, 96, 128];
|
|
@@ -21,7 +20,7 @@ function SelectFontSize({
|
|
|
21
20
|
const [size] = useWindowResize();
|
|
22
21
|
const val = activeMark(editor, format);
|
|
23
22
|
const value = getBreakPointsValue(val, size?.device);
|
|
24
|
-
const
|
|
23
|
+
const timerRef = useRef();
|
|
25
24
|
const updateMarkData = newVal => {
|
|
26
25
|
let upData = {
|
|
27
26
|
...getBreakPointsValue(val),
|
|
@@ -52,11 +51,6 @@ function SelectFontSize({
|
|
|
52
51
|
setFontSize(null);
|
|
53
52
|
}
|
|
54
53
|
};
|
|
55
|
-
useEffect(() => {
|
|
56
|
-
if (deboundedValue) {
|
|
57
|
-
onChangeSize(deboundedValue);
|
|
58
|
-
}
|
|
59
|
-
}, [deboundedValue]);
|
|
60
54
|
const getSizeVal = () => {
|
|
61
55
|
try {
|
|
62
56
|
let size = `${value}`?.indexOf("px") >= 0 ? value : sizeMap[value] || value;
|
|
@@ -73,6 +67,14 @@ function SelectFontSize({
|
|
|
73
67
|
useEffect(() => {
|
|
74
68
|
setFontSize(getSizeVal());
|
|
75
69
|
}, [value]);
|
|
70
|
+
const onChange = e => {
|
|
71
|
+
clearTimeout(timerRef.current);
|
|
72
|
+
const value = e.target.value;
|
|
73
|
+
setFontSize(value);
|
|
74
|
+
timerRef.current = setTimeout(() => {
|
|
75
|
+
onChangeSize(value);
|
|
76
|
+
}, 500);
|
|
77
|
+
};
|
|
76
78
|
return /*#__PURE__*/_jsxs("div", {
|
|
77
79
|
ref: containerRef,
|
|
78
80
|
style: {
|
|
@@ -82,7 +84,7 @@ function SelectFontSize({
|
|
|
82
84
|
children: [/*#__PURE__*/_jsx(TextField, {
|
|
83
85
|
sx: classes?.miniFontSizeInput,
|
|
84
86
|
value: fontSize,
|
|
85
|
-
onChange:
|
|
87
|
+
onChange: onChange,
|
|
86
88
|
size: "small"
|
|
87
89
|
}), /*#__PURE__*/_jsx(IconButton, {
|
|
88
90
|
onClick: e => {
|
|
@@ -10,6 +10,7 @@ import { useEditorSelection } from "../../hooks/useMouseMove";
|
|
|
10
10
|
import SectionStyle from "./styles";
|
|
11
11
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
12
12
|
import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
13
|
+
const list_types = ["orderedList", "unorderedList"];
|
|
13
14
|
const Section = props => {
|
|
14
15
|
const classes = SectionStyle();
|
|
15
16
|
const {
|
|
@@ -77,7 +78,7 @@ const Section = props => {
|
|
|
77
78
|
at: path
|
|
78
79
|
});
|
|
79
80
|
};
|
|
80
|
-
const needHover = element?.children?.find(f => f.type === "grid") ? "needHover" : "";
|
|
81
|
+
const needHover = element?.children?.find(f => f.type === "grid" && !list_types.includes(element.type)) ? "needHover" : "";
|
|
81
82
|
const sectionBgImage = sectionBackgroundImage && sectionBackgroundImage !== "none" ? {
|
|
82
83
|
backgroundImage: `url(${sectionBackgroundImage})`
|
|
83
84
|
} : {};
|
|
@@ -50,15 +50,19 @@ const buttonStyle = [{
|
|
|
50
50
|
key: "borderColor",
|
|
51
51
|
type: "color"
|
|
52
52
|
}]
|
|
53
|
-
},
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
53
|
+
},
|
|
54
|
+
// {
|
|
55
|
+
// tab: "Link",
|
|
56
|
+
// value: "link",
|
|
57
|
+
// fields: [
|
|
58
|
+
// {
|
|
59
|
+
// label: "Button Link",
|
|
60
|
+
// key: "buttonLink",
|
|
61
|
+
// type: "buttonLink",
|
|
62
|
+
// },
|
|
63
|
+
// ],
|
|
64
|
+
// },
|
|
65
|
+
{
|
|
62
66
|
tab: "Banner Spacing",
|
|
63
67
|
value: "bannerSpacing",
|
|
64
68
|
fields: [{
|
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
import { Transforms, Editor, Element, Node } from "slate";
|
|
2
2
|
import deserialize from "../helper/deserialize";
|
|
3
|
+
import { decodeAndParseBase64 } from "../utils/helper";
|
|
4
|
+
const avoidDefaultInsert = ["table", "grid"];
|
|
5
|
+
const loopChildren = (children = [], defaultInsert) => {
|
|
6
|
+
if (!children?.length) {
|
|
7
|
+
return defaultInsert;
|
|
8
|
+
}
|
|
9
|
+
for (let child of children) {
|
|
10
|
+
if (avoidDefaultInsert.includes(child?.type)) {
|
|
11
|
+
defaultInsert = false;
|
|
12
|
+
break;
|
|
13
|
+
}
|
|
14
|
+
defaultInsert = loopChildren(child.children, defaultInsert);
|
|
15
|
+
}
|
|
16
|
+
return defaultInsert;
|
|
17
|
+
};
|
|
3
18
|
const getCurrentElement = editor => {
|
|
4
19
|
try {
|
|
5
20
|
if (editor.selection) {
|
|
@@ -52,11 +67,17 @@ const withHtml = editor => {
|
|
|
52
67
|
const [tableNode] = Editor.nodes(editor, {
|
|
53
68
|
match: n => !Editor.isEditor(n) && Element.isElement(n) && n.type === "table"
|
|
54
69
|
});
|
|
55
|
-
// do not paste table cell inside table cell
|
|
56
|
-
// only plain text for internal paste
|
|
57
70
|
if (tableNode && tableNode[0]) {
|
|
58
|
-
const
|
|
59
|
-
|
|
71
|
+
const decoded = decodeAndParseBase64(slateHTML);
|
|
72
|
+
const defaultInsert = loopChildren(decoded, true);
|
|
73
|
+
if (defaultInsert) {
|
|
74
|
+
insertData(data);
|
|
75
|
+
} else {
|
|
76
|
+
// do not paste table, grid inside table cell
|
|
77
|
+
// only plain text for internal paste
|
|
78
|
+
const text = data?.getData("text/plain");
|
|
79
|
+
Transforms.insertText(editor, text);
|
|
80
|
+
}
|
|
60
81
|
} else {
|
|
61
82
|
insertData(data);
|
|
62
83
|
}
|
|
@@ -1,10 +1,35 @@
|
|
|
1
1
|
import { Editor, Range, Point, Element, Transforms, Node } from "slate";
|
|
2
|
+
import { TableUtil, createTableCell } from "../utils/table";
|
|
2
3
|
const NON_DELETABLE_BLOCKS = ["table-cell", "carousel-item"];
|
|
3
4
|
const withTable = editor => {
|
|
4
5
|
const {
|
|
5
6
|
deleteBackward,
|
|
6
|
-
deleteForward
|
|
7
|
+
deleteForward,
|
|
8
|
+
delete: slateDelete
|
|
7
9
|
} = editor;
|
|
10
|
+
editor.delete = arg => {
|
|
11
|
+
if (arg.reverse) {
|
|
12
|
+
const table = new TableUtil(editor);
|
|
13
|
+
const cellsSelected = table.isCellSelected(editor.selection);
|
|
14
|
+
if (cellsSelected) {
|
|
15
|
+
cellsSelected.forEach(cellPath => {
|
|
16
|
+
Transforms.removeNodes(editor, {
|
|
17
|
+
at: cellPath
|
|
18
|
+
});
|
|
19
|
+
Transforms.insertNodes(editor, createTableCell(""), {
|
|
20
|
+
at: cellPath
|
|
21
|
+
});
|
|
22
|
+
});
|
|
23
|
+
Transforms.deselect(editor, {
|
|
24
|
+
at: editor.selection
|
|
25
|
+
});
|
|
26
|
+
} else {
|
|
27
|
+
slateDelete(arg);
|
|
28
|
+
}
|
|
29
|
+
} else {
|
|
30
|
+
slateDelete(arg);
|
|
31
|
+
}
|
|
32
|
+
};
|
|
8
33
|
editor.deleteBackward = unit => {
|
|
9
34
|
const {
|
|
10
35
|
selection
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import { Transforms } from "slate";
|
|
2
1
|
import default_grid from "../Elements/Grid/templates/default_grid";
|
|
3
|
-
import insertNewLine from "./insertNewLine";
|
|
4
2
|
import { gridItem } from "./gridItem";
|
|
3
|
+
import { customInsertNode } from "./helper";
|
|
5
4
|
export const insertPlainGrid = count => {
|
|
6
5
|
const size = 12 / count;
|
|
7
6
|
const items = Array.from(Array(count).keys()).map(() => gridItem({
|
|
@@ -38,11 +37,10 @@ export const insertGrid = (editor, item, path) => {
|
|
|
38
37
|
const {
|
|
39
38
|
selection
|
|
40
39
|
} = editor;
|
|
41
|
-
|
|
40
|
+
customInsertNode(editor, grid, {
|
|
42
41
|
at: path || selection.focus.path,
|
|
43
42
|
select: true
|
|
44
43
|
});
|
|
45
|
-
insertNewLine(editor);
|
|
46
44
|
} catch (err) {
|
|
47
45
|
console.log(err);
|
|
48
46
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Editor, Node, Transforms, Element } from "slate";
|
|
2
2
|
import { ReactEditor } from "slate-react";
|
|
3
|
+
import insertNewLine from "./insertNewLine";
|
|
3
4
|
export const windowVar = {};
|
|
4
5
|
export const formatDate = (date, format = "MM/DD/YYYY") => {
|
|
5
6
|
if (!date) return "";
|
|
@@ -149,4 +150,56 @@ export const isListItem = editor => {
|
|
|
149
150
|
match: n => !Editor.isEditor(n) && Element.isElement(n) && format.indexOf(n.type) > -1
|
|
150
151
|
});
|
|
151
152
|
return node;
|
|
153
|
+
};
|
|
154
|
+
const getNode = (editor, path) => {
|
|
155
|
+
try {
|
|
156
|
+
return Node.get(editor, path);
|
|
157
|
+
} catch (err) {
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
};
|
|
161
|
+
export const customInsertNode = (editor, insertNode, defaultInsertOptions = {}) => {
|
|
162
|
+
const [parent, parentPath] = Editor.parent(editor, editor.selection.focus.path);
|
|
163
|
+
const isListItem = parent?.type === "list-item" || parent?.type === "check-list-item";
|
|
164
|
+
let newParentPath;
|
|
165
|
+
if (isListItem) {
|
|
166
|
+
const lastPathIndex = parentPath.length - 1;
|
|
167
|
+
const otherPaths = parentPath.slice(0, lastPathIndex);
|
|
168
|
+
const nextChildrenPath = parentPath[lastPathIndex] + 1;
|
|
169
|
+
newParentPath = [...otherPaths, nextChildrenPath];
|
|
170
|
+
const haveElem = getNode(editor, newParentPath);
|
|
171
|
+
if (haveElem) {
|
|
172
|
+
Transforms.splitNodes(editor, {
|
|
173
|
+
at: newParentPath
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
const {
|
|
177
|
+
anchor,
|
|
178
|
+
focus
|
|
179
|
+
} = editor.selection;
|
|
180
|
+
|
|
181
|
+
// if editor has selection, e.g /table, /grid is selected, delete that selection
|
|
182
|
+
if (focus.offset > anchor.offset) {
|
|
183
|
+
Transforms.delete(editor, {
|
|
184
|
+
at: editor.selection
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
const insertOptions = {
|
|
189
|
+
...defaultInsertOptions
|
|
190
|
+
};
|
|
191
|
+
if (isListItem) {
|
|
192
|
+
insertOptions.at = editor.selection.focus;
|
|
193
|
+
}
|
|
194
|
+
Transforms.insertNodes(editor, insertNode, insertOptions);
|
|
195
|
+
insertNewLine(editor);
|
|
196
|
+
};
|
|
197
|
+
export const decodeAndParseBase64 = encodedString => {
|
|
198
|
+
// Decode the Base64-encoded string
|
|
199
|
+
const decodedString = atob(encodedString);
|
|
200
|
+
|
|
201
|
+
// URL-decode the decoded string
|
|
202
|
+
const decodedURLString = decodeURIComponent(decodedString);
|
|
203
|
+
const jsonData = JSON.parse(decodedURLString);
|
|
204
|
+
return jsonData;
|
|
152
205
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Transforms, Editor, Range, Element, Path, Node } from "slate";
|
|
2
2
|
import { ReactEditor } from "slate-react";
|
|
3
|
-
import
|
|
3
|
+
import { customInsertNode } from "./helper";
|
|
4
4
|
const prefixKey = (obj, pk = "") => {
|
|
5
5
|
return Object.keys(obj).reduce((a, b) => {
|
|
6
6
|
a[`${pk}${b}`] = obj[b];
|
|
@@ -36,11 +36,7 @@ export class TableUtil {
|
|
|
36
36
|
length: columns
|
|
37
37
|
}, () => ""));
|
|
38
38
|
const newTable = createTableNode(cellText, rows, columns);
|
|
39
|
-
|
|
40
|
-
// to insert in current line
|
|
41
|
-
// at: this.editor.selection.anchor.path,
|
|
42
|
-
});
|
|
43
|
-
insertNewLine(this.editor);
|
|
39
|
+
customInsertNode(this.editor, newTable);
|
|
44
40
|
};
|
|
45
41
|
removeTable = () => {
|
|
46
42
|
Transforms.removeNodes(this.editor, {
|
|
@@ -318,7 +314,7 @@ export class TableUtil {
|
|
|
318
314
|
};
|
|
319
315
|
isCellSelected = selection => {
|
|
320
316
|
try {
|
|
321
|
-
if (!selection
|
|
317
|
+
if (!selection) {
|
|
322
318
|
return false;
|
|
323
319
|
}
|
|
324
320
|
const [tableNode] = Editor.nodes(this.editor, {
|
|
@@ -332,7 +328,7 @@ export class TableUtil {
|
|
|
332
328
|
anchor,
|
|
333
329
|
focus
|
|
334
330
|
} = this.editor.selection || {};
|
|
335
|
-
if (tableNode && tableNode[0] &&
|
|
331
|
+
if (tableNode && tableNode[0] && focus?.path) {
|
|
336
332
|
let startCell = anchor?.path;
|
|
337
333
|
let endCell = focus?.path;
|
|
338
334
|
|