@vonaffenfels/slate-editor 1.1.48 → 1.1.50

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vonaffenfels/slate-editor",
3
- "version": "1.1.48",
3
+ "version": "1.1.50",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {
@@ -72,7 +72,7 @@
72
72
  "cssnano": "^5.0.1",
73
73
  "escape-html": "^1.0.3"
74
74
  },
75
- "gitHead": "68c4f7e68c395df48a22103e83988f674df3474d",
75
+ "gitHead": "0cede70748584b53424ae59e9d81271db780745c",
76
76
  "publishConfig": {
77
77
  "access": "public"
78
78
  }
package/scss/editor.scss CHANGED
@@ -11,7 +11,7 @@
11
11
  max-width: 100%;
12
12
  width: 100%;
13
13
 
14
- .slate-editor-element-selected {
14
+ .slate-editor-element-selected:not(.storybook-element-missing-attributes) {
15
15
  .storybook-element-component {
16
16
  outline: 2px dashed #61a2e9;
17
17
  }
@@ -25,6 +25,13 @@
25
25
  outline: 3px dashed #036fe3;
26
26
  }
27
27
 
28
+ &.storybook-element-missing-attributes {
29
+ .storybook-element-component-overlay {
30
+ display: flex;
31
+ outline: 3px dashed #ff0000;
32
+ }
33
+ }
34
+
28
35
  &.storybook-inline {
29
36
  display: inline-block;
30
37
 
@@ -46,6 +46,7 @@ export default function BlockEditor({
46
46
  storybookComponentLoader={storybookComponentLoader}
47
47
  storybookComponentDataLoader={storybookComponentDataLoader}
48
48
  elementPropsMap={elementPropsMap}
49
+ elementStory={loadedStorybookStories?.find(v => props.element?.block?.toLowerCase() === v.id?.toLowerCase())}
49
50
  onStorybookElementClick={(element, attributes) => {
50
51
  let node = ReactEditor.toSlateNode(editor, attributes.ref.current);
51
52
  let path = ReactEditor.findPath(editor, node);
@@ -58,7 +59,6 @@ export default function BlockEditor({
58
59
  attributes.ref.current.classList.add("slate-editor-element-selected");
59
60
  }
60
61
 
61
-
62
62
  setSelectedStorybookElement({
63
63
  ...element,
64
64
  editorAttributes: attributes,
@@ -237,9 +237,6 @@ export default function BlockEditor({
237
237
  }, []);
238
238
 
239
239
  const handleSidebarEditorChange = newElement => {
240
- console.log("Vincent-Debug, BlockEditor.js:237", "sidebar editor change");
241
-
242
-
243
240
  let newNodeProps = {
244
241
  block: newElement.block,
245
242
  isEmpty: false,
@@ -397,7 +394,6 @@ export default function BlockEditor({
397
394
  value={value}
398
395
  onChange={v => {
399
396
  onSlateChange(v);
400
- console.log("YEEEEEE");
401
397
  }}
402
398
  >
403
399
  <div>
package/src/Nodes/Leaf.js CHANGED
@@ -1,8 +1,16 @@
1
1
  import React from "react";
2
- import {Bold, Italic, Text, Underlined, Strikethrough, Small} from "./Text";
3
-
4
- export const Leaf = ({attributes, children, leaf, isRenderer, typeProps, ...props}) => {
2
+ import {
3
+ Bold, Italic, Text, Underlined, Strikethrough, Small, SuperscriptUp,
4
+ } from "./Text";
5
5
 
6
+ export const Leaf = ({
7
+ attributes,
8
+ children,
9
+ leaf,
10
+ isRenderer,
11
+ typeProps,
12
+ ...props
13
+ }) => {
6
14
  if (leaf.bold) {
7
15
  children = <Bold typeProps={typeProps} attributes={attributes}><Text
8
16
  attributes={attributes}
@@ -36,5 +44,12 @@ export const Leaf = ({attributes, children, leaf, isRenderer, typeProps, ...prop
36
44
  isRenderer={isRenderer}>{children}</Text></Small>;
37
45
  }
38
46
 
47
+ if (leaf.superscriptUp) {
48
+ children = <SuperscriptUp typeProps={typeProps} attributes={attributes}><Text
49
+ attributes={attributes}
50
+ typeProps={typeProps}
51
+ isRenderer={isRenderer}>{children}</Text></SuperscriptUp>;
52
+ }
53
+
39
54
  return <Text attributes={attributes} typeProps={typeProps} isRenderer={isRenderer}>{children}</Text>;
40
55
  };
@@ -1,5 +1,5 @@
1
1
  import React, {
2
- memo, useContext, useState,
2
+ memo, useContext, useEffect, useState,
3
3
  } from "react";
4
4
  import {FontAwesomeIcon} from "@fortawesome/react-fontawesome";
5
5
  import {
@@ -22,11 +22,23 @@ const StorybookNodeComponent = ({
22
22
  storybookComponentLoader,
23
23
  storybookComponentDataLoader,
24
24
  onStorybookElementClick,
25
+ ...props
25
26
  }) => {
26
27
  const onEditClick = () => {
27
28
  onStorybookElementClick(element, attributes);
28
29
  };
29
30
 
31
+ const hasMissingAttributes = () => {
32
+ let elementStory = props.elementStory;
33
+ let requiredFields = Object.keys(elementStory?.argTypes || {}).filter(key => elementStory.argTypes[key].required);
34
+
35
+ let missingField = requiredFields.find(fieldName => {
36
+ return !element?.attributes?.[fieldName];
37
+ });
38
+
39
+ return !!missingField;
40
+ };
41
+
30
42
  const onDeleteClick = () => {
31
43
  let node = ReactEditor.toSlateNode(editor, attributes.ref.current);
32
44
  let path = ReactEditor.findPath(editor, node);
@@ -115,12 +127,13 @@ const StorybookNodeComponent = ({
115
127
  return (
116
128
  <span
117
129
  {...attributes}
118
- onClick={() => onStorybookElementClick(element, attributes)}
130
+ onClick={onEditClick}
119
131
  className={classNames({
120
132
  "storybook-element options-wrapper cursor-pointer": true,
121
133
  "storybook-inline": element.isInline,
122
134
  "storybook-element-float-left": element?.attributes?.float === "left",
123
135
  "storybook-element-float-right": element?.attributes?.float === "right",
136
+ "storybook-element-missing-attributes": hasMissingAttributes(),
124
137
  })}>
125
138
  <span className="options-container">
126
139
  {!element.isInline && (<>
@@ -1,4 +1,5 @@
1
1
  import React, {
2
+ isValidElement,
2
3
  useEffect, useRef, useState,
3
4
  } from "react";
4
5
  import {EmptyBlock} from "../Blocks/EmptyBlock";
@@ -80,7 +81,7 @@ const BlockComponent = ({
80
81
  isEditor,
81
82
  }) => {
82
83
  const [loadedAttributes, setLoadedAttributes] = useState(attributes);
83
- let [LoadedComponent, setLoadedComponent] = useState(storybookComponentLoader(block));
84
+ let LoadedComponent = storybookComponentLoader(block);
84
85
 
85
86
  useEffect(() => {
86
87
  if (!storybookComponentDataLoader) {
@@ -105,12 +106,8 @@ const BlockComponent = ({
105
106
  }
106
107
  });
107
108
 
108
- let loadedComponent = storybookComponentLoader(block);
109
-
110
109
  setLoadedAttributes({...attributes});
111
110
 
112
- setLoadedComponent(loadedComponent);
113
-
114
111
  return () => {
115
112
  mounted = false;
116
113
  };
@@ -118,17 +115,6 @@ const BlockComponent = ({
118
115
 
119
116
  if (!LoadedComponent) {
120
117
  LoadedComponent = EmptyBlock;
121
- } else {
122
- try {
123
- if (LoadedComponent.render) {
124
- LoadedComponent.render.displayName = block; // set displayname to block for better debug
125
- }
126
- } catch (e) {
127
- // this happens if we SSR a non ssr component, its a weird edge case of next/dynamic... so we just ignore it
128
- // LoadedComponent for some reason is not a component here....
129
- // console.error(`Error in setting displayName for ${block} :: ${e.message}`);
130
- return null;
131
- }
132
118
  }
133
119
 
134
120
  const WrapperTag = loadedAttributes.isInline ? "span" : "div";
package/src/Nodes/Text.js CHANGED
@@ -2,7 +2,12 @@ import React, {Fragment} from "react";
2
2
 
3
3
  const EmptyWrapper = ({children}) => <>{children}</>;
4
4
 
5
- export const Text = ({isRenderer, attributes, children, typeProps}) => {
5
+ export const Text = ({
6
+ isRenderer,
7
+ attributes,
8
+ children,
9
+ typeProps,
10
+ }) => {
6
11
  if (isRenderer) {
7
12
  if (!children) {
8
13
  return null;
@@ -23,7 +28,6 @@ export const Text = ({isRenderer, attributes, children, typeProps}) => {
23
28
  {children}
24
29
  </Fragment>;
25
30
  }
26
-
27
31
  }
28
32
 
29
33
  return <span {...attributes}>{children}</span>;
@@ -46,22 +50,49 @@ function renderTextLine(text, typeProps) {
46
50
  return text;
47
51
  }
48
52
 
49
- export const Bold = ({attributes, children}) => {
53
+ export const Bold = ({
54
+ attributes,
55
+ children,
56
+ }) => {
50
57
  return <strong {...attributes}>{children}</strong>;
51
58
  };
52
59
 
53
- export const Italic = ({attributes, children}) => {
60
+ export const Italic = ({
61
+ attributes,
62
+ children,
63
+ }) => {
54
64
  return <i {...attributes}>{children}</i>;
55
65
  };
56
66
 
57
- export const Underlined = ({attributes, children}) => {
67
+ export const Underlined = ({
68
+ attributes,
69
+ children,
70
+ }) => {
58
71
  return <u {...attributes}>{children}</u>;
59
72
  };
60
73
 
61
- export const Strikethrough = ({attributes, children}) => {
74
+ export const Strikethrough = ({
75
+ attributes,
76
+ children,
77
+ }) => {
62
78
  return <del {...attributes}>{children}</del>;
63
79
  };
64
80
 
65
- export const Small = ({attributes, children}) => {
81
+ export const Small = ({
82
+ attributes,
83
+ children,
84
+ }) => {
66
85
  return <small {...attributes}>{children}</small>;
86
+ };
87
+
88
+ export const SuperscriptUp = ({
89
+ attributes,
90
+ children,
91
+ }) => {
92
+ return <span
93
+ style={{
94
+ fontSize: "60%",
95
+ verticalAlign: "top",
96
+ }}
97
+ {...attributes}>{children}</span>;
67
98
  };
@@ -10,6 +10,7 @@ import {CloudinaryContentSelect} from "./Fields/CloudinaryContentSelect";
10
10
  import {MVP} from "./Fields/MVP";
11
11
  import {ColorPicker} from "./Fields/ColorPicker";
12
12
  import {RemoteMultiSelect} from "./Fields/RemoteMultiSelect";
13
+ import classNames from "classnames";
13
14
 
14
15
  export const SidebarEditorField = ({
15
16
  field,
@@ -62,7 +63,7 @@ export const SidebarEditorField = ({
62
63
 
63
64
  switch (field?.control?.type) {
64
65
  case "text":
65
- return <Textarea onChange={e => onChange(fieldKey, e.target.value)} value={value} />;
66
+ return <Textarea onChange={e => onChange(fieldKey, e.target.value)} value={value === undefined ? "" : value} />;
66
67
  case "boolean":
67
68
  return (
68
69
  <div className="flex items-center">
@@ -238,7 +239,10 @@ export const SidebarEditorField = ({
238
239
 
239
240
  return (
240
241
  <div key={`${field.name}`} className="mb-2">
241
- <label className="block">{field.name || fieldKey}</label>
242
+ <label className={classNames({
243
+ "block": true,
244
+ "!text-red-500": field?.required && !value,
245
+ })}>{field.name || fieldKey} {field.required ? "*" : ""}</label>
242
246
  {inputField}
243
247
  </div>
244
248
  );
@@ -109,7 +109,7 @@ const SidebarEditor = ({
109
109
  [fieldKey]: value,
110
110
  },
111
111
  };
112
-
112
+
113
113
  onChange(newStorybookElement);
114
114
  }
115
115
  }
@@ -2,10 +2,18 @@ import {useSlate} from "slate-react";
2
2
  import {FontAwesomeIcon} from "@fortawesome/react-fontawesome";
3
3
  import React, {useState} from "react";
4
4
  import classNames from "classnames";
5
- import {Editor, Text, Transforms} from "slate";
6
- import {faBold, faItalic, faUnderline, faStrikethrough} from "@fortawesome/free-solid-svg-icons";
5
+ import {
6
+ Editor, Text, Transforms,
7
+ } from "slate";
8
+ import {
9
+ faBold, faItalic, faUnderline, faStrikethrough, faSuperscript,
10
+ } from "@fortawesome/free-solid-svg-icons";
7
11
 
8
- export const FormatButton = ({format, icon, children}) => {
12
+ export const FormatButton = ({
13
+ format,
14
+ icon,
15
+ children,
16
+ }) => {
9
17
  const editor = useSlate();
10
18
  const onClick = (event) => {
11
19
  event.preventDefault();
@@ -57,4 +65,8 @@ export const FormatButtonUnderline = () => {
57
65
 
58
66
  export const FormatButtonStrikethrough = () => {
59
67
  return <FormatButton format="strikethrough" icon={faStrikethrough}/>;
68
+ };
69
+
70
+ export const FormatButtonSuperscriptUp = () => {
71
+ return <FormatButton format="superscriptUp" icon={faSuperscript}/>;
60
72
  };
@@ -8,7 +8,7 @@ import classNames from "classnames";
8
8
  // eslint-disable-next-line import/no-unresolved
9
9
  import "scss/toolbar.scss";
10
10
  import {
11
- FormatButtonBold, FormatButtonItalic, FormatButtonStrikethrough, FormatButtonUnderline,
11
+ FormatButtonBold, FormatButtonItalic, FormatButtonStrikethrough, FormatButtonSuperscriptUp, FormatButtonUnderline,
12
12
  } from "./Formats";
13
13
  import {
14
14
  AlignButtonLeft, AlignButtonCenter, AlignButtonRight,
@@ -144,6 +144,7 @@ export const Toolbar = ({
144
144
  <FormatButtonItalic/>
145
145
  <FormatButtonUnderline/>
146
146
  <FormatButtonStrikethrough/>
147
+ <FormatButtonSuperscriptUp />
147
148
 
148
149
  <LinkButton/>
149
150