@blockslides/ai-context 0.2.0 → 0.3.1

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