@flozy/editor 1.2.8 → 1.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.
@@ -158,8 +158,10 @@ const CommonEditor = /*#__PURE__*/forwardRef((props, ref) => {
158
158
  setIsInteracted(true);
159
159
  }
160
160
  };
161
+ const isReadOnly = readOnly === "readonly";
161
162
  const customProps = {
162
- ...(otherProps || {})
163
+ ...(otherProps || {}),
164
+ readOnly: isReadOnly
163
165
  };
164
166
  const renderElement = useCallback(props => {
165
167
  return /*#__PURE__*/_jsx(Element, {
@@ -198,7 +200,6 @@ const CommonEditor = /*#__PURE__*/forwardRef((props, ref) => {
198
200
  });
199
201
  }
200
202
  }, [chars, editor, target, mentions, setMentions]);
201
- const isReadOnly = readOnly === "readonly";
202
203
  const Overlay = collaborativeEditor && !isReadOnly ? RemoteCursorOverlay : React.Fragment;
203
204
  return /*#__PURE__*/_jsx(DialogWrapper, {
204
205
  ...props,
@@ -6,6 +6,7 @@ const ButtonPopup = props => {
6
6
  const {
7
7
  element,
8
8
  onSave,
9
+ customProps,
9
10
  onClose
10
11
  } = props;
11
12
  return /*#__PURE__*/_jsx(StyleBuilder, {
@@ -14,7 +15,8 @@ const ButtonPopup = props => {
14
15
  element: element,
15
16
  onSave: onSave,
16
17
  onClose: onClose,
17
- renderTabs: buttonStyle
18
+ renderTabs: buttonStyle,
19
+ customProps: customProps
18
20
  });
19
21
  };
20
22
  export default ButtonPopup;
@@ -3,6 +3,7 @@ import { Transforms } from "slate";
3
3
  import { ReactEditor, useSlateStatic } from "slate-react";
4
4
  import { Menu, MenuItem } from "@mui/material";
5
5
  import ButtonPopup from "./ButtonPopup";
6
+ import { actionButtonRedirect } from "../../service/actionTrigger";
6
7
  import { jsx as _jsx } from "react/jsx-runtime";
7
8
  import { jsxs as _jsxs } from "react/jsx-runtime";
8
9
  const EditorButton = props => {
@@ -12,7 +13,8 @@ const EditorButton = props => {
12
13
  customProps
13
14
  } = props;
14
15
  const {
15
- readOnly
16
+ readOnly,
17
+ metadata
16
18
  } = customProps;
17
19
  const editor = useSlateStatic();
18
20
  const path = ReactEditor.findPath(editor, element);
@@ -25,8 +27,13 @@ const EditorButton = props => {
25
27
  bannerSpacing,
26
28
  textColor,
27
29
  url,
28
- borderColor
30
+ borderColor,
31
+ buttonLink
29
32
  } = element;
33
+ const {
34
+ linkType,
35
+ redirectOnURLResult
36
+ } = buttonLink || {};
30
37
  const {
31
38
  topLeft,
32
39
  topRight,
@@ -39,13 +46,34 @@ const EditorButton = props => {
39
46
  right,
40
47
  bottom
41
48
  } = bannerSpacing || {};
42
- const onClick = e => {
43
- setAnchorEl(e.currentTarget);
49
+ const onClick = async e => {
50
+ if (readOnly) {
51
+ if (metadata?.buttonLink?.handler) {
52
+ metadata.buttonLink.handler("click");
53
+ } else if (linkType === "actionTrigger") {
54
+ if (redirectOnURLResult) {
55
+ // call api and redirect based on api result
56
+ const apiResult = await actionButtonRedirect({}, {
57
+ url: buttonLink?.url
58
+ });
59
+ window.open(apiResult, "_blank").focus();
60
+ } else {
61
+ const refUrl = buttonLink?.url ? buttonLink?.url.includes("http") ? buttonLink?.url : `//${buttonLink?.url}` : "Link";
62
+ window.open(refUrl, "_blank").focus();
63
+ }
64
+ } else {
65
+ const refUrl = url ? url.includes("http") ? url : `//${url}` : "Link";
66
+ window.open(refUrl, "_blank").focus();
67
+ }
68
+ } else {
69
+ setAnchorEl(e.currentTarget);
70
+ }
44
71
  };
45
72
  const handleClose = () => {
46
73
  setAnchorEl(null);
47
74
  };
48
75
  const onMenuClick = val => () => {
76
+ console.log(val, url);
49
77
  switch (val) {
50
78
  case "open":
51
79
  const refUrl = url ? url.includes("http") ? url : `//${url}` : "Link";
@@ -117,7 +145,8 @@ const EditorButton = props => {
117
145
  }), edit && /*#__PURE__*/_jsx(ButtonPopup, {
118
146
  element: element,
119
147
  onSave: onSave,
120
- onClose: onClose
148
+ onClose: onClose,
149
+ customProps: customProps
121
150
  })]
122
151
  });
123
152
  };
@@ -68,6 +68,7 @@ const Embed = ({
68
68
  [e.target.name]: e.target.value
69
69
  });
70
70
  };
71
+ const imageURL = formData?.url === "none" || !formData?.url ? "" : formData?.url;
71
72
  return /*#__PURE__*/_jsxs(_Fragment, {
72
73
  children: [/*#__PURE__*/_jsx(IconButton, {
73
74
  className: isBlockActive(editor, format) ? "active" : "",
@@ -127,7 +128,7 @@ const Embed = ({
127
128
  size: "small",
128
129
  fullWidth: true,
129
130
  onChange: handleChange,
130
- value: formData?.url || ""
131
+ value: imageURL || ""
131
132
  })
132
133
  }), /*#__PURE__*/_jsx(Uploader, {
133
134
  value: formData,
@@ -1,14 +1,41 @@
1
1
  import React from "react";
2
+ import { IconButton } from "@mui/material";
3
+ import DeleteIcon from "@mui/icons-material/Delete";
4
+ import { Transforms } from "slate";
5
+ import { ReactEditor, useSlateStatic } from "slate-react";
2
6
  import { jsx as _jsx } from "react/jsx-runtime";
7
+ import { jsxs as _jsxs } from "react/jsx-runtime";
3
8
  const ImageText = props => {
4
9
  const {
5
10
  attributes,
11
+ element,
6
12
  children
7
13
  } = props;
8
- return /*#__PURE__*/_jsx("div", {
14
+ const editor = useSlateStatic();
15
+ const onDelete = () => {
16
+ const path = ReactEditor.findPath(editor, element);
17
+ Transforms.removeNodes(editor, {
18
+ at: [...path]
19
+ });
20
+ };
21
+ return /*#__PURE__*/_jsxs("div", {
9
22
  className: "image-text",
10
23
  ...attributes,
11
- children: children
24
+ style: {
25
+ position: "relative"
26
+ },
27
+ children: [children, /*#__PURE__*/_jsx("div", {
28
+ children: /*#__PURE__*/_jsx(IconButton, {
29
+ onClick: onDelete,
30
+ style: {
31
+ background: "#FFF",
32
+ position: "absolute",
33
+ right: "0px",
34
+ top: "0px"
35
+ },
36
+ children: /*#__PURE__*/_jsx(DeleteIcon, {})
37
+ })
38
+ })]
12
39
  });
13
40
  };
14
41
  export default ImageText;
@@ -1,8 +1,7 @@
1
1
  import { useRef, useState } from "react";
2
2
  import { Transforms } from "slate";
3
- import { Dialog, DialogActions, DialogContent, DialogTitle, FormControl, FormControlLabel, Grid, TextField, Button, IconButton, Typography } from "@mui/material";
3
+ import { Dialog, DialogActions, DialogContent, DialogTitle, FormControl, FormControlLabel, Grid, TextField, Button, IconButton, Typography, Checkbox } from "@mui/material";
4
4
  import CloseIcon from "@mui/icons-material/Close";
5
- import { CheckBox } from "@mui/icons-material";
6
5
  import { insertLink } from "../../utils/link";
7
6
  import Icon from "../../common/Icon";
8
7
  import { isBlockActive } from "../../utils/SlateUtilityFunctions";
@@ -112,7 +111,7 @@ const LinkButton = props => {
112
111
  },
113
112
  children: /*#__PURE__*/_jsx(FormControl, {
114
113
  children: /*#__PURE__*/_jsx(FormControlLabel, {
115
- control: /*#__PURE__*/_jsx(CheckBox, {
114
+ control: /*#__PURE__*/_jsx(Checkbox, {
116
115
  checked: showInNewTab,
117
116
  onChange: handleInputChange
118
117
  }),
@@ -2,9 +2,9 @@ import React from "react";
2
2
  import { IconButton } from "@mui/material";
3
3
  import KeyboardReturnIcon from "@mui/icons-material/KeyboardReturn";
4
4
  import { Transforms } from "slate";
5
- import { useSlateStatic } from "slate-react";
5
+ import { ReactEditor, useSlateStatic } from "slate-react";
6
6
  import { jsx as _jsx } from "react/jsx-runtime";
7
- const NewLineButton = props => {
7
+ const NewLineButton = () => {
8
8
  const editor = useSlateStatic();
9
9
  const onAddNewLine = () => {
10
10
  Transforms.insertNodes(editor, [{
@@ -13,17 +13,19 @@ const NewLineButton = props => {
13
13
  text: ""
14
14
  }]
15
15
  }], {
16
- at: [editor.children.length]
16
+ at: [editor.children.length],
17
+ select: true
17
18
  });
19
+ ReactEditor.focus(editor);
18
20
  };
19
21
  return /*#__PURE__*/_jsx(IconButton, {
20
22
  title: "New Line",
21
23
  onClick: onAddNewLine,
22
24
  children: /*#__PURE__*/_jsx(KeyboardReturnIcon, {
23
25
  sx: {
24
- fill: '#64748B',
25
- width: '18px',
26
- height: '18px'
26
+ fill: "#64748B",
27
+ width: "18px",
28
+ height: "18px"
27
29
  }
28
30
  })
29
31
  });
@@ -5,10 +5,14 @@ const buttonStyle = [{
5
5
  label: "Button Text",
6
6
  key: "label",
7
7
  type: "text"
8
- }, {
9
- label: "Button URL",
10
- type: "text",
11
- key: "url"
8
+ }]
9
+ }, {
10
+ tab: "Link",
11
+ value: "link",
12
+ fields: [{
13
+ label: "Button Link",
14
+ key: "buttonLink",
15
+ type: "buttonLink"
12
16
  }]
13
17
  }, {
14
18
  tab: "Banner Spacing",
@@ -1,12 +1,4 @@
1
1
  const embedImageStyle = [{
2
- tab: "Image Texts",
3
- value: "imageTexts",
4
- fields: [{
5
- label: "Image Texts",
6
- key: "imageTexts",
7
- type: "imageTexts"
8
- }]
9
- }, {
10
2
  tab: "Banner Spacing",
11
3
  value: "bannerSpacing",
12
4
  fields: [{
@@ -0,0 +1,113 @@
1
+ import React from "react";
2
+ import { FormControl, FormLabel, RadioGroup, FormControlLabel, Grid, Radio, TextField, Select, MenuItem } from "@mui/material";
3
+ import { jsx as _jsx } from "react/jsx-runtime";
4
+ import { jsxs as _jsxs } from "react/jsx-runtime";
5
+ const ButtonLink = props => {
6
+ const {
7
+ value,
8
+ data,
9
+ elementProps,
10
+ customProps,
11
+ onChange
12
+ } = props;
13
+ const {
14
+ key
15
+ } = data;
16
+ const {
17
+ metadata
18
+ } = customProps || {
19
+ metadata: {}
20
+ };
21
+ const {
22
+ buttonLink
23
+ } = metadata || {
24
+ actionTrigger: {}
25
+ };
26
+ const {
27
+ actionTrigger
28
+ } = buttonLink || {};
29
+ const {
30
+ options,
31
+ onClick
32
+ } = actionTrigger || {
33
+ options: []
34
+ };
35
+ const optSelected = options.filter(f => f.selected) || [];
36
+ const handleChange = e => {
37
+ onChange({
38
+ [key]: {
39
+ ...value,
40
+ [e.target.name]: e.target.value,
41
+ onClick: onClick || {}
42
+ }
43
+ });
44
+ };
45
+ const onURLChange = e => {
46
+ onChange({
47
+ url: e.target.value
48
+ });
49
+ };
50
+ const renderLinkTypeFields = () => {
51
+ if (value?.linkType === "webAddress") {
52
+ return /*#__PURE__*/_jsx(Grid, {
53
+ item: true,
54
+ xs: 12,
55
+ children: /*#__PURE__*/_jsx(TextField, {
56
+ fullWidth: true,
57
+ size: "small",
58
+ placeholder: "https://",
59
+ onChange: onURLChange,
60
+ value: elementProps?.url
61
+ })
62
+ });
63
+ } else if (value?.linkType === "actionTrigger") {
64
+ return /*#__PURE__*/_jsx(Grid, {
65
+ item: true,
66
+ xs: 12,
67
+ children: /*#__PURE__*/_jsx(Select, {
68
+ name: "actionStep",
69
+ size: "small",
70
+ fullWidth: true,
71
+ value: optSelected[0]?.value || "",
72
+ children: optSelected.map(m => {
73
+ return /*#__PURE__*/_jsx(MenuItem, {
74
+ value: m.value,
75
+ children: m.label
76
+ }, `bl_tr_opt_${m.value}`);
77
+ })
78
+ })
79
+ });
80
+ }
81
+ };
82
+ return /*#__PURE__*/_jsxs(Grid, {
83
+ container: true,
84
+ padding: 4,
85
+ spacing: 1,
86
+ children: [/*#__PURE__*/_jsx(Grid, {
87
+ item: true,
88
+ xs: 12,
89
+ children: /*#__PURE__*/_jsxs(FormControl, {
90
+ children: [/*#__PURE__*/_jsx(FormLabel, {
91
+ id: "demo-radio-buttons-group-label",
92
+ children: "Where do you want to Link?"
93
+ }), /*#__PURE__*/_jsxs(RadioGroup, {
94
+ row: true,
95
+ "aria-labelledby": "demo-radio-buttons-group-label",
96
+ value: value?.linkType || "",
97
+ name: "linkType",
98
+ onChange: handleChange,
99
+ children: [/*#__PURE__*/_jsx(FormControlLabel, {
100
+ value: "actionTrigger",
101
+ control: /*#__PURE__*/_jsx(Radio, {}),
102
+ label: "Action Trigger"
103
+ }), /*#__PURE__*/_jsx(FormControlLabel, {
104
+ value: "webAddress",
105
+ control: /*#__PURE__*/_jsx(Radio, {}),
106
+ label: "Web Address"
107
+ })]
108
+ })]
109
+ })
110
+ }), renderLinkTypeFields()]
111
+ });
112
+ };
113
+ export default ButtonLink;
@@ -8,6 +8,7 @@ import GridSize from "./gridSize";
8
8
  import ElementSize from "./elementSize";
9
9
  import ImageTexts from "./imageTexts";
10
10
  import MenusArray from "./menusArray";
11
+ import ButtonLink from "./buttonLink";
11
12
  const FieldMap = {
12
13
  text: Text,
13
14
  bannerSpacing: BannerSpacing,
@@ -18,6 +19,7 @@ const FieldMap = {
18
19
  gridSize: GridSize,
19
20
  elementSize: ElementSize,
20
21
  imageTexts: ImageTexts,
21
- menusArray: MenusArray
22
+ menusArray: MenusArray,
23
+ buttonLink: ButtonLink
22
24
  };
23
25
  export default FieldMap;
@@ -16,6 +16,7 @@ const withEmbeds = editor => {
16
16
  editor.insertBreak = (...args) => {
17
17
  const parentPath = Path.parent(editor.selection.focus.path);
18
18
  const parentNode = Node.get(editor, parentPath);
19
+ console.log(parentNode, parentPath, args);
19
20
  if (editor.isVoid(parentNode)) {
20
21
  const nextPath = Path.next(parentPath);
21
22
  Transforms.insertNodes(editor, {
@@ -0,0 +1,16 @@
1
+ export const actionButtonRedirect = async (formData, props) => {
2
+ try {
3
+ const response = await fetch(`${props.url}`, {
4
+ method: "POST",
5
+ headers: {
6
+ "Content-Type": "application/json"
7
+ },
8
+ body: JSON.stringify(formData)
9
+ });
10
+ const result = await response.json();
11
+ return result.data;
12
+ } catch (err) {
13
+ console.log(err);
14
+ return err;
15
+ }
16
+ };
@@ -4,7 +4,10 @@ export const insertButton = editor => {
4
4
  type: "button",
5
5
  children: [{
6
6
  text: ""
7
- }]
7
+ }],
8
+ buttonLink: {
9
+ linkType: "webAddress"
10
+ }
8
11
  };
9
12
  Transforms.insertNodes(editor, button);
10
13
  Transforms.move(editor);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flozy/editor",
3
- "version": "1.2.8",
3
+ "version": "1.2.9",
4
4
  "description": "An Editor for flozy app brain",
5
5
  "files": [
6
6
  "dist"