@blockslides/ai-context 0.2.0 → 0.3.0

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