@blockslides/ai-context 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/dist/index.cjs +987 -996
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.d.cts +709 -191
  4. package/dist/index.d.ts +709 -191
  5. package/dist/index.js +987 -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,10 @@ ${[
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, {
1002
+ a: () => a,
900
1003
  blocks: () => blocks,
901
1004
  buildPresetTemplate: () => buildPresetTemplate,
902
1005
  createTemplate: () => createTemplate,
@@ -916,23 +1019,9 @@ var defaults = {
916
1019
  className: (_c = attrs == null ? void 0 : attrs.className) != null ? _c : ""
917
1020
  };
918
1021
  },
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
- }
1022
+ column: (attrs) => ({
1023
+ ...attrs
1024
+ })
936
1025
  };
937
1026
  var textNode = (text) => ({
938
1027
  type: "text",
@@ -985,27 +1074,34 @@ var blocks = {
985
1074
  youtube: (attrs) => ({
986
1075
  type: "youtube",
987
1076
  attrs
1077
+ }),
1078
+ column: (content, attrs) => ({
1079
+ type: "column",
1080
+ attrs: attrs != null ? attrs : {},
1081
+ content
1082
+ }),
1083
+ columnGroup: (columns, attrs) => ({
1084
+ type: "columnGroup",
1085
+ attrs: attrs != null ? attrs : {},
1086
+ content: columns
988
1087
  })
989
1088
  };
990
1089
  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
- }),
1090
+ /**
1091
+ * Create a slide with direct block content (no column wrapper).
1092
+ */
1093
+ (opts = {}) => {
1094
+ var _a;
1095
+ return {
1096
+ type: "slide",
1097
+ attrs: defaults.slide(opts.slideAttrs),
1098
+ content: (_a = opts.content) != null ? _a : []
1099
+ };
1100
+ },
1008
1101
  {
1102
+ /**
1103
+ * Single column layout - wraps content in one column block.
1104
+ */
1009
1105
  singleCol: (opts = {}) => {
1010
1106
  var _a;
1011
1107
  return {
@@ -1013,47 +1109,58 @@ var slide2 = Object.assign(
1013
1109
  attrs: defaults.slide(opts.slideAttrs),
1014
1110
  content: [
1015
1111
  {
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
- ]
1112
+ type: "column",
1113
+ attrs: defaults.column(opts.columnAttrs),
1114
+ content: (_a = opts.content) != null ? _a : []
1025
1115
  }
1026
1116
  ]
1027
1117
  };
1028
1118
  },
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
- }
1119
+ /**
1120
+ * Two column layout - columns grouped side-by-side via columnGroup.
1121
+ * Pass two column objects created with blocks.column().
1122
+ */
1123
+ twoCol: (col1, col2, slideAttrs) => ({
1124
+ type: "slide",
1125
+ attrs: defaults.slide(slideAttrs),
1126
+ content: [
1127
+ {
1128
+ type: "columnGroup",
1129
+ attrs: { fill: true },
1130
+ content: [col1, col2]
1131
+ }
1132
+ ]
1133
+ }),
1134
+ /**
1135
+ * Three column layout - columns grouped side-by-side via columnGroup.
1136
+ * Pass three column objects created with blocks.column().
1137
+ */
1138
+ threeCol: (col1, col2, col3, slideAttrs) => ({
1139
+ type: "slide",
1140
+ attrs: defaults.slide(slideAttrs),
1141
+ content: [
1142
+ {
1143
+ type: "columnGroup",
1144
+ attrs: { fill: true },
1145
+ content: [col1, col2, col3]
1146
+ }
1147
+ ]
1148
+ }),
1149
+ /**
1150
+ * Four column layout - columns grouped side-by-side via columnGroup.
1151
+ * Pass four column objects created with blocks.column().
1152
+ */
1153
+ fourCol: (col1, col2, col3, col4, slideAttrs) => ({
1154
+ type: "slide",
1155
+ attrs: defaults.slide(slideAttrs),
1156
+ content: [
1157
+ {
1158
+ type: "columnGroup",
1159
+ attrs: { fill: true },
1160
+ content: [col1, col2, col3, col4]
1161
+ }
1162
+ ]
1163
+ })
1057
1164
  }
1058
1165
  );
1059
1166
  var column2 = (attrs, content = []) => ({
@@ -1061,148 +1168,102 @@ var column2 = (attrs, content = []) => ({
1061
1168
  attrs: defaults.column(attrs),
1062
1169
  content
1063
1170
  });
1064
- var row2 = (layout, content, attrs) => ({
1065
- type: "row",
1066
- attrs: defaults.row({ layout, ...attrs }),
1067
- content
1068
- });
1069
1171
  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;
1172
+ 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
1173
  switch (input.preset) {
1072
1174
  case "slide.empty":
1073
1175
  return slide2({
1074
1176
  slideAttrs: input.slideAttrs,
1075
- rowAttrs: input.rowAttrs,
1076
- columnAttrs: input.columnAttrs
1177
+ content: []
1077
1178
  });
1078
1179
  case "slide.singleCol":
1079
1180
  return slide2.singleCol({
1080
1181
  slideAttrs: input.slideAttrs,
1081
- rowAttrs: input.rowAttrs,
1082
1182
  columnAttrs: input.columnAttrs,
1083
1183
  content: (_a = input.content) != null ? _a : []
1084
1184
  });
1085
1185
  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
- });
1186
+ return slide2.twoCol(
1187
+ blocks.column((_b = input.left) != null ? _b : [], input.leftColumnAttrs),
1188
+ blocks.column((_c = input.right) != null ? _c : [], input.rightColumnAttrs),
1189
+ input.slideAttrs
1190
+ );
1094
1191
  case "slide.hero": {
1095
1192
  const opts = (_d = input.heroOpts) != null ? _d : {};
1096
1193
  return {
1097
1194
  type: "slide",
1098
- attrs: defaults.slide({ className: "bg-slate-950 text-white", ...opts.slideAttrs }),
1195
+ attrs: defaults.slide({ ...opts.slideAttrs, backgroundColor: (_f = (_e = opts.slideAttrs) == null ? void 0 : _e.backgroundColor) != null ? _f : "#020617" }),
1099
1196
  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 }
1197
+ column2(
1198
+ { justify: "center", align: "center", padding: "lg", fill: true, ...opts.columnAttrs },
1199
+ (_g = opts.content) != null ? _g : [
1200
+ blocks.heading("Your headline", 1),
1201
+ blocks.paragraph("Subhead goes here."),
1202
+ blocks.paragraph("Add supporting details here.")
1203
+ ]
1113
1204
  )
1114
1205
  ]
1115
1206
  };
1116
1207
  }
1117
1208
  case "slide.imageCover": {
1118
- const opts = (_i = input.imageCoverOpts) != null ? _i : {};
1119
- const image2 = (_j = opts.image) != null ? _j : {
1209
+ const opts = (_h = input.imageCoverOpts) != null ? _h : {};
1210
+ const image2 = (_i = opts.image) != null ? _i : {
1120
1211
  src: "https://placehold.co/1600x900/png",
1121
- layout: "cover",
1122
- fullBleed: true,
1123
- align: "center"
1212
+ size: "fill"
1124
1213
  };
1125
- const overlay = (_k = opts.overlay) != null ? _k : [blocks.heading("Overlay title", 1)];
1214
+ const overlay = (_j = opts.overlay) != null ? _j : [blocks.heading("Overlay title", 1)];
1126
1215
  return {
1127
1216
  type: "slide",
1128
- attrs: defaults.slide({ className: "bg-black text-white", ...opts.slideAttrs }),
1217
+ attrs: defaults.slide({ ...opts.slideAttrs, backgroundColor: (_l = (_k = opts.slideAttrs) == null ? void 0 : _k.backgroundColor) != null ? _l : "#000000" }),
1129
1218
  content: [
1130
- row2(
1131
- (_m = (_l = opts.rowAttrs) == null ? void 0 : _l.layout) != null ? _m : "1",
1219
+ column2(
1220
+ { fill: true, padding: "none", ...opts.columnAttrs },
1132
1221
  [
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 }
1222
+ blocks.imageBlock(image2),
1223
+ ...overlay
1224
+ ]
1152
1225
  )
1153
1226
  ]
1154
1227
  };
1155
1228
  }
1156
1229
  case "slide.quote": {
1157
- const opts = (_n = input.quoteOpts) != null ? _n : {};
1230
+ const opts = (_m = input.quoteOpts) != null ? _m : {};
1158
1231
  return {
1159
1232
  type: "slide",
1160
- attrs: defaults.slide({ className: "bg-white text-slate-900", ...opts.slideAttrs }),
1233
+ attrs: defaults.slide({ ...opts.slideAttrs, backgroundColor: (_o = (_n = opts.slideAttrs) == null ? void 0 : _n.backgroundColor) != null ? _o : "#ffffff" }),
1161
1234
  content: [
1162
- row2(
1163
- (_p = (_o = opts.rowAttrs) == null ? void 0 : _o.layout) != null ? _p : "1",
1235
+ column2(
1236
+ { justify: "center", align: "center", padding: "lg", gap: "md", fill: true, ...opts.columnAttrs },
1164
1237
  [
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
- )
1238
+ blocks.blockquote(
1239
+ (_p = opts.quote) != null ? _p : [
1240
+ blocks.paragraph("Add your quote here."),
1241
+ blocks.paragraph("\u2014 Author")
1174
1242
  ]
1175
1243
  )
1176
- ],
1177
- { className: "min-h-[640px] items-center justify-center", ...opts.rowAttrs }
1244
+ ]
1178
1245
  )
1179
1246
  ]
1180
1247
  };
1181
1248
  }
1182
1249
  case "slide.agenda": {
1183
- const opts = (_s = input.agendaOpts) != null ? _s : {};
1250
+ const opts = (_q = input.agendaOpts) != null ? _q : {};
1184
1251
  return {
1185
1252
  type: "slide",
1186
- attrs: defaults.slide({ className: "bg-white text-slate-900", ...opts.slideAttrs }),
1253
+ attrs: defaults.slide({ ...opts.slideAttrs, backgroundColor: (_s = (_r = opts.slideAttrs) == null ? void 0 : _r.backgroundColor) != null ? _s : "#ffffff" }),
1187
1254
  content: [
1188
- row2(
1189
- (_u = (_t = opts.rowAttrs) == null ? void 0 : _t.layout) != null ? _u : "1",
1255
+ column2(
1256
+ { padding: "lg", gap: "lg", ...opts.columnAttrs },
1190
1257
  [
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 }
1258
+ blocks.heading("Agenda", 1),
1259
+ blocks.bulletList((_t = opts.items) != null ? _t : ["Topic 1", "Topic 2", "Topic 3"])
1260
+ ]
1200
1261
  )
1201
1262
  ]
1202
1263
  };
1203
1264
  }
1204
1265
  case "slide.grid3": {
1205
- const opts = (_x = input.multiColOpts) != null ? _x : { columns: [] };
1266
+ const opts = (_u = input.multiColOpts) != null ? _u : { columns: [] };
1206
1267
  const cols = opts.columns.length > 0 ? opts.columns : [
1207
1268
  { content: [blocks.heading("One", 3), blocks.paragraph("Details.")] },
1208
1269
  { content: [blocks.heading("Two", 3), blocks.paragraph("Details.")] },
@@ -1210,21 +1271,15 @@ var createTemplate = (input) => {
1210
1271
  ];
1211
1272
  return {
1212
1273
  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
- ]
1274
+ attrs: defaults.slide({ ...opts.slideAttrs, backgroundColor: (_w = (_v = opts.slideAttrs) == null ? void 0 : _v.backgroundColor) != null ? _w : "#ffffff" }),
1275
+ content: cols.map((c) => {
1276
+ var _a2;
1277
+ return column2({ padding: "md", gap: "sm", fill: true, ...c.attrs }, (_a2 = c.content) != null ? _a2 : []);
1278
+ })
1224
1279
  };
1225
1280
  }
1226
1281
  case "slide.grid4": {
1227
- const opts = (_A = input.multiColOpts) != null ? _A : { columns: [] };
1282
+ const opts = (_x = input.multiColOpts) != null ? _x : { columns: [] };
1228
1283
  const cols = opts.columns.length > 0 ? opts.columns : [
1229
1284
  { content: [blocks.heading("One", 4)] },
1230
1285
  { content: [blocks.heading("Two", 4)] },
@@ -1233,55 +1288,37 @@ var createTemplate = (input) => {
1233
1288
  ];
1234
1289
  return {
1235
1290
  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
- ]
1291
+ attrs: defaults.slide({ ...opts.slideAttrs, backgroundColor: (_z = (_y = opts.slideAttrs) == null ? void 0 : _y.backgroundColor) != null ? _z : "#ffffff" }),
1292
+ content: cols.map((c) => {
1293
+ var _a2;
1294
+ return column2({ padding: "md", gap: "sm", fill: true, ...c.attrs }, (_a2 = c.content) != null ? _a2 : []);
1295
+ })
1247
1296
  };
1248
1297
  }
1249
1298
  case "slide.oneTwo": {
1250
- const opts = (_D = input.mediaTextOpts) != null ? _D : {};
1299
+ const opts = (_A = input.mediaTextOpts) != null ? _A : {};
1251
1300
  return {
1252
1301
  type: "slide",
1253
- attrs: defaults.slide({ className: "bg-white text-slate-900", ...opts.slideAttrs }),
1302
+ attrs: defaults.slide({ ...opts.slideAttrs, backgroundColor: (_C = (_B = opts.slideAttrs) == null ? void 0 : _B.backgroundColor) != null ? _C : "#ffffff" }),
1254
1303
  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
- )
1304
+ column2({ padding: "md", gap: "sm", width: "33%", ...opts.textColumnAttrs }, (_D = opts.text) != null ? _D : []),
1305
+ column2({ padding: "md", gap: "sm", fill: true, ...opts.mediaColumnAttrs }, (_E = opts.media) != null ? _E : [])
1263
1306
  ]
1264
1307
  };
1265
1308
  }
1266
1309
  case "slide.twoOne": {
1267
- const opts = (_K = input.mediaTextOpts) != null ? _K : {};
1310
+ const opts = (_F = input.mediaTextOpts) != null ? _F : {};
1268
1311
  return {
1269
1312
  type: "slide",
1270
- attrs: defaults.slide({ className: "bg-white text-slate-900", ...opts.slideAttrs }),
1313
+ attrs: defaults.slide({ ...opts.slideAttrs, backgroundColor: (_H = (_G = opts.slideAttrs) == null ? void 0 : _G.backgroundColor) != null ? _H : "#ffffff" }),
1271
1314
  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
- )
1315
+ column2({ padding: "md", gap: "sm", fill: true, ...opts.mediaColumnAttrs }, (_I = opts.media) != null ? _I : []),
1316
+ column2({ padding: "md", gap: "sm", width: "33%", ...opts.textColumnAttrs }, (_J = opts.text) != null ? _J : [])
1280
1317
  ]
1281
1318
  };
1282
1319
  }
1283
1320
  case "slide.oneTwoOne": {
1284
- const opts = (_R = input.multiColOpts) != null ? _R : { columns: [] };
1321
+ const opts = (_K = input.multiColOpts) != null ? _K : { columns: [] };
1285
1322
  const cols = opts.columns.length > 0 ? opts.columns : [
1286
1323
  { content: [blocks.paragraph("Left")] },
1287
1324
  { content: [blocks.paragraph("Center")] },
@@ -1289,86 +1326,54 @@ var createTemplate = (input) => {
1289
1326
  ];
1290
1327
  return {
1291
1328
  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
- ]
1329
+ attrs: defaults.slide({ ...opts.slideAttrs, backgroundColor: (_M = (_L = opts.slideAttrs) == null ? void 0 : _L.backgroundColor) != null ? _M : "#ffffff" }),
1330
+ content: cols.map((c, i) => {
1331
+ var _a2;
1332
+ return column2({ padding: "md", gap: "sm", width: i === 1 ? "50%" : "25%", ...c.attrs }, (_a2 = c.content) != null ? _a2 : []);
1333
+ })
1303
1334
  };
1304
1335
  }
1305
1336
  case "slide.textMedia": {
1306
- const opts = (_U = input.mediaTextOpts) != null ? _U : {};
1337
+ const opts = (_N = input.mediaTextOpts) != null ? _N : {};
1307
1338
  return {
1308
1339
  type: "slide",
1309
- attrs: defaults.slide({ className: "bg-white text-slate-900", ...opts.slideAttrs }),
1340
+ attrs: defaults.slide({ ...opts.slideAttrs, backgroundColor: (_P = (_O = opts.slideAttrs) == null ? void 0 : _O.backgroundColor) != null ? _P : "#ffffff" }),
1310
1341
  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
- )
1342
+ column2({ padding: "lg", gap: "sm", fill: true, ...opts.textColumnAttrs }, (_Q = opts.text) != null ? _Q : []),
1343
+ column2({ padding: "lg", gap: "sm", fill: true, backgroundColor: "#f8fafc", ...opts.mediaColumnAttrs }, (_R = opts.media) != null ? _R : [])
1319
1344
  ]
1320
1345
  };
1321
1346
  }
1322
1347
  case "slide.mediaText": {
1323
- const opts = (_$ = input.mediaTextOpts) != null ? _$ : {};
1348
+ const opts = (_S = input.mediaTextOpts) != null ? _S : {};
1324
1349
  return {
1325
1350
  type: "slide",
1326
- attrs: defaults.slide({ className: "bg-white text-slate-900", ...opts.slideAttrs }),
1351
+ attrs: defaults.slide({ ...opts.slideAttrs, backgroundColor: (_U = (_T = opts.slideAttrs) == null ? void 0 : _T.backgroundColor) != null ? _U : "#ffffff" }),
1327
1352
  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
- )
1353
+ column2({ padding: "lg", gap: "sm", fill: true, backgroundColor: "#f8fafc", ...opts.mediaColumnAttrs }, (_V = opts.media) != null ? _V : []),
1354
+ column2({ padding: "lg", gap: "sm", fill: true, ...opts.textColumnAttrs }, (_W = opts.text) != null ? _W : [])
1336
1355
  ]
1337
1356
  };
1338
1357
  }
1339
1358
  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
- };
1359
+ const opts = (_X = input.stack2Opts) != null ? _X : {};
1360
+ const top = (_Y = opts.topColumns) != null ? _Y : [{ content: [blocks.heading("Title", 1), blocks.paragraph("Subhead")] }];
1361
+ const bottom = (_Z = opts.bottomColumns) != null ? _Z : [
1362
+ { content: [blocks.paragraph("Left detail")] },
1363
+ { content: [blocks.paragraph("Right detail")] }
1364
+ ];
1352
1365
  return {
1353
1366
  type: "slide",
1354
- attrs: defaults.slide({ className: "bg-white text-slate-900", ...opts.slideAttrs }),
1367
+ attrs: defaults.slide({ ...opts.slideAttrs, backgroundColor: (_$ = (__ = opts.slideAttrs) == null ? void 0 : __.backgroundColor) != null ? _$ : "#ffffff" }),
1355
1368
  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
- )
1369
+ ...top.map((c) => {
1370
+ var _a2;
1371
+ return column2({ padding: "md", gap: "sm", ...c.attrs }, (_a2 = c.content) != null ? _a2 : []);
1372
+ }),
1373
+ ...bottom.map((c) => {
1374
+ var _a2;
1375
+ return column2({ padding: "md", gap: "sm", ...c.attrs }, (_a2 = c.content) != null ? _a2 : []);
1376
+ })
1372
1377
  ]
1373
1378
  };
1374
1379
  }
@@ -1396,40 +1401,65 @@ var listTemplates = () => [
1396
1401
  var templatesV1Context = `
1397
1402
  BlockSlides templates API (v1)
1398
1403
 
1404
+ Document Hierarchy:
1405
+ doc \u2192 slide+ \u2192 block+
1406
+ Slides contain blocks directly - no mandatory row wrapper.
1407
+ Adjacent columns automatically form horizontal layouts via CSS.
1408
+
1399
1409
  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:
1410
+ - slide({ content?, slideAttrs? }): slide with direct block content
1411
+ - slide.singleCol({ content?, slideAttrs?, columnAttrs? }): single column layout
1412
+ - slide.twoCol(column1, column2, slideAttrs?): two columns side by side
1413
+ - slide.threeCol(col1, col2, col3, slideAttrs?): three columns side by side
1414
+ - slide.fourCol(col1, col2, col3, col4, slideAttrs?): four columns side by side
1415
+ - slide.hero({ heroOpts }): centered content on dark background
1416
+ - slide.imageCover({ imageCoverOpts }): full-bleed image with overlay
1417
+ - slide.quote({ quoteOpts }): centered blockquote
1418
+ - slide.agenda({ agendaOpts }): title with bullet list
1419
+ - slide.grid3/grid4({ multiColOpts }): equal-width column grids
1420
+ - slide.oneTwo/twoOne({ mediaTextOpts }): asymmetric layouts
1421
+ - slide.textMedia/mediaText({ mediaTextOpts }): text and media columns
1422
+ - slide.stack2({ stack2Opts }): stacked column sections
1423
+
1424
+ Base Block Attributes (available on ALL blocks):
1425
+ - align: "left" | "center" | "right" | "stretch" - horizontal alignment
1426
+ - justify: "start" | "center" | "end" | "space-between" - vertical distribution
1427
+ - padding: "none" | "sm" | "md" | "lg" - internal spacing (8px/16px/32px)
1428
+ - margin: "none" | "sm" | "md" | "lg" - external spacing
1429
+ - gap: "none" | "sm" | "md" | "lg" - space between children
1430
+ - backgroundColor: CSS color
1431
+ - backgroundImage: URL
1432
+ - borderRadius: "none" | "sm" | "md" | "lg" (4px/8px/16px)
1433
+ - border: CSS border
1434
+ - fill: boolean - fill available space
1435
+ - width: CSS width
1436
+ - height: CSS height
1437
+
1438
+ Block Helpers:
1413
1439
  - blocks.text(text, marks?)
1414
- - blocks.heading(text, level?)
1440
+ - blocks.heading(text, level?) - level 1-6
1415
1441
  - blocks.paragraph(text?)
1416
1442
  - blocks.bulletList([string | Block][])
1417
1443
  - blocks.codeBlock(code, language?)
1418
1444
  - blocks.horizontalRule()
1419
1445
  - blocks.hardBreak()
1420
- - blocks.imageBlock({ src, alt?, layout?, fullBleed?, align?, ...ImageBlockAttrs })
1446
+ - blocks.imageBlock({ src, size?, crop?, alt?, caption?, credit? })
1447
+ - size: "fill" | "fit" | "natural" - how image fills container
1448
+ - crop: "center" | "top" | "bottom" | "left" | "right" | corner positions
1421
1449
  - blocks.blockquote(content?)
1422
1450
  - blocks.listItem(content?)
1423
- - blocks.image({ src, alt?, title?, width?, height? })
1424
1451
  - blocks.youtube({ src?, start?, width?, height? })
1425
1452
 
1426
1453
  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.
1454
+ - Use blocks.column(content, attrs) to create columns
1455
+ - Use blocks.columnGroup(columns) to group columns horizontally
1456
+ - Call createTemplate({ preset: "slide.twoCol", left: [...], right: [...] })
1457
+ - Wrap returned slides in { type: "doc", content: [/* slides here */] }
1429
1458
 
1430
1459
  Notes:
1431
- - Size defaults to 16x9; override via slideAttrs.size.
1432
- - Layout defaults: singleCol uses "1"; twoCol uses "1-1" unless rowAttrs.layout overrides.
1460
+ - Size defaults to 16x9; override via slideAttrs.size
1461
+ - Use fill: true on columns to distribute space evenly
1462
+ - Use semantic spacing tokens (sm/md/lg) instead of raw pixel values
1433
1463
  `.trim();
1434
1464
 
1435
1465
  // src/templates/v1/presetTemplateBuilder.ts
@@ -1440,11 +1470,13 @@ var titleAndSubheader = {
1440
1470
  description: "Centered title and subtitle for a new presentation",
1441
1471
  icon: titleAndSubheaderIcon,
1442
1472
  build: () => slide2.singleCol({
1443
- rowAttrs: { className: "min-h-[720px] items-center justify-center" },
1444
1473
  columnAttrs: {
1445
- verticalAlign: "center",
1446
- horizontalAlign: "center",
1447
- className: "gap-6 p-12 text-center bg-white"
1474
+ justify: "center",
1475
+ align: "center",
1476
+ gap: "md",
1477
+ padding: "lg",
1478
+ fill: true,
1479
+ backgroundColor: "#ffffff"
1448
1480
  },
1449
1481
  content: [
1450
1482
  blocks.heading("Lorem ipsum dolor sit amet", 1),
@@ -1452,6 +1484,7 @@ var titleAndSubheader = {
1452
1484
  ]
1453
1485
  })
1454
1486
  };
1487
+ var a = titleAndSubheader;
1455
1488
  var imageTextIcon = '<svg width="96" height="72" viewBox="0 0 96 72" fill="none" xmlns="http://www.w3.org/2000/svg"><rect x="6" y="6" width="84" height="60" rx="4" stroke="#D4D4D8" stroke-width="2" fill="#F9FAFB"/><rect x="16" y="26" width="24" height="16" rx="2" fill="#E5E7EB"/><rect x="21" y="31" width="14" height="6" rx="1" fill="#D4D4D8"/><rect x="46" y="24" width="34" height="6" rx="1.5" fill="#D4D4D8"/><rect x="46" y="33" width="34" height="5" rx="1.5" fill="#E5E7EB"/><rect x="46" y="41" width="28" height="5" rx="1.5" fill="#E5E7EB"/></svg>';
1456
1489
  var textImageIcon = '<svg width="96" height="72" viewBox="0 0 96 72" fill="none" xmlns="http://www.w3.org/2000/svg"><rect x="6" y="6" width="84" height="60" rx="4" stroke="#D4D4D8" stroke-width="2" fill="#F9FAFB"/><rect x="18" y="24" width="34" height="6" rx="1.5" fill="#D4D4D8"/><rect x="18" y="33" width="34" height="5" rx="1.5" fill="#E5E7EB"/><rect x="18" y="41" width="28" height="5" rx="1.5" fill="#E5E7EB"/><rect x="56" y="26" width="24" height="16" rx="2" fill="#E5E7EB"/><rect x="61" y="31" width="14" height="6" rx="1" fill="#D4D4D8"/></svg>';
1457
1490
  var twoColumnsIcon = '<svg width="96" height="72" viewBox="0 0 96 72" fill="none" xmlns="http://www.w3.org/2000/svg"><rect x="6" y="6" width="84" height="60" rx="4" stroke="#D4D4D8" stroke-width="2" fill="#F9FAFB"/><rect x="18" y="22" width="26" height="6" rx="1.5" fill="#D4D4D8"/><rect x="18" y="31" width="26" height="5" rx="1.5" fill="#E5E7EB"/><rect x="18" y="39" width="22" height="5" rx="1.5" fill="#E5E7EB"/><rect x="52" y="22" width="26" height="6" rx="1.5" fill="#D4D4D8"/><rect x="52" y="31" width="26" height="5" rx="1.5" fill="#E5E7EB"/><rect x="52" y="39" width="22" height="5" rx="1.5" fill="#E5E7EB"/></svg>';
@@ -1474,94 +1507,93 @@ var imageAndText = {
1474
1507
  label: "Image & Text",
1475
1508
  description: "Image on left, text on right",
1476
1509
  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
- })
1510
+ build: () => slide2.twoCol(
1511
+ blocks.column(
1512
+ [
1513
+ blocks.imageBlock({
1514
+ src: "https://placehold.co/640x480/png",
1515
+ size: "fit"
1516
+ })
1517
+ ],
1518
+ {}
1519
+ ),
1520
+ blocks.column(
1521
+ [
1522
+ blocks.heading("Lorem ipsum dolor sit amet", 2),
1523
+ blocks.paragraph("Consectetur adipiscing elit. Sed do eiusmod tempor incididunt."),
1524
+ blocks.paragraph("Ut enim ad minim veniam, quis nostrud exercitation.")
1525
+ ],
1526
+ {
1527
+ padding: "lg",
1528
+ gap: "sm",
1529
+ fill: true
1530
+ }
1531
+ )
1532
+ )
1501
1533
  };
1502
1534
  var textAndImage = {
1503
1535
  key: "tpl.textAndImage",
1504
1536
  label: "Text & Image",
1505
1537
  description: "Text on left, image on right",
1506
1538
  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
- })
1539
+ build: () => slide2.twoCol(
1540
+ blocks.column(
1541
+ [
1542
+ blocks.heading("Lorem ipsum dolor sit amet", 2),
1543
+ blocks.paragraph("Consectetur adipiscing elit. Sed do eiusmod tempor incididunt."),
1544
+ blocks.paragraph("Ut enim ad minim veniam, quis nostrud exercitation.")
1545
+ ],
1546
+ {
1547
+ justify: "center",
1548
+ padding: "lg",
1549
+ gap: "sm",
1550
+ fill: true
1551
+ }
1552
+ ),
1553
+ blocks.column(
1554
+ [
1555
+ blocks.imageBlock({
1556
+ src: "https://placehold.co/640x480/png",
1557
+ size: "fit"
1558
+ })
1559
+ ],
1560
+ {
1561
+ align: "center",
1562
+ justify: "center",
1563
+ padding: "lg",
1564
+ fill: true
1565
+ }
1566
+ )
1567
+ )
1531
1568
  };
1532
1569
  var twoColumns = {
1533
1570
  key: "tpl.twoColumns",
1534
1571
  label: "Two Columns",
1535
1572
  description: "Header above two balanced text columns",
1536
1573
  icon: twoColumnsIcon,
1537
- build: () => slide2.singleCol({
1538
- columnAttrs: { className: "w-full p-6 gap-4", horizontalAlign: "stretch" },
1574
+ build: () => ({
1575
+ type: "slide",
1576
+ attrs: { id: "slide-1", size: "16x9" },
1539
1577
  content: [
1540
1578
  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
- }
1579
+ blocks.columnGroup([
1580
+ blocks.column(
1581
+ [
1582
+ blocks.paragraph("Lorem ipsum dolor sit amet."),
1583
+ blocks.paragraph("Consectetur adipiscing elit. Sed do eiusmod tempor incididunt."),
1584
+ blocks.paragraph("Ut enim ad minim veniam, quis nostrud exercitation.")
1585
+ ],
1586
+ { padding: "md", gap: "sm", fill: true }
1587
+ ),
1588
+ blocks.column(
1589
+ [
1590
+ blocks.paragraph("Lorem ipsum dolor sit amet."),
1591
+ blocks.paragraph("Consectetur adipiscing elit. Sed do eiusmod tempor incididunt."),
1592
+ blocks.paragraph("Ut enim ad minim veniam, quis nostrud exercitation.")
1593
+ ],
1594
+ { padding: "md", gap: "sm", fill: true }
1595
+ )
1596
+ ])
1565
1597
  ]
1566
1598
  })
1567
1599
  };
@@ -1570,34 +1602,29 @@ var twoColumnsWithHeader = {
1570
1602
  label: "Two Columns + Header",
1571
1603
  description: "Header plus two columns, each with its own heading",
1572
1604
  icon: twoColumnsHeaderIcon,
1573
- build: () => slide2.singleCol({
1574
- columnAttrs: { className: "w-full p-6 gap-4", horizontalAlign: "stretch" },
1605
+ build: () => ({
1606
+ type: "slide",
1607
+ attrs: { id: "slide-1", size: "16x9" },
1575
1608
  content: [
1576
1609
  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
- }
1610
+ blocks.columnGroup([
1611
+ blocks.column(
1612
+ [
1613
+ blocks.heading("Column heading", 4),
1614
+ blocks.paragraph("Consectetur adipiscing elit. Sed do eiusmod tempor incididunt."),
1615
+ blocks.paragraph("Ut enim ad minim veniam, quis nostrud exercitation.")
1616
+ ],
1617
+ { padding: "md", gap: "sm", fill: true }
1618
+ ),
1619
+ blocks.column(
1620
+ [
1621
+ blocks.heading("Column heading", 4),
1622
+ blocks.paragraph("Consectetur adipiscing elit. Sed do eiusmod tempor incididunt."),
1623
+ blocks.paragraph("Ut enim ad minim veniam, quis nostrud exercitation.")
1624
+ ],
1625
+ { padding: "md", gap: "sm", fill: true }
1626
+ )
1627
+ ])
1601
1628
  ]
1602
1629
  })
1603
1630
  };
@@ -1606,39 +1633,33 @@ var threeColumns = {
1606
1633
  label: "Three Columns",
1607
1634
  description: "Balanced three-column text",
1608
1635
  icon: threeColumnsIcon,
1609
- build: () => slide2.singleCol({
1610
- columnAttrs: { className: "w-full p-6 gap-4", horizontalAlign: "stretch" },
1636
+ build: () => ({
1637
+ type: "slide",
1638
+ attrs: { id: "slide-1", size: "16x9" },
1611
1639
  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
- }
1640
+ blocks.columnGroup([
1641
+ blocks.column(
1642
+ [
1643
+ blocks.paragraph("Lorem ipsum dolor sit amet."),
1644
+ blocks.paragraph("Consectetur adipiscing elit. Sed do eiusmod tempor incididunt.")
1645
+ ],
1646
+ { padding: "sm", gap: "sm", fill: true }
1647
+ ),
1648
+ blocks.column(
1649
+ [
1650
+ blocks.paragraph("Ut enim ad minim veniam."),
1651
+ blocks.paragraph("Quis nostrud exercitation ullamco laboris.")
1652
+ ],
1653
+ { padding: "sm", gap: "sm", fill: true }
1654
+ ),
1655
+ blocks.column(
1656
+ [
1657
+ blocks.paragraph("Nisi ut aliquip ex ea commodo consequat."),
1658
+ blocks.paragraph("Duis aute irure dolor in reprehenderit.")
1659
+ ],
1660
+ { padding: "sm", gap: "sm", fill: true }
1661
+ )
1662
+ ])
1642
1663
  ]
1643
1664
  })
1644
1665
  };
@@ -1647,43 +1668,37 @@ var threeColumnsWithHeader = {
1647
1668
  label: "Three Columns + Header",
1648
1669
  description: "Header plus three columns",
1649
1670
  icon: threeColumnsHeaderIcon,
1650
- build: () => slide2.singleCol({
1651
- columnAttrs: { className: "w-full p-6 gap-4", horizontalAlign: "stretch" },
1671
+ build: () => ({
1672
+ type: "slide",
1673
+ attrs: { id: "slide-1", size: "16x9" },
1652
1674
  content: [
1653
1675
  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
- }
1676
+ blocks.columnGroup([
1677
+ blocks.column(
1678
+ [
1679
+ blocks.heading("Column heading", 4),
1680
+ blocks.paragraph("Lorem ipsum dolor sit amet."),
1681
+ blocks.paragraph("Consectetur adipiscing elit. Sed do eiusmod tempor incididunt.")
1682
+ ],
1683
+ { padding: "sm", gap: "sm", fill: true }
1684
+ ),
1685
+ blocks.column(
1686
+ [
1687
+ blocks.heading("Column heading", 4),
1688
+ blocks.paragraph("Ut enim ad minim veniam."),
1689
+ blocks.paragraph("Quis nostrud exercitation ullamco laboris.")
1690
+ ],
1691
+ { padding: "sm", gap: "sm", fill: true }
1692
+ ),
1693
+ blocks.column(
1694
+ [
1695
+ blocks.heading("Column heading", 4),
1696
+ blocks.paragraph("Nisi ut aliquip ex ea commodo consequat."),
1697
+ blocks.paragraph("Duis aute irure dolor in reprehenderit.")
1698
+ ],
1699
+ { padding: "sm", gap: "sm", fill: true }
1700
+ )
1701
+ ])
1687
1702
  ]
1688
1703
  })
1689
1704
  };
@@ -1692,52 +1707,45 @@ var fourColumnsWithHeader = {
1692
1707
  label: "Four Columns + Header",
1693
1708
  description: "Header plus four columns",
1694
1709
  icon: fourColumnsHeaderIcon,
1695
- build: () => slide2.singleCol({
1696
- columnAttrs: { className: "w-full p-6 gap-4", horizontalAlign: "stretch" },
1710
+ build: () => ({
1711
+ type: "slide",
1712
+ attrs: { id: "slide-1", size: "16x9" },
1697
1713
  content: [
1698
1714
  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
- }
1715
+ blocks.columnGroup([
1716
+ blocks.column(
1717
+ [
1718
+ blocks.heading("Column heading", 4),
1719
+ blocks.paragraph("Lorem ipsum dolor sit amet."),
1720
+ blocks.paragraph("Consectetur adipiscing elit.")
1721
+ ],
1722
+ { padding: "sm", gap: "sm", fill: true }
1723
+ ),
1724
+ blocks.column(
1725
+ [
1726
+ blocks.heading("Column heading", 4),
1727
+ blocks.paragraph("Ut enim ad minim veniam."),
1728
+ blocks.paragraph("Quis nostrud exercitation ullamco laboris.")
1729
+ ],
1730
+ { padding: "sm", gap: "sm", fill: true }
1731
+ ),
1732
+ blocks.column(
1733
+ [
1734
+ blocks.heading("Column heading", 4),
1735
+ blocks.paragraph("Nisi ut aliquip ex ea commodo consequat."),
1736
+ blocks.paragraph("Duis aute irure dolor in reprehenderit.")
1737
+ ],
1738
+ { padding: "sm", gap: "sm", fill: true }
1739
+ ),
1740
+ blocks.column(
1741
+ [
1742
+ blocks.heading("Column heading", 4),
1743
+ blocks.paragraph("Excepteur sint occaecat cupidatat."),
1744
+ blocks.paragraph("Sunt in culpa qui officia.")
1745
+ ],
1746
+ { padding: "sm", gap: "sm", fill: true }
1747
+ )
1748
+ ])
1741
1749
  ]
1742
1750
  })
1743
1751
  };
@@ -1747,14 +1755,12 @@ var fullImage = {
1747
1755
  description: "Edge-to-edge image filling the slide",
1748
1756
  icon: fullImageIcon,
1749
1757
  build: () => slide2.singleCol({
1750
- rowAttrs: { className: "min-h-[720px]" },
1751
- columnAttrs: { className: "p-0 w-full h-full", horizontalAlign: "stretch" },
1758
+ columnAttrs: { padding: "none", fill: true, align: "stretch" },
1752
1759
  content: [
1753
1760
  blocks.imageBlock({
1754
1761
  src: "https://placehold.co/1920x1080/png",
1755
- layout: "cover",
1756
- fullBleed: true,
1757
- align: "center"
1762
+ size: "fill",
1763
+ crop: "center"
1758
1764
  })
1759
1765
  ]
1760
1766
  })
@@ -1764,21 +1770,21 @@ var fourColumns = {
1764
1770
  label: "Four Columns",
1765
1771
  description: "Balanced four-column text",
1766
1772
  icon: fourColumnsIcon,
1767
- build: () => slide2.singleCol({
1768
- columnAttrs: { className: "w-full p-4 gap-4", horizontalAlign: "stretch" },
1773
+ build: () => ({
1774
+ type: "slide",
1775
+ attrs: { id: "slide-1", size: "16x9" },
1769
1776
  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
- }
1777
+ blocks.columnGroup(
1778
+ Array.from({ length: 4 }).map(
1779
+ () => blocks.column(
1780
+ [
1781
+ blocks.paragraph("Lorem ipsum dolor sit amet."),
1782
+ blocks.paragraph("Consectetur adipiscing elit.")
1783
+ ],
1784
+ { padding: "sm", gap: "sm", fill: true }
1785
+ )
1786
+ )
1787
+ )
1782
1788
  ]
1783
1789
  })
1784
1790
  };
@@ -1788,7 +1794,7 @@ var titleWithBullets = {
1788
1794
  description: "Header and a bullet list",
1789
1795
  icon: titleBulletsIcon,
1790
1796
  build: () => slide2.singleCol({
1791
- columnAttrs: { className: "p-6 gap-4" },
1797
+ columnAttrs: { padding: "md", gap: "md" },
1792
1798
  content: [
1793
1799
  blocks.heading("Lorem ipsum dolor sit amet", 2),
1794
1800
  blocks.bulletList([
@@ -1804,86 +1810,95 @@ var titleBulletsAndImage = {
1804
1810
  label: "Title, Bullets & Image",
1805
1811
  description: "Title with bullets and an image",
1806
1812
  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
- })
1813
+ build: () => slide2.twoCol(
1814
+ blocks.column(
1815
+ [
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
+ { padding: "md", gap: "sm", fill: true }
1824
+ ),
1825
+ blocks.column(
1826
+ [
1827
+ blocks.imageBlock({
1828
+ src: "https://placehold.co/480x360/png",
1829
+ size: "fit"
1830
+ })
1831
+ ],
1832
+ {
1833
+ align: "center",
1834
+ justify: "center",
1835
+ padding: "md",
1836
+ fill: true
1837
+ }
1838
+ )
1839
+ )
1831
1840
  };
1832
1841
  var accentLeft = {
1833
1842
  key: "tpl.accentLeft",
1834
1843
  label: "Accent left",
1835
1844
  description: "Accent band with image on the left, text on the right",
1836
1845
  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
- })
1846
+ build: () => slide2.twoCol(
1847
+ blocks.column(
1848
+ [
1849
+ blocks.imageBlock({
1850
+ src: "https://placehold.co/320x240/png",
1851
+ size: "fill",
1852
+ crop: "center"
1853
+ })
1854
+ ],
1855
+ {
1856
+ backgroundColor: "#f1f5f9",
1857
+ padding: "none",
1858
+ fill: true,
1859
+ align: "stretch"
1860
+ }
1861
+ ),
1862
+ blocks.column(
1863
+ [
1864
+ blocks.heading("Accent left", 3),
1865
+ blocks.paragraph("Short supporting copy goes here."),
1866
+ blocks.paragraph("Add one more line if needed.")
1867
+ ],
1868
+ { padding: "md", gap: "sm", fill: true, justify: "center" }
1869
+ )
1870
+ )
1859
1871
  };
1860
1872
  var accentRight = {
1861
1873
  key: "tpl.accentRight",
1862
1874
  label: "Accent right",
1863
1875
  description: "Accent band with image on the right, text on the left",
1864
1876
  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
- })
1877
+ build: () => slide2.twoCol(
1878
+ blocks.column(
1879
+ [
1880
+ blocks.heading("Accent right", 3),
1881
+ blocks.paragraph("Short supporting copy goes here."),
1882
+ blocks.paragraph("Add one more line if needed.")
1883
+ ],
1884
+ { padding: "md", gap: "sm", fill: true, justify: "center" }
1885
+ ),
1886
+ blocks.column(
1887
+ [
1888
+ blocks.imageBlock({
1889
+ src: "https://placehold.co/320x240/png",
1890
+ size: "fill",
1891
+ crop: "center"
1892
+ })
1893
+ ],
1894
+ {
1895
+ backgroundColor: "#f1f5f9",
1896
+ padding: "none",
1897
+ fill: true,
1898
+ align: "stretch"
1899
+ }
1900
+ )
1901
+ )
1887
1902
  };
1888
1903
  var accentTop = {
1889
1904
  key: "tpl.accentTop",
@@ -1892,39 +1907,26 @@ var accentTop = {
1892
1907
  icon: accentTopIcon,
1893
1908
  build: () => ({
1894
1909
  type: "slide",
1895
- attrs: { id: "slide-1", size: "16x9", className: "" },
1910
+ attrs: { id: "slide-1", size: "16x9" },
1896
1911
  content: [
1897
1912
  {
1898
- type: "row",
1899
- attrs: { layout: "1", className: "w-full items-stretch h-[20vh] min-h-[140px]" },
1913
+ type: "column",
1914
+ attrs: { backgroundColor: "#f1f5f9", padding: "none", height: "200px", align: "stretch" },
1900
1915
  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
- }
1916
+ blocks.imageBlock({
1917
+ src: "https://placehold.co/1200x400/png",
1918
+ size: "fill",
1919
+ crop: "center"
1920
+ })
1913
1921
  ]
1914
1922
  },
1915
1923
  {
1916
- type: "row",
1917
- attrs: { layout: "1", className: "w-full flex-1" },
1924
+ type: "column",
1925
+ attrs: { padding: "md", gap: "sm", fill: true, justify: "end" },
1918
1926
  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
- }
1927
+ blocks.heading("Accent top", 3),
1928
+ blocks.paragraph("Short supporting copy goes here."),
1929
+ blocks.paragraph("Add one more line if needed.")
1928
1930
  ]
1929
1931
  }
1930
1932
  ]
@@ -1935,112 +1937,105 @@ var accentRightFit = {
1935
1937
  label: "Accent right (fit)",
1936
1938
  description: "Text with a tighter image card on the right",
1937
1939
  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: [
1940
+ build: () => slide2.twoCol(
1941
+ blocks.column(
1942
+ [
1943
+ blocks.heading("Accent right (fit)", 3),
1944
+ blocks.paragraph("Short supporting copy goes here."),
1945
+ blocks.paragraph("Add one more line if needed.")
1946
+ ],
1947
+ { padding: "md", gap: "sm", fill: true, justify: "center" }
1948
+ ),
1949
+ blocks.column(
1950
+ [
1951
+ blocks.column(
1952
+ [
1953
+ blocks.imageBlock({
1954
+ src: "https://placehold.co/240x200/png",
1955
+ size: "fit"
1956
+ })
1957
+ ],
1958
+ { backgroundColor: "#f1f5f9", padding: "md", gap: "sm", borderRadius: "lg", align: "center" }
1959
+ )
1960
+ ],
1952
1961
  {
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
- ]
1962
+ padding: "md",
1963
+ fill: true,
1964
+ justify: "center",
1965
+ align: "center"
1963
1966
  }
1964
- ]
1965
- })
1967
+ )
1968
+ )
1966
1969
  };
1967
1970
  var accentLeftFit = {
1968
1971
  key: "tpl.accentLeftFit",
1969
1972
  label: "Accent left (fit)",
1970
1973
  description: "Compact image card on the left, text on the right",
1971
1974
  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: [
1975
+ build: () => slide2.twoCol(
1976
+ blocks.column(
1977
+ [
1978
+ blocks.column(
1979
+ [
1980
+ blocks.imageBlock({
1981
+ src: "https://placehold.co/240x200/png",
1982
+ size: "fit"
1983
+ })
1984
+ ],
1985
+ { backgroundColor: "#f1f5f9", padding: "md", gap: "sm", borderRadius: "lg", align: "center" }
1986
+ )
1987
+ ],
1981
1988
  {
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
- ]
1989
+ padding: "md",
1990
+ fill: true,
1991
+ justify: "center",
1992
+ align: "center"
1992
1993
  }
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
- })
1994
+ ),
1995
+ blocks.column(
1996
+ [
1997
+ blocks.heading("Accent left (fit)", 3),
1998
+ blocks.paragraph("Short supporting copy goes here."),
1999
+ blocks.paragraph("Add one more line if needed.")
2000
+ ],
2001
+ { padding: "md", gap: "sm", fill: true, justify: "center" }
2002
+ )
2003
+ )
2000
2004
  };
2001
2005
  var twoImageColumns = {
2002
2006
  key: "tpl.twoImageColumns",
2003
2007
  label: "2 image columns",
2004
2008
  description: "Header with two image cards",
2005
2009
  icon: twoImageColumnsIcon,
2006
- build: () => slide2.singleCol({
2007
- columnAttrs: { className: "w-full p-6 gap-4", horizontalAlign: "stretch" },
2010
+ build: () => ({
2011
+ type: "slide",
2012
+ attrs: { id: "slide-1", size: "16x9" },
2008
2013
  content: [
2009
2014
  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
- }
2015
+ blocks.columnGroup([
2016
+ blocks.column(
2017
+ [
2018
+ blocks.imageBlock({
2019
+ src: "https://placehold.co/640x360/png",
2020
+ size: "fit"
2021
+ }),
2022
+ blocks.heading("Image title", 4),
2023
+ blocks.paragraph("Short supporting copy goes here.")
2024
+ ],
2025
+ { padding: "md", gap: "sm", fill: true }
2026
+ ),
2027
+ blocks.column(
2028
+ [
2029
+ blocks.imageBlock({
2030
+ src: "https://placehold.co/640x360/png",
2031
+ size: "fit"
2032
+ }),
2033
+ blocks.heading("Image title", 4),
2034
+ blocks.paragraph("Short supporting copy goes here.")
2035
+ ],
2036
+ { padding: "md", gap: "sm", fill: true }
2037
+ )
2038
+ ])
2044
2039
  ]
2045
2040
  })
2046
2041
  };
@@ -2067,11 +2062,9 @@ var registry = {
2067
2062
  var listPresetTemplates = () => Object.values(registry);
2068
2063
  var buildPresetTemplate = (key) => registry[key].build();
2069
2064
  export {
2070
- v1_exports4 as bundlesV1,
2065
+ v1_exports3 as bundlesV1,
2071
2066
  v1_exports as contextsV1,
2072
- v1_exports2 as examplesV1,
2073
- v1_exports5 as recipesV1,
2074
- v1_exports3 as schemasV1,
2075
- v1_exports6 as templatesV1
2067
+ v1_exports2 as schemasV1,
2068
+ v1_exports4 as templatesV1
2076
2069
  };
2077
2070
  //# sourceMappingURL=index.js.map