@vonaffenfels/slate-editor 1.0.4 → 1.0.10

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.0.4",
3
+ "version": "1.0.10",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {
@@ -71,7 +71,7 @@
71
71
  "cssnano": "^5.0.1",
72
72
  "escape-html": "^1.0.3"
73
73
  },
74
- "gitHead": "ba6d3fea2cca04a822de7e3d7dff5949e62a9d46",
74
+ "gitHead": "bd271f5265184e34c8ebef5f49936ab95fe29dcf",
75
75
  "publishConfig": {
76
76
  "access": "public"
77
77
  }
package/scss/editor.scss CHANGED
@@ -61,23 +61,26 @@
61
61
  //outline: #CECECE dashed;
62
62
 
63
63
  &:after {
64
- font-size: 24px;
64
+ font-size: 16px;
65
65
  content: "P";
66
66
  color: #CECECE;
67
67
  position: absolute;
68
68
  left: -20px;
69
69
  text-transform: uppercase;
70
- top: 1px;
70
+ top: 0;
71
71
  user-select: none;
72
72
  }
73
73
  }
74
74
 
75
75
  h1[data-slate-node="element"] {
76
76
  position: relative;
77
+ font-size: 26px;
78
+ font-weight: bold;
79
+ padding-bottom: 20px;
77
80
 
78
81
  &:after {
79
82
  content: "h1";
80
- font-size: 24px;
83
+ font-size: 26px;
81
84
  color: #CECECE;
82
85
  position: absolute;
83
86
  left: -36px;
@@ -89,85 +92,110 @@
89
92
 
90
93
  h2[data-slate-node="element"] {
91
94
  position: relative;
95
+ font-size: 24px;
96
+ padding-bottom: 20px;
97
+ font-weight: bold;
92
98
 
93
99
  &:after {
94
100
  content: "h2";
95
101
  font-size: 24px;
96
102
  color: #CECECE;
97
103
  position: absolute;
98
- left: -36px;
104
+ left: -30px;
99
105
  text-transform: uppercase;
100
- top: 1px;
106
+ top: 0;
101
107
  user-select: none;
102
108
  }
103
109
  }
104
110
 
105
111
  h3[data-slate-node="element"] {
106
112
  position: relative;
113
+ font-size: 20px;
114
+ padding-bottom: 20px;
115
+ font-weight: bold;
107
116
 
108
117
  &:after {
109
118
  content: "h3";
110
- font-size: 24px;
119
+ font-size: 20px;
111
120
  color: #CECECE;
112
121
  position: absolute;
113
- left: -36px;
122
+ left: -26px;
114
123
  text-transform: uppercase;
115
- top: 1px;
124
+ top: 0;
116
125
  user-select: none;
117
126
  }
118
127
  }
119
128
 
120
129
  h4[data-slate-node="element"] {
121
130
  position: relative;
131
+ font-size: 16px;
132
+ padding-bottom: 20px;
133
+ font-weight: bold;
122
134
 
123
135
  &:after {
124
136
  content: "h4";
125
- font-size: 24px;
137
+ font-size: 16px;
126
138
  color: #CECECE;
127
139
  position: absolute;
128
140
  left: -36px;
129
141
  text-transform: uppercase;
130
- top: 1px;
142
+ top: 0;
131
143
  user-select: none;
132
144
  }
133
145
  }
134
146
 
135
147
  h5[data-slate-node="element"] {
136
148
  position: relative;
149
+ font-size: 14px;
150
+ padding-bottom: 20px;
151
+ font-weight: bold;
137
152
 
138
153
  &:after {
139
154
  content: "h5";
140
- font-size: 24px;
155
+ font-size: 14px;
141
156
  color: #CECECE;
142
157
  position: absolute;
143
158
  left: -36px;
144
159
  text-transform: uppercase;
145
- top: 1px;
160
+ top: 0;
146
161
  user-select: none;
147
162
  }
148
163
  }
149
164
 
150
165
  h6[data-slate-node="element"] {
151
166
  position: relative;
167
+ font-size: 12px;
168
+ padding-bottom: 20px;
169
+ font-weight: bold;
152
170
 
153
171
  &:after {
154
172
  content: "h6";
155
- font-size: 24px;
173
+ font-size: 12px;
156
174
  color: #CECECE;
157
175
  position: absolute;
158
176
  left: -36px;
159
177
  text-transform: uppercase;
160
- top: 1px;
178
+ top: 0;
161
179
  user-select: none;
162
180
  }
163
181
  }
164
182
 
165
183
  ul[data-slate-node="element"] {
166
184
  list-style: circle;
185
+ padding-bottom: 20px;
167
186
  }
168
187
 
169
188
  ol[data-slate-node="element"] {
170
189
  list-style: decimal;
190
+ padding-bottom: 20px;
191
+ }
192
+
193
+ .arrow-list {
194
+ list-style-type: "🠆" !important;
195
+ }
196
+
197
+ .arrow-list li::before {
198
+ content: none !important;
171
199
  }
172
200
 
173
201
  a[data-slate-node="element"] {
@@ -175,6 +203,13 @@
175
203
  text-decoration: underline;
176
204
  }
177
205
 
206
+ blockquote[data-slate-node="element"] {
207
+ display: block;
208
+ border-left: 5px solid #CECECE;
209
+ padding: 1em;
210
+ margin-bottom: 20px;
211
+ }
212
+
178
213
  div[data-slate-editor="true"] {
179
214
  height: 100%;
180
215
  }
@@ -399,10 +434,6 @@
399
434
  }
400
435
  }
401
436
  }
402
-
403
- .selected-storybook-element {
404
- outline: dashed #036fe3;
405
- }
406
437
  }
407
438
 
408
439
  button {
@@ -61,7 +61,7 @@
61
61
  display: block;
62
62
  position: relative;
63
63
 
64
- &:not(.selected-storybook-element):hover {
64
+ &:hover {
65
65
  .storybook-element-component-overlay {
66
66
  user-select: none;
67
67
  display: flex;
@@ -37,29 +37,19 @@ export default function BlockEditor({
37
37
  storybookComponentLoader={storybookComponentLoader}
38
38
  storybookComponentDataLoader={storybookComponentDataLoader}
39
39
  elementPropsMap={elementPropsMap}
40
- onStorybookElementClick={(element, attributes, e) => {
41
- clearSelectionOutlines();
42
-
43
- if (attributes?.ref?.current) {
44
- let targetDOMElement = attributes.ref.current.querySelectorAll(".storybook-element-component")[0];
45
-
46
- if (targetDOMElement) {
47
- targetDOMElement.classList.add("selected-storybook-element");
48
- }
49
- }
40
+ onStorybookElementClick={(element, attributes) => {
41
+ let node = ReactEditor.toSlateNode(editor, attributes.ref.current);
42
+ let path = ReactEditor.findPath(editor, node);
50
43
 
51
44
  setSelectedStorybookElement({
52
45
  ...element,
53
46
  editorAttributes: attributes,
47
+ path,
48
+ node,
54
49
  });
55
50
  }}
56
- onElementClick={(element) => {
57
- console.log({element});
58
- let hasBlockElement = element.children.find(child => child.block) !== undefined;
59
-
60
- if (!hasBlockElement) {
61
- setSelectedStorybookElement(null);
62
- }
51
+ onElementClick={() => {
52
+ setSelectedStorybookElement(null);
63
53
  }}/>;
64
54
  }, []);
65
55
  const renderLeaf = useCallback(props => <Leaf {...props} elementPropsMap={elementPropsMap}/>, []);
@@ -153,20 +143,7 @@ export default function BlockEditor({
153
143
  return editor;
154
144
  }, []);
155
145
 
156
- const clearSelectionOutlines = () => {
157
- let selectedDOMElements = document.querySelectorAll(".selected-storybook-element");
158
-
159
- if (selectedDOMElements && selectedDOMElements.length) {
160
- Array.from(selectedDOMElements).forEach(e => {
161
- e.classList.remove("selected-storybook-element");
162
- });
163
- }
164
- };
165
-
166
146
  const handleSidebarEditorChange = newStorybookElement => {
167
- let node = ReactEditor.toSlateNode(editor, selectedStorybookElement.editorAttributes.ref.current);
168
- let path = ReactEditor.findPath(editor, node);
169
-
170
147
  let newNodeProps = {
171
148
  block: newStorybookElement.block,
172
149
  isEmpty: false,
@@ -174,12 +151,12 @@ export default function BlockEditor({
174
151
  attributes: newStorybookElement.attributes,
175
152
  };
176
153
 
177
- Transforms.setNodes(editor, newNodeProps, {at: path});
154
+ Transforms.setNodes(editor, newNodeProps, {at: selectedStorybookElement.path});
178
155
 
179
156
  onSlateChange(editor.children);
180
157
  setSelectedStorybookElement({
158
+ ...selectedStorybookElement,
181
159
  ...newNodeProps,
182
- editorAttributes: selectedStorybookElement.editorAttributes,
183
160
  });
184
161
  };
185
162
 
@@ -194,13 +171,10 @@ export default function BlockEditor({
194
171
  })
195
172
  .then((result) => {
196
173
  if (result) {
197
- let node = ReactEditor.toSlateNode(editor, element.editorAttributes.ref.current);
198
- let path = ReactEditor.findPath(editor, node);
174
+ Transforms.setNodes(editor, {isDeleted: true}, {at: selectedStorybookElement.path});
175
+ Transforms.removeNodes(editor, {at: selectedStorybookElement.path});
199
176
 
200
- Transforms.setNodes(editor, {isDeleted: true}, {at: path});
201
- Transforms.removeNodes(editor, {at: path});
202
-
203
- clearSelectionOutlines();
177
+ onSlateChange(editor.children);
204
178
 
205
179
  setSelectedStorybookElement(null);
206
180
  }
@@ -208,8 +182,7 @@ export default function BlockEditor({
208
182
  };
209
183
 
210
184
  const handleSidebarMoveClick = (element, direction) => {
211
- let node = ReactEditor.toSlateNode(editor, element.editorAttributes.ref.current);
212
- let path = ReactEditor.findPath(editor, node);
185
+ let path = element.path;
213
186
 
214
187
  let to;
215
188
 
@@ -231,14 +204,19 @@ export default function BlockEditor({
231
204
  mode: "highest",
232
205
  voids: false,
233
206
  });
207
+
208
+ onSlateChange(editor.children);
209
+
210
+ setSelectedStorybookElement({
211
+ ...selectedStorybookElement,
212
+ path: to,
213
+ });
234
214
  } catch (e) {
235
215
  console.error(e);
236
216
  }
237
217
  };
238
218
 
239
219
  const handleSidebarClose = () => {
240
- clearSelectionOutlines();
241
-
242
220
  setSelectedStorybookElement(null);
243
221
  };
244
222
 
@@ -286,7 +264,9 @@ export default function BlockEditor({
286
264
  storybookStories={storybookStories}
287
265
  onClose={handleSidebarClose}
288
266
  onDelete={handleSidebarDeleteClick}
289
- onMove={handleSidebarMoveClick}/>}
267
+ onMove={handleSidebarMoveClick}
268
+ editor={editor}/>
269
+ }
290
270
  </div>
291
271
  );
292
272
  }
@@ -18,6 +18,8 @@ export const Element = ({
18
18
  }) => {
19
19
  const {isInSlot} = useContext(LayoutSlotContext);
20
20
 
21
+ console.log({props});
22
+
21
23
  const getPropsForType = (type) => {
22
24
  if (!props.elementPropsMap) {
23
25
  return {};
@@ -36,7 +38,9 @@ export const Element = ({
36
38
 
37
39
  switch (props.element.type) {
38
40
  case 'storybook':
39
- return <div className="inline" onClick={e => e.stopPropagation()}>
41
+ return <div
42
+ className="inline"
43
+ onClick={e => e.stopPropagation()}>
40
44
  <StorybookNode
41
45
  {...props}
42
46
  {...typeProps}
@@ -8,7 +8,7 @@ export const AssetList = ({
8
8
  assets,
9
9
  onChange,
10
10
  sdk,
11
- cloudinary,
11
+ cloudinary = false,
12
12
  }) => {
13
13
  const renderAssets = assets.filter(Boolean).map((asset, index) => (
14
14
  <>
@@ -58,15 +58,15 @@ export const Asset = ({
58
58
  onDeleteClick,
59
59
  onMoveClick,
60
60
  sdk,
61
- cloudinary,
61
+ cloudinary = false,
62
62
  }) => {
63
63
  const [mediaUrl, setMediaUrl] = useState(null);
64
64
 
65
65
  let id = asset?.sys?.id;
66
- let title = asset?.fields?.title?.["en-US"] || asset?.fields?.title?.["de-DE"];
66
+ let title = asset?.fields?.title?.["en-US"] || asset?.fields?.title?.["de"];
67
67
  let space = asset?.sys?.space?.sys?.id;
68
68
  let environment = asset?.sys?.environment?.sys?.id;
69
- let mediaAssetId = asset?.fields?.media?.["de-DE"]?.sys?.id || asset?.fields?.media?.["en-US"]?.sys?.id;
69
+ let mediaAssetId = asset?.fields?.media?.["en-US"]?.sys?.id || asset?.fields?.media?.["de"]?.sys?.id;
70
70
  let href = `https://app.contentful.com/spaces/${space}/environments/${environment}/entries/${id}`;
71
71
 
72
72
  if (cloudinary) {
@@ -87,7 +87,7 @@ export const Asset = ({
87
87
 
88
88
  sdk.space.getAsset(mediaAssetId)
89
89
  .then(a => {
90
- let url = a?.fields?.file?.["de-DE"]?.url || a?.fields?.file?.["en-US"]?.url;
90
+ let url = a?.fields?.file?.["en-US"]?.url || a?.fields?.file?.["de"]?.url;
91
91
 
92
92
  if (url) {
93
93
  let params = new URLSearchParams({
@@ -108,7 +108,7 @@ export const Asset = ({
108
108
  <div className="flex flex-col">
109
109
  <div className="flex">
110
110
  <div className="grow">
111
- <b className="mt-[4px] block break-all">{title}</b>
111
+ <b className="mt-[3px] block break-words">{title}</b>
112
112
  </div>
113
113
  <div className="ml-2 shrink-0">
114
114
  {!!onMoveClick && (
@@ -14,6 +14,7 @@ const SidebarEditor = ({
14
14
  onChange,
15
15
  onDelete,
16
16
  onMove,
17
+ editor,
17
18
  }) => {
18
19
  const [versions, setVersions] = useState([]);
19
20
  const [lastChangedProperty, setLastChangedProperty] = useState(null);
@@ -160,6 +161,8 @@ const SidebarEditor = ({
160
161
 
161
162
  useEffect(() => resetVersions, [storybookElement?.editorAttributes?.ref]);
162
163
 
164
+ console.log({storybookElement});
165
+
163
166
  return (
164
167
  <div id="sidebar-editor">
165
168
  <div>
@@ -172,10 +175,10 @@ const SidebarEditor = ({
172
175
  <IconButton title="Wiederherstellen" onClick={redo} disabled={currentVersion >= versionCount || versionCount === 0}>↻</IconButton>
173
176
  </div>
174
177
  <div className="icon-button-group mr-1">
175
- <IconButton title="Nach oben verschieben" onClick={() => onMove && onMove(storybookElement, "up")}>
178
+ <IconButton title="Nach oben verschieben" onClick={() => onMove && onMove(storybookElement, "up")} disabled={storybookElement.path[0] === 0}>
176
179
 
177
180
  </IconButton>
178
- <IconButton title="Nach unten verschieben" onClick={() => onMove && onMove(storybookElement, "down")}>
181
+ <IconButton title="Nach unten verschieben" onClick={() => onMove && onMove(storybookElement, "down")} disabled={storybookElement.path[0] === editor.children.length - 1}>
179
182
 
180
183
  </IconButton>
181
184
  </div>
@@ -112,14 +112,14 @@ export default {
112
112
  name: "Contentful Asset",
113
113
  control: {
114
114
  type: 'contentful-content',
115
- contentTypes: ["image"],
115
+ contentTypes: ["asset"],
116
116
  },
117
117
  },
118
118
  contentfulAssets: {
119
119
  name: "Contentful Assets",
120
120
  control: {
121
121
  type: 'contentful-contents',
122
- contentTypes: ["image"],
122
+ contentTypes: ["asset"],
123
123
  },
124
124
  },
125
125
  cloudinaryImage: {