@vonaffenfels/slate-editor 1.0.5 → 1.0.12
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/componentLoader.js +0 -2
- package/dist/BlockEditor.css +2 -2
- package/dist/BlockEditor.js +1 -1
- package/dist/index.css +2 -2
- package/dist/index.js +1 -1
- package/package.json +2 -2
- package/scss/editor.scss +49 -18
- package/scss/storybook.scss +1 -1
- package/src/BlockEditor.js +23 -43
- package/src/Nodes/Element.js +5 -1
- package/src/SidebarEditor/AssetList.js +6 -6
- package/src/SidebarEditor.js +5 -2
- package/src/dev/testComponents/TestStory.stories.js +2 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vonaffenfels/slate-editor",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.12",
|
|
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": "
|
|
74
|
+
"gitHead": "19e0f8e8f553733b6b461f9c4b9d771c67bf0611",
|
|
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:
|
|
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:
|
|
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:
|
|
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: -
|
|
104
|
+
left: -30px;
|
|
99
105
|
text-transform: uppercase;
|
|
100
|
-
top:
|
|
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:
|
|
119
|
+
font-size: 20px;
|
|
111
120
|
color: #CECECE;
|
|
112
121
|
position: absolute;
|
|
113
|
-
left: -
|
|
122
|
+
left: -26px;
|
|
114
123
|
text-transform: uppercase;
|
|
115
|
-
top:
|
|
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:
|
|
137
|
+
font-size: 16px;
|
|
126
138
|
color: #CECECE;
|
|
127
139
|
position: absolute;
|
|
128
140
|
left: -36px;
|
|
129
141
|
text-transform: uppercase;
|
|
130
|
-
top:
|
|
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:
|
|
155
|
+
font-size: 14px;
|
|
141
156
|
color: #CECECE;
|
|
142
157
|
position: absolute;
|
|
143
158
|
left: -36px;
|
|
144
159
|
text-transform: uppercase;
|
|
145
|
-
top:
|
|
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:
|
|
173
|
+
font-size: 12px;
|
|
156
174
|
color: #CECECE;
|
|
157
175
|
position: absolute;
|
|
158
176
|
left: -36px;
|
|
159
177
|
text-transform: uppercase;
|
|
160
|
-
top:
|
|
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 {
|
package/scss/storybook.scss
CHANGED
package/src/BlockEditor.js
CHANGED
|
@@ -37,29 +37,19 @@ export default function BlockEditor({
|
|
|
37
37
|
storybookComponentLoader={storybookComponentLoader}
|
|
38
38
|
storybookComponentDataLoader={storybookComponentDataLoader}
|
|
39
39
|
elementPropsMap={elementPropsMap}
|
|
40
|
-
onStorybookElementClick={(element, attributes
|
|
41
|
-
|
|
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={(
|
|
57
|
-
|
|
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
|
-
|
|
198
|
-
|
|
174
|
+
Transforms.setNodes(editor, {isDeleted: true}, {at: selectedStorybookElement.path});
|
|
175
|
+
Transforms.removeNodes(editor, {at: selectedStorybookElement.path});
|
|
199
176
|
|
|
200
|
-
|
|
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
|
|
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
|
}
|
package/src/Nodes/Element.js
CHANGED
|
@@ -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
|
|
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
|
|
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?.["
|
|
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?.["
|
|
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-[
|
|
111
|
+
<b className="mt-[3px] block break-words">{title}</b>
|
|
112
112
|
</div>
|
|
113
113
|
<div className="ml-2 shrink-0">
|
|
114
114
|
{!!onMoveClick && (
|
package/src/SidebarEditor.js
CHANGED
|
@@ -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: ["
|
|
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: ["
|
|
122
|
+
contentTypes: ["asset"],
|
|
123
123
|
},
|
|
124
124
|
},
|
|
125
125
|
cloudinaryImage: {
|