@blockslides/ai-context 0.2.0 → 0.3.1

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