@blockslides/ai-context 0.1.6 → 0.3.0

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.
Files changed (50) hide show
  1. package/dist/index.cjs +1453 -287
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.d.cts +3522 -163
  4. package/dist/index.d.ts +3522 -163
  5. package/dist/index.js +1451 -284
  6. package/dist/index.js.map +1 -1
  7. package/package.json +1 -1
  8. package/src/bundles/v1/all.ts +0 -1
  9. package/src/bundles/v1/allContexts.ts +1 -1
  10. package/src/bundles/v1/minimalCreate.ts +2 -2
  11. package/src/contexts/v1/blockquote.ts +10 -5
  12. package/src/contexts/v1/bulletList.ts +10 -5
  13. package/src/contexts/v1/codeBlock.ts +11 -3
  14. package/src/contexts/v1/column.ts +34 -14
  15. package/src/contexts/v1/columnGroup.ts +44 -0
  16. package/src/contexts/v1/core.ts +24 -4
  17. package/src/contexts/v1/editingRules.ts +5 -5
  18. package/src/contexts/v1/heading.ts +11 -4
  19. package/src/contexts/v1/horizontalRule.ts +9 -4
  20. package/src/contexts/v1/imageBlock.ts +31 -22
  21. package/src/contexts/v1/index.ts +1 -1
  22. package/src/contexts/v1/paragraph.ts +11 -5
  23. package/src/contexts/v1/slide.ts +5 -1
  24. package/src/contexts/v1/youtube.ts +14 -7
  25. package/src/index.ts +1 -3
  26. package/src/schemas/v1/blockquote.schema.json +13 -2
  27. package/src/schemas/v1/bulletList.schema.json +13 -2
  28. package/src/schemas/v1/codeBlock.schema.json +12 -3
  29. package/src/schemas/v1/column.schema.json +18 -14
  30. package/src/schemas/v1/columnGroup.schema.json +45 -0
  31. package/src/schemas/v1/heading.schema.json +12 -7
  32. package/src/schemas/v1/horizontalRule.schema.json +7 -2
  33. package/src/schemas/v1/imageBlock.schema.json +25 -15
  34. package/src/schemas/v1/index.ts +1 -1
  35. package/src/schemas/v1/paragraph.schema.json +13 -2
  36. package/src/schemas/v1/slide.schema.json +6 -0
  37. package/src/schemas/v1/youtube.schema.json +9 -6
  38. package/src/templates/v1/index.ts +2 -0
  39. package/src/templates/v1/presetTemplateBuilder.ts +697 -0
  40. package/src/templates/v1/schemaBuilder.ts +604 -0
  41. package/src/types/v1.ts +40 -25
  42. package/src/contexts/v1/row.ts +0 -25
  43. package/src/examples/v1/flyers.ts +0 -30
  44. package/src/examples/v1/index.ts +0 -4
  45. package/src/examples/v1/slides.ts +0 -31
  46. package/src/recipes/v1/addTwoColumns.ts +0 -13
  47. package/src/recipes/v1/createSlide.ts +0 -29
  48. package/src/recipes/v1/editImageToCover.ts +0 -13
  49. package/src/recipes/v1/index.ts +0 -5
  50. package/src/schemas/v1/row.schema.json +0 -29
package/dist/index.cjs CHANGED
@@ -20,11 +20,10 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/index.ts
21
21
  var index_exports = {};
22
22
  __export(index_exports, {
23
- bundlesV1: () => v1_exports4,
23
+ bundlesV1: () => v1_exports3,
24
24
  contextsV1: () => v1_exports,
25
- examplesV1: () => v1_exports2,
26
- recipesV1: () => v1_exports5,
27
- schemasV1: () => v1_exports3
25
+ schemasV1: () => v1_exports2,
26
+ templatesV1: () => v1_exports4
28
27
  });
29
28
  module.exports = __toCommonJS(index_exports);
30
29
 
@@ -35,6 +34,7 @@ __export(v1_exports, {
35
34
  bulletList: () => bulletList,
36
35
  codeBlock: () => codeBlock,
37
36
  column: () => column,
37
+ columnGroup: () => columnGroup,
38
38
  core: () => core,
39
39
  editingRules: () => editingRules,
40
40
  fullDocument: () => fullDocument,
@@ -44,7 +44,6 @@ __export(v1_exports, {
44
44
  image: () => image,
45
45
  imageBlock: () => imageBlock,
46
46
  paragraph: () => paragraph,
47
- row: () => row,
48
47
  sizing: () => sizing,
49
48
  slide: () => slide,
50
49
  style: () => style,
@@ -58,15 +57,35 @@ You are given a BlockSlides document to CREATE or EDIT.
58
57
 
59
58
  Document shape:
60
59
  - doc: { type: "doc", content: slide[] }
61
- - slide: { type: "slide", attrs?, content: row[] }
62
- - row: { type: "row", attrs?, content: column[] | block[] }
63
- - column: { type: "column", attrs?, content: (block | row)[] }
64
- - block: includes nodes like paragraph, heading, imageBlock, etc.
60
+ - slide: { type: "slide", attrs?, content: block[] }
61
+ - block: includes heading, paragraph, column, imageBlock, bulletList, codeBlock, blockquote, horizontalRule, youtube, etc.
62
+ - column: { type: "column", attrs?, content: block[] }
63
+
64
+ Key changes:
65
+ - Slides can contain columns, columnGroups, or any block-level content
66
+ - Use column directly in slide for full-width blocks
67
+ - Use columnGroup to place multiple columns side-by-side
68
+ - All block types inherit common attributes from BaseBlockAttributes
69
+
70
+ BaseBlockAttributes (available on all blocks):
71
+ - align: "left" | "center" | "right" | "stretch"
72
+ - justify: "start" | "center" | "end" | "space-between" (for containers)
73
+ - padding: "none" | "sm" | "md" | "lg"
74
+ - margin: "none" | "sm" | "md" | "lg"
75
+ - gap: "none" | "sm" | "md" | "lg"
76
+ - backgroundColor: string (CSS color)
77
+ - backgroundImage: string (URL)
78
+ - borderRadius: "none" | "sm" | "md" | "lg"
79
+ - border: string (CSS border)
80
+ - fill: boolean (fill available space)
81
+ - width: string (CSS width)
82
+ - height: string (CSS height)
65
83
 
66
84
  Rules:
67
85
  - Use only known node types and valid attrs. Do not invent attributes.
68
86
  - Prefer stable references: preserve slide.attrs.id if present.
69
87
  - Slides and flyers share the same JSON; flyers are slides sized via attrs and theme.
88
+ - Use semantic spacing tokens (sm/md/lg) instead of raw pixel values
70
89
  </core>
71
90
  `.trim();
72
91
 
@@ -81,79 +100,129 @@ Output contract:
81
100
  // src/contexts/v1/imageBlock.ts
82
101
  var imageBlock = `
83
102
  <imageBlock>
84
- Node: imageBlock
85
- Attrs:
86
- - src (required): string (URL)
87
- - alt (optional): string
88
- - caption (optional): string
89
- - credit (optional): string
90
- - layout (optional): "cover" | "contain" | "fill" | "focus" | "pattern"
91
- - align (optional): "left" | "center" | "right" | "stretch" (default "center")
92
- - width (optional): number (px) or string ("%"/"px")
93
- - height (optional): number (px) or string ("%"/"px")
94
- - fullBleed (optional): boolean (removes radius; stretches width)
95
- - assetId (optional): string
96
- - focalX, focalY (optional): 0\u2013100; spotlight position (when relevant)
97
-
98
- Behavior:
99
- - Numbers for width/height are interpreted as pixels.
100
- - layout:
101
- - cover: Fill container; crop edges as needed.
102
- - contain: Fit entirely; may letterbox.
103
- - fill: Stretch to container (may distort).
104
- - focus: Cover + radial spotlight at focalX/focalY.
105
- - pattern: Hide <img>; use tiled background (from src).
106
- - Do not set unknown attributes. Preserve existing valid attrs.
107
- </imageBlock>
108
- `.trim();
109
-
110
- // src/contexts/v1/row.ts
111
- var row = `
112
- <row>
113
- Node: row
114
- Attrs:
115
- - layout (optional): "", "1", "1-1", "2-1", "1-2", "1-1-1", "2-1-1", "1-2-1", "1-1-2", "1-1-1-1"
116
- - className (optional): string (CSS classes)
117
- - backgroundMode (optional): "none" | "color" | "image" | "imageOverlay"
118
- - backgroundColor (optional): string (CSS color for row background)
119
- - backgroundImage (optional): string (URL for row-level background image)
120
- - backgroundOverlayColor (optional): string (overlay color when using imageOverlay)
121
- - backgroundOverlayOpacity (optional): number (0\u20131, overlay opacity)
103
+ Node: imageBlock (block group)
104
+ Attrs (required):
105
+ - src (required): string (image URL)
106
+
107
+ Attrs (optional - image-specific):
108
+ - alt (optional): string - alt text for accessibility
109
+ - caption (optional): string - image caption
110
+ - credit (optional): string - image credit/attribution
111
+ - assetId (optional): string - asset reference
112
+ - size (optional): "fill" | "fit" | "natural" - how image fills container
113
+ - fill: Cover entire container (width:100%, height:100%, object-fit:cover)
114
+ - fit: Fit inside container with letterboxing (object-fit:contain)
115
+ - natural: Use image's natural dimensions
116
+ - crop (optional): "center" | "top" | "bottom" | "left" | "right" | "top-left" | "top-right" | "bottom-left" | "bottom-right"
117
+ - Focal point for fill/fit modes (default: "center")
118
+
119
+ Attrs (inherited from BaseBlockAttributes):
120
+ - align (optional): "left" | "center" | "right" | "stretch" - block alignment
121
+ - padding (optional): "none" | "sm" | "md" | "lg" - internal padding
122
+ - margin (optional): "none" | "sm" | "md" | "lg" - external margin
123
+ - backgroundColor (optional): string - background color
124
+ - borderRadius (optional): "none" | "sm" | "md" | "lg" - corner rounding
125
+ - width (optional): string - explicit width override (CSS value)
126
+ - height (optional): string - explicit height override (CSS value)
127
+
128
+ Deprecated attributes (kept for backwards compatibility, do not use):
129
+ - layout, fullBleed, focalX, focalY
122
130
 
123
- Semantics:
124
- - Fractions determine relative column flex:
125
- - 1-1: two equal columns
126
- - 2-1: first column is double width
127
- - 1-2: second column is double width
128
- - 1-1-1: three equal columns
129
- - 1-1-1-1: four equal columns
130
- - Empty layout ("", "1") acts as a single full-width column.
131
- - Use row backgrounds for horizontal bands (e.g., header strip) instead of attaching everything to the slide.
132
- </row>
131
+ Notes:
132
+ - Default size is "fill" if not specified
133
+ - Use crop to control which part of the image is visible when cropped
134
+ - width/height overrides apply on top of size mode
135
+ </imageBlock>
133
136
  `.trim();
134
137
 
135
138
  // src/contexts/v1/column.ts
136
139
  var column = `
137
140
  <column>
138
- Node: column
139
- Attrs:
140
- - className (optional): string
141
- - contentMode (optional): "default" (future-friendly)
142
- - verticalAlign (optional): "top" | "center" | "bottom" (default "top")
143
- - horizontalAlign (optional): "left" | "center" | "right" | "stretch" (default "left")
144
- - padding (optional): "none" (future-friendly)
145
- - backgroundMode (optional): "none" | "color" | "image" | "imageOverlay"
146
- - backgroundColor (optional): string (CSS color for the column background)
147
- - backgroundImage (optional): string (URL for column-level background image)
148
- - backgroundOverlayColor (optional): string (overlay color when using imageOverlay)
149
- - backgroundOverlayOpacity (optional): number (0\u20131, overlay opacity)
141
+ Node: column (block group)
142
+ Attrs (inherits from BaseBlockAttributes):
143
+ - align (optional): "left" | "center" | "right" | "stretch" - horizontal alignment
144
+ - justify (optional): "start" | "center" | "end" | "space-between" - vertical distribution of children
145
+ - padding (optional): "none" | "sm" | "md" | "lg" - internal spacing (semantic tokens)
146
+ - margin (optional): "none" | "sm" | "md" | "lg" - external spacing
147
+ - gap (optional): "none" | "sm" | "md" | "lg" - space between child blocks
148
+ - backgroundColor (optional): string - CSS color
149
+ - backgroundImage (optional): string - background image URL
150
+ - borderRadius (optional): "none" | "sm" | "md" | "lg" - corner rounding
151
+ - border (optional): string - CSS border value
152
+ - fill (optional): boolean - whether to fill available space
153
+ - width (optional): string - explicit width (CSS value)
154
+ - height (optional): string - explicit height (CSS value)
155
+
156
+ Content:
157
+ - Contains one or more blocks (heading, paragraph, imageBlock, bulletList, etc.)
158
+ - Columns cannot nest other columns
159
+
160
+ Spacing tokens:
161
+ - none: 0
162
+ - sm: 8px
163
+ - md: 16px
164
+ - lg: 32px
165
+
166
+ Border radius tokens:
167
+ - none: 0
168
+ - sm: 4px
169
+ - md: 8px
170
+ - lg: 16px
150
171
 
151
172
  Notes:
152
- - Use className for spacing, colors, typography (e.g., Tailwind).
153
- - Keep nesting shallow; columns can contain rows or blocks as needed.
173
+ - Use column directly in slide for full-width content
174
+ - Wrap columns in columnGroup to place them side-by-side
175
+ - Use justify to control vertical distribution of child blocks
176
+ - Use gap for spacing between children instead of margins
154
177
  </column>
155
178
  `.trim();
156
179
 
180
+ // src/contexts/v1/columnGroup.ts
181
+ var columnGroup = `
182
+ <columnGroup>
183
+ Node: columnGroup (horizontal container)
184
+ Purpose: Groups multiple columns side-by-side horizontally
185
+
186
+ Attrs:
187
+ - layout (optional): string - Layout ratio for columns (e.g., "1-1" for equal width, "2-1" for 2:1 ratio, "1-2-1" for three columns)
188
+ - fill (optional): boolean - Whether the columnGroup fills available vertical space
189
+ - className (optional): string - CSS classes
190
+ - backgroundMode (optional): "none" | "color" | "image" | "imageOverlay"
191
+ - backgroundColor (optional): string - CSS color for background
192
+ - backgroundImage (optional): string - URL for background image
193
+ - backgroundOverlayColor (optional): string - Color for overlay when using imageOverlay
194
+ - backgroundOverlayOpacity (optional): number (0-1) - Opacity for overlay
195
+
196
+ Content:
197
+ - Contains one or more column nodes
198
+ - Columns within a columnGroup are displayed side-by-side horizontally
199
+ - Each column shares the horizontal space (equal width by default, or based on layout attribute)
200
+
201
+ Usage:
202
+ - Use columnGroup when you want columns to appear next to each other horizontally
203
+ - For full-width content, use column directly in the slide (without columnGroup)
204
+ - You can have multiple columnGroups in a slide to create different rows of columns
205
+
206
+ Examples:
207
+ 1. Two equal columns side-by-side:
208
+ columnGroup { content: [column, column] }
209
+
210
+ 2. Three columns with 2:1:1 ratio:
211
+ columnGroup { attrs: { layout: "2-1-1" }, content: [column, column, column] }
212
+
213
+ 3. Full-width content above and below a two-column section:
214
+ slide {
215
+ content: [
216
+ column { ... }, // full-width
217
+ columnGroup { // side-by-side
218
+ content: [column, column]
219
+ },
220
+ column { ... } // full-width
221
+ ]
222
+ }
223
+ </columnGroup>
224
+ `.trim();
225
+
157
226
  // src/contexts/v1/slide.ts
158
227
  var slide = `
159
228
  <slide>
@@ -169,12 +238,16 @@ Attrs:
169
238
  - backgroundOverlayOpacity (optional): number (0\u20131, opacity for the overlay)
170
239
 
171
240
  Content:
172
- - slide contains one or more rows.
241
+ - slide can contain columns, columnGroups, or any block-level content (heading, paragraph, imageBlock, bulletList, codeBlock, etc.)
242
+ - Use column directly for full-width content
243
+ - Use columnGroup to place multiple columns side-by-side
244
+ - You can mix columns, columnGroups, and other blocks in any order
173
245
 
174
246
  Notes:
175
247
  - Flyers are slides sized for paper (e.g., size: "a4-portrait").
176
248
  - Set size to control canvas dimensions; theme applies the exact width/height.
177
249
  - For background images, prefer backgroundMode/backgroundImage over Tailwind bg-[url(...)]; the extension will inject the correct CSS.
250
+ - To create multi-column layouts, wrap columns in a columnGroup
178
251
  </slide>
179
252
  `.trim();
180
253
 
@@ -194,7 +267,7 @@ var editingRules = `
194
267
  - Preserve existing ids and valid attributes. Do not remove or rename known attrs.
195
268
  - Use only allowed enum values. Do not invent new enum values.
196
269
  - Avoid introducing new attributes that are not documented. If styling is needed, prefer className.
197
- - Keep the document valid: slide > row > column > blocks.
270
+ - Keep the document valid: slide > (column | columnGroup > column) > blocks.
198
271
  </General editing rules>
199
272
 
200
273
  <Centering content in a column>
@@ -208,17 +281,17 @@ var editingRules = `
208
281
  - After: column.attrs = { verticalAlign: "center", horizontalAlign: "center", padding: "none" }
209
282
  </Centering content in a column>
210
283
 
211
- <Backgrounds (slides, rows, columns)>
284
+ <Backgrounds (slides, columnGroups, columns)>
212
285
  - Use structured background attrs instead of raw Tailwind bg-[url(...)] when setting background images.
213
286
  - If you use bg-[...], the image will not work because the tailwind classes we need have been tree shaken off - instead use the attributes.
214
287
  - For slide-level backgrounds (hero/flyer):
215
288
  - Use slide.attrs.backgroundMode = "color" | "image" | "imageOverlay".
216
289
  - For images, set slide.attrs.backgroundImage to the image URL.
217
290
  - For overlays, set slide.attrs.backgroundOverlayColor (e.g., "rgba(0,0,0,0.8)") and slide.attrs.backgroundOverlayOpacity (0\u20131).
218
- - For horizontal bands, use row-level backgrounds (row.attrs.background*).
291
+ - For horizontal bands, use columnGroup-level backgrounds (columnGroup.attrs.background*).
219
292
  - For panel-style sections, use column-level backgrounds (column.attrs.background*).
220
- - Do not mix multiple background images on the same node; prefer one backgroundMode per slide/row/column and layer additional visuals as imageBlock nodes.
221
- </Backgrounds (slides, rows, columns)>
293
+ - Do not mix multiple background images on the same node; prefer one backgroundMode per slide/columnGroup/column and layer additional visuals as imageBlock nodes.
294
+ </Backgrounds (slides, columnGroups, columns)>
222
295
 
223
296
  <Text editing (headings and paragraphs)>
224
297
  - Preserve semantic types: do not turn headings into paragraphs or vice versa unless explicitly asked.
@@ -253,42 +326,60 @@ Sizing
253
326
  // src/contexts/v1/blockquote.ts
254
327
  var blockquote = `
255
328
  <blockquote>
256
- Node: blockquote
257
- Attrs:
258
- - HTML-only; no required JSON attrs beyond optional styling such as className.
329
+ Node: blockquote (block group)
330
+ Attrs (inherited from BaseBlockAttributes):
331
+ - align: "left" | "center" | "right"
332
+ - padding: "none" | "sm" | "md" | "lg"
333
+ - margin: "none" | "sm" | "md" | "lg"
334
+ - backgroundColor: string (CSS color)
335
+ - borderRadius: "none" | "sm" | "md" | "lg"
336
+ - (and other base attributes)
259
337
 
260
338
  Content:
261
339
  - One or more block nodes (typically paragraphs, headings, lists).
262
340
 
263
341
  Semantics:
264
- - Use for quoted text or callouts inside a column or row.
265
- - Styling should be applied via className on the surrounding column/slide, not by inventing new attrs here.
342
+ - Use for quoted text or callouts inside a column or slide.
343
+ - BaseBlockAttributes provide consistent styling capabilities.
266
344
  </blockquote>
267
345
  `.trim();
268
346
 
269
347
  // src/contexts/v1/bulletList.ts
270
348
  var bulletList = `
271
349
  <bulletList>
272
- Node: bulletList
273
- Attrs:
274
- - HTML-only; no required JSON attrs beyond optional styling such as className.
350
+ Node: bulletList (block group)
351
+ Attrs (inherited from BaseBlockAttributes):
352
+ - align: "left" | "center" | "right"
353
+ - padding: "none" | "sm" | "md" | "lg"
354
+ - margin: "none" | "sm" | "md" | "lg"
355
+ - backgroundColor: string (CSS color)
356
+ - borderRadius: "none" | "sm" | "md" | "lg"
357
+ - (and other base attributes)
275
358
 
276
359
  Content:
277
360
  - One or more list item nodes (listItem) that contain paragraphs or inline content.
278
361
 
279
362
  Semantics:
280
363
  - Represents an unordered list rendered as <ul>.
281
- - Use when you need bullet points inside a column or blockquote.
282
- - Do not use bulletList as a top-level child of doc; it belongs inside a column/row structure.
364
+ - Use when you need bullet points inside a column or slide.
365
+ - Can be placed directly in slides or within columns.
283
366
  </bulletList>
284
367
  `.trim();
285
368
 
286
369
  // src/contexts/v1/codeBlock.ts
287
370
  var codeBlock = `
288
371
  <codeBlock>
289
- Node: codeBlock
290
- Attrs:
291
- - language (optional): string | null (e.g., "js", "ts", "python").
372
+ Node: codeBlock (block group)
373
+ Attrs (codeBlock-specific):
374
+ - language (optional): string | null (e.g., "js", "ts", "python")
375
+
376
+ Attrs (inherited from BaseBlockAttributes):
377
+ - align: "left" | "center" | "right"
378
+ - padding: "none" | "sm" | "md" | "lg"
379
+ - margin: "none" | "sm" | "md" | "lg"
380
+ - backgroundColor: string (CSS color)
381
+ - borderRadius: "none" | "sm" | "md" | "lg"
382
+ - (and other base attributes)
292
383
 
293
384
  Content:
294
385
  - Plain text only (no child nodes); used for preformatted code samples.
@@ -319,16 +410,21 @@ Semantics:
319
410
  // src/contexts/v1/horizontalRule.ts
320
411
  var horizontalRule = `
321
412
  <horizontalRule>
322
- Node: horizontalRule
323
- Attrs:
324
- - HTML-only; no JSON attrs beyond optional styling via surrounding layout.
413
+ Node: horizontalRule (block group)
414
+ Attrs (inherited from BaseBlockAttributes):
415
+ - align: "left" | "center" | "right" | "stretch"
416
+ - padding: "none" | "sm" | "md" | "lg"
417
+ - margin: "none" | "sm" | "md" | "lg"
418
+ - backgroundColor: string (CSS color)
419
+ - (and other base attributes)
325
420
 
326
421
  Content:
327
422
  - No children; this is a self-contained separator.
328
423
 
329
424
  Semantics:
330
425
  - Renders as <hr>.
331
- - Use to visually separate sections within a slide (for example, between rows of text).
426
+ - Use to visually separate sections within a slide.
427
+ - Can control spacing around the rule with padding/margin.
332
428
  </horizontalRule>
333
429
  `.trim();
334
430
 
@@ -354,9 +450,17 @@ Semantics:
354
450
  // src/contexts/v1/heading.ts
355
451
  var heading = `
356
452
  <heading>
357
- Node: heading
358
- Attrs:
359
- - level (required): 1 | 2 | 3 | 4 | 5 | 6.
453
+ Node: heading (block group)
454
+ Attrs (heading-specific):
455
+ - level (required): 1 | 2 | 3 | 4 | 5 | 6
456
+
457
+ Attrs (inherited from BaseBlockAttributes):
458
+ - align: "left" | "center" | "right"
459
+ - padding: "none" | "sm" | "md" | "lg"
460
+ - margin: "none" | "sm" | "md" | "lg"
461
+ - backgroundColor: string (CSS color)
462
+ - borderRadius: "none" | "sm" | "md" | "lg"
463
+ - (and other base attributes)
360
464
 
361
465
  Content:
362
466
  - Inline content (text, marks, inline nodes).
@@ -364,117 +468,61 @@ Content:
364
468
  Semantics:
365
469
  - Renders as <h1>\u2026<h6> depending on level.
366
470
  - Use level 1\u20132 for main slide titles, 3\u20134 for section headings, 5\u20136 for subtle labels.
367
- - Do not invent other attrs; typography/styling should come from className on columns/slides.
368
471
  </heading>
369
472
  `.trim();
370
473
 
371
474
  // src/contexts/v1/paragraph.ts
372
475
  var paragraph = `
373
476
  <paragraph>
374
- Node: paragraph
375
- Attrs:
376
- - HTML-only; no structured JSON attrs beyond optional styling such as className.
477
+ Node: paragraph (block group)
478
+ Attrs (inherited from BaseBlockAttributes):
479
+ - align: "left" | "center" | "right"
480
+ - padding: "none" | "sm" | "md" | "lg"
481
+ - margin: "none" | "sm" | "md" | "lg"
482
+ - backgroundColor: string (CSS color)
483
+ - borderRadius: "none" | "sm" | "md" | "lg"
484
+ - (and other base attributes)
377
485
 
378
486
  Content:
379
487
  - Inline content (text with marks, inline nodes such as image or hardBreak).
380
488
 
381
489
  Semantics:
382
- - Default text block inside columns and rows.
383
- - Multiple paragraphs can be stacked within the same column to create vertical rhythm.
490
+ - Default text block inside columns and slides.
491
+ - Multiple paragraphs can be stacked to create vertical rhythm.
492
+ - Use gap on parent column instead of margin on individual paragraphs for consistent spacing.
384
493
  </paragraph>
385
494
  `.trim();
386
495
 
387
496
  // src/contexts/v1/youtube.ts
388
497
  var youtube = `
389
498
  <youtube>
390
- Node: youtube
391
- Attrs:
392
- - src (required): string (public YouTube URL).
393
- - start (optional): number (start time in seconds).
394
- - width (optional): number (frame width in px).
395
- - height (optional): number (frame height in px).
499
+ Node: youtube (block group)
500
+ Attrs (youtube-specific):
501
+ - src (required): string (public YouTube URL)
502
+ - start (optional): number (start time in seconds)
503
+ - width (optional): number (frame width in px)
504
+ - height (optional): number (frame height in px)
505
+
506
+ Attrs (inherited from BaseBlockAttributes):
507
+ - align: "left" | "center" | "right" | "stretch"
508
+ - padding: "none" | "sm" | "md" | "lg"
509
+ - margin: "none" | "sm" | "md" | "lg"
510
+ - borderRadius: "none" | "sm" | "md" | "lg"
511
+ - (and other base attributes)
396
512
 
397
513
  Content:
398
514
  - No children; this is an atomic embed node.
399
515
 
400
516
  Semantics:
401
517
  - Renders as an embedded YouTube iframe wrapped in a container <div>.
402
- - Use for video embeds inside a column or row; keep other text in separate paragraphs/columns.
518
+ - Use for video embeds inside a column or slide.
403
519
  - Do not embed raw <iframe> HTML directly; always use the youtube node with attrs.
404
520
  </youtube>
405
521
  `.trim();
406
522
 
407
- // src/examples/v1/index.ts
408
- var v1_exports2 = {};
409
- __export(v1_exports2, {
410
- flyers: () => flyers,
411
- slides: () => slides
412
- });
413
-
414
- // src/examples/v1/slides.ts
415
- var slides = `
416
- Examples: Slides (full-document output)
417
-
418
- {
419
- "type": "doc",
420
- "content": [
421
- {
422
- "type": "slide",
423
- "attrs": { "id": "intro", "size": "16x9" },
424
- "content": [
425
- {
426
- "type": "row",
427
- "attrs": { "layout": "1-1" },
428
- "content": [
429
- { "type": "column", "content": [
430
- { "type": "heading", "attrs": { "level": 2 }, "content": [{ "type": "text", "text": "Welcome" }] }
431
- ]},
432
- { "type": "column", "content": [
433
- { "type": "imageBlock", "attrs": { "src": "https://picsum.photos/seed/welcome/1200/800", "layout": "cover", "align": "center" } }
434
- ]}
435
- ]
436
- }
437
- ]
438
- }
439
- ]
440
- }
441
-
442
- /* more-slide-examples to be added here */
443
- `.trim();
444
-
445
- // src/examples/v1/flyers.ts
446
- var flyers = `
447
- Examples: Flyers (A4 slides; full-document output)
448
-
449
- {
450
- "type": "doc",
451
- "content": [
452
- {
453
- "type": "slide",
454
- "attrs": { "id": "a4-flyer", "size": "a4-portrait", "className": "bg-white text-slate-900" },
455
- "content": [
456
- {
457
- "type": "row",
458
- "attrs": { "layout": "1" },
459
- "content": [
460
- { "type": "column", "content": [
461
- { "type": "heading", "attrs": { "level": 2 }, "content": [{ "type": "text", "text": "Event Title" }] },
462
- { "type": "paragraph", "content": [{ "type": "text", "text": "Date \xB7 Location" }] },
463
- { "type": "imageBlock", "attrs": { "src": "https://picsum.photos/seed/a4/1600/1000", "layout": "contain", "align": "center", "height": 320 } }
464
- ]}
465
- ]
466
- }
467
- ]
468
- }
469
- ]
470
- }
471
-
472
- /* more-flyer-examples to be added here */
473
- `.trim();
474
-
475
523
  // src/bundles/v1/index.ts
476
- var v1_exports4 = {};
477
- __export(v1_exports4, {
524
+ var v1_exports3 = {};
525
+ __export(v1_exports3, {
478
526
  all: () => all,
479
527
  allContexts: () => allContexts,
480
528
  allSchemas: () => allSchemas,
@@ -483,7 +531,7 @@ __export(v1_exports4, {
483
531
  });
484
532
 
485
533
  // src/bundles/v1/minimalCreate.ts
486
- var minimalCreate = [core, fullDocument, slide, row, column, style].join("\n\n");
534
+ var minimalCreate = [core, fullDocument, slide, column, style].join("\n\n");
487
535
 
488
536
  // src/bundles/v1/imageEditing.ts
489
537
  var imageEditing = [core, fullDocument, imageBlock, editingRules].join("\n\n");
@@ -493,7 +541,6 @@ var all = [
493
541
  core,
494
542
  fullDocument,
495
543
  slide,
496
- row,
497
544
  column,
498
545
  style,
499
546
  sizing,
@@ -511,19 +558,19 @@ var all = [
511
558
  ].join("\n\n");
512
559
 
513
560
  // src/schemas/v1/index.ts
514
- var v1_exports3 = {};
515
- __export(v1_exports3, {
561
+ var v1_exports2 = {};
562
+ __export(v1_exports2, {
516
563
  blockquote: () => blockquote_schema_default,
517
564
  bulletList: () => bulletList_schema_default,
518
565
  codeBlock: () => codeBlock_schema_default,
519
566
  column: () => column_schema_default,
567
+ columnGroup: () => columnGroup_schema_default,
520
568
  hardBreak: () => hardBreak_schema_default,
521
569
  heading: () => heading_schema_default,
522
570
  horizontalRule: () => horizontalRule_schema_default,
523
571
  image: () => image_schema_default,
524
572
  imageBlock: () => imageBlock_schema_default,
525
573
  paragraph: () => paragraph_schema_default,
526
- row: () => row_schema_default,
527
574
  slide: () => slide_schema_default,
528
575
  youtube: () => youtube_schema_default
529
576
  });
@@ -532,77 +579,101 @@ __export(v1_exports3, {
532
579
  var imageBlock_schema_default = {
533
580
  $schema: "https://json-schema.org/draft/2020-12/schema",
534
581
  title: "imageBlock",
582
+ description: "An image block with simplified size and crop controls. Also inherits common block attributes.",
535
583
  type: "object",
536
584
  properties: {
537
585
  type: { const: "imageBlock" },
538
586
  attrs: {
539
587
  type: "object",
540
588
  properties: {
541
- src: { type: "string", minLength: 1 },
542
- alt: { type: "string" },
543
- caption: { type: "string" },
544
- credit: { type: "string" },
545
- layout: { enum: ["cover", "contain", "fill", "focus", "pattern", null] },
546
- align: { enum: ["left", "center", "right", "stretch", null] },
547
- width: { type: ["number", "string", "null"] },
548
- height: { type: ["number", "string", "null"] },
549
- fullBleed: { type: "boolean" },
550
- assetId: { type: ["string", "null"] },
551
- focalX: { type: ["number", "null"], minimum: 0, maximum: 100 },
552
- focalY: { type: ["number", "null"], minimum: 0, maximum: 100 }
589
+ src: { type: "string", minLength: 1, description: "Image URL (required)" },
590
+ alt: { type: "string", description: "Alt text for accessibility" },
591
+ caption: { type: "string", description: "Image caption" },
592
+ credit: { type: "string", description: "Image credit/attribution" },
593
+ size: {
594
+ enum: ["fill", "fit", "natural", null],
595
+ description: "How the image fills its container: fill (cover), fit (contain), or natural (original size)"
596
+ },
597
+ crop: {
598
+ enum: ["center", "top", "bottom", "left", "right", "top-left", "top-right", "bottom-left", "bottom-right", null],
599
+ description: "Crop/focus position for fill/fit modes"
600
+ },
601
+ align: { enum: ["left", "center", "right", "stretch", null], description: "Block alignment within parent" },
602
+ padding: { enum: ["none", "sm", "md", "lg", null], description: "Internal padding" },
603
+ backgroundColor: { type: ["string", "null"], description: "Background color" },
604
+ borderRadius: { enum: ["none", "sm", "md", "lg", null], description: "Corner rounding" },
605
+ width: { type: ["string", "null"], description: "Explicit width override" },
606
+ height: { type: ["string", "null"], description: "Explicit height override" },
607
+ assetId: { type: ["string", "null"], description: "Asset ID reference" },
608
+ layout: { enum: ["cover", "contain", "fill", "focus", "pattern", null], description: "DEPRECATED: Use size instead" },
609
+ fullBleed: { type: "boolean", description: "DEPRECATED: Use size='fill' instead" },
610
+ focalX: { type: ["number", "null"], minimum: 0, maximum: 100, description: "DEPRECATED: Use crop instead" },
611
+ focalY: { type: ["number", "null"], minimum: 0, maximum: 100, description: "DEPRECATED: Use crop instead" }
553
612
  },
554
613
  required: ["src"],
555
- additionalProperties: false
614
+ additionalProperties: true
556
615
  }
557
616
  },
558
617
  required: ["type"],
559
618
  additionalProperties: false
560
619
  };
561
620
 
562
- // src/schemas/v1/row.schema.json
563
- var row_schema_default = {
621
+ // src/schemas/v1/column.schema.json
622
+ var column_schema_default = {
564
623
  $schema: "https://json-schema.org/draft/2020-12/schema",
565
- title: "row",
624
+ title: "column",
625
+ description: "A container block that holds other blocks. Common attributes (align, padding, gap, backgroundColor, etc.) are shared with all block types.",
566
626
  type: "object",
567
627
  properties: {
568
- type: { const: "row" },
628
+ type: { const: "column" },
569
629
  attrs: {
570
630
  type: "object",
571
631
  properties: {
572
- layout: {
573
- enum: ["", "1", "1-1", "2-1", "1-2", "1-1-1", "2-1-1", "1-2-1", "1-1-2", "1-1-1-1", null]
574
- },
575
- className: { type: ["string", "null"] },
576
- backgroundMode: {
577
- enum: ["none", "color", "image", "imageOverlay", null]
578
- },
579
- backgroundColor: { type: ["string", "null"] },
580
- backgroundImage: { type: ["string", "null"] },
581
- backgroundOverlayColor: { type: ["string", "null"] },
582
- backgroundOverlayOpacity: { type: ["number", "null"] }
632
+ align: { enum: ["left", "center", "right", "stretch", null], description: "Horizontal alignment of content" },
633
+ justify: { enum: ["start", "center", "end", "space-between", null], description: "Vertical distribution of children" },
634
+ padding: { enum: ["none", "sm", "md", "lg", null], description: "Internal padding" },
635
+ margin: { enum: ["none", "sm", "md", "lg", null], description: "External margin" },
636
+ gap: { enum: ["none", "sm", "md", "lg", null], description: "Gap between child blocks" },
637
+ backgroundColor: { type: ["string", "null"], description: "Background color" },
638
+ backgroundImage: { type: ["string", "null"], description: "Background image URL" },
639
+ borderRadius: { enum: ["none", "sm", "md", "lg", null], description: "Corner rounding" },
640
+ border: { type: ["string", "null"], description: "CSS border value" },
641
+ fill: { type: ["boolean", "null"], description: "Whether to fill available space" },
642
+ width: { type: ["string", "null"], description: "Explicit width" },
643
+ height: { type: ["string", "null"], description: "Explicit height" }
583
644
  },
584
645
  additionalProperties: true
646
+ },
647
+ content: {
648
+ type: "array",
649
+ items: { type: "object" },
650
+ description: "Child blocks"
585
651
  }
586
652
  },
587
653
  required: ["type"],
588
654
  additionalProperties: false
589
655
  };
590
656
 
591
- // src/schemas/v1/column.schema.json
592
- var column_schema_default = {
657
+ // src/schemas/v1/columnGroup.schema.json
658
+ var columnGroup_schema_default = {
593
659
  $schema: "https://json-schema.org/draft/2020-12/schema",
594
- title: "column",
660
+ title: "columnGroup",
661
+ description: "A horizontal container that groups multiple columns side-by-side. Use columnGroup when you want columns to be placed next to each other horizontally. For full-width content, use column directly in the slide.",
595
662
  type: "object",
596
663
  properties: {
597
- type: { const: "column" },
664
+ type: { const: "columnGroup" },
598
665
  attrs: {
599
666
  type: "object",
600
667
  properties: {
668
+ layout: {
669
+ type: ["string", "null"],
670
+ description: "Layout ratio for columns (e.g., '1-1' for equal, '2-1' for 2:1 ratio)"
671
+ },
672
+ fill: {
673
+ type: ["boolean", "null"],
674
+ description: "Whether the columnGroup should fill available vertical space"
675
+ },
601
676
  className: { type: ["string", "null"] },
602
- contentMode: { enum: ["default", null] },
603
- verticalAlign: { enum: ["top", "center", "bottom", null] },
604
- horizontalAlign: { enum: ["left", "center", "right", "stretch", null] },
605
- padding: { enum: ["none", null] },
606
677
  backgroundMode: {
607
678
  enum: ["none", "color", "image", "imageOverlay", null]
608
679
  },
@@ -612,9 +683,21 @@ var column_schema_default = {
612
683
  backgroundOverlayOpacity: { type: ["number", "null"] }
613
684
  },
614
685
  additionalProperties: true
686
+ },
687
+ content: {
688
+ type: "array",
689
+ items: {
690
+ type: "object",
691
+ properties: {
692
+ type: { const: "column" }
693
+ },
694
+ required: ["type"]
695
+ },
696
+ minItems: 1,
697
+ description: "Array of column nodes"
615
698
  }
616
699
  },
617
- required: ["type"],
700
+ required: ["type", "content"],
618
701
  additionalProperties: false
619
702
  };
620
703
 
@@ -622,6 +705,7 @@ var column_schema_default = {
622
705
  var slide_schema_default = {
623
706
  $schema: "https://json-schema.org/draft/2020-12/schema",
624
707
  title: "slide",
708
+ description: "A slide containing blocks directly. Blocks can be any block-level node (heading, paragraph, column, imageBlock, etc.). Adjacent columns automatically form horizontal layouts.",
625
709
  type: "object",
626
710
  properties: {
627
711
  type: { const: "slide" },
@@ -651,6 +735,11 @@ var slide_schema_default = {
651
735
  backgroundOverlayOpacity: { type: ["number", "null"] }
652
736
  },
653
737
  additionalProperties: true
738
+ },
739
+ content: {
740
+ type: "array",
741
+ items: { type: "object" },
742
+ description: "Block-level content (heading, paragraph, column, imageBlock, etc.)"
654
743
  }
655
744
  },
656
745
  required: ["type"],
@@ -661,12 +750,25 @@ var slide_schema_default = {
661
750
  var blockquote_schema_default = {
662
751
  $schema: "https://json-schema.org/draft/2020-12/schema",
663
752
  title: "blockquote",
753
+ description: "A blockquote. Inherits common block attributes.",
664
754
  type: "object",
665
755
  properties: {
666
756
  type: { const: "blockquote" },
667
757
  attrs: {
668
758
  type: "object",
759
+ properties: {
760
+ align: { enum: ["left", "center", "right", null], description: "Text alignment" },
761
+ padding: { enum: ["none", "sm", "md", "lg", null], description: "Internal padding" },
762
+ margin: { enum: ["none", "sm", "md", "lg", null], description: "External margin" },
763
+ backgroundColor: { type: ["string", "null"], description: "Background color" },
764
+ borderRadius: { enum: ["none", "sm", "md", "lg", null], description: "Corner rounding" }
765
+ },
669
766
  additionalProperties: true
767
+ },
768
+ content: {
769
+ type: "array",
770
+ items: { type: "object" },
771
+ description: "Block content"
670
772
  }
671
773
  },
672
774
  required: ["type"],
@@ -677,12 +779,25 @@ var blockquote_schema_default = {
677
779
  var bulletList_schema_default = {
678
780
  $schema: "https://json-schema.org/draft/2020-12/schema",
679
781
  title: "bulletList",
782
+ description: "A bullet list block. Inherits common block attributes.",
680
783
  type: "object",
681
784
  properties: {
682
785
  type: { const: "bulletList" },
683
786
  attrs: {
684
787
  type: "object",
788
+ properties: {
789
+ align: { enum: ["left", "center", "right", null], description: "Text alignment" },
790
+ padding: { enum: ["none", "sm", "md", "lg", null], description: "Internal padding" },
791
+ margin: { enum: ["none", "sm", "md", "lg", null], description: "External margin" },
792
+ backgroundColor: { type: ["string", "null"], description: "Background color" },
793
+ borderRadius: { enum: ["none", "sm", "md", "lg", null], description: "Corner rounding" }
794
+ },
685
795
  additionalProperties: true
796
+ },
797
+ content: {
798
+ type: "array",
799
+ items: { type: "object" },
800
+ description: "List items"
686
801
  }
687
802
  },
688
803
  required: ["type"],
@@ -693,15 +808,26 @@ var bulletList_schema_default = {
693
808
  var codeBlock_schema_default = {
694
809
  $schema: "https://json-schema.org/draft/2020-12/schema",
695
810
  title: "codeBlock",
811
+ description: "A code block. Inherits common block attributes.",
696
812
  type: "object",
697
813
  properties: {
698
814
  type: { const: "codeBlock" },
699
815
  attrs: {
700
816
  type: "object",
701
817
  properties: {
702
- language: { type: ["string", "null"] }
818
+ language: { type: ["string", "null"], description: "Programming language for syntax highlighting" },
819
+ align: { enum: ["left", "center", "right", null], description: "Block alignment" },
820
+ padding: { enum: ["none", "sm", "md", "lg", null], description: "Internal padding" },
821
+ margin: { enum: ["none", "sm", "md", "lg", null], description: "External margin" },
822
+ backgroundColor: { type: ["string", "null"], description: "Background color" },
823
+ borderRadius: { enum: ["none", "sm", "md", "lg", null], description: "Corner rounding" }
703
824
  },
704
825
  additionalProperties: true
826
+ },
827
+ content: {
828
+ type: "array",
829
+ items: { type: "object" },
830
+ description: "Code text content"
705
831
  }
706
832
  },
707
833
  required: ["type"],
@@ -728,11 +854,18 @@ var hardBreak_schema_default = {
728
854
  var horizontalRule_schema_default = {
729
855
  $schema: "https://json-schema.org/draft/2020-12/schema",
730
856
  title: "horizontalRule",
857
+ description: "A horizontal rule/divider. Inherits common block attributes.",
731
858
  type: "object",
732
859
  properties: {
733
860
  type: { const: "horizontalRule" },
734
861
  attrs: {
735
862
  type: "object",
863
+ properties: {
864
+ align: { enum: ["left", "center", "right", "stretch", null], description: "Alignment" },
865
+ padding: { enum: ["none", "sm", "md", "lg", null], description: "Padding around rule" },
866
+ margin: { enum: ["none", "sm", "md", "lg", null], description: "Margin around rule" },
867
+ backgroundColor: { type: ["string", "null"], description: "Background color" }
868
+ },
736
869
  additionalProperties: true
737
870
  }
738
871
  },
@@ -767,19 +900,26 @@ var image_schema_default = {
767
900
  var heading_schema_default = {
768
901
  $schema: "https://json-schema.org/draft/2020-12/schema",
769
902
  title: "heading",
903
+ description: "A heading block (h1-h6). Inherits common block attributes.",
770
904
  type: "object",
771
905
  properties: {
772
906
  type: { const: "heading" },
773
907
  attrs: {
774
908
  type: "object",
775
909
  properties: {
776
- level: {
777
- type: "integer",
778
- minimum: 1,
779
- maximum: 6
780
- }
910
+ level: { type: "integer", minimum: 1, maximum: 6, description: "Heading level (1-6)" },
911
+ align: { enum: ["left", "center", "right", null], description: "Text alignment" },
912
+ padding: { enum: ["none", "sm", "md", "lg", null], description: "Internal padding" },
913
+ margin: { enum: ["none", "sm", "md", "lg", null], description: "External margin" },
914
+ backgroundColor: { type: ["string", "null"], description: "Background color" },
915
+ borderRadius: { enum: ["none", "sm", "md", "lg", null], description: "Corner rounding" }
781
916
  },
782
917
  additionalProperties: true
918
+ },
919
+ content: {
920
+ type: "array",
921
+ items: { type: "object" },
922
+ description: "Inline content (text, marks)"
783
923
  }
784
924
  },
785
925
  required: ["type"],
@@ -790,12 +930,25 @@ var heading_schema_default = {
790
930
  var paragraph_schema_default = {
791
931
  $schema: "https://json-schema.org/draft/2020-12/schema",
792
932
  title: "paragraph",
933
+ description: "A paragraph block. Inherits common block attributes.",
793
934
  type: "object",
794
935
  properties: {
795
936
  type: { const: "paragraph" },
796
937
  attrs: {
797
938
  type: "object",
939
+ properties: {
940
+ align: { enum: ["left", "center", "right", null], description: "Text alignment" },
941
+ padding: { enum: ["none", "sm", "md", "lg", null], description: "Internal padding" },
942
+ margin: { enum: ["none", "sm", "md", "lg", null], description: "External margin" },
943
+ backgroundColor: { type: ["string", "null"], description: "Background color" },
944
+ borderRadius: { enum: ["none", "sm", "md", "lg", null], description: "Corner rounding" }
945
+ },
798
946
  additionalProperties: true
947
+ },
948
+ content: {
949
+ type: "array",
950
+ items: { type: "object" },
951
+ description: "Inline content (text, marks)"
799
952
  }
800
953
  },
801
954
  required: ["type"],
@@ -806,16 +959,21 @@ var paragraph_schema_default = {
806
959
  var youtube_schema_default = {
807
960
  $schema: "https://json-schema.org/draft/2020-12/schema",
808
961
  title: "youtube",
962
+ description: "A YouTube video embed. Inherits common block attributes.",
809
963
  type: "object",
810
964
  properties: {
811
965
  type: { const: "youtube" },
812
966
  attrs: {
813
967
  type: "object",
814
968
  properties: {
815
- src: { type: ["string", "null"] },
816
- start: { type: "number" },
817
- width: { type: "number" },
818
- height: { type: "number" }
969
+ src: { type: ["string", "null"], description: "YouTube video URL or ID" },
970
+ start: { type: "number", description: "Start time in seconds" },
971
+ width: { type: "number", description: "Video width" },
972
+ height: { type: "number", description: "Video height" },
973
+ align: { enum: ["left", "center", "right", "stretch", null], description: "Block alignment" },
974
+ padding: { enum: ["none", "sm", "md", "lg", null], description: "Padding" },
975
+ margin: { enum: ["none", "sm", "md", "lg", null], description: "Margin" },
976
+ borderRadius: { enum: ["none", "sm", "md", "lg", null], description: "Corner rounding" }
819
977
  },
820
978
  additionalProperties: true
821
979
  }
@@ -827,7 +985,7 @@ var youtube_schema_default = {
827
985
  // src/bundles/v1/allSchemas.ts
828
986
  var allSchemas = `
829
987
  <Schemas>
830
- ${Object.entries(v1_exports3).map(
988
+ ${Object.entries(v1_exports2).map(
831
989
  ([name, schema]) => `<${name}Schema>
832
990
  ` + JSON.stringify(schema, null, 2) + `
833
991
  </${name}Schema>`
@@ -842,8 +1000,8 @@ ${[
842
1000
  core,
843
1001
  fullDocument,
844
1002
  slide,
845
- row,
846
1003
  column,
1004
+ columnGroup,
847
1005
  style,
848
1006
  sizing,
849
1007
  imageBlock,
@@ -861,68 +1019,1076 @@ ${[
861
1019
  </Context>
862
1020
  `.trim();
863
1021
 
864
- // src/recipes/v1/index.ts
865
- var v1_exports5 = {};
866
- __export(v1_exports5, {
867
- addTwoColumns: () => addTwoColumns,
868
- createSlide: () => createSlide,
869
- editImageToCover: () => editImageToCover
1022
+ // src/templates/v1/index.ts
1023
+ var v1_exports4 = {};
1024
+ __export(v1_exports4, {
1025
+ a: () => a,
1026
+ blocks: () => blocks,
1027
+ buildPresetTemplate: () => buildPresetTemplate,
1028
+ createTemplate: () => createTemplate,
1029
+ listPresetTemplates: () => listPresetTemplates,
1030
+ listTemplates: () => listTemplates,
1031
+ slide: () => slide2,
1032
+ templatesV1Context: () => templatesV1Context
870
1033
  });
871
1034
 
872
- // src/recipes/v1/createSlide.ts
873
- var createSlide = [
874
- core,
875
- fullDocument,
876
- slide,
877
- row,
878
- column,
879
- `
880
- Return a single JSON document that creates one 16x9 slide with a 1-1 row:
881
- {
882
- "type": "doc",
883
- "content": [
884
- {
885
- "type": "slide",
886
- "attrs": { "size": "16x9" },
887
- "content": [
888
- { "type": "row", "attrs": { "layout": "1-1" }, "content": [
889
- { "type": "column", "content": [{ "type": "paragraph", "content": [{ "type": "text", "text": "Left" }] }] },
890
- { "type": "column", "content": [{ "type": "paragraph", "content": [{ "type": "text", "text": "Right" }] }] }
891
- ] }
1035
+ // src/templates/v1/schemaBuilder.ts
1036
+ var defaults = {
1037
+ slide: (attrs) => {
1038
+ var _a, _b, _c;
1039
+ return {
1040
+ id: (_a = attrs == null ? void 0 : attrs.id) != null ? _a : "slide-1",
1041
+ size: (_b = attrs == null ? void 0 : attrs.size) != null ? _b : "16x9",
1042
+ className: (_c = attrs == null ? void 0 : attrs.className) != null ? _c : ""
1043
+ };
1044
+ },
1045
+ column: (attrs) => ({
1046
+ ...attrs
1047
+ })
1048
+ };
1049
+ var textNode = (text) => ({
1050
+ type: "text",
1051
+ text
1052
+ });
1053
+ var blocks = {
1054
+ text: (text, marks) => marks && marks.length > 0 ? { type: "text", text, marks } : textNode(text),
1055
+ paragraph: (text) => ({
1056
+ type: "paragraph",
1057
+ content: text ? [textNode(text)] : []
1058
+ }),
1059
+ heading: (text, level = 2) => ({
1060
+ type: "heading",
1061
+ attrs: { level },
1062
+ content: [textNode(text)]
1063
+ }),
1064
+ bulletList: (items) => ({
1065
+ type: "bulletList",
1066
+ content: items.map(
1067
+ (item) => typeof item === "string" ? {
1068
+ type: "listItem",
1069
+ content: [{ type: "paragraph", content: [textNode(item)] }]
1070
+ } : { type: "listItem", content: [item] }
1071
+ )
1072
+ }),
1073
+ horizontalRule: () => ({ type: "horizontalRule" }),
1074
+ hardBreak: () => ({ type: "hardBreak" }),
1075
+ codeBlock: (code, language) => ({
1076
+ type: "codeBlock",
1077
+ attrs: language ? { language } : void 0,
1078
+ content: code ? [textNode(code)] : []
1079
+ }),
1080
+ imageBlock: (attrs) => ({
1081
+ type: "imageBlock",
1082
+ attrs
1083
+ }),
1084
+ // Additional nodes to mirror extensions/schemas
1085
+ blockquote: (content = []) => ({
1086
+ type: "blockquote",
1087
+ content
1088
+ }),
1089
+ listItem: (content = []) => ({
1090
+ type: "listItem",
1091
+ content
1092
+ }),
1093
+ image: (attrs) => ({
1094
+ type: "image",
1095
+ attrs
1096
+ }),
1097
+ youtube: (attrs) => ({
1098
+ type: "youtube",
1099
+ attrs
1100
+ }),
1101
+ column: (content, attrs) => ({
1102
+ type: "column",
1103
+ attrs: attrs != null ? attrs : {},
1104
+ content
1105
+ }),
1106
+ columnGroup: (columns, attrs) => ({
1107
+ type: "columnGroup",
1108
+ attrs: attrs != null ? attrs : {},
1109
+ content: columns
1110
+ })
1111
+ };
1112
+ var slide2 = Object.assign(
1113
+ /**
1114
+ * Create a slide with direct block content (no column wrapper).
1115
+ */
1116
+ (opts = {}) => {
1117
+ var _a;
1118
+ return {
1119
+ type: "slide",
1120
+ attrs: defaults.slide(opts.slideAttrs),
1121
+ content: (_a = opts.content) != null ? _a : []
1122
+ };
1123
+ },
1124
+ {
1125
+ /**
1126
+ * Single column layout - wraps content in one column block.
1127
+ */
1128
+ singleCol: (opts = {}) => {
1129
+ var _a;
1130
+ return {
1131
+ type: "slide",
1132
+ attrs: defaults.slide(opts.slideAttrs),
1133
+ content: [
1134
+ {
1135
+ type: "column",
1136
+ attrs: defaults.column(opts.columnAttrs),
1137
+ content: (_a = opts.content) != null ? _a : []
1138
+ }
1139
+ ]
1140
+ };
1141
+ },
1142
+ /**
1143
+ * Two column layout - columns grouped side-by-side via columnGroup.
1144
+ * Pass two column objects created with blocks.column().
1145
+ */
1146
+ twoCol: (col1, col2, slideAttrs) => ({
1147
+ type: "slide",
1148
+ attrs: defaults.slide(slideAttrs),
1149
+ content: [
1150
+ {
1151
+ type: "columnGroup",
1152
+ attrs: { fill: true },
1153
+ content: [col1, col2]
1154
+ }
1155
+ ]
1156
+ }),
1157
+ /**
1158
+ * Three column layout - columns grouped side-by-side via columnGroup.
1159
+ * Pass three column objects created with blocks.column().
1160
+ */
1161
+ threeCol: (col1, col2, col3, slideAttrs) => ({
1162
+ type: "slide",
1163
+ attrs: defaults.slide(slideAttrs),
1164
+ content: [
1165
+ {
1166
+ type: "columnGroup",
1167
+ attrs: { fill: true },
1168
+ content: [col1, col2, col3]
1169
+ }
892
1170
  ]
1171
+ }),
1172
+ /**
1173
+ * Four column layout - columns grouped side-by-side via columnGroup.
1174
+ * Pass four column objects created with blocks.column().
1175
+ */
1176
+ fourCol: (col1, col2, col3, col4, slideAttrs) => ({
1177
+ type: "slide",
1178
+ attrs: defaults.slide(slideAttrs),
1179
+ content: [
1180
+ {
1181
+ type: "columnGroup",
1182
+ attrs: { fill: true },
1183
+ content: [col1, col2, col3, col4]
1184
+ }
1185
+ ]
1186
+ })
1187
+ }
1188
+ );
1189
+ var column2 = (attrs, content = []) => ({
1190
+ type: "column",
1191
+ attrs: defaults.column(attrs),
1192
+ content
1193
+ });
1194
+ var createTemplate = (input) => {
1195
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F, _G, _H, _I, _J, _K, _L, _M, _N, _O, _P, _Q, _R, _S, _T, _U, _V, _W, _X, _Y, _Z, __, _$;
1196
+ switch (input.preset) {
1197
+ case "slide.empty":
1198
+ return slide2({
1199
+ slideAttrs: input.slideAttrs,
1200
+ content: []
1201
+ });
1202
+ case "slide.singleCol":
1203
+ return slide2.singleCol({
1204
+ slideAttrs: input.slideAttrs,
1205
+ columnAttrs: input.columnAttrs,
1206
+ content: (_a = input.content) != null ? _a : []
1207
+ });
1208
+ case "slide.twoCol":
1209
+ return slide2.twoCol(
1210
+ blocks.column((_b = input.left) != null ? _b : [], input.leftColumnAttrs),
1211
+ blocks.column((_c = input.right) != null ? _c : [], input.rightColumnAttrs),
1212
+ input.slideAttrs
1213
+ );
1214
+ case "slide.hero": {
1215
+ const opts = (_d = input.heroOpts) != null ? _d : {};
1216
+ return {
1217
+ type: "slide",
1218
+ attrs: defaults.slide({ ...opts.slideAttrs, backgroundColor: (_f = (_e = opts.slideAttrs) == null ? void 0 : _e.backgroundColor) != null ? _f : "#020617" }),
1219
+ content: [
1220
+ column2(
1221
+ { justify: "center", align: "center", padding: "lg", fill: true, ...opts.columnAttrs },
1222
+ (_g = opts.content) != null ? _g : [
1223
+ blocks.heading("Your headline", 1),
1224
+ blocks.paragraph("Subhead goes here."),
1225
+ blocks.paragraph("Add supporting details here.")
1226
+ ]
1227
+ )
1228
+ ]
1229
+ };
893
1230
  }
894
- ]
895
- }
896
- `.trim()
897
- ].join("\n\n");
1231
+ case "slide.imageCover": {
1232
+ const opts = (_h = input.imageCoverOpts) != null ? _h : {};
1233
+ const image2 = (_i = opts.image) != null ? _i : {
1234
+ src: "https://placehold.co/1600x900/png",
1235
+ size: "fill"
1236
+ };
1237
+ const overlay = (_j = opts.overlay) != null ? _j : [blocks.heading("Overlay title", 1)];
1238
+ return {
1239
+ type: "slide",
1240
+ attrs: defaults.slide({ ...opts.slideAttrs, backgroundColor: (_l = (_k = opts.slideAttrs) == null ? void 0 : _k.backgroundColor) != null ? _l : "#000000" }),
1241
+ content: [
1242
+ column2(
1243
+ { fill: true, padding: "none", ...opts.columnAttrs },
1244
+ [
1245
+ blocks.imageBlock(image2),
1246
+ ...overlay
1247
+ ]
1248
+ )
1249
+ ]
1250
+ };
1251
+ }
1252
+ case "slide.quote": {
1253
+ const opts = (_m = input.quoteOpts) != null ? _m : {};
1254
+ return {
1255
+ type: "slide",
1256
+ attrs: defaults.slide({ ...opts.slideAttrs, backgroundColor: (_o = (_n = opts.slideAttrs) == null ? void 0 : _n.backgroundColor) != null ? _o : "#ffffff" }),
1257
+ content: [
1258
+ column2(
1259
+ { justify: "center", align: "center", padding: "lg", gap: "md", fill: true, ...opts.columnAttrs },
1260
+ [
1261
+ blocks.blockquote(
1262
+ (_p = opts.quote) != null ? _p : [
1263
+ blocks.paragraph("Add your quote here."),
1264
+ blocks.paragraph("\u2014 Author")
1265
+ ]
1266
+ )
1267
+ ]
1268
+ )
1269
+ ]
1270
+ };
1271
+ }
1272
+ case "slide.agenda": {
1273
+ const opts = (_q = input.agendaOpts) != null ? _q : {};
1274
+ return {
1275
+ type: "slide",
1276
+ attrs: defaults.slide({ ...opts.slideAttrs, backgroundColor: (_s = (_r = opts.slideAttrs) == null ? void 0 : _r.backgroundColor) != null ? _s : "#ffffff" }),
1277
+ content: [
1278
+ column2(
1279
+ { padding: "lg", gap: "lg", ...opts.columnAttrs },
1280
+ [
1281
+ blocks.heading("Agenda", 1),
1282
+ blocks.bulletList((_t = opts.items) != null ? _t : ["Topic 1", "Topic 2", "Topic 3"])
1283
+ ]
1284
+ )
1285
+ ]
1286
+ };
1287
+ }
1288
+ case "slide.grid3": {
1289
+ const opts = (_u = input.multiColOpts) != null ? _u : { columns: [] };
1290
+ const cols = opts.columns.length > 0 ? opts.columns : [
1291
+ { content: [blocks.heading("One", 3), blocks.paragraph("Details.")] },
1292
+ { content: [blocks.heading("Two", 3), blocks.paragraph("Details.")] },
1293
+ { content: [blocks.heading("Three", 3), blocks.paragraph("Details.")] }
1294
+ ];
1295
+ return {
1296
+ type: "slide",
1297
+ attrs: defaults.slide({ ...opts.slideAttrs, backgroundColor: (_w = (_v = opts.slideAttrs) == null ? void 0 : _v.backgroundColor) != null ? _w : "#ffffff" }),
1298
+ content: cols.map((c) => {
1299
+ var _a2;
1300
+ return column2({ padding: "md", gap: "sm", fill: true, ...c.attrs }, (_a2 = c.content) != null ? _a2 : []);
1301
+ })
1302
+ };
1303
+ }
1304
+ case "slide.grid4": {
1305
+ const opts = (_x = input.multiColOpts) != null ? _x : { columns: [] };
1306
+ const cols = opts.columns.length > 0 ? opts.columns : [
1307
+ { content: [blocks.heading("One", 4)] },
1308
+ { content: [blocks.heading("Two", 4)] },
1309
+ { content: [blocks.heading("Three", 4)] },
1310
+ { content: [blocks.heading("Four", 4)] }
1311
+ ];
1312
+ return {
1313
+ type: "slide",
1314
+ attrs: defaults.slide({ ...opts.slideAttrs, backgroundColor: (_z = (_y = opts.slideAttrs) == null ? void 0 : _y.backgroundColor) != null ? _z : "#ffffff" }),
1315
+ content: cols.map((c) => {
1316
+ var _a2;
1317
+ return column2({ padding: "md", gap: "sm", fill: true, ...c.attrs }, (_a2 = c.content) != null ? _a2 : []);
1318
+ })
1319
+ };
1320
+ }
1321
+ case "slide.oneTwo": {
1322
+ const opts = (_A = input.mediaTextOpts) != null ? _A : {};
1323
+ return {
1324
+ type: "slide",
1325
+ attrs: defaults.slide({ ...opts.slideAttrs, backgroundColor: (_C = (_B = opts.slideAttrs) == null ? void 0 : _B.backgroundColor) != null ? _C : "#ffffff" }),
1326
+ content: [
1327
+ column2({ padding: "md", gap: "sm", width: "33%", ...opts.textColumnAttrs }, (_D = opts.text) != null ? _D : []),
1328
+ column2({ padding: "md", gap: "sm", fill: true, ...opts.mediaColumnAttrs }, (_E = opts.media) != null ? _E : [])
1329
+ ]
1330
+ };
1331
+ }
1332
+ case "slide.twoOne": {
1333
+ const opts = (_F = input.mediaTextOpts) != null ? _F : {};
1334
+ return {
1335
+ type: "slide",
1336
+ attrs: defaults.slide({ ...opts.slideAttrs, backgroundColor: (_H = (_G = opts.slideAttrs) == null ? void 0 : _G.backgroundColor) != null ? _H : "#ffffff" }),
1337
+ content: [
1338
+ column2({ padding: "md", gap: "sm", fill: true, ...opts.mediaColumnAttrs }, (_I = opts.media) != null ? _I : []),
1339
+ column2({ padding: "md", gap: "sm", width: "33%", ...opts.textColumnAttrs }, (_J = opts.text) != null ? _J : [])
1340
+ ]
1341
+ };
1342
+ }
1343
+ case "slide.oneTwoOne": {
1344
+ const opts = (_K = input.multiColOpts) != null ? _K : { columns: [] };
1345
+ const cols = opts.columns.length > 0 ? opts.columns : [
1346
+ { content: [blocks.paragraph("Left")] },
1347
+ { content: [blocks.paragraph("Center")] },
1348
+ { content: [blocks.paragraph("Right")] }
1349
+ ];
1350
+ return {
1351
+ type: "slide",
1352
+ attrs: defaults.slide({ ...opts.slideAttrs, backgroundColor: (_M = (_L = opts.slideAttrs) == null ? void 0 : _L.backgroundColor) != null ? _M : "#ffffff" }),
1353
+ content: cols.map((c, i) => {
1354
+ var _a2;
1355
+ return column2({ padding: "md", gap: "sm", width: i === 1 ? "50%" : "25%", ...c.attrs }, (_a2 = c.content) != null ? _a2 : []);
1356
+ })
1357
+ };
1358
+ }
1359
+ case "slide.textMedia": {
1360
+ const opts = (_N = input.mediaTextOpts) != null ? _N : {};
1361
+ return {
1362
+ type: "slide",
1363
+ attrs: defaults.slide({ ...opts.slideAttrs, backgroundColor: (_P = (_O = opts.slideAttrs) == null ? void 0 : _O.backgroundColor) != null ? _P : "#ffffff" }),
1364
+ content: [
1365
+ column2({ padding: "lg", gap: "sm", fill: true, ...opts.textColumnAttrs }, (_Q = opts.text) != null ? _Q : []),
1366
+ column2({ padding: "lg", gap: "sm", fill: true, backgroundColor: "#f8fafc", ...opts.mediaColumnAttrs }, (_R = opts.media) != null ? _R : [])
1367
+ ]
1368
+ };
1369
+ }
1370
+ case "slide.mediaText": {
1371
+ const opts = (_S = input.mediaTextOpts) != null ? _S : {};
1372
+ return {
1373
+ type: "slide",
1374
+ attrs: defaults.slide({ ...opts.slideAttrs, backgroundColor: (_U = (_T = opts.slideAttrs) == null ? void 0 : _T.backgroundColor) != null ? _U : "#ffffff" }),
1375
+ content: [
1376
+ column2({ padding: "lg", gap: "sm", fill: true, backgroundColor: "#f8fafc", ...opts.mediaColumnAttrs }, (_V = opts.media) != null ? _V : []),
1377
+ column2({ padding: "lg", gap: "sm", fill: true, ...opts.textColumnAttrs }, (_W = opts.text) != null ? _W : [])
1378
+ ]
1379
+ };
1380
+ }
1381
+ case "slide.stack2": {
1382
+ const opts = (_X = input.stack2Opts) != null ? _X : {};
1383
+ const top = (_Y = opts.topColumns) != null ? _Y : [{ content: [blocks.heading("Title", 1), blocks.paragraph("Subhead")] }];
1384
+ const bottom = (_Z = opts.bottomColumns) != null ? _Z : [
1385
+ { content: [blocks.paragraph("Left detail")] },
1386
+ { content: [blocks.paragraph("Right detail")] }
1387
+ ];
1388
+ return {
1389
+ type: "slide",
1390
+ attrs: defaults.slide({ ...opts.slideAttrs, backgroundColor: (_$ = (__ = opts.slideAttrs) == null ? void 0 : __.backgroundColor) != null ? _$ : "#ffffff" }),
1391
+ content: [
1392
+ ...top.map((c) => {
1393
+ var _a2;
1394
+ return column2({ padding: "md", gap: "sm", ...c.attrs }, (_a2 = c.content) != null ? _a2 : []);
1395
+ }),
1396
+ ...bottom.map((c) => {
1397
+ var _a2;
1398
+ return column2({ padding: "md", gap: "sm", ...c.attrs }, (_a2 = c.content) != null ? _a2 : []);
1399
+ })
1400
+ ]
1401
+ };
1402
+ }
1403
+ default:
1404
+ return slide2();
1405
+ }
1406
+ };
1407
+ var listTemplates = () => [
1408
+ "slide.empty",
1409
+ "slide.singleCol",
1410
+ "slide.twoCol",
1411
+ "slide.hero",
1412
+ "slide.imageCover",
1413
+ "slide.quote",
1414
+ "slide.agenda",
1415
+ "slide.grid3",
1416
+ "slide.grid4",
1417
+ "slide.oneTwo",
1418
+ "slide.twoOne",
1419
+ "slide.oneTwoOne",
1420
+ "slide.textMedia",
1421
+ "slide.mediaText",
1422
+ "slide.stack2"
1423
+ ];
1424
+ var templatesV1Context = `
1425
+ BlockSlides templates API (v1)
1426
+
1427
+ Document Hierarchy:
1428
+ doc \u2192 slide+ \u2192 block+
1429
+ Slides contain blocks directly - no mandatory row wrapper.
1430
+ Adjacent columns automatically form horizontal layouts via CSS.
1431
+
1432
+ Presets:
1433
+ - slide({ content?, slideAttrs? }): slide with direct block content
1434
+ - slide.singleCol({ content?, slideAttrs?, columnAttrs? }): single column layout
1435
+ - slide.twoCol(column1, column2, slideAttrs?): two columns side by side
1436
+ - slide.threeCol(col1, col2, col3, slideAttrs?): three columns side by side
1437
+ - slide.fourCol(col1, col2, col3, col4, slideAttrs?): four columns side by side
1438
+ - slide.hero({ heroOpts }): centered content on dark background
1439
+ - slide.imageCover({ imageCoverOpts }): full-bleed image with overlay
1440
+ - slide.quote({ quoteOpts }): centered blockquote
1441
+ - slide.agenda({ agendaOpts }): title with bullet list
1442
+ - slide.grid3/grid4({ multiColOpts }): equal-width column grids
1443
+ - slide.oneTwo/twoOne({ mediaTextOpts }): asymmetric layouts
1444
+ - slide.textMedia/mediaText({ mediaTextOpts }): text and media columns
1445
+ - slide.stack2({ stack2Opts }): stacked column sections
1446
+
1447
+ Base Block Attributes (available on ALL blocks):
1448
+ - align: "left" | "center" | "right" | "stretch" - horizontal alignment
1449
+ - justify: "start" | "center" | "end" | "space-between" - vertical distribution
1450
+ - padding: "none" | "sm" | "md" | "lg" - internal spacing (8px/16px/32px)
1451
+ - margin: "none" | "sm" | "md" | "lg" - external spacing
1452
+ - gap: "none" | "sm" | "md" | "lg" - space between children
1453
+ - backgroundColor: CSS color
1454
+ - backgroundImage: URL
1455
+ - borderRadius: "none" | "sm" | "md" | "lg" (4px/8px/16px)
1456
+ - border: CSS border
1457
+ - fill: boolean - fill available space
1458
+ - width: CSS width
1459
+ - height: CSS height
1460
+
1461
+ Block Helpers:
1462
+ - blocks.text(text, marks?)
1463
+ - blocks.heading(text, level?) - level 1-6
1464
+ - blocks.paragraph(text?)
1465
+ - blocks.bulletList([string | Block][])
1466
+ - blocks.codeBlock(code, language?)
1467
+ - blocks.horizontalRule()
1468
+ - blocks.hardBreak()
1469
+ - blocks.imageBlock({ src, size?, crop?, alt?, caption?, credit? })
1470
+ - size: "fill" | "fit" | "natural" - how image fills container
1471
+ - crop: "center" | "top" | "bottom" | "left" | "right" | corner positions
1472
+ - blocks.blockquote(content?)
1473
+ - blocks.listItem(content?)
1474
+ - blocks.youtube({ src?, start?, width?, height? })
1475
+
1476
+ Agent/tool usage:
1477
+ - Use blocks.column(content, attrs) to create columns
1478
+ - Use blocks.columnGroup(columns) to group columns horizontally
1479
+ - Call createTemplate({ preset: "slide.twoCol", left: [...], right: [...] })
1480
+ - Wrap returned slides in { type: "doc", content: [/* slides here */] }
898
1481
 
899
- // src/recipes/v1/addTwoColumns.ts
900
- var addTwoColumns = [
901
- core,
902
- fullDocument,
903
- row,
904
- column,
905
- `
906
- Return a full document where the first slide contains a row with layout "1-1" and two columns with simple text paragraphs.
907
- `.trim()
908
- ].join("\n\n");
1482
+ Notes:
1483
+ - Size defaults to 16x9; override via slideAttrs.size
1484
+ - Use fill: true on columns to distribute space evenly
1485
+ - Use semantic spacing tokens (sm/md/lg) instead of raw pixel values
1486
+ `.trim();
909
1487
 
910
- // src/recipes/v1/editImageToCover.ts
911
- var editImageToCover = [
912
- core,
913
- fullDocument,
914
- imageBlock,
915
- editingRules,
916
- `
917
- Update an existing imageBlock on the first slide so it uses layout "cover" and align "center". Preserve all other attributes.
918
- `.trim()
919
- ].join("\n\n");
1488
+ // src/templates/v1/presetTemplateBuilder.ts
1489
+ var titleAndSubheaderIcon = '<svg width="96" height="72" viewBox="0 0 96 72" fill="none" xmlns="http://www.w3.org/2000/svg"><rect x="6" y="6" width="84" height="60" rx="4" stroke="#D4D4D8" stroke-width="2" fill="#F9FAFB"/><rect x="18" y="22" width="60" height="12" rx="2" fill="#D4D4D8"/><rect x="26" y="38" width="44" height="8" rx="2" fill="#E5E7EB"/></svg>';
1490
+ var titleAndSubheader = {
1491
+ key: "tpl.titleAndSubheader",
1492
+ label: "Title & Subheader",
1493
+ description: "Centered title and subtitle for a new presentation",
1494
+ icon: titleAndSubheaderIcon,
1495
+ build: () => slide2.singleCol({
1496
+ columnAttrs: {
1497
+ justify: "center",
1498
+ align: "center",
1499
+ gap: "md",
1500
+ padding: "lg",
1501
+ fill: true,
1502
+ backgroundColor: "#ffffff"
1503
+ },
1504
+ content: [
1505
+ blocks.heading("Lorem ipsum dolor sit amet", 1),
1506
+ blocks.paragraph("Consectetur adipiscing elit. Sed do eiusmod tempor incididunt.")
1507
+ ]
1508
+ })
1509
+ };
1510
+ var a = titleAndSubheader;
1511
+ var imageTextIcon = '<svg width="96" height="72" viewBox="0 0 96 72" fill="none" xmlns="http://www.w3.org/2000/svg"><rect x="6" y="6" width="84" height="60" rx="4" stroke="#D4D4D8" stroke-width="2" fill="#F9FAFB"/><rect x="16" y="26" width="24" height="16" rx="2" fill="#E5E7EB"/><rect x="21" y="31" width="14" height="6" rx="1" fill="#D4D4D8"/><rect x="46" y="24" width="34" height="6" rx="1.5" fill="#D4D4D8"/><rect x="46" y="33" width="34" height="5" rx="1.5" fill="#E5E7EB"/><rect x="46" y="41" width="28" height="5" rx="1.5" fill="#E5E7EB"/></svg>';
1512
+ var textImageIcon = '<svg width="96" height="72" viewBox="0 0 96 72" fill="none" xmlns="http://www.w3.org/2000/svg"><rect x="6" y="6" width="84" height="60" rx="4" stroke="#D4D4D8" stroke-width="2" fill="#F9FAFB"/><rect x="18" y="24" width="34" height="6" rx="1.5" fill="#D4D4D8"/><rect x="18" y="33" width="34" height="5" rx="1.5" fill="#E5E7EB"/><rect x="18" y="41" width="28" height="5" rx="1.5" fill="#E5E7EB"/><rect x="56" y="26" width="24" height="16" rx="2" fill="#E5E7EB"/><rect x="61" y="31" width="14" height="6" rx="1" fill="#D4D4D8"/></svg>';
1513
+ var twoColumnsIcon = '<svg width="96" height="72" viewBox="0 0 96 72" fill="none" xmlns="http://www.w3.org/2000/svg"><rect x="6" y="6" width="84" height="60" rx="4" stroke="#D4D4D8" stroke-width="2" fill="#F9FAFB"/><rect x="18" y="22" width="26" height="6" rx="1.5" fill="#D4D4D8"/><rect x="18" y="31" width="26" height="5" rx="1.5" fill="#E5E7EB"/><rect x="18" y="39" width="22" height="5" rx="1.5" fill="#E5E7EB"/><rect x="52" y="22" width="26" height="6" rx="1.5" fill="#D4D4D8"/><rect x="52" y="31" width="26" height="5" rx="1.5" fill="#E5E7EB"/><rect x="52" y="39" width="22" height="5" rx="1.5" fill="#E5E7EB"/></svg>';
1514
+ var twoColumnsHeaderIcon = '<svg width="96" height="72" viewBox="0 0 96 72" fill="none" xmlns="http://www.w3.org/2000/svg"><rect x="6" y="6" width="84" height="60" rx="4" stroke="#D4D4D8" stroke-width="2" fill="#F9FAFB"/><rect x="18" y="18" width="60" height="6" rx="1.5" fill="#D4D4D8"/><rect x="18" y="28" width="26" height="6" rx="1.5" fill="#D4D4D8"/><rect x="18" y="37" width="26" height="5" rx="1.5" fill="#E5E7EB"/><rect x="18" y="45" width="22" height="5" rx="1.5" fill="#E5E7EB"/><rect x="52" y="28" width="26" height="6" rx="1.5" fill="#D4D4D8"/><rect x="52" y="37" width="26" height="5" rx="1.5" fill="#E5E7EB"/><rect x="52" y="45" width="22" height="5" rx="1.5" fill="#E5E7EB"/></svg>';
1515
+ var threeColumnsIcon = '<svg width="96" height="72" viewBox="0 0 96 72" fill="none" xmlns="http://www.w3.org/2000/svg"><rect x="6" y="6" width="84" height="60" rx="4" stroke="#D4D4D8" stroke-width="2" fill="#F9FAFB"/><rect x="14" y="22" width="20" height="6" rx="1.5" fill="#D4D4D8"/><rect x="14" y="31" width="20" height="5" rx="1.5" fill="#E5E7EB"/><rect x="14" y="39" width="18" height="5" rx="1.5" fill="#E5E7EB"/><rect x="38" y="22" width="20" height="6" rx="1.5" fill="#D4D4D8"/><rect x="38" y="31" width="20" height="5" rx="1.5" fill="#E5E7EB"/><rect x="38" y="39" width="18" height="5" rx="1.5" fill="#E5E7EB"/><rect x="62" y="22" width="20" height="6" rx="1.5" fill="#D4D4D8"/><rect x="62" y="31" width="20" height="5" rx="1.5" fill="#E5E7EB"/><rect x="62" y="39" width="18" height="5" rx="1.5" fill="#E5E7EB"/></svg>';
1516
+ var threeColumnsHeaderIcon = '<svg width="96" height="72" viewBox="0 0 96 72" fill="none" xmlns="http://www.w3.org/2000/svg"><rect x="6" y="6" width="84" height="60" rx="4" stroke="#D4D4D8" stroke-width="2" fill="#F9FAFB"/><rect x="16" y="16" width="60" height="6" rx="1.5" fill="#D4D4D8"/><rect x="14" y="28" width="20" height="6" rx="1.5" fill="#D4D4D8"/><rect x="14" y="37" width="20" height="5" rx="1.5" fill="#E5E7EB"/><rect x="14" y="45" width="18" height="5" rx="1.5" fill="#E5E7EB"/><rect x="38" y="28" width="20" height="6" rx="1.5" fill="#D4D4D8"/><rect x="38" y="37" width="20" height="5" rx="1.5" fill="#E5E7EB"/><rect x="38" y="45" width="18" height="5" rx="1.5" fill="#E5E7EB"/><rect x="62" y="28" width="20" height="6" rx="1.5" fill="#D4D4D8"/><rect x="62" y="37" width="20" height="5" rx="1.5" fill="#E5E7EB"/><rect x="62" y="45" width="18" height="5" rx="1.5" fill="#E5E7EB"/></svg>';
1517
+ var fourColumnsHeaderIcon = '<svg width="96" height="72" viewBox="0 0 96 72" fill="none" xmlns="http://www.w3.org/2000/svg"><rect x="6" y="6" width="84" height="60" rx="4" stroke="#D4D4D8" stroke-width="2" fill="#F9FAFB"/><rect x="16" y="16" width="60" height="6" rx="1.5" fill="#D4D4D8"/><rect x="12" y="28" width="16" height="6" rx="1.5" fill="#D4D4D8"/><rect x="12" y="37" width="16" height="5" rx="1.5" fill="#E5E7EB"/><rect x="12" y="45" width="14" height="5" rx="1.5" fill="#E5E7EB"/><rect x="32" y="28" width="16" height="6" rx="1.5" fill="#D4D4D8"/><rect x="32" y="37" width="16" height="5" rx="1.5" fill="#E5E7EB"/><rect x="32" y="45" width="14" height="5" rx="1.5" fill="#E5E7EB"/><rect x="52" y="28" width="16" height="6" rx="1.5" fill="#D4D4D8"/><rect x="52" y="37" width="16" height="5" rx="1.5" fill="#E5E7EB"/><rect x="52" y="45" width="14" height="5" rx="1.5" fill="#E5E7EB"/><rect x="72" y="28" width="16" height="6" rx="1.5" fill="#D4D4D8"/><rect x="72" y="37" width="16" height="5" rx="1.5" fill="#E5E7EB"/><rect x="72" y="45" width="14" height="5" rx="1.5" fill="#E5E7EB"/></svg>';
1518
+ var fourColumnsIcon = '<svg width="96" height="72" viewBox="0 0 96 72" fill="none" xmlns="http://www.w3.org/2000/svg"><rect x="6" y="6" width="84" height="60" rx="4" stroke="#D4D4D8" stroke-width="2" fill="#F9FAFB"/><rect x="12" y="22" width="16" height="6" rx="1.5" fill="#D4D4D8"/><rect x="12" y="31" width="16" height="5" rx="1.5" fill="#E5E7EB"/><rect x="12" y="39" width="16" height="5" rx="1.5" fill="#E5E7EB"/><rect x="32" y="22" width="16" height="6" rx="1.5" fill="#D4D4D8"/><rect x="32" y="31" width="16" height="5" rx="1.5" fill="#E5E7EB"/><rect x="32" y="39" width="16" height="5" rx="1.5" fill="#E5E7EB"/><rect x="52" y="22" width="16" height="6" rx="1.5" fill="#D4D4D8"/><rect x="52" y="31" width="16" height="5" rx="1.5" fill="#E5E7EB"/><rect x="52" y="39" width="16" height="5" rx="1.5" fill="#E5E7EB"/><rect x="72" y="22" width="16" height="6" rx="1.5" fill="#D4D4D8"/><rect x="72" y="31" width="16" height="5" rx="1.5" fill="#E5E7EB"/><rect x="72" y="39" width="16" height="5" rx="1.5" fill="#E5E7EB"/></svg>';
1519
+ var fullImageIcon = '<svg width="96" height="72" viewBox="0 0 96 72" fill="none" xmlns="http://www.w3.org/2000/svg"><rect x="6" y="6" width="84" height="60" rx="4" stroke="#D4D4D8" stroke-width="2" fill="#F9FAFB"/><rect x="14" y="14" width="68" height="44" rx="3" fill="#E5E7EB"/><path d="M18 50 34 32l12 14 8-10 16 14H18Z" fill="#D4D4D8"/><circle cx="32" cy="26" r="4" fill="#D4D4D8"/></svg>';
1520
+ var twoImageColumnsIcon = '<svg width="96" height="72" viewBox="0 0 96 72" fill="none" xmlns="http://www.w3.org/2000/svg"><rect x="6" y="6" width="84" height="60" rx="4" stroke="#D4D4D8" stroke-width="2" fill="#F9FAFB"/><rect x="16" y="18" width="64" height="6" rx="1.5" fill="#D4D4D8"/><rect x="16" y="28" width="28" height="14" rx="2" fill="#E5E7EB"/><rect x="52" y="28" width="28" height="14" rx="2" fill="#E5E7EB"/><rect x="16" y="46" width="20" height="4" rx="1" fill="#D4D4D8"/><rect x="52" y="46" width="20" height="4" rx="1" fill="#D4D4D8"/></svg>';
1521
+ var accentLeftIcon = '<svg width="96" height="72" viewBox="0 0 96 72" fill="none" xmlns="http://www.w3.org/2000/svg"><rect x="6" y="6" width="84" height="60" rx="4" stroke="#D4D4D8" stroke-width="2" fill="#F9FAFB"/><rect x="12" y="18" width="20" height="36" rx="2" fill="#EFEFEF"/><rect x="18" y="30" width="8" height="8" rx="1" fill="#CCCCCC"/><rect x="36" y="26" width="42" height="6" rx="1.5" fill="#D4D4D8"/><rect x="36" y="36" width="38" height="5" rx="1.5" fill="#E5E7EB"/><rect x="36" y="44" width="32" height="5" rx="1.5" fill="#E5E7EB"/></svg>';
1522
+ var accentRightIcon = '<svg width="96" height="72" viewBox="0 0 96 72" fill="none" xmlns="http://www.w3.org/2000/svg"><rect x="6" y="6" width="84" height="60" rx="4" stroke="#D4D4D8" stroke-width="2" fill="#F9FAFB"/><rect x="64" y="18" width="20" height="36" rx="2" fill="#EFEFEF"/><rect x="70" y="30" width="8" height="8" rx="1" fill="#CCCCCC"/><rect x="16" y="26" width="42" height="6" rx="1.5" fill="#D4D4D8"/><rect x="16" y="36" width="38" height="5" rx="1.5" fill="#E5E7EB"/><rect x="16" y="44" width="32" height="5" rx="1.5" fill="#E5E7EB"/></svg>';
1523
+ var accentTopIcon = '<svg width="96" height="72" viewBox="0 0 96 72" fill="none" xmlns="http://www.w3.org/2000/svg"><rect x="6" y="6" width="84" height="60" rx="4" stroke="#D4D4D8" stroke-width="2" fill="#F9FAFB"/><rect x="14" y="14" width="68" height="16" rx="2" fill="#EFEFEF"/><rect x="44" y="18" width="8" height="8" rx="1" fill="#CCCCCC"/><rect x="18" y="36" width="60" height="6" rx="1.5" fill="#D4D4D8"/><rect x="18" y="46" width="56" height="5" rx="1.5" fill="#E5E7EB"/><rect x="18" y="54" width="48" height="5" rx="1.5" fill="#E5E7EB"/></svg>';
1524
+ var accentRightFitIcon = '<svg width="96" height="72" viewBox="0 0 96 72" fill="none" xmlns="http://www.w3.org/2000/svg"><rect x="6" y="6" width="84" height="60" rx="4" stroke="#D4D4D8" stroke-width="2" fill="#F9FAFB"/><rect x="64" y="24" width="16" height="20" rx="2" fill="#E5E7EB"/><rect x="68" y="28" width="8" height="8" rx="1" fill="#CCCCCC"/><rect x="14" y="28" width="44" height="6" rx="1.5" fill="#D4D4D8"/><rect x="14" y="38" width="40" height="5" rx="1.5" fill="#E5E7EB"/><rect x="14" y="46" width="32" height="5" rx="1.5" fill="#E5E7EB"/></svg>';
1525
+ var accentLeftFitIcon = '<svg width="96" height="72" viewBox="0 0 96 72" fill="none" xmlns="http://www.w3.org/2000/svg"><rect x="6" y="6" width="84" height="60" rx="4" stroke="#D4D4D8" stroke-width="2" fill="#F9FAFB"/><rect x="16" y="24" width="16" height="20" rx="2" fill="#E5E7EB"/><rect x="20" y="28" width="8" height="8" rx="1" fill="#CCCCCC"/><rect x="36" y="28" width="44" height="6" rx="1.5" fill="#D4D4D8"/><rect x="36" y="38" width="40" height="5" rx="1.5" fill="#E5E7EB"/><rect x="36" y="46" width="32" height="5" rx="1.5" fill="#E5E7EB"/></svg>';
1526
+ var titleBulletsIcon = '<svg width="96" height="72" viewBox="0 0 96 72" fill="none" xmlns="http://www.w3.org/2000/svg"><rect x="6" y="6" width="84" height="60" rx="4" stroke="#D4D4D8" stroke-width="2" fill="#F9FAFB"/><rect x="18" y="20" width="60" height="6" rx="1.5" fill="#D4D4D8"/><circle cx="22" cy="32" r="2" fill="#D4D4D8"/><rect x="28" y="30" width="44" height="4" rx="1" fill="#E5E7EB"/><circle cx="22" cy="39" r="2" fill="#D4D4D8"/><rect x="28" y="37" width="44" height="4" rx="1" fill="#E5E7EB"/><circle cx="22" cy="46" r="2" fill="#D4D4D8"/><rect x="28" y="44" width="36" height="4" rx="1" fill="#E5E7EB"/></svg>';
1527
+ var titleBulletsImageIcon = '<svg width="96" height="72" viewBox="0 0 96 72" fill="none" xmlns="http://www.w3.org/2000/svg"><rect x="6" y="6" width="84" height="60" rx="4" stroke="#D4D4D8" stroke-width="2" fill="#F9FAFB"/><rect x="16" y="18" width="64" height="6" rx="1.5" fill="#D4D4D8"/><circle cx="20" cy="31" r="2" fill="#D4D4D8"/><rect x="26" y="29" width="24" height="4" rx="1" fill="#E5E7EB"/><circle cx="20" cy="38" r="2" fill="#D4D4D8"/><rect x="26" y="36" width="24" height="4" rx="1" fill="#E5E7EB"/><circle cx="20" cy="45" r="2" fill="#D4D4D8"/><rect x="26" y="43" width="20" height="4" rx="1" fill="#E5E7EB"/><rect x="56" y="31" width="24" height="16" rx="2" fill="#E5E7EB"/><rect x="61" y="36" width="14" height="6" rx="1" fill="#D4D4D8"/></svg>';
1528
+ var imageAndText = {
1529
+ key: "tpl.imageAndText",
1530
+ label: "Image & Text",
1531
+ description: "Image on left, text on right",
1532
+ icon: imageTextIcon,
1533
+ build: () => slide2.twoCol(
1534
+ blocks.column(
1535
+ [
1536
+ blocks.imageBlock({
1537
+ src: "https://placehold.co/640x480/png",
1538
+ size: "fit"
1539
+ })
1540
+ ],
1541
+ {}
1542
+ ),
1543
+ blocks.column(
1544
+ [
1545
+ blocks.heading("Lorem ipsum dolor sit amet", 2),
1546
+ blocks.paragraph("Consectetur adipiscing elit. Sed do eiusmod tempor incididunt."),
1547
+ blocks.paragraph("Ut enim ad minim veniam, quis nostrud exercitation.")
1548
+ ],
1549
+ {
1550
+ padding: "lg",
1551
+ gap: "sm",
1552
+ fill: true
1553
+ }
1554
+ )
1555
+ )
1556
+ };
1557
+ var textAndImage = {
1558
+ key: "tpl.textAndImage",
1559
+ label: "Text & Image",
1560
+ description: "Text on left, image on right",
1561
+ icon: textImageIcon,
1562
+ build: () => slide2.twoCol(
1563
+ blocks.column(
1564
+ [
1565
+ blocks.heading("Lorem ipsum dolor sit amet", 2),
1566
+ blocks.paragraph("Consectetur adipiscing elit. Sed do eiusmod tempor incididunt."),
1567
+ blocks.paragraph("Ut enim ad minim veniam, quis nostrud exercitation.")
1568
+ ],
1569
+ {
1570
+ justify: "center",
1571
+ padding: "lg",
1572
+ gap: "sm",
1573
+ fill: true
1574
+ }
1575
+ ),
1576
+ blocks.column(
1577
+ [
1578
+ blocks.imageBlock({
1579
+ src: "https://placehold.co/640x480/png",
1580
+ size: "fit"
1581
+ })
1582
+ ],
1583
+ {
1584
+ align: "center",
1585
+ justify: "center",
1586
+ padding: "lg",
1587
+ fill: true
1588
+ }
1589
+ )
1590
+ )
1591
+ };
1592
+ var twoColumns = {
1593
+ key: "tpl.twoColumns",
1594
+ label: "Two Columns",
1595
+ description: "Header above two balanced text columns",
1596
+ icon: twoColumnsIcon,
1597
+ build: () => ({
1598
+ type: "slide",
1599
+ attrs: { id: "slide-1", size: "16x9" },
1600
+ content: [
1601
+ blocks.heading("Section heading", 2),
1602
+ blocks.columnGroup([
1603
+ blocks.column(
1604
+ [
1605
+ blocks.paragraph("Lorem ipsum dolor sit amet."),
1606
+ blocks.paragraph("Consectetur adipiscing elit. Sed do eiusmod tempor incididunt."),
1607
+ blocks.paragraph("Ut enim ad minim veniam, quis nostrud exercitation.")
1608
+ ],
1609
+ { padding: "md", gap: "sm", fill: true }
1610
+ ),
1611
+ blocks.column(
1612
+ [
1613
+ blocks.paragraph("Lorem ipsum dolor sit amet."),
1614
+ blocks.paragraph("Consectetur adipiscing elit. Sed do eiusmod tempor incididunt."),
1615
+ blocks.paragraph("Ut enim ad minim veniam, quis nostrud exercitation.")
1616
+ ],
1617
+ { padding: "md", gap: "sm", fill: true }
1618
+ )
1619
+ ])
1620
+ ]
1621
+ })
1622
+ };
1623
+ var twoColumnsWithHeader = {
1624
+ key: "tpl.twoColumnsWithHeader",
1625
+ label: "Two Columns + Header",
1626
+ description: "Header plus two columns, each with its own heading",
1627
+ icon: twoColumnsHeaderIcon,
1628
+ build: () => ({
1629
+ type: "slide",
1630
+ attrs: { id: "slide-1", size: "16x9" },
1631
+ content: [
1632
+ blocks.heading("Section heading", 2),
1633
+ blocks.columnGroup([
1634
+ blocks.column(
1635
+ [
1636
+ blocks.heading("Column heading", 4),
1637
+ blocks.paragraph("Consectetur adipiscing elit. Sed do eiusmod tempor incididunt."),
1638
+ blocks.paragraph("Ut enim ad minim veniam, quis nostrud exercitation.")
1639
+ ],
1640
+ { padding: "md", gap: "sm", fill: true }
1641
+ ),
1642
+ blocks.column(
1643
+ [
1644
+ blocks.heading("Column heading", 4),
1645
+ blocks.paragraph("Consectetur adipiscing elit. Sed do eiusmod tempor incididunt."),
1646
+ blocks.paragraph("Ut enim ad minim veniam, quis nostrud exercitation.")
1647
+ ],
1648
+ { padding: "md", gap: "sm", fill: true }
1649
+ )
1650
+ ])
1651
+ ]
1652
+ })
1653
+ };
1654
+ var threeColumns = {
1655
+ key: "tpl.threeColumns",
1656
+ label: "Three Columns",
1657
+ description: "Balanced three-column text",
1658
+ icon: threeColumnsIcon,
1659
+ build: () => ({
1660
+ type: "slide",
1661
+ attrs: { id: "slide-1", size: "16x9" },
1662
+ content: [
1663
+ blocks.columnGroup([
1664
+ blocks.column(
1665
+ [
1666
+ blocks.paragraph("Lorem ipsum dolor sit amet."),
1667
+ blocks.paragraph("Consectetur adipiscing elit. Sed do eiusmod tempor incididunt.")
1668
+ ],
1669
+ { padding: "sm", gap: "sm", fill: true }
1670
+ ),
1671
+ blocks.column(
1672
+ [
1673
+ blocks.paragraph("Ut enim ad minim veniam."),
1674
+ blocks.paragraph("Quis nostrud exercitation ullamco laboris.")
1675
+ ],
1676
+ { padding: "sm", gap: "sm", fill: true }
1677
+ ),
1678
+ blocks.column(
1679
+ [
1680
+ blocks.paragraph("Nisi ut aliquip ex ea commodo consequat."),
1681
+ blocks.paragraph("Duis aute irure dolor in reprehenderit.")
1682
+ ],
1683
+ { padding: "sm", gap: "sm", fill: true }
1684
+ )
1685
+ ])
1686
+ ]
1687
+ })
1688
+ };
1689
+ var threeColumnsWithHeader = {
1690
+ key: "tpl.threeColumnsWithHeader",
1691
+ label: "Three Columns + Header",
1692
+ description: "Header plus three columns",
1693
+ icon: threeColumnsHeaderIcon,
1694
+ build: () => ({
1695
+ type: "slide",
1696
+ attrs: { id: "slide-1", size: "16x9" },
1697
+ content: [
1698
+ blocks.heading("Section heading", 2),
1699
+ blocks.columnGroup([
1700
+ blocks.column(
1701
+ [
1702
+ blocks.heading("Column heading", 4),
1703
+ blocks.paragraph("Lorem ipsum dolor sit amet."),
1704
+ blocks.paragraph("Consectetur adipiscing elit. Sed do eiusmod tempor incididunt.")
1705
+ ],
1706
+ { padding: "sm", gap: "sm", fill: true }
1707
+ ),
1708
+ blocks.column(
1709
+ [
1710
+ blocks.heading("Column heading", 4),
1711
+ blocks.paragraph("Ut enim ad minim veniam."),
1712
+ blocks.paragraph("Quis nostrud exercitation ullamco laboris.")
1713
+ ],
1714
+ { padding: "sm", gap: "sm", fill: true }
1715
+ ),
1716
+ blocks.column(
1717
+ [
1718
+ blocks.heading("Column heading", 4),
1719
+ blocks.paragraph("Nisi ut aliquip ex ea commodo consequat."),
1720
+ blocks.paragraph("Duis aute irure dolor in reprehenderit.")
1721
+ ],
1722
+ { padding: "sm", gap: "sm", fill: true }
1723
+ )
1724
+ ])
1725
+ ]
1726
+ })
1727
+ };
1728
+ var fourColumnsWithHeader = {
1729
+ key: "tpl.fourColumnsWithHeader",
1730
+ label: "Four Columns + Header",
1731
+ description: "Header plus four columns",
1732
+ icon: fourColumnsHeaderIcon,
1733
+ build: () => ({
1734
+ type: "slide",
1735
+ attrs: { id: "slide-1", size: "16x9" },
1736
+ content: [
1737
+ blocks.heading("Section heading", 2),
1738
+ blocks.columnGroup([
1739
+ blocks.column(
1740
+ [
1741
+ blocks.heading("Column heading", 4),
1742
+ blocks.paragraph("Lorem ipsum dolor sit amet."),
1743
+ blocks.paragraph("Consectetur adipiscing elit.")
1744
+ ],
1745
+ { padding: "sm", gap: "sm", fill: true }
1746
+ ),
1747
+ blocks.column(
1748
+ [
1749
+ blocks.heading("Column heading", 4),
1750
+ blocks.paragraph("Ut enim ad minim veniam."),
1751
+ blocks.paragraph("Quis nostrud exercitation ullamco laboris.")
1752
+ ],
1753
+ { padding: "sm", gap: "sm", fill: true }
1754
+ ),
1755
+ blocks.column(
1756
+ [
1757
+ blocks.heading("Column heading", 4),
1758
+ blocks.paragraph("Nisi ut aliquip ex ea commodo consequat."),
1759
+ blocks.paragraph("Duis aute irure dolor in reprehenderit.")
1760
+ ],
1761
+ { padding: "sm", gap: "sm", fill: true }
1762
+ ),
1763
+ blocks.column(
1764
+ [
1765
+ blocks.heading("Column heading", 4),
1766
+ blocks.paragraph("Excepteur sint occaecat cupidatat."),
1767
+ blocks.paragraph("Sunt in culpa qui officia.")
1768
+ ],
1769
+ { padding: "sm", gap: "sm", fill: true }
1770
+ )
1771
+ ])
1772
+ ]
1773
+ })
1774
+ };
1775
+ var fullImage = {
1776
+ key: "tpl.fullImage",
1777
+ label: "Full Image",
1778
+ description: "Edge-to-edge image filling the slide",
1779
+ icon: fullImageIcon,
1780
+ build: () => slide2.singleCol({
1781
+ columnAttrs: { padding: "none", fill: true, align: "stretch" },
1782
+ content: [
1783
+ blocks.imageBlock({
1784
+ src: "https://placehold.co/1920x1080/png",
1785
+ size: "fill",
1786
+ crop: "center"
1787
+ })
1788
+ ]
1789
+ })
1790
+ };
1791
+ var fourColumns = {
1792
+ key: "tpl.fourColumns",
1793
+ label: "Four Columns",
1794
+ description: "Balanced four-column text",
1795
+ icon: fourColumnsIcon,
1796
+ build: () => ({
1797
+ type: "slide",
1798
+ attrs: { id: "slide-1", size: "16x9" },
1799
+ content: [
1800
+ blocks.columnGroup(
1801
+ Array.from({ length: 4 }).map(
1802
+ () => blocks.column(
1803
+ [
1804
+ blocks.paragraph("Lorem ipsum dolor sit amet."),
1805
+ blocks.paragraph("Consectetur adipiscing elit.")
1806
+ ],
1807
+ { padding: "sm", gap: "sm", fill: true }
1808
+ )
1809
+ )
1810
+ )
1811
+ ]
1812
+ })
1813
+ };
1814
+ var titleWithBullets = {
1815
+ key: "tpl.titleWithBullets",
1816
+ label: "Title with Bullets",
1817
+ description: "Header and a bullet list",
1818
+ icon: titleBulletsIcon,
1819
+ build: () => slide2.singleCol({
1820
+ columnAttrs: { padding: "md", gap: "md" },
1821
+ content: [
1822
+ blocks.heading("Lorem ipsum dolor sit amet", 2),
1823
+ blocks.bulletList([
1824
+ "Consectetur adipiscing elit.",
1825
+ "Sed do eiusmod tempor incididunt.",
1826
+ "Ut enim ad minim veniam."
1827
+ ])
1828
+ ]
1829
+ })
1830
+ };
1831
+ var titleBulletsAndImage = {
1832
+ key: "tpl.titleBulletsAndImage",
1833
+ label: "Title, Bullets & Image",
1834
+ description: "Title with bullets and an image",
1835
+ icon: titleBulletsImageIcon,
1836
+ build: () => slide2.twoCol(
1837
+ blocks.column(
1838
+ [
1839
+ blocks.heading("Lorem ipsum dolor sit amet", 2),
1840
+ blocks.bulletList([
1841
+ "Consectetur adipiscing elit.",
1842
+ "Sed do eiusmod tempor incididunt.",
1843
+ "Ut enim ad minim veniam."
1844
+ ])
1845
+ ],
1846
+ { padding: "md", gap: "sm", fill: true }
1847
+ ),
1848
+ blocks.column(
1849
+ [
1850
+ blocks.imageBlock({
1851
+ src: "https://placehold.co/480x360/png",
1852
+ size: "fit"
1853
+ })
1854
+ ],
1855
+ {
1856
+ align: "center",
1857
+ justify: "center",
1858
+ padding: "md",
1859
+ fill: true
1860
+ }
1861
+ )
1862
+ )
1863
+ };
1864
+ var accentLeft = {
1865
+ key: "tpl.accentLeft",
1866
+ label: "Accent left",
1867
+ description: "Accent band with image on the left, text on the right",
1868
+ icon: accentLeftIcon,
1869
+ build: () => slide2.twoCol(
1870
+ blocks.column(
1871
+ [
1872
+ blocks.imageBlock({
1873
+ src: "https://placehold.co/320x240/png",
1874
+ size: "fill",
1875
+ crop: "center"
1876
+ })
1877
+ ],
1878
+ {
1879
+ backgroundColor: "#f1f5f9",
1880
+ padding: "none",
1881
+ fill: true,
1882
+ align: "stretch"
1883
+ }
1884
+ ),
1885
+ blocks.column(
1886
+ [
1887
+ blocks.heading("Accent left", 3),
1888
+ blocks.paragraph("Short supporting copy goes here."),
1889
+ blocks.paragraph("Add one more line if needed.")
1890
+ ],
1891
+ { padding: "md", gap: "sm", fill: true, justify: "center" }
1892
+ )
1893
+ )
1894
+ };
1895
+ var accentRight = {
1896
+ key: "tpl.accentRight",
1897
+ label: "Accent right",
1898
+ description: "Accent band with image on the right, text on the left",
1899
+ icon: accentRightIcon,
1900
+ build: () => slide2.twoCol(
1901
+ blocks.column(
1902
+ [
1903
+ blocks.heading("Accent right", 3),
1904
+ blocks.paragraph("Short supporting copy goes here."),
1905
+ blocks.paragraph("Add one more line if needed.")
1906
+ ],
1907
+ { padding: "md", gap: "sm", fill: true, justify: "center" }
1908
+ ),
1909
+ blocks.column(
1910
+ [
1911
+ blocks.imageBlock({
1912
+ src: "https://placehold.co/320x240/png",
1913
+ size: "fill",
1914
+ crop: "center"
1915
+ })
1916
+ ],
1917
+ {
1918
+ backgroundColor: "#f1f5f9",
1919
+ padding: "none",
1920
+ fill: true,
1921
+ align: "stretch"
1922
+ }
1923
+ )
1924
+ )
1925
+ };
1926
+ var accentTop = {
1927
+ key: "tpl.accentTop",
1928
+ label: "Accent top",
1929
+ description: "Accent band on top with image, text below",
1930
+ icon: accentTopIcon,
1931
+ build: () => ({
1932
+ type: "slide",
1933
+ attrs: { id: "slide-1", size: "16x9" },
1934
+ content: [
1935
+ {
1936
+ type: "column",
1937
+ attrs: { backgroundColor: "#f1f5f9", padding: "none", height: "200px", align: "stretch" },
1938
+ content: [
1939
+ blocks.imageBlock({
1940
+ src: "https://placehold.co/1200x400/png",
1941
+ size: "fill",
1942
+ crop: "center"
1943
+ })
1944
+ ]
1945
+ },
1946
+ {
1947
+ type: "column",
1948
+ attrs: { padding: "md", gap: "sm", fill: true, justify: "end" },
1949
+ content: [
1950
+ blocks.heading("Accent top", 3),
1951
+ blocks.paragraph("Short supporting copy goes here."),
1952
+ blocks.paragraph("Add one more line if needed.")
1953
+ ]
1954
+ }
1955
+ ]
1956
+ })
1957
+ };
1958
+ var accentRightFit = {
1959
+ key: "tpl.accentRightFit",
1960
+ label: "Accent right (fit)",
1961
+ description: "Text with a tighter image card on the right",
1962
+ icon: accentRightFitIcon,
1963
+ build: () => slide2.twoCol(
1964
+ blocks.column(
1965
+ [
1966
+ blocks.heading("Accent right (fit)", 3),
1967
+ blocks.paragraph("Short supporting copy goes here."),
1968
+ blocks.paragraph("Add one more line if needed.")
1969
+ ],
1970
+ { padding: "md", gap: "sm", fill: true, justify: "center" }
1971
+ ),
1972
+ blocks.column(
1973
+ [
1974
+ blocks.column(
1975
+ [
1976
+ blocks.imageBlock({
1977
+ src: "https://placehold.co/240x200/png",
1978
+ size: "fit"
1979
+ })
1980
+ ],
1981
+ { backgroundColor: "#f1f5f9", padding: "md", gap: "sm", borderRadius: "lg", align: "center" }
1982
+ )
1983
+ ],
1984
+ {
1985
+ padding: "md",
1986
+ fill: true,
1987
+ justify: "center",
1988
+ align: "center"
1989
+ }
1990
+ )
1991
+ )
1992
+ };
1993
+ var accentLeftFit = {
1994
+ key: "tpl.accentLeftFit",
1995
+ label: "Accent left (fit)",
1996
+ description: "Compact image card on the left, text on the right",
1997
+ icon: accentLeftFitIcon,
1998
+ build: () => slide2.twoCol(
1999
+ blocks.column(
2000
+ [
2001
+ blocks.column(
2002
+ [
2003
+ blocks.imageBlock({
2004
+ src: "https://placehold.co/240x200/png",
2005
+ size: "fit"
2006
+ })
2007
+ ],
2008
+ { backgroundColor: "#f1f5f9", padding: "md", gap: "sm", borderRadius: "lg", align: "center" }
2009
+ )
2010
+ ],
2011
+ {
2012
+ padding: "md",
2013
+ fill: true,
2014
+ justify: "center",
2015
+ align: "center"
2016
+ }
2017
+ ),
2018
+ blocks.column(
2019
+ [
2020
+ blocks.heading("Accent left (fit)", 3),
2021
+ blocks.paragraph("Short supporting copy goes here."),
2022
+ blocks.paragraph("Add one more line if needed.")
2023
+ ],
2024
+ { padding: "md", gap: "sm", fill: true, justify: "center" }
2025
+ )
2026
+ )
2027
+ };
2028
+ var twoImageColumns = {
2029
+ key: "tpl.twoImageColumns",
2030
+ label: "2 image columns",
2031
+ description: "Header with two image cards",
2032
+ icon: twoImageColumnsIcon,
2033
+ build: () => ({
2034
+ type: "slide",
2035
+ attrs: { id: "slide-1", size: "16x9" },
2036
+ content: [
2037
+ blocks.heading("Images", 2),
2038
+ blocks.columnGroup([
2039
+ blocks.column(
2040
+ [
2041
+ blocks.imageBlock({
2042
+ src: "https://placehold.co/640x360/png",
2043
+ size: "fit"
2044
+ }),
2045
+ blocks.heading("Image title", 4),
2046
+ blocks.paragraph("Short supporting copy goes here.")
2047
+ ],
2048
+ { padding: "md", gap: "sm", fill: true }
2049
+ ),
2050
+ blocks.column(
2051
+ [
2052
+ blocks.imageBlock({
2053
+ src: "https://placehold.co/640x360/png",
2054
+ size: "fit"
2055
+ }),
2056
+ blocks.heading("Image title", 4),
2057
+ blocks.paragraph("Short supporting copy goes here.")
2058
+ ],
2059
+ { padding: "md", gap: "sm", fill: true }
2060
+ )
2061
+ ])
2062
+ ]
2063
+ })
2064
+ };
2065
+ var registry = {
2066
+ "tpl.titleAndSubheader": titleAndSubheader,
2067
+ "tpl.imageAndText": imageAndText,
2068
+ "tpl.textAndImage": textAndImage,
2069
+ "tpl.twoColumns": twoColumns,
2070
+ "tpl.twoColumnsWithHeader": twoColumnsWithHeader,
2071
+ "tpl.threeColumns": threeColumns,
2072
+ "tpl.threeColumnsWithHeader": threeColumnsWithHeader,
2073
+ "tpl.fourColumns": fourColumns,
2074
+ "tpl.fourColumnsWithHeader": fourColumnsWithHeader,
2075
+ "tpl.titleWithBullets": titleWithBullets,
2076
+ "tpl.titleBulletsAndImage": titleBulletsAndImage,
2077
+ "tpl.fullImage": fullImage,
2078
+ "tpl.accentLeft": accentLeft,
2079
+ "tpl.accentRight": accentRight,
2080
+ "tpl.accentTop": accentTop,
2081
+ "tpl.accentRightFit": accentRightFit,
2082
+ "tpl.accentLeftFit": accentLeftFit,
2083
+ "tpl.twoImageColumns": twoImageColumns
2084
+ };
2085
+ var listPresetTemplates = () => Object.values(registry);
2086
+ var buildPresetTemplate = (key) => registry[key].build();
920
2087
  // Annotate the CommonJS export names for ESM import in node:
921
2088
  0 && (module.exports = {
922
2089
  bundlesV1,
923
2090
  contextsV1,
924
- examplesV1,
925
- recipesV1,
926
- schemasV1
2091
+ schemasV1,
2092
+ templatesV1
927
2093
  });
928
2094
  //# sourceMappingURL=index.cjs.map