@vonaffenfels/slate-editor 1.0.2 → 1.0.4
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 +10 -8
- package/dist/BlockEditor.css +4 -95
- package/dist/BlockEditor.js +1 -1
- package/dist/BlockEditor.js.LICENSE.txt +0 -33
- package/dist/index.css +4 -95
- package/dist/index.js +1 -1
- package/dist/index.js.LICENSE.txt +0 -33
- package/package.json +2 -3
- package/scss/demo.scss +7 -0
- package/scss/editor.scss +70 -38
- package/scss/sidebarEditor.scss +143 -0
- 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 +164 -93
- package/src/SidebarEditor.js +266 -116
- 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.css +0 -92
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 "./SidebarEditor.css";
|
|
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,109 +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);
|
|
80
93
|
}
|
|
81
94
|
}
|
|
82
95
|
};
|
|
83
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);
|
|
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);
|
|
150
|
+
}
|
|
151
|
+
};
|
|
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
|
-
↑
|
|
110
|
-
</div>
|
|
111
|
-
<div className="cursor-pointer p-2" title="Nach unten verschieben" onClick={() => onMove && onMove(storybookElement, "down")}>
|
|
112
|
-
↓
|
|
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
|
-
🗑
|
|
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
|
-
<Accordion>
|
|
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
|
+
})}
|
|
146
229
|
{Object.keys(fields.tables).map(tableKey => {
|
|
147
230
|
return (
|
|
148
|
-
<
|
|
149
|
-
{
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
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>
|
|
163
249
|
);
|
|
164
250
|
})}
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
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>
|
|
168
309
|
</div>
|
|
169
310
|
);
|
|
170
311
|
};
|
|
@@ -176,21 +317,26 @@ const VariantSelect = ({
|
|
|
176
317
|
}) => {
|
|
177
318
|
const stories = story?.stories?.filter(s => s.title !== story.title) || [];
|
|
178
319
|
|
|
179
|
-
if (
|
|
320
|
+
if (!onChange) {
|
|
180
321
|
return null;
|
|
181
322
|
}
|
|
182
323
|
|
|
183
|
-
return
|
|
184
|
-
className={className}
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
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
|
+
);
|
|
194
340
|
};
|
|
195
341
|
|
|
196
342
|
const BlockSelect = ({
|
|
@@ -210,27 +356,31 @@ const BlockSelect = ({
|
|
|
210
356
|
|
|
211
357
|
// reset to the first story
|
|
212
358
|
onChange({
|
|
359
|
+
...active,
|
|
213
360
|
block: story.id,
|
|
214
361
|
attributes: {...(story?.stories?.[0]?.args || {})},
|
|
215
362
|
});
|
|
216
363
|
};
|
|
217
364
|
|
|
218
365
|
return (
|
|
219
|
-
<
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
<option
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
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>
|
|
234
384
|
);
|
|
235
385
|
};
|
|
236
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
|
}
|