@flozy/editor 3.1.0 → 3.1.1
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 +114 -30
- package/dist/Editor/Elements/Form/Form.js +6 -2
- package/dist/Editor/Toolbar/Mini/Options/Options.js +1 -1
- 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,89 @@ 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
|
+
props.href = `/${url}`.replace("home", "");
|
|
111
|
+
if (openInNewTab) {
|
|
112
|
+
props.target = "_blank";
|
|
113
|
+
}
|
|
114
|
+
break;
|
|
115
|
+
case "email":
|
|
116
|
+
props.component = "a";
|
|
117
|
+
props.href = `mailto:${url}`;
|
|
118
|
+
break;
|
|
119
|
+
case "phone":
|
|
120
|
+
props.component = "a";
|
|
121
|
+
props.href = `tel:${url}`;
|
|
122
|
+
break;
|
|
123
|
+
case "scrollTopOrBottom":
|
|
124
|
+
props.component = "button";
|
|
125
|
+
props.onClick = () => {
|
|
126
|
+
const scrollEle = document.getElementById("slate-wrapper-scroll-container");
|
|
127
|
+
if (scrollEle) {
|
|
128
|
+
if (url === "top") {
|
|
129
|
+
// top of the page
|
|
130
|
+
scrollEle.scrollTo(0, 0);
|
|
131
|
+
} else if (url === "bottom") {
|
|
132
|
+
// bottom of the page
|
|
133
|
+
scrollEle.scrollTo(0, scrollEle.scrollHeight);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
break;
|
|
76
138
|
}
|
|
139
|
+
return props;
|
|
77
140
|
};
|
|
141
|
+
const buttonProps = handleLinkType(readOnly, openInNewTab);
|
|
78
142
|
const onMenuClick = val => () => {
|
|
79
143
|
switch (val) {
|
|
80
|
-
case "open":
|
|
81
|
-
const refUrl = url ? url.includes("http") ? url : `//${url}` : "Link";
|
|
82
|
-
window.open(refUrl, "_blank").focus();
|
|
83
|
-
return;
|
|
84
144
|
case "edit":
|
|
85
145
|
setEdit(true);
|
|
86
146
|
return;
|
|
@@ -89,16 +149,22 @@ const EditorButton = props => {
|
|
|
89
149
|
at: [...path]
|
|
90
150
|
});
|
|
91
151
|
return;
|
|
152
|
+
case "nav":
|
|
153
|
+
setOpenNav(true);
|
|
154
|
+
return;
|
|
92
155
|
default:
|
|
93
156
|
return;
|
|
94
157
|
}
|
|
95
158
|
};
|
|
96
159
|
const Toolbar = () => {
|
|
160
|
+
const btnProps = handleLinkType(true, true);
|
|
97
161
|
return !readOnly ? /*#__PURE__*/_jsxs("div", {
|
|
98
162
|
className: "element-toolbar hr",
|
|
99
163
|
style: {
|
|
100
164
|
width: "max-content",
|
|
101
|
-
top: "-38px"
|
|
165
|
+
top: "-38px",
|
|
166
|
+
alignItems: "center",
|
|
167
|
+
cursor: "pointer"
|
|
102
168
|
},
|
|
103
169
|
children: [/*#__PURE__*/_jsx(Tooltip, {
|
|
104
170
|
title: "Settings",
|
|
@@ -108,10 +174,21 @@ const EditorButton = props => {
|
|
|
108
174
|
children: /*#__PURE__*/_jsx(SettingsIcon, {})
|
|
109
175
|
})
|
|
110
176
|
}), /*#__PURE__*/_jsx(Tooltip, {
|
|
111
|
-
title: "
|
|
177
|
+
title: "Nav Settings",
|
|
112
178
|
arrow: true,
|
|
113
179
|
children: /*#__PURE__*/_jsx(IconButton, {
|
|
114
|
-
onClick: onMenuClick("
|
|
180
|
+
onClick: onMenuClick("nav"),
|
|
181
|
+
children: /*#__PURE__*/_jsx(LinkIcon, {})
|
|
182
|
+
})
|
|
183
|
+
}), /*#__PURE__*/_jsx(Tooltip, {
|
|
184
|
+
title: "Open Link",
|
|
185
|
+
arrow: true,
|
|
186
|
+
children: /*#__PURE__*/_jsx(Box, {
|
|
187
|
+
sx: {
|
|
188
|
+
display: "inline-flex",
|
|
189
|
+
color: "rgba(0, 0, 0, 0.54)"
|
|
190
|
+
},
|
|
191
|
+
...btnProps,
|
|
115
192
|
children: /*#__PURE__*/_jsx(OpenInNewIcon, {})
|
|
116
193
|
})
|
|
117
194
|
})]
|
|
@@ -152,7 +229,7 @@ const EditorButton = props => {
|
|
|
152
229
|
},
|
|
153
230
|
"&:hover": {
|
|
154
231
|
"& .element-toolbar": {
|
|
155
|
-
display: "
|
|
232
|
+
display: "flex"
|
|
156
233
|
}
|
|
157
234
|
}
|
|
158
235
|
},
|
|
@@ -161,8 +238,8 @@ const EditorButton = props => {
|
|
|
161
238
|
position: "relative"
|
|
162
239
|
},
|
|
163
240
|
children: [/*#__PURE__*/_jsxs(Box, {
|
|
164
|
-
component: "button",
|
|
165
241
|
sx: {
|
|
242
|
+
textDecoration: "none",
|
|
166
243
|
background: bgColor || "rgb(30, 75, 122)",
|
|
167
244
|
borderBlockStyle: "solid",
|
|
168
245
|
borderColor: borderColor || "transparent",
|
|
@@ -187,11 +264,11 @@ const EditorButton = props => {
|
|
|
187
264
|
color: `${textColorHover || textColor || "#FFFFFF"}`,
|
|
188
265
|
background: bgColorHover || bgColor || "rgb(30, 75, 122)",
|
|
189
266
|
"& .element-toolbar": {
|
|
190
|
-
display: "
|
|
267
|
+
display: "flex"
|
|
191
268
|
}
|
|
192
269
|
}
|
|
193
270
|
},
|
|
194
|
-
|
|
271
|
+
...buttonProps,
|
|
195
272
|
children: [BtnIcon && iconPosition === "start" && /*#__PURE__*/_jsx(BtnIcon, {
|
|
196
273
|
style: {
|
|
197
274
|
paddingLeft: "4px",
|
|
@@ -220,7 +297,14 @@ const EditorButton = props => {
|
|
|
220
297
|
onClose: onClose,
|
|
221
298
|
onDelete: onMenuClick("delete"),
|
|
222
299
|
customProps: customProps
|
|
223
|
-
})
|
|
300
|
+
}), openNav ? /*#__PURE__*/_jsx(ButtonNavSettings, {
|
|
301
|
+
open: openNav,
|
|
302
|
+
handleClose: () => setOpenNav(false),
|
|
303
|
+
onSave: onSave,
|
|
304
|
+
customProps: customProps,
|
|
305
|
+
element: element,
|
|
306
|
+
editor: editor
|
|
307
|
+
}) : null]
|
|
224
308
|
});
|
|
225
309
|
};
|
|
226
310
|
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
|
}
|
|
@@ -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
|
|