@vonaffenfels/slate-editor 1.0.3 → 1.0.5
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 +9 -2
- package/dist/BlockEditor.css +4 -4
- package/dist/BlockEditor.js +1 -1
- package/dist/BlockEditor.js.LICENSE.txt +0 -33
- package/dist/Renderer.js +1 -1
- package/dist/index.css +4 -4
- package/dist/index.js +1 -1
- package/dist/index.js.LICENSE.txt +0 -33
- package/package.json +2 -2
- package/scss/demo.scss +7 -0
- package/scss/editor.scss +70 -38
- package/scss/sidebarEditor.scss +60 -21
- package/scss/storybook.scss +73 -5
- package/scss/toolbar.scss +2 -0
- package/src/BlockEditor.js +85 -45
- package/src/Nodes/Element.js +11 -9
- package/src/Nodes/Storybook.js +13 -32
- package/src/SidebarEditor/AssetList.js +129 -0
- package/src/SidebarEditor/SidebarEditorField.js +132 -64
- package/src/SidebarEditor.js +270 -121
- package/src/Toolbar/Toolbar.js +39 -34
- package/src/dev/App.js +6 -0
- package/src/dev/testComponents/TestStory.js +68 -2
- package/src/dev/testComponents/TestStory.stories.js +13 -3
- package/src/helper/array.js +9 -0
- package/webpack.config.build.js +2 -0
package/src/SidebarEditor.js
CHANGED
|
@@ -1,19 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
Button,
|
|
5
|
-
FormLabel,
|
|
6
|
-
Note,
|
|
7
|
-
Switch,
|
|
8
|
-
Heading,
|
|
9
|
-
IconButton,
|
|
10
|
-
Icon,
|
|
11
|
-
} from "@contentful/forma-36-react-components";
|
|
12
|
-
|
|
13
|
-
import "../scss/sidebarEditor.scss";
|
|
2
|
+
useState, useEffect,
|
|
3
|
+
} from "react";
|
|
14
4
|
import {SidebarEditorField} from "./SidebarEditor/SidebarEditorField";
|
|
15
5
|
import {ToolMargin} from "./Tools/Margin";
|
|
16
6
|
|
|
7
|
+
import "../scss/sidebarEditor.scss";
|
|
8
|
+
|
|
17
9
|
const SidebarEditor = ({
|
|
18
10
|
sdk,
|
|
19
11
|
storybookElement,
|
|
@@ -23,6 +15,11 @@ const SidebarEditor = ({
|
|
|
23
15
|
onDelete,
|
|
24
16
|
onMove,
|
|
25
17
|
}) => {
|
|
18
|
+
const [versions, setVersions] = useState([]);
|
|
19
|
+
const [lastChangedProperty, setLastChangedProperty] = useState(null);
|
|
20
|
+
const [versionCount, setVersionCount] = useState(0);
|
|
21
|
+
const [currentVersion, setCurrentVersion] = useState(0);
|
|
22
|
+
|
|
26
23
|
const fields = {
|
|
27
24
|
fields: {},
|
|
28
25
|
tables: {},
|
|
@@ -49,6 +46,18 @@ const SidebarEditor = ({
|
|
|
49
46
|
const handleFieldValueChange = (
|
|
50
47
|
fieldKey, value, mvpFieldKey, mvpIndex,
|
|
51
48
|
) => {
|
|
49
|
+
let targetFieldKey = mvpFieldKey ? `${fieldKey}-${mvpIndex}-${mvpFieldKey}` : fieldKey;
|
|
50
|
+
|
|
51
|
+
if (lastChangedProperty !== targetFieldKey) {
|
|
52
|
+
addVersion(storybookElement);
|
|
53
|
+
|
|
54
|
+
if (mvpFieldKey) {
|
|
55
|
+
setLastChangedProperty(`${fieldKey}-${mvpIndex}-${mvpFieldKey}`);
|
|
56
|
+
} else {
|
|
57
|
+
setLastChangedProperty(fieldKey);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
52
61
|
if (onChange) {
|
|
53
62
|
if (mvpFieldKey !== undefined && mvpIndex !== undefined) {
|
|
54
63
|
let newMVPValue = storybookElement.attributes[fieldKey].map((f, index) => {
|
|
@@ -62,110 +71,241 @@ const SidebarEditor = ({
|
|
|
62
71
|
return f;
|
|
63
72
|
});
|
|
64
73
|
|
|
65
|
-
|
|
74
|
+
let newStorybookElement = {
|
|
66
75
|
...storybookElement,
|
|
67
76
|
attributes: {
|
|
68
77
|
...storybookElement.attributes,
|
|
69
78
|
[fieldKey]: newMVPValue,
|
|
70
79
|
},
|
|
71
|
-
}
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
onChange(newStorybookElement);
|
|
72
83
|
} else {
|
|
73
|
-
|
|
84
|
+
let newStorybookElement = {
|
|
74
85
|
...storybookElement,
|
|
75
86
|
attributes: {
|
|
76
87
|
...storybookElement.attributes,
|
|
77
88
|
[fieldKey]: value,
|
|
78
89
|
},
|
|
79
|
-
}
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
onChange(newStorybookElement);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
const addVersion = (content) => {
|
|
98
|
+
let newVersionCount = versionCount + 1;
|
|
99
|
+
|
|
100
|
+
setVersions([...versions, {
|
|
101
|
+
content,
|
|
102
|
+
id: newVersionCount,
|
|
103
|
+
}]);
|
|
104
|
+
|
|
105
|
+
setCurrentVersion(newVersionCount + 1);
|
|
106
|
+
setVersionCount(newVersionCount);
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
const undo = () => {
|
|
110
|
+
let targetVersionId = currentVersion - 1;
|
|
111
|
+
let targetVersion = versions.find(v => v.id === targetVersionId);
|
|
112
|
+
|
|
113
|
+
if (targetVersion) {
|
|
114
|
+
if (currentVersion > versionCount) {
|
|
115
|
+
addVersion(storybookElement);
|
|
80
116
|
}
|
|
117
|
+
|
|
118
|
+
onChange(targetVersion.content);
|
|
119
|
+
setCurrentVersion(targetVersionId);
|
|
120
|
+
setLastChangedProperty(null);
|
|
121
|
+
} else {
|
|
122
|
+
console.error(`Version with ID ${targetVersionId} not found`, versions);
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
const redo = () => {
|
|
127
|
+
let targetVersionId = currentVersion + 1;
|
|
128
|
+
let targetVersion = versions.find(v => v.id === targetVersionId);
|
|
129
|
+
|
|
130
|
+
if (targetVersion) {
|
|
131
|
+
onChange(targetVersion.content);
|
|
132
|
+
setCurrentVersion(targetVersionId);
|
|
133
|
+
} else {
|
|
134
|
+
console.error(`Version with ID ${targetVersionId} not found`, versions);
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
const resetVersions = () => {
|
|
139
|
+
setVersionCount(0);
|
|
140
|
+
setCurrentVersion(0);
|
|
141
|
+
setLastChangedProperty(null);
|
|
142
|
+
setVersions([]);
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
const handleBlockSelectChange = (block) => {
|
|
146
|
+
if (onChange) {
|
|
147
|
+
setLastChangedProperty(null);
|
|
148
|
+
addVersion(storybookElement);
|
|
149
|
+
onChange(block);
|
|
81
150
|
}
|
|
82
151
|
};
|
|
83
152
|
|
|
153
|
+
const handleVariantSelectChange = (variant) => {
|
|
154
|
+
if (onChange) {
|
|
155
|
+
setLastChangedProperty(null);
|
|
156
|
+
addVersion(storybookElement);
|
|
157
|
+
onChange(variant);
|
|
158
|
+
}
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
useEffect(() => resetVersions, [storybookElement?.editorAttributes?.ref]);
|
|
162
|
+
|
|
84
163
|
return (
|
|
85
164
|
<div id="sidebar-editor">
|
|
86
|
-
<div
|
|
87
|
-
<div className="flex items-center">
|
|
88
|
-
<div className="grow
|
|
89
|
-
|
|
165
|
+
<div>
|
|
166
|
+
<div className="flex items-center justify-end">
|
|
167
|
+
<div className="grow">
|
|
168
|
+
{storybookElement?.block && (
|
|
169
|
+
<div className="flex items-center">
|
|
170
|
+
<div className="icon-button-group mr-1">
|
|
171
|
+
<IconButton title="Rückgängig" onClick={undo} disabled={currentVersion <= 1}>↺</IconButton>
|
|
172
|
+
<IconButton title="Wiederherstellen" onClick={redo} disabled={currentVersion >= versionCount || versionCount === 0}>↻</IconButton>
|
|
173
|
+
</div>
|
|
174
|
+
<div className="icon-button-group mr-1">
|
|
175
|
+
<IconButton title="Nach oben verschieben" onClick={() => onMove && onMove(storybookElement, "up")}>
|
|
176
|
+
↑
|
|
177
|
+
</IconButton>
|
|
178
|
+
<IconButton title="Nach unten verschieben" onClick={() => onMove && onMove(storybookElement, "down")}>
|
|
179
|
+
↓
|
|
180
|
+
</IconButton>
|
|
181
|
+
</div>
|
|
182
|
+
<IconButton title="Löschen" onClick={() => onDelete && onDelete(storybookElement)}>
|
|
183
|
+
🗑
|
|
184
|
+
</IconButton>
|
|
185
|
+
<div className="ml-1 flex items-center">
|
|
186
|
+
<ToolMargin
|
|
187
|
+
margin={storybookElement.attributes.margin}
|
|
188
|
+
onChange={value => handleFieldValueChange("margin", value)} />
|
|
189
|
+
</div>
|
|
190
|
+
</div>
|
|
191
|
+
)}
|
|
90
192
|
</div>
|
|
91
|
-
{!!onClose && <
|
|
193
|
+
{!!onClose && <IconButton onClick={onClose} title="Schließen">⨯</IconButton>}
|
|
92
194
|
</div>
|
|
195
|
+
<hr className="mt-2" style={{borderColor: "#cfd9e0"}}/>
|
|
93
196
|
</div>
|
|
94
|
-
|
|
95
|
-
<div>
|
|
96
|
-
<
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
className="
|
|
102
|
-
<
|
|
103
|
-
<option value={undefined}>Volle Breite</option>
|
|
104
|
-
<option value={"article"}>Artikel Breite</option>
|
|
105
|
-
<option value={"site"}>Seiten Breite</option>
|
|
106
|
-
<option value={"small"}>Klein</option>
|
|
107
|
-
</select>
|
|
108
|
-
<div className="cursor-pointer p-2" title="Nach oben verschieben" onClick={() => onMove && onMove(storybookElement, "up")}>
|
|
109
|
-
<Icon icon="ArrowUp" />
|
|
110
|
-
</div>
|
|
111
|
-
<div className="cursor-pointer p-2" title="Nach unten verschieben" onClick={() => onMove && onMove(storybookElement, "down")}>
|
|
112
|
-
<Icon icon="ArrowDown" />
|
|
113
|
-
</div>
|
|
114
|
-
<div className="p-2 pt-3">
|
|
115
|
-
<ToolMargin
|
|
116
|
-
margin={storybookElement.attributes.margin}
|
|
117
|
-
onChange={value => handleFieldValueChange("margin", value)} />
|
|
118
|
-
</div>
|
|
119
|
-
<div className="cursor-pointer p-2" title="Löschen" onClick={() => onDelete && onDelete(storybookElement)}>
|
|
120
|
-
<Icon icon="Delete" />
|
|
197
|
+
<div className="grow overflow-y-auto pr-2 pt-2">
|
|
198
|
+
<div className="mb-2">
|
|
199
|
+
<BlockSelect stories={storybookStories} active={storybookElement} onChange={handleBlockSelectChange} />
|
|
200
|
+
</div>
|
|
201
|
+
{storybookElement?.block && (
|
|
202
|
+
<div>
|
|
203
|
+
<div className="mb-2 grid grid-flow-col grid-cols-2 gap-2">
|
|
204
|
+
<VariantSelect className="w-full" story={story} onChange={handleVariantSelectChange} />
|
|
205
|
+
<BlockWidthSelect className="w-full" value={storybookElement.attributes.blockWidth} onChange={e => handleFieldValueChange("blockWidth", e.target.value)} />
|
|
121
206
|
</div>
|
|
207
|
+
<hr className="my-4" style={{borderColor: "#cfd9e0"}}/>
|
|
122
208
|
</div>
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
209
|
+
)}
|
|
210
|
+
{!!story && (
|
|
211
|
+
<>
|
|
212
|
+
{Object.keys(fields.fields).map(key => {
|
|
213
|
+
const field = fields.fields[key];
|
|
214
|
+
|
|
215
|
+
return <SidebarEditorField
|
|
216
|
+
sdk={sdk}
|
|
217
|
+
value={storybookElement?.attributes?.[key]}
|
|
218
|
+
key={key}
|
|
219
|
+
storybookElement={storybookElement}
|
|
220
|
+
fieldKey={key}
|
|
221
|
+
field={field}
|
|
222
|
+
onChange={(
|
|
223
|
+
key, value, mvpField, mvpIndex,
|
|
224
|
+
) => handleFieldValueChange(
|
|
225
|
+
key, value, mvpField, mvpIndex,
|
|
226
|
+
)}
|
|
227
|
+
/>;
|
|
228
|
+
})}
|
|
229
|
+
{Object.keys(fields.tables).map(tableKey => {
|
|
230
|
+
return (
|
|
231
|
+
<details key={`accordion-item-${tableKey}`}>
|
|
232
|
+
<summary>{tableKey}</summary>
|
|
233
|
+
<div className="mt-4">
|
|
234
|
+
{Object.keys(fields.tables[tableKey]).map(key => {
|
|
235
|
+
const field = fields.tables[tableKey][key];
|
|
236
|
+
|
|
237
|
+
return <SidebarEditorField
|
|
238
|
+
sdk={sdk}
|
|
239
|
+
value={storybookElement?.attributes?.[key]}
|
|
240
|
+
key={key}
|
|
241
|
+
fieldKey={key}
|
|
242
|
+
story={storybookElement}
|
|
243
|
+
field={field}
|
|
244
|
+
onChange={value => handleFieldValueChange(key, value)}
|
|
245
|
+
/>;
|
|
246
|
+
})}
|
|
247
|
+
</div>
|
|
248
|
+
</details>
|
|
249
|
+
);
|
|
250
|
+
})}
|
|
251
|
+
</>
|
|
252
|
+
)}
|
|
253
|
+
</div>
|
|
254
|
+
</div>
|
|
255
|
+
);
|
|
256
|
+
};
|
|
257
|
+
|
|
258
|
+
export const IconButton = ({
|
|
259
|
+
children,
|
|
260
|
+
disabled,
|
|
261
|
+
size = "medium",
|
|
262
|
+
className,
|
|
263
|
+
...props
|
|
264
|
+
}) => {
|
|
265
|
+
let classNames = "icon-button cursor-pointer select-none !p-1";
|
|
266
|
+
|
|
267
|
+
if (disabled) {
|
|
268
|
+
classNames += " disabled";
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
if (className) {
|
|
272
|
+
classNames += ` ${className}`;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
switch (size) {
|
|
276
|
+
case "small":
|
|
277
|
+
classNames += " !text-xs min-w-[28px]";
|
|
278
|
+
break;
|
|
279
|
+
case "medium":
|
|
280
|
+
default:
|
|
281
|
+
classNames += " !text-sm min-w-[32px]";
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
return (
|
|
285
|
+
<div className={classNames} {...props}>
|
|
286
|
+
{children}
|
|
287
|
+
</div>
|
|
288
|
+
);
|
|
289
|
+
};
|
|
290
|
+
|
|
291
|
+
const BlockWidthSelect = ({
|
|
292
|
+
value,
|
|
293
|
+
onChange,
|
|
294
|
+
className,
|
|
295
|
+
}) => {
|
|
296
|
+
return (
|
|
297
|
+
<div>
|
|
298
|
+
<label className="block">Breite</label>
|
|
299
|
+
<select
|
|
300
|
+
value={value || ""}
|
|
301
|
+
onChange={onChange}
|
|
302
|
+
className={className}>
|
|
303
|
+
<option disabled>Breite wählen</option>
|
|
304
|
+
<option value={""}>Volle Breite</option>
|
|
305
|
+
<option value={"article"}>Artikel Breite</option>
|
|
306
|
+
<option value={"site"}>Seiten Breite</option>
|
|
307
|
+
<option value={"small"}>Klein</option>
|
|
308
|
+
</select>
|
|
169
309
|
</div>
|
|
170
310
|
);
|
|
171
311
|
};
|
|
@@ -177,21 +317,26 @@ const VariantSelect = ({
|
|
|
177
317
|
}) => {
|
|
178
318
|
const stories = story?.stories?.filter(s => s.title !== story.title) || [];
|
|
179
319
|
|
|
180
|
-
if (
|
|
320
|
+
if (!onChange) {
|
|
181
321
|
return null;
|
|
182
322
|
}
|
|
183
323
|
|
|
184
|
-
return
|
|
185
|
-
className={className}
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
324
|
+
return (
|
|
325
|
+
<div className={className}>
|
|
326
|
+
<label className="block">Preset</label>
|
|
327
|
+
<select
|
|
328
|
+
disabled={stories.length <= 1}
|
|
329
|
+
onChange={e => onChange && onChange({
|
|
330
|
+
block: story.id,
|
|
331
|
+
attributes: {...stories.find(s => s.title === e.target.value)?.args || {}},
|
|
332
|
+
})}>
|
|
333
|
+
<option>Preset wählen</option>
|
|
334
|
+
{stories.map(s => (
|
|
335
|
+
<option key={`variant-option-${s.title}`} value={s.title}>{s.title}</option>
|
|
336
|
+
))}
|
|
337
|
+
</select>
|
|
338
|
+
</div>
|
|
339
|
+
);
|
|
195
340
|
};
|
|
196
341
|
|
|
197
342
|
const BlockSelect = ({
|
|
@@ -211,27 +356,31 @@ const BlockSelect = ({
|
|
|
211
356
|
|
|
212
357
|
// reset to the first story
|
|
213
358
|
onChange({
|
|
359
|
+
...active,
|
|
214
360
|
block: story.id,
|
|
215
361
|
attributes: {...(story?.stories?.[0]?.args || {})},
|
|
216
362
|
});
|
|
217
363
|
};
|
|
218
364
|
|
|
219
365
|
return (
|
|
220
|
-
<
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
<option
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
366
|
+
<div className={className}>
|
|
367
|
+
<label className="block">Element</label>
|
|
368
|
+
<select
|
|
369
|
+
onChange={e => onSelectChange(stories.find(s => s.id === e.target.value))}
|
|
370
|
+
className="font-bold"
|
|
371
|
+
>
|
|
372
|
+
<option>Element wählen</option>
|
|
373
|
+
{stories.map(s => (
|
|
374
|
+
<option
|
|
375
|
+
key={`variant-option-${s.id}`}
|
|
376
|
+
selected={active?.block === s.id}
|
|
377
|
+
value={s.id}
|
|
378
|
+
>
|
|
379
|
+
{s.title}
|
|
380
|
+
</option>
|
|
381
|
+
))}
|
|
382
|
+
</select>
|
|
383
|
+
</div>
|
|
235
384
|
);
|
|
236
385
|
};
|
|
237
386
|
|
package/src/Toolbar/Toolbar.js
CHANGED
|
@@ -26,7 +26,10 @@ export const Portal = ({children}) => {
|
|
|
26
26
|
return ReactDOM.createPortal(children, window.document.body);
|
|
27
27
|
};
|
|
28
28
|
|
|
29
|
-
export const Toolbar = ({
|
|
29
|
+
export const Toolbar = ({
|
|
30
|
+
hover,
|
|
31
|
+
onSaveClick,
|
|
32
|
+
}) => {
|
|
30
33
|
const ref = useRef();
|
|
31
34
|
const editor = useSlate();
|
|
32
35
|
|
|
@@ -90,39 +93,41 @@ export const Toolbar = ({hover}) => {
|
|
|
90
93
|
})}
|
|
91
94
|
>
|
|
92
95
|
<div className="toolbar-btns">
|
|
93
|
-
<
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
<
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
<
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
<
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
<
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
96
|
+
<div className="flex grow">
|
|
97
|
+
<FormatButtonBold/>
|
|
98
|
+
<FormatButtonItalic/>
|
|
99
|
+
<FormatButtonUnderline/>
|
|
100
|
+
<FormatButtonStrikethrough/>
|
|
101
|
+
|
|
102
|
+
<LinkButton/>
|
|
103
|
+
|
|
104
|
+
<ToobarHoverExpandButton>
|
|
105
|
+
<BlockButtonHeading level={2}/>
|
|
106
|
+
<BlockButtonHeading level={3}/>
|
|
107
|
+
<BlockButtonHeading level={4}/>
|
|
108
|
+
</ToobarHoverExpandButton>
|
|
109
|
+
|
|
110
|
+
<ToobarHoverExpandButton>
|
|
111
|
+
<BlockButtonUnorderedList/>
|
|
112
|
+
<BlockButtonOrderedList/>
|
|
113
|
+
<BlockButtonArrowList/>
|
|
114
|
+
</ToobarHoverExpandButton>
|
|
115
|
+
|
|
116
|
+
<BlockButtonBlockquote/>
|
|
117
|
+
|
|
118
|
+
<ToobarHoverExpandButton>
|
|
119
|
+
<AlignButtonLeft/>
|
|
120
|
+
<AlignButtonCenter/>
|
|
121
|
+
<AlignButtonRight/>
|
|
122
|
+
</ToobarHoverExpandButton>
|
|
123
|
+
|
|
124
|
+
<ToobarHoverExpandButton>
|
|
125
|
+
<StorybookButton/>
|
|
126
|
+
<InsertDividerButton/>
|
|
127
|
+
<InsertGridButton/>
|
|
128
|
+
</ToobarHoverExpandButton>
|
|
129
|
+
</div>
|
|
130
|
+
{!!onSaveClick && <button className="!w-auto !border-0 !bg-green-600 !text-xs font-bold text-white hover:!bg-green-700" onClick={onSaveClick}>Änderungen speichern</button>}
|
|
126
131
|
</div>
|
|
127
132
|
</Menu>;
|
|
128
133
|
}
|
package/src/dev/App.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import React, {useEffect} from 'react';
|
|
2
2
|
import BlockEditor from "../BlockEditor";
|
|
3
|
+
import Renderer from "../Renderer";
|
|
3
4
|
// eslint-disable-next-line import/no-unresolved
|
|
4
5
|
import "scss/demo.scss";
|
|
5
6
|
import "./index.css";
|
|
@@ -53,6 +54,11 @@ function App() {
|
|
|
53
54
|
</div>
|
|
54
55
|
<div className="editor-demo-output">
|
|
55
56
|
<textarea value={JSON.stringify(value)}/>
|
|
57
|
+
<Renderer
|
|
58
|
+
value={value}
|
|
59
|
+
storybookComponentLoader={(block) => {
|
|
60
|
+
return componentLoader(block);
|
|
61
|
+
}}/>
|
|
56
62
|
</div>
|
|
57
63
|
</div>
|
|
58
64
|
);
|
|
@@ -1,9 +1,75 @@
|
|
|
1
1
|
export default function TestStory({
|
|
2
|
-
title,
|
|
2
|
+
title,
|
|
3
|
+
mvp,
|
|
4
|
+
...props
|
|
3
5
|
}) {
|
|
4
6
|
return <div className="bg-green flex flex-col space-y-8 p-4 text-black">
|
|
5
7
|
<h1>{title}</h1>
|
|
8
|
+
<div className="grid grid-cols-4">
|
|
9
|
+
<div className="border border-black p-4" data-teasermanager-slot="test-1">
|
|
10
|
+
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ad aperiam beatae consequatur consequuntur deserunt exercitationem fugit, magni necessitatibus pariatur quae quia, quisquam saepe sunt, tenetur!
|
|
11
|
+
</div>
|
|
12
|
+
<div className="border border-black p-4" data-teasermanager-slot="test-2">
|
|
13
|
+
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Molestias, obcaecati, unde! In labore nesciunt optio, possimus praesentium sunt temporibus vero.
|
|
14
|
+
</div>
|
|
15
|
+
<div className="border border-black p-4" data-teasermanager-slot="test-3">
|
|
16
|
+
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Commodi, rem, sapiente! At consequatur cum distinctio dolorem doloribus eligendi labore necessitatibus nemo officia, perspiciatis porro quisquam quos, saepe vitae voluptas. Eligendi?
|
|
17
|
+
</div>
|
|
18
|
+
<div className="border border-black p-4" data-teasermanager-slot="test-4">
|
|
19
|
+
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ad alias beatae doloribus ex, impedit labore maxime perspiciatis quas. Alias aspernatur cupiditate, error impedit ipsa libero obcaecati reprehenderit sit sunt veniam.
|
|
20
|
+
</div>
|
|
21
|
+
<div className="border border-black p-4" data-teasermanager-slot="test-5">
|
|
22
|
+
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Asperiores at consequatur cupiditate dolore, dolorem, eligendi et eum explicabo harum illum inventore maxime molestias porro quod recusandae, reiciendis repellat repudiandae saepe sint tempora tempore temporibus veniam voluptates. Dignissimos explicabo iusto reprehenderit.
|
|
23
|
+
</div>
|
|
24
|
+
<div className="border border-black p-4" data-teasermanager-slot="test-6">
|
|
25
|
+
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ad aperiam beatae consequatur consequuntur deserunt exercitationem fugit, magni necessitatibus pariatur quae quia, quisquam saepe sunt, tenetur!
|
|
26
|
+
</div>
|
|
27
|
+
<div className="border border-black p-4" data-teasermanager-slot="test-7">
|
|
28
|
+
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Molestias, obcaecati, unde! In labore nesciunt optio, possimus praesentium sunt temporibus vero.
|
|
29
|
+
</div>
|
|
30
|
+
<div className="border border-black p-4" data-teasermanager-slot="test-8">
|
|
31
|
+
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Commodi, rem, sapiente! At consequatur cum distinctio dolorem doloribus eligendi labore necessitatibus nemo officia, perspiciatis porro quisquam quos, saepe vitae voluptas. Eligendi?
|
|
32
|
+
</div>
|
|
33
|
+
<div className="border border-black p-4" data-teasermanager-slot="test-9">
|
|
34
|
+
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ad alias beatae doloribus ex, impedit labore maxime perspiciatis quas. Alias aspernatur cupiditate, error impedit ipsa libero obcaecati reprehenderit sit sunt veniam.
|
|
35
|
+
</div>
|
|
36
|
+
<div className="border border-black p-4" data-teasermanager-slot="test-10">
|
|
37
|
+
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Asperiores at consequatur cupiditate dolore, dolorem, eligendi et eum explicabo harum illum inventore maxime molestias porro quod recusandae, reiciendis repellat repudiandae saepe sint tempora tempore temporibus veniam voluptates. Dignissimos explicabo iusto reprehenderit.
|
|
38
|
+
</div>
|
|
39
|
+
<div className="border border-black p-4" data-teasermanager-slot="test-11">
|
|
40
|
+
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ad aperiam beatae consequatur consequuntur deserunt exercitationem fugit, magni necessitatibus pariatur quae quia, quisquam saepe sunt, tenetur!
|
|
41
|
+
</div>
|
|
42
|
+
<div className="border border-black p-4" data-teasermanager-slot="test-12">
|
|
43
|
+
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Molestias, obcaecati, unde! In labore nesciunt optio, possimus praesentium sunt temporibus vero.
|
|
44
|
+
</div>
|
|
45
|
+
<div className="border border-black p-4" data-teasermanager-slot="test-13">
|
|
46
|
+
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Commodi, rem, sapiente! At consequatur cum distinctio dolorem doloribus eligendi labore necessitatibus nemo officia, perspiciatis porro quisquam quos, saepe vitae voluptas. Eligendi?
|
|
47
|
+
</div>
|
|
48
|
+
<div className="border border-black p-4" data-teasermanager-slot="test-14">
|
|
49
|
+
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ad alias beatae doloribus ex, impedit labore maxime perspiciatis quas. Alias aspernatur cupiditate, error impedit ipsa libero obcaecati reprehenderit sit sunt veniam.
|
|
50
|
+
</div>
|
|
51
|
+
<div className="border border-black p-4" data-teasermanager-slot="test-15">
|
|
52
|
+
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Asperiores at consequatur cupiditate dolore, dolorem, eligendi et eum explicabo harum illum inventore maxime molestias porro quod recusandae, reiciendis repellat repudiandae saepe sint tempora tempore temporibus veniam voluptates. Dignissimos explicabo iusto reprehenderit.
|
|
53
|
+
</div>
|
|
54
|
+
<div className="border border-black p-4" data-teasermanager-slot="test-16">
|
|
55
|
+
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ad aperiam beatae consequatur consequuntur deserunt exercitationem fugit, magni necessitatibus pariatur quae quia, quisquam saepe sunt, tenetur!
|
|
56
|
+
</div>
|
|
57
|
+
</div>
|
|
6
58
|
<h2>Props</h2>
|
|
7
|
-
|
|
59
|
+
{!!mvp && mvp.length > 0 && (
|
|
60
|
+
<ul>
|
|
61
|
+
{mvp.map(m => (
|
|
62
|
+
<li key={m.feld1}>
|
|
63
|
+
<b>{m.feld1}</b>:
|
|
64
|
+
<span>{m.feld2}</span>
|
|
65
|
+
</li>
|
|
66
|
+
))}
|
|
67
|
+
</ul>
|
|
68
|
+
)}
|
|
69
|
+
<div>{JSON.stringify({
|
|
70
|
+
...props,
|
|
71
|
+
mvp,
|
|
72
|
+
title,
|
|
73
|
+
})}</div>
|
|
8
74
|
</div>;
|
|
9
75
|
}
|