@schneiderelli/cms-runtime 0.0.2 → 0.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/dist/components/BlockRenderer.svelte +106 -71
- package/dist/components/BlockRenderer.svelte.d.ts +15 -4
- package/dist/components/blocks/AdBlock.svelte +58 -0
- package/dist/components/blocks/AdBlock.svelte.d.ts +9 -0
- package/dist/components/blocks/AffiliateBlock.svelte +50 -0
- package/dist/components/blocks/AffiliateBlock.svelte.d.ts +9 -0
- package/dist/components/blocks/BreadcrumbBlock.svelte +30 -0
- package/dist/components/blocks/BreadcrumbBlock.svelte.d.ts +9 -0
- package/dist/components/blocks/ChildrenBlock.svelte +46 -0
- package/dist/components/blocks/ChildrenBlock.svelte.d.ts +9 -0
- package/dist/components/blocks/DividerBlock.svelte +9 -0
- package/dist/components/blocks/DividerBlock.svelte.d.ts +26 -0
- package/dist/components/blocks/FaqBlock.svelte +77 -0
- package/dist/components/blocks/FaqBlock.svelte.d.ts +7 -0
- package/dist/components/blocks/HeadingBlock.svelte +35 -5
- package/dist/components/blocks/HeadingBlock.svelte.d.ts +3 -3
- package/dist/components/blocks/HeroBlock.svelte +43 -0
- package/dist/components/blocks/HeroBlock.svelte.d.ts +7 -0
- package/dist/components/blocks/HowToBlock.svelte +100 -0
- package/dist/components/blocks/HowToBlock.svelte.d.ts +7 -0
- package/dist/components/blocks/ImageBlock.svelte +42 -3
- package/dist/components/blocks/ImageBlock.svelte.d.ts +3 -3
- package/dist/components/blocks/LinksBlock.svelte +66 -0
- package/dist/components/blocks/LinksBlock.svelte.d.ts +7 -0
- package/dist/components/blocks/MarkdownBlock.svelte +118 -0
- package/dist/components/blocks/MarkdownBlock.svelte.d.ts +7 -0
- package/dist/components/blocks/NoteBlock.svelte +59 -0
- package/dist/components/blocks/NoteBlock.svelte.d.ts +7 -0
- package/dist/components/blocks/QuoteBlock.svelte +44 -0
- package/dist/components/blocks/QuoteBlock.svelte.d.ts +7 -0
- package/dist/index.d.ts +16 -1
- package/dist/index.js +26 -1
- package/dist/registry.d.ts +43 -0
- package/dist/registry.js +374 -0
- package/dist/types.d.ts +143 -25
- package/dist/types.js +30 -4
- package/package.json +2 -1
- package/dist/components/blocks/TextBlock.svelte +0 -8
- package/dist/components/blocks/TextBlock.svelte.d.ts +0 -7
- package/dist/resolve.d.ts +0 -15
- package/dist/resolve.js +0 -15
package/dist/registry.js
ADDED
|
@@ -0,0 +1,374 @@
|
|
|
1
|
+
// =============================================================================
|
|
2
|
+
// CSM-RUNTIME REGISTRY
|
|
3
|
+
// =============================================================================
|
|
4
|
+
// Block-Metadaten für den Editor
|
|
5
|
+
// Beschreibt welche Blocks verfügbar sind und wie sie konfiguriert werden
|
|
6
|
+
// =============================================================================
|
|
7
|
+
// -----------------------------------------------------------------------------
|
|
8
|
+
// BLOCK REGISTRY - Alle verfügbaren Blocks
|
|
9
|
+
// -----------------------------------------------------------------------------
|
|
10
|
+
export const blockRegistry = [
|
|
11
|
+
// =========================================================================
|
|
12
|
+
// CONTENT BLOCKS
|
|
13
|
+
// =========================================================================
|
|
14
|
+
{
|
|
15
|
+
type: 'markdown',
|
|
16
|
+
label: 'Markdown',
|
|
17
|
+
icon: '📝',
|
|
18
|
+
description: 'Freier Text mit Markdown-Formatierung',
|
|
19
|
+
category: 'content',
|
|
20
|
+
defaults: { content: '' },
|
|
21
|
+
fields: [
|
|
22
|
+
{
|
|
23
|
+
name: 'content',
|
|
24
|
+
label: 'Inhalt',
|
|
25
|
+
type: 'markdown',
|
|
26
|
+
required: true,
|
|
27
|
+
placeholder: 'Schreibe hier deinen Text...'
|
|
28
|
+
}
|
|
29
|
+
]
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
type: 'heading',
|
|
33
|
+
label: 'Überschrift',
|
|
34
|
+
icon: '🔤',
|
|
35
|
+
description: 'Überschrift H1-H6',
|
|
36
|
+
category: 'content',
|
|
37
|
+
defaults: { text: '', level: 2 },
|
|
38
|
+
fields: [
|
|
39
|
+
{
|
|
40
|
+
name: 'text',
|
|
41
|
+
label: 'Text',
|
|
42
|
+
type: 'text',
|
|
43
|
+
required: true,
|
|
44
|
+
placeholder: 'Überschrift eingeben...'
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
name: 'level',
|
|
48
|
+
label: 'Level',
|
|
49
|
+
type: 'select',
|
|
50
|
+
options: [
|
|
51
|
+
{ value: '1', label: 'H1 - Hauptüberschrift' },
|
|
52
|
+
{ value: '2', label: 'H2 - Abschnitt' },
|
|
53
|
+
{ value: '3', label: 'H3 - Unterabschnitt' },
|
|
54
|
+
{ value: '4', label: 'H4' },
|
|
55
|
+
{ value: '5', label: 'H5' },
|
|
56
|
+
{ value: '6', label: 'H6' }
|
|
57
|
+
]
|
|
58
|
+
}
|
|
59
|
+
]
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
type: 'quote',
|
|
63
|
+
label: 'Zitat',
|
|
64
|
+
icon: '💬',
|
|
65
|
+
description: 'Zitat mit optionaler Quellenangabe',
|
|
66
|
+
category: 'content',
|
|
67
|
+
defaults: { content: '', source: '' },
|
|
68
|
+
fields: [
|
|
69
|
+
{
|
|
70
|
+
name: 'content',
|
|
71
|
+
label: 'Zitat',
|
|
72
|
+
type: 'textarea',
|
|
73
|
+
required: true,
|
|
74
|
+
placeholder: 'Zitat eingeben...'
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
name: 'source',
|
|
78
|
+
label: 'Quelle',
|
|
79
|
+
type: 'text',
|
|
80
|
+
placeholder: 'Autor oder Quelle...'
|
|
81
|
+
}
|
|
82
|
+
]
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
type: 'note',
|
|
86
|
+
label: 'Hinweis',
|
|
87
|
+
icon: '💡',
|
|
88
|
+
description: 'Info-Box, Warnung, Tipp oder Fehler',
|
|
89
|
+
category: 'content',
|
|
90
|
+
defaults: { content: '', variant: 'info' },
|
|
91
|
+
fields: [
|
|
92
|
+
{
|
|
93
|
+
name: 'content',
|
|
94
|
+
label: 'Inhalt',
|
|
95
|
+
type: 'markdown',
|
|
96
|
+
required: true,
|
|
97
|
+
placeholder: 'Hinweis-Text...'
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
name: 'variant',
|
|
101
|
+
label: 'Typ',
|
|
102
|
+
type: 'select',
|
|
103
|
+
options: [
|
|
104
|
+
{ value: 'info', label: '💙 Info' },
|
|
105
|
+
{ value: 'tip', label: '💚 Tipp' },
|
|
106
|
+
{ value: 'warning', label: '💛 Warnung' },
|
|
107
|
+
{ value: 'danger', label: '❤️ Achtung' }
|
|
108
|
+
]
|
|
109
|
+
}
|
|
110
|
+
]
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
type: 'faq',
|
|
114
|
+
label: 'FAQ',
|
|
115
|
+
icon: '❓',
|
|
116
|
+
description: 'Häufig gestellte Fragen',
|
|
117
|
+
category: 'content',
|
|
118
|
+
defaults: { title: '', items: [] },
|
|
119
|
+
fields: [
|
|
120
|
+
{
|
|
121
|
+
name: 'title',
|
|
122
|
+
label: 'Titel (optional)',
|
|
123
|
+
type: 'text',
|
|
124
|
+
placeholder: 'Häufige Fragen'
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
name: 'items',
|
|
128
|
+
label: 'Fragen',
|
|
129
|
+
type: 'list',
|
|
130
|
+
listFields: [
|
|
131
|
+
{ name: 'q', label: 'Frage', type: 'text', required: true },
|
|
132
|
+
{ name: 'a', label: 'Antwort', type: 'markdown', required: true }
|
|
133
|
+
]
|
|
134
|
+
}
|
|
135
|
+
]
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
type: 'howto',
|
|
139
|
+
label: 'Anleitung',
|
|
140
|
+
icon: '📋',
|
|
141
|
+
description: 'Schritt-für-Schritt-Anleitung',
|
|
142
|
+
category: 'content',
|
|
143
|
+
defaults: { title: '', steps: [] },
|
|
144
|
+
fields: [
|
|
145
|
+
{
|
|
146
|
+
name: 'title',
|
|
147
|
+
label: 'Titel (optional)',
|
|
148
|
+
type: 'text',
|
|
149
|
+
placeholder: 'So gehts...'
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
name: 'steps',
|
|
153
|
+
label: 'Schritte',
|
|
154
|
+
type: 'list',
|
|
155
|
+
listFields: [
|
|
156
|
+
{ name: 'title', label: 'Schritt-Titel', type: 'text', required: true },
|
|
157
|
+
{ name: 'description', label: 'Beschreibung', type: 'markdown', required: true }
|
|
158
|
+
]
|
|
159
|
+
}
|
|
160
|
+
]
|
|
161
|
+
},
|
|
162
|
+
{
|
|
163
|
+
type: 'hero',
|
|
164
|
+
label: 'Hero',
|
|
165
|
+
icon: '🦸',
|
|
166
|
+
description: 'Großer Titel-Bereich',
|
|
167
|
+
category: 'content',
|
|
168
|
+
defaults: { title: '', subtitle: '' },
|
|
169
|
+
fields: [
|
|
170
|
+
{
|
|
171
|
+
name: 'title',
|
|
172
|
+
label: 'Titel',
|
|
173
|
+
type: 'text',
|
|
174
|
+
required: true,
|
|
175
|
+
placeholder: 'Haupttitel'
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
name: 'subtitle',
|
|
179
|
+
label: 'Untertitel',
|
|
180
|
+
type: 'textarea',
|
|
181
|
+
placeholder: 'Kurze Beschreibung...'
|
|
182
|
+
}
|
|
183
|
+
]
|
|
184
|
+
},
|
|
185
|
+
{
|
|
186
|
+
type: 'divider',
|
|
187
|
+
label: 'Trennlinie',
|
|
188
|
+
icon: '➖',
|
|
189
|
+
description: 'Horizontale Trennlinie',
|
|
190
|
+
category: 'content',
|
|
191
|
+
defaults: {},
|
|
192
|
+
fields: []
|
|
193
|
+
},
|
|
194
|
+
// =========================================================================
|
|
195
|
+
// MEDIA BLOCKS
|
|
196
|
+
// =========================================================================
|
|
197
|
+
{
|
|
198
|
+
type: 'image',
|
|
199
|
+
label: 'Bild',
|
|
200
|
+
icon: '🖼️',
|
|
201
|
+
description: 'Bild mit optionaler Beschriftung',
|
|
202
|
+
category: 'media',
|
|
203
|
+
defaults: { src: '', alt: '', caption: '' },
|
|
204
|
+
fields: [
|
|
205
|
+
{
|
|
206
|
+
name: 'src',
|
|
207
|
+
label: 'Bild',
|
|
208
|
+
type: 'image',
|
|
209
|
+
required: true
|
|
210
|
+
},
|
|
211
|
+
{
|
|
212
|
+
name: 'alt',
|
|
213
|
+
label: 'Alt-Text',
|
|
214
|
+
type: 'text',
|
|
215
|
+
placeholder: 'Beschreibung für Screenreader...'
|
|
216
|
+
},
|
|
217
|
+
{
|
|
218
|
+
name: 'caption',
|
|
219
|
+
label: 'Bildunterschrift',
|
|
220
|
+
type: 'text',
|
|
221
|
+
placeholder: 'Optionale Bildunterschrift...'
|
|
222
|
+
}
|
|
223
|
+
]
|
|
224
|
+
},
|
|
225
|
+
// =========================================================================
|
|
226
|
+
// LAYOUT BLOCKS
|
|
227
|
+
// =========================================================================
|
|
228
|
+
{
|
|
229
|
+
type: 'children',
|
|
230
|
+
label: 'Unterseiten',
|
|
231
|
+
icon: '📂',
|
|
232
|
+
description: 'Zeigt Kind-Seiten als Grid',
|
|
233
|
+
category: 'layout',
|
|
234
|
+
defaults: { title: '', columns: 3 },
|
|
235
|
+
fields: [
|
|
236
|
+
{
|
|
237
|
+
name: 'title',
|
|
238
|
+
label: 'Titel (optional)',
|
|
239
|
+
type: 'text',
|
|
240
|
+
placeholder: 'Alle Themen'
|
|
241
|
+
},
|
|
242
|
+
{
|
|
243
|
+
name: 'columns',
|
|
244
|
+
label: 'Spalten',
|
|
245
|
+
type: 'select',
|
|
246
|
+
options: [
|
|
247
|
+
{ value: '2', label: '2 Spalten' },
|
|
248
|
+
{ value: '3', label: '3 Spalten' },
|
|
249
|
+
{ value: '4', label: '4 Spalten' }
|
|
250
|
+
]
|
|
251
|
+
}
|
|
252
|
+
]
|
|
253
|
+
},
|
|
254
|
+
{
|
|
255
|
+
type: 'links',
|
|
256
|
+
label: 'Link-Liste',
|
|
257
|
+
icon: '🔗',
|
|
258
|
+
description: 'Liste von Links',
|
|
259
|
+
category: 'layout',
|
|
260
|
+
defaults: { title: '', items: [] },
|
|
261
|
+
fields: [
|
|
262
|
+
{
|
|
263
|
+
name: 'title',
|
|
264
|
+
label: 'Titel (optional)',
|
|
265
|
+
type: 'text'
|
|
266
|
+
},
|
|
267
|
+
{
|
|
268
|
+
name: 'items',
|
|
269
|
+
label: 'Links',
|
|
270
|
+
type: 'list',
|
|
271
|
+
listFields: [
|
|
272
|
+
{ name: 'label', label: 'Text', type: 'text', required: true },
|
|
273
|
+
{ name: 'href', label: 'URL', type: 'text', required: true },
|
|
274
|
+
{ name: 'icon', label: 'Icon', type: 'text' }
|
|
275
|
+
]
|
|
276
|
+
}
|
|
277
|
+
]
|
|
278
|
+
},
|
|
279
|
+
{
|
|
280
|
+
type: 'breadcrumb',
|
|
281
|
+
label: 'Breadcrumb',
|
|
282
|
+
icon: '🧭',
|
|
283
|
+
description: 'Navigationspfad',
|
|
284
|
+
category: 'layout',
|
|
285
|
+
defaults: {},
|
|
286
|
+
fields: []
|
|
287
|
+
},
|
|
288
|
+
// =========================================================================
|
|
289
|
+
// MONETIZATION BLOCKS
|
|
290
|
+
// =========================================================================
|
|
291
|
+
{
|
|
292
|
+
type: 'affiliate',
|
|
293
|
+
label: 'Affiliate',
|
|
294
|
+
icon: '🛒',
|
|
295
|
+
description: 'Affiliate-Produkt-Empfehlung',
|
|
296
|
+
category: 'monetization',
|
|
297
|
+
defaults: { ref: '', variant: 'box' },
|
|
298
|
+
fields: [
|
|
299
|
+
{
|
|
300
|
+
name: 'ref',
|
|
301
|
+
label: 'Referenz',
|
|
302
|
+
type: 'text',
|
|
303
|
+
placeholder: 'z.B. dyson/v11'
|
|
304
|
+
},
|
|
305
|
+
{
|
|
306
|
+
name: 'variant',
|
|
307
|
+
label: 'Darstellung',
|
|
308
|
+
type: 'select',
|
|
309
|
+
options: [
|
|
310
|
+
{ value: 'inline', label: 'Inline' },
|
|
311
|
+
{ value: 'box', label: 'Box' },
|
|
312
|
+
{ value: 'sticky', label: 'Sticky (Mobile)' },
|
|
313
|
+
{ value: 'floating', label: 'Floating (Desktop)' }
|
|
314
|
+
]
|
|
315
|
+
}
|
|
316
|
+
]
|
|
317
|
+
},
|
|
318
|
+
{
|
|
319
|
+
type: 'ad',
|
|
320
|
+
label: 'Werbung',
|
|
321
|
+
icon: '📢',
|
|
322
|
+
description: 'Werbeplatz',
|
|
323
|
+
category: 'monetization',
|
|
324
|
+
defaults: { slot: '', variant: 'inline' },
|
|
325
|
+
fields: [
|
|
326
|
+
{
|
|
327
|
+
name: 'slot',
|
|
328
|
+
label: 'Slot-ID',
|
|
329
|
+
type: 'text'
|
|
330
|
+
},
|
|
331
|
+
{
|
|
332
|
+
name: 'variant',
|
|
333
|
+
label: 'Darstellung',
|
|
334
|
+
type: 'select',
|
|
335
|
+
options: [
|
|
336
|
+
{ value: 'inline', label: 'Inline' },
|
|
337
|
+
{ value: 'banner', label: 'Banner' },
|
|
338
|
+
{ value: 'sidebar', label: 'Sidebar' }
|
|
339
|
+
]
|
|
340
|
+
}
|
|
341
|
+
]
|
|
342
|
+
}
|
|
343
|
+
];
|
|
344
|
+
// -----------------------------------------------------------------------------
|
|
345
|
+
// HELPER FUNCTIONS
|
|
346
|
+
// -----------------------------------------------------------------------------
|
|
347
|
+
/** Holt Block-Definition by Type */
|
|
348
|
+
export function getBlockDefinition(type) {
|
|
349
|
+
return blockRegistry.find(b => b.type === type);
|
|
350
|
+
}
|
|
351
|
+
/** Gruppiert Blocks nach Kategorie */
|
|
352
|
+
export function getBlocksByCategory() {
|
|
353
|
+
const categories = {
|
|
354
|
+
content: [],
|
|
355
|
+
media: [],
|
|
356
|
+
layout: [],
|
|
357
|
+
monetization: []
|
|
358
|
+
};
|
|
359
|
+
for (const block of blockRegistry) {
|
|
360
|
+
categories[block.category].push(block);
|
|
361
|
+
}
|
|
362
|
+
return categories;
|
|
363
|
+
}
|
|
364
|
+
/** Erstellt einen neuen Block mit Default-Werten */
|
|
365
|
+
export function createBlockFromDefinition(type) {
|
|
366
|
+
const def = getBlockDefinition(type);
|
|
367
|
+
if (!def)
|
|
368
|
+
return undefined;
|
|
369
|
+
return {
|
|
370
|
+
id: `block-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`,
|
|
371
|
+
type,
|
|
372
|
+
...def.defaults
|
|
373
|
+
};
|
|
374
|
+
}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,43 +1,161 @@
|
|
|
1
|
-
export interface
|
|
2
|
-
|
|
1
|
+
export interface Page {
|
|
2
|
+
/** Eindeutige ID (für D1 Storage) */
|
|
3
|
+
id: string;
|
|
4
|
+
/** URL-Slug */
|
|
5
|
+
slug: string;
|
|
6
|
+
/** Seitentitel (H1 und <title>) */
|
|
7
|
+
title: string;
|
|
8
|
+
/** Meta Description für SEO */
|
|
9
|
+
description?: string;
|
|
10
|
+
/** Parent-Slug für Hierarchie */
|
|
11
|
+
parent?: string;
|
|
12
|
+
/** Icon (Emoji) für Navigation */
|
|
13
|
+
icon?: string;
|
|
14
|
+
/** Reihenfolge in Navigation */
|
|
15
|
+
order?: number;
|
|
16
|
+
/** In Navigation anzeigen? */
|
|
17
|
+
showInNav?: boolean;
|
|
18
|
+
/** Kurzname für Navigation */
|
|
19
|
+
navTitle?: string;
|
|
20
|
+
/** Die Inhalte */
|
|
21
|
+
blocks: Block[];
|
|
22
|
+
/** Metadata */
|
|
23
|
+
createdAt?: string;
|
|
24
|
+
updatedAt?: string;
|
|
25
|
+
}
|
|
26
|
+
export interface BaseBlock {
|
|
27
|
+
/** Eindeutige Block-ID */
|
|
28
|
+
id: string;
|
|
29
|
+
/** Block-Typ */
|
|
30
|
+
type: string;
|
|
31
|
+
}
|
|
32
|
+
/** Markdown Block - Der wichtigste Block */
|
|
33
|
+
export interface MarkdownBlock extends BaseBlock {
|
|
34
|
+
type: 'markdown';
|
|
35
|
+
/** Markdown Content */
|
|
3
36
|
content: string;
|
|
4
37
|
}
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
38
|
+
/** Heading Block */
|
|
39
|
+
export interface HeadingBlock extends BaseBlock {
|
|
40
|
+
type: 'heading';
|
|
41
|
+
/** Überschrift-Text */
|
|
8
42
|
text: string;
|
|
43
|
+
/** Level: 1-6 */
|
|
44
|
+
level: 1 | 2 | 3 | 4 | 5 | 6;
|
|
9
45
|
}
|
|
10
|
-
|
|
11
|
-
|
|
46
|
+
/** Image Block */
|
|
47
|
+
export interface ImageBlock extends BaseBlock {
|
|
48
|
+
type: 'image';
|
|
49
|
+
/** Bild-URL (R2 oder extern) */
|
|
12
50
|
src: string;
|
|
51
|
+
/** Alt-Text */
|
|
13
52
|
alt?: string;
|
|
53
|
+
/** Bildunterschrift */
|
|
54
|
+
caption?: string;
|
|
14
55
|
}
|
|
15
|
-
|
|
16
|
-
|
|
56
|
+
/** Quote Block */
|
|
57
|
+
export interface QuoteBlock extends BaseBlock {
|
|
58
|
+
type: 'quote';
|
|
59
|
+
/** Zitat-Text (kann Markdown sein) */
|
|
17
60
|
content: string;
|
|
61
|
+
/** Quelle/Autor */
|
|
62
|
+
source?: string;
|
|
18
63
|
}
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
author?: string;
|
|
64
|
+
/** Divider Block */
|
|
65
|
+
export interface DividerBlock extends BaseBlock {
|
|
66
|
+
type: 'divider';
|
|
23
67
|
}
|
|
24
|
-
|
|
25
|
-
|
|
68
|
+
/** Note/Callout Block */
|
|
69
|
+
export interface NoteBlock extends BaseBlock {
|
|
70
|
+
type: 'note';
|
|
71
|
+
/** Inhalt (kann Markdown sein) */
|
|
72
|
+
content: string;
|
|
73
|
+
/** Variante */
|
|
74
|
+
variant: 'info' | 'warning' | 'tip' | 'danger';
|
|
75
|
+
}
|
|
76
|
+
/** FAQ Block */
|
|
77
|
+
export interface FaqBlock extends BaseBlock {
|
|
78
|
+
type: 'faq';
|
|
79
|
+
/** Optionaler Titel */
|
|
80
|
+
title?: string;
|
|
81
|
+
/** FAQ-Einträge */
|
|
82
|
+
items: FaqItem[];
|
|
26
83
|
}
|
|
27
|
-
export interface
|
|
28
|
-
|
|
29
|
-
|
|
84
|
+
export interface FaqItem {
|
|
85
|
+
/** Frage */
|
|
86
|
+
q: string;
|
|
87
|
+
/** Antwort (Markdown) */
|
|
88
|
+
a: string;
|
|
30
89
|
}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
90
|
+
/** HowTo/Steps Block */
|
|
91
|
+
export interface HowToBlock extends BaseBlock {
|
|
92
|
+
type: 'howto';
|
|
93
|
+
/** Optionaler Titel */
|
|
94
|
+
title?: string;
|
|
95
|
+
/** Schritte */
|
|
96
|
+
steps: HowToStep[];
|
|
34
97
|
}
|
|
35
98
|
export interface HowToStep {
|
|
99
|
+
/** Schritt-Titel */
|
|
36
100
|
title: string;
|
|
101
|
+
/** Beschreibung (Markdown) */
|
|
37
102
|
description: string;
|
|
38
103
|
}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
104
|
+
/** Hero Block */
|
|
105
|
+
export interface HeroBlock extends BaseBlock {
|
|
106
|
+
type: 'hero';
|
|
107
|
+
/** Haupttitel */
|
|
108
|
+
title: string;
|
|
109
|
+
/** Untertitel */
|
|
110
|
+
subtitle?: string;
|
|
111
|
+
}
|
|
112
|
+
/** Children Block - Zeigt Kind-Seiten */
|
|
113
|
+
export interface ChildrenBlock extends BaseBlock {
|
|
114
|
+
type: 'children';
|
|
115
|
+
/** Optionaler Titel */
|
|
116
|
+
title?: string;
|
|
117
|
+
/** Anzahl Spalten */
|
|
118
|
+
columns?: 2 | 3 | 4;
|
|
119
|
+
}
|
|
120
|
+
/** Link List Block */
|
|
121
|
+
export interface LinksBlock extends BaseBlock {
|
|
122
|
+
type: 'links';
|
|
123
|
+
/** Optionaler Titel */
|
|
124
|
+
title?: string;
|
|
125
|
+
/** Links */
|
|
126
|
+
items: LinkItem[];
|
|
127
|
+
}
|
|
128
|
+
export interface LinkItem {
|
|
129
|
+
/** Link-Text */
|
|
130
|
+
label: string;
|
|
131
|
+
/** URL */
|
|
132
|
+
href: string;
|
|
133
|
+
/** Icon (Emoji) */
|
|
134
|
+
icon?: string;
|
|
135
|
+
}
|
|
136
|
+
/** Breadcrumb Block */
|
|
137
|
+
export interface BreadcrumbBlock extends BaseBlock {
|
|
138
|
+
type: 'breadcrumb';
|
|
139
|
+
}
|
|
140
|
+
/** Affiliate Block */
|
|
141
|
+
export interface AffiliateBlock extends BaseBlock {
|
|
142
|
+
type: 'affiliate';
|
|
143
|
+
/** Referenz zum Affiliate */
|
|
144
|
+
ref?: string;
|
|
145
|
+
/** Darstellung */
|
|
146
|
+
variant?: 'inline' | 'box' | 'sticky' | 'floating';
|
|
147
|
+
}
|
|
148
|
+
/** Ad Block */
|
|
149
|
+
export interface AdBlock extends BaseBlock {
|
|
150
|
+
type: 'ad';
|
|
151
|
+
/** Slot-ID */
|
|
152
|
+
slot?: string;
|
|
153
|
+
/** Darstellung */
|
|
154
|
+
variant?: 'inline' | 'banner' | 'sidebar';
|
|
42
155
|
}
|
|
43
|
-
export type Block =
|
|
156
|
+
export type Block = MarkdownBlock | HeadingBlock | ImageBlock | QuoteBlock | DividerBlock | NoteBlock | FaqBlock | HowToBlock | HeroBlock | ChildrenBlock | LinksBlock | BreadcrumbBlock | AffiliateBlock | AdBlock;
|
|
157
|
+
export type BlockType = Block['type'];
|
|
158
|
+
export declare function createBlock<T extends Block>(type: T['type'], data: Omit<T, 'id' | 'type'>): T;
|
|
159
|
+
export declare function createPage(data: Omit<Page, 'id' | 'blocks' | 'createdAt' | 'updatedAt'> & {
|
|
160
|
+
blocks?: Block[];
|
|
161
|
+
}): Page;
|
package/dist/types.js
CHANGED
|
@@ -1,4 +1,30 @@
|
|
|
1
|
-
//
|
|
2
|
-
//
|
|
3
|
-
//
|
|
4
|
-
|
|
1
|
+
// =============================================================================
|
|
2
|
+
// CSM-RUNTIME TYPES
|
|
3
|
+
// =============================================================================
|
|
4
|
+
// Zentrale Type-Definitionen für Content Blocks
|
|
5
|
+
// Wird von Editor UND Website-Framework genutzt
|
|
6
|
+
// =============================================================================
|
|
7
|
+
// -----------------------------------------------------------------------------
|
|
8
|
+
// HELPER: Block erstellen mit Auto-ID
|
|
9
|
+
// -----------------------------------------------------------------------------
|
|
10
|
+
let blockIdCounter = 0;
|
|
11
|
+
export function createBlock(type, data) {
|
|
12
|
+
return {
|
|
13
|
+
id: `block-${Date.now()}-${++blockIdCounter}`,
|
|
14
|
+
type,
|
|
15
|
+
...data
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
// -----------------------------------------------------------------------------
|
|
19
|
+
// HELPER: Page erstellen
|
|
20
|
+
// -----------------------------------------------------------------------------
|
|
21
|
+
export function createPage(data) {
|
|
22
|
+
const now = new Date().toISOString();
|
|
23
|
+
return {
|
|
24
|
+
id: `page-${Date.now()}`,
|
|
25
|
+
blocks: [],
|
|
26
|
+
createdAt: now,
|
|
27
|
+
updatedAt: now,
|
|
28
|
+
...data
|
|
29
|
+
};
|
|
30
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@schneiderelli/cms-runtime",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.4",
|
|
4
|
+
"description": "Content System Manager Runtime - Shared types and components for CMS editor and website framework",
|
|
4
5
|
"scripts": {
|
|
5
6
|
"dev": "vite dev",
|
|
6
7
|
"build": "vite build && npm run prepack",
|
package/dist/resolve.d.ts
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import TextBlock from "./components/blocks/TextBlock.svelte";
|
|
2
|
-
import HeadingBlock from "./components/blocks/HeadingBlock.svelte";
|
|
3
|
-
import ImageBlock from "./components/blocks/ImageBlock.svelte";
|
|
4
|
-
export declare const BlockRegistry: {
|
|
5
|
-
text: import("svelte").Component<{
|
|
6
|
-
block: TextBlock;
|
|
7
|
-
}, {}, "">;
|
|
8
|
-
heading: import("svelte").Component<{
|
|
9
|
-
block: HeadingBlock;
|
|
10
|
-
}, {}, "">;
|
|
11
|
-
image: import("svelte").Component<{
|
|
12
|
-
block: ImageBlock;
|
|
13
|
-
}, {}, "">;
|
|
14
|
-
};
|
|
15
|
-
export declare const resolveBlockComponent: (block: any) => any;
|
package/dist/resolve.js
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import TextBlock from "./components/blocks/TextBlock.svelte";
|
|
2
|
-
import HeadingBlock from "./components/blocks/HeadingBlock.svelte";
|
|
3
|
-
import ImageBlock from "./components/blocks/ImageBlock.svelte";
|
|
4
|
-
export const BlockRegistry = {
|
|
5
|
-
text: TextBlock,
|
|
6
|
-
heading: HeadingBlock,
|
|
7
|
-
image: ImageBlock
|
|
8
|
-
};
|
|
9
|
-
export const resolveBlockComponent = (block) => {
|
|
10
|
-
const Component = BlockRegistry[block.type];
|
|
11
|
-
if (!Component) {
|
|
12
|
-
throw new Error(`Unknown block type: ${block.type}`);
|
|
13
|
-
}
|
|
14
|
-
return Component;
|
|
15
|
-
};
|