@flozy/editor 3.2.8 → 3.2.9

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.
@@ -99,6 +99,7 @@ const EditorButton = props => {
99
99
  };
100
100
  const Toolbar = () => {
101
101
  const btnProps = handleLinkType(refURl, linkType, true, true, handleTrigger);
102
+ const hideOpenLink = linkType === "page" || !linkType;
102
103
  return !readOnly ? /*#__PURE__*/_jsxs("div", {
103
104
  className: "element-toolbar hr",
104
105
  style: {
@@ -121,7 +122,7 @@ const EditorButton = props => {
121
122
  onClick: onMenuClick("nav"),
122
123
  children: /*#__PURE__*/_jsx(LinkIcon, {})
123
124
  })
124
- }), linkType === "page" ? null : /*#__PURE__*/_jsx(Tooltip, {
125
+ }), hideOpenLink ? null : /*#__PURE__*/_jsx(Tooltip, {
125
126
  title: "Open Link",
126
127
  arrow: true,
127
128
  children: /*#__PURE__*/_jsx(Box, {
@@ -1,4 +1,6 @@
1
1
  import React, { useEffect, useRef } from "react";
2
+ import sanitizeHtml from "sanitize-html";
3
+ import { allowedDomains } from "../../utils/helper";
2
4
 
3
5
  // const sanitize = (input) => {
4
6
  // const doc = new DOMParser().parseFromString(input, "text/html");
@@ -25,7 +27,14 @@ const Code = props => {
25
27
  } = element;
26
28
  useEffect(() => {
27
29
  if (codeRef?.current) {
28
- const slotHtml = document.createRange().createContextualFragment(embedData); // Create a 'tiny' document and parse the html string
30
+ const clean = sanitizeHtml(embedData, {
31
+ allowedTags: false,
32
+ // Allow all tags
33
+ allowedAttributes: false,
34
+ // Allow all attributes
35
+ allowedScriptDomains: allowedDomains
36
+ });
37
+ const slotHtml = document.createRange().createContextualFragment(clean); // Create a 'tiny' document and parse the html string
29
38
  codeRef.current.innerHTML = ""; // Clear the container
30
39
  codeRef.current.appendChild(slotHtml);
31
40
  }
@@ -165,15 +165,13 @@ export const toolbarGroups = [[{
165
165
  format: "video",
166
166
  type: "embed",
167
167
  group: "elements"
168
- },
169
- // {
170
- // id: 49,
171
- // lbT: "embedScript",
172
- // format: "embedScript",
173
- // type: "embedScript",
174
- // group: "elements",
175
- // },
176
- {
168
+ }, {
169
+ id: 49,
170
+ lbT: "embedScript",
171
+ format: "embedScript",
172
+ type: "embedScript",
173
+ group: "elements"
174
+ }, {
177
175
  id: 45,
178
176
  format: "topbanner",
179
177
  type: "topbanner",
@@ -103,7 +103,7 @@ export const SelectPage = props => {
103
103
  };
104
104
  export const Trigger = props => {
105
105
  return /*#__PURE__*/_jsx(Typography, {
106
- variant: "h6",
106
+ variant: "subtitle1",
107
107
  gutterBottom: true,
108
108
  children: "Choosing this will trigger the next step"
109
109
  });
@@ -1,17 +1,20 @@
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 LinkSettingsStyles from './style';
11
- import { getNavOptions } from './navOptions';
12
- import { ScrollTopBottom, SelectPage, TextInput, Trigger } from './NavComponents';
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 { Box, FormControl, FormControlLabel, Grid, MenuItem, Radio, RadioGroup, Select, Typography } from "@mui/material";
9
+ import { useState } from "react";
10
+ import LinkSettingsStyles from "./style";
11
+ import { getNavOptions } from "./navOptions";
12
+ import { ScrollTopBottom, SelectPage, TextInput, Trigger } from "./NavComponents";
13
+ import SwipeableDrawer from "../SwipeableDrawer";
14
+ import { useEditorContext } from "../../hooks/useMouseMove";
13
15
  import { jsx as _jsx } from "react/jsx-runtime";
14
16
  import { jsxs as _jsxs } from "react/jsx-runtime";
17
+ import { Fragment as _Fragment } from "react/jsx-runtime";
15
18
  const MAP_COMPONENT = {
16
19
  webAddress: TextInput,
17
20
  email: TextInput,
@@ -20,6 +23,12 @@ const MAP_COMPONENT = {
20
23
  scrollTopOrBottom: ScrollTopBottom,
21
24
  page: SelectPage
22
25
  };
26
+ function getNav(navType, navOptions) {
27
+ return navType ? navOptions.find(n => n.value === navType) : {
28
+ label: "None",
29
+ value: ""
30
+ };
31
+ }
23
32
  export default function LinkSettings(props) {
24
33
  const {
25
34
  handleClose,
@@ -27,86 +36,157 @@ export default function LinkSettings(props) {
27
36
  customProps,
28
37
  navType
29
38
  } = props;
39
+ const {
40
+ isMobile
41
+ } = customProps;
30
42
  const navOptions = getNavOptions(customProps.hideTools);
31
43
  const classes = LinkSettingsStyles();
32
- const [nav, setNav] = useState(navType ? navOptions.find(n => n.value === navType) : {
33
- label: "None",
34
- value: ""
35
- });
44
+ const [nav, setNav] = useState(getNav(navType, navOptions));
36
45
  const [navValue, setNavValue] = useState(props?.navValue || "");
37
46
  const [openInNewTab, setOpenInNewTab] = useState(props.openInNewTab || false);
38
47
  const NavSettings = MAP_COMPONENT[nav?.value];
39
48
  const onChange = value => {
40
49
  setNavValue(value);
41
50
  };
42
- return /*#__PURE__*/_jsxs(Dialog, {
43
- onClose: handleClose,
44
- open: true,
45
- sx: classes.dialogContainer,
46
- fullWidth: true,
47
- maxWidth: "sm",
48
- children: [/*#__PURE__*/_jsx(DialogTitle, {
49
- children: "What do you want to link to?"
50
- }), /*#__PURE__*/_jsx(IconButton, {
51
- "aria-label": "close",
52
- onClick: handleClose,
53
- sx: classes.closeIcon,
54
- children: /*#__PURE__*/_jsx(CloseIcon, {})
55
- }), /*#__PURE__*/_jsx(DialogContent, {
56
- dividers: true,
57
- children: /*#__PURE__*/_jsxs(Grid, {
58
- container: true,
59
- spacing: 2,
60
- children: [/*#__PURE__*/_jsx(Grid, {
61
- item: true,
62
- xs: 6,
63
- sx: classes.gridDivider,
64
- children: /*#__PURE__*/_jsx(FormControl, {
65
- children: /*#__PURE__*/_jsx(RadioGroup, {
66
- value: nav?.value,
67
- children: navOptions?.map((navOption, i) => {
68
- return /*#__PURE__*/_jsx(FormControlLabel, {
69
- value: navOption.value,
70
- control: /*#__PURE__*/_jsx(Radio, {}),
71
- label: navOption.label,
72
- onChange: () => {
73
- setNav(navOption);
74
- setNavValue("");
75
- }
76
- }, i);
77
- })
51
+ const onSubmit = () => {
52
+ onSave({
53
+ linkType: nav?.value,
54
+ navValue,
55
+ openInNewTab
56
+ });
57
+ };
58
+ if (isMobile) {
59
+ return /*#__PURE__*/_jsxs(SwipeableDrawer, {
60
+ onClose: handleClose,
61
+ children: [/*#__PURE__*/_jsx(Typography, {
62
+ variant: "subtitle1",
63
+ gutterBottom: true,
64
+ sx: {
65
+ fontWeight: 600
66
+ },
67
+ children: "What do you want to link to?"
68
+ }), /*#__PURE__*/_jsx(Select, {
69
+ size: "small",
70
+ fullWidth: true,
71
+ value: nav?.value,
72
+ onChange: e => {
73
+ const {
74
+ value
75
+ } = e.target;
76
+ const selected = getNav(value, navOptions);
77
+ setNav(selected);
78
+ setNavValue("");
79
+ },
80
+ displayEmpty: true,
81
+ children: navOptions.map((navOption, i) => {
82
+ return /*#__PURE__*/_jsx(MenuItem, {
83
+ value: navOption.value,
84
+ children: /*#__PURE__*/_jsx(Typography, {
85
+ variant: "body2",
86
+ children: navOption.label
78
87
  })
79
- })
80
- }), /*#__PURE__*/_jsx(Grid, {
81
- item: true,
82
- xs: 6,
83
- children: NavSettings && /*#__PURE__*/_jsx(NavSettings, {
84
- placeholder: nav?.placeholder,
85
- nav: nav,
86
- onChange: onChange,
87
- value: navValue,
88
- openInNewTab: openInNewTab,
89
- onNewTabChange: () => setOpenInNewTab(prev => !prev),
90
- services: customProps.services
91
- })
92
- })]
93
- })
94
- }), /*#__PURE__*/_jsxs(DialogActions, {
95
- children: [/*#__PURE__*/_jsx(Button, {
96
- onClick: handleClose,
97
- sx: classes.closeBtn,
98
- children: "Cancel"
99
- }), /*#__PURE__*/_jsx(Button, {
100
- onClick: () => {
101
- onSave({
102
- linkType: nav?.value,
103
- navValue,
104
- openInNewTab
105
- });
88
+ }, i);
89
+ })
90
+ }), /*#__PURE__*/_jsx(Box, {
91
+ sx: {
92
+ paddingTop: "14px"
106
93
  },
107
- sx: classes.saveBtn,
108
- children: "Save"
94
+ children: NavSettings && /*#__PURE__*/_jsx(NavSettings, {
95
+ placeholder: nav?.placeholder,
96
+ nav: nav,
97
+ onChange: onChange,
98
+ value: navValue,
99
+ openInNewTab: openInNewTab,
100
+ onNewTabChange: () => setOpenInNewTab(prev => !prev),
101
+ services: customProps.services
102
+ })
103
+ }), /*#__PURE__*/_jsx(Box, {
104
+ component: "div",
105
+ sx: classes.mobileActionBtns,
106
+ children: /*#__PURE__*/_jsx(ActionsButtons, {
107
+ classes: classes,
108
+ onCancel: handleClose,
109
+ onSave: onSubmit
110
+ })
111
+ })]
112
+ });
113
+ } else {
114
+ return /*#__PURE__*/_jsxs(Dialog, {
115
+ onClose: handleClose,
116
+ open: true,
117
+ sx: classes.dialogContainer,
118
+ fullWidth: true,
119
+ maxWidth: "sm",
120
+ children: [/*#__PURE__*/_jsx(DialogTitle, {
121
+ children: "What do you want to link to?"
122
+ }), /*#__PURE__*/_jsx(IconButton, {
123
+ "aria-label": "close",
124
+ onClick: handleClose,
125
+ sx: classes.closeIcon,
126
+ children: /*#__PURE__*/_jsx(CloseIcon, {})
127
+ }), /*#__PURE__*/_jsx(DialogContent, {
128
+ dividers: true,
129
+ children: /*#__PURE__*/_jsxs(Grid, {
130
+ container: true,
131
+ spacing: 2,
132
+ children: [/*#__PURE__*/_jsx(Grid, {
133
+ item: true,
134
+ xs: 6,
135
+ sx: classes.gridDivider,
136
+ children: /*#__PURE__*/_jsx(FormControl, {
137
+ children: /*#__PURE__*/_jsx(RadioGroup, {
138
+ value: nav?.value,
139
+ children: navOptions?.map((navOption, i) => {
140
+ return /*#__PURE__*/_jsx(FormControlLabel, {
141
+ value: navOption.value,
142
+ control: /*#__PURE__*/_jsx(Radio, {}),
143
+ label: navOption.label,
144
+ onChange: () => {
145
+ setNav(navOption);
146
+ setNavValue("");
147
+ }
148
+ }, i);
149
+ })
150
+ })
151
+ })
152
+ }), /*#__PURE__*/_jsx(Grid, {
153
+ item: true,
154
+ xs: 6,
155
+ children: NavSettings && /*#__PURE__*/_jsx(NavSettings, {
156
+ placeholder: nav?.placeholder,
157
+ nav: nav,
158
+ onChange: onChange,
159
+ value: navValue,
160
+ openInNewTab: openInNewTab,
161
+ onNewTabChange: () => setOpenInNewTab(prev => !prev),
162
+ services: customProps.services
163
+ })
164
+ })]
165
+ })
166
+ }), /*#__PURE__*/_jsx(DialogActions, {
167
+ children: /*#__PURE__*/_jsx(ActionsButtons, {
168
+ classes: classes,
169
+ onCancel: handleClose,
170
+ onSave: onSubmit
171
+ })
109
172
  })]
173
+ });
174
+ }
175
+ }
176
+ function ActionsButtons({
177
+ classes,
178
+ onCancel,
179
+ onSave
180
+ }) {
181
+ return /*#__PURE__*/_jsxs(_Fragment, {
182
+ children: [/*#__PURE__*/_jsx(Button, {
183
+ onClick: onCancel,
184
+ sx: classes.closeBtn,
185
+ children: "Cancel"
186
+ }), /*#__PURE__*/_jsx(Button, {
187
+ onClick: onSave,
188
+ sx: classes.saveBtn,
189
+ children: "Save"
110
190
  })]
111
191
  });
112
192
  }
@@ -50,6 +50,14 @@ const ButtonNavSettingsStyles = () => ({
50
50
  },
51
51
  gridDivider: {
52
52
  borderRight: "1px solid rgba(0, 0, 0, 0.12)"
53
+ },
54
+ mobileActionBtns: {
55
+ display: "flex",
56
+ justifyContent: "flex-end",
57
+ gap: "8px",
58
+ paddingTop: "14px",
59
+ marginTop: "14px",
60
+ borderTop: theme => `1px solid ${theme.palette.grey[300]}`
53
61
  }
54
62
  });
55
63
  export default ButtonNavSettingsStyles;
@@ -0,0 +1,34 @@
1
+ import { Box, SwipeableDrawer, Typography } from "@mui/material";
2
+ import DrawerStyles from "./style";
3
+ import { grey } from "@mui/material/colors";
4
+ import { styled } from "@mui/material/styles";
5
+ import { jsx as _jsx } from "react/jsx-runtime";
6
+ import { jsxs as _jsxs } from "react/jsx-runtime";
7
+ const Puller = styled("div")(({
8
+ theme
9
+ }) => ({
10
+ width: 30,
11
+ height: 6,
12
+ backgroundColor: theme?.palette?.mode === "light" ? grey[300] : grey[900],
13
+ borderRadius: 3,
14
+ margin: "auto",
15
+ marginTop: "14px"
16
+ }));
17
+ function SwipeableDrawerComponent({
18
+ open,
19
+ onClose,
20
+ children
21
+ }) {
22
+ const classes = DrawerStyles();
23
+ return /*#__PURE__*/_jsxs(SwipeableDrawer, {
24
+ anchor: "bottom",
25
+ open: true,
26
+ onClose: onClose,
27
+ sx: classes.drawerContainer,
28
+ children: [/*#__PURE__*/_jsx(Puller, {}), /*#__PURE__*/_jsx(Box, {
29
+ sx: classes.childContainer,
30
+ children: children
31
+ })]
32
+ });
33
+ }
34
+ export default SwipeableDrawerComponent;
@@ -0,0 +1,12 @@
1
+ const Styles = () => ({
2
+ drawerContainer: {
3
+ "& .MuiDrawer-paper": {
4
+ borderTopLeftRadius: 8,
5
+ borderTopRightRadius: 8
6
+ }
7
+ },
8
+ childContainer: {
9
+ padding: "20px"
10
+ }
11
+ });
12
+ export default Styles;
@@ -296,4 +296,5 @@ export const handleLinkType = (url, linkType, readOnly, openInNewTab, onClick =
296
296
  };
297
297
  }
298
298
  return props;
299
- };
299
+ };
300
+ export const allowedDomains = ["youtube.com", "lemcal.com", "facebook.com", "calendly.com"];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flozy/editor",
3
- "version": "3.2.8",
3
+ "version": "3.2.9",
4
4
  "description": "An Editor for flozy app brain",
5
5
  "files": [
6
6
  "dist"
@@ -39,6 +39,7 @@
39
39
  "react-scripts": "5.0.1",
40
40
  "react-signature-canvas": "^1.0.6",
41
41
  "react-slick": "^0.29.0",
42
+ "sanitize-html": "^2.13.0",
42
43
  "slate": "^0.94.1",
43
44
  "slate-history": "^0.93.0",
44
45
  "slate-hyperscript": "^0.100.0",
@@ -63,7 +64,7 @@
63
64
  "storybook": "storybook dev -p 6006",
64
65
  "build-storybook": "storybook build",
65
66
  "publish:npm": "rm -rf dist && mkdir dist && babel src/components -d dist --copy-files",
66
- "publish:local": "rm -rf /Users/agmac23/Desktop/surya/sweetpsocial-2.0/client/node_modules/@flozy/editor/dist && babel src/components -d /Users/agmac23/Desktop/surya/sweetpsocial-2.0/client/node_modules/@flozy/editor/dist --copy-files"
67
+ "publish:local": "rm -rf /Users/agmac03/flozy/client/node_modules/@flozy/editor/dist && babel src/components -d /Users/agmac03/flozy/client/node_modules/@flozy/editor/dist --copy-files"
67
68
  },
68
69
  "eslintConfig": {
69
70
  "extends": [