@unlayer/react-elements 0.1.9 → 0.1.10

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.
package/dist/index.d.cts CHANGED
@@ -257,20 +257,69 @@ type ItemProps<TValues> = SemanticProps$1<TValues, React.ReactNode> & {
257
257
  style?: React.CSSProperties;
258
258
  mode?: "web" | "email" | "document";
259
259
  };
260
+ /** fontFamily accepts a ready stack object or a bare family-name string. */
261
+ type FontFamilyInput = {
262
+ label: string;
263
+ value: string;
264
+ } | string;
265
+ /** fontWeight accepts a number, a numeric string, or a CSS keyword. */
266
+ type FontWeightInput = number | `${number}` | "normal" | "bold" | "lighter" | "bolder";
267
+ /** A CSS size: a number (treated as px) or a string ("24px", "50%", "1.5em"). */
268
+ type SizeInput = number | (string & {});
269
+ /** Heading levels (h1–h6). */
270
+ type HeadingLevel = "h1" | "h2" | "h3" | "h4" | "h5" | "h6";
271
+ /** Shared text/style props, agent-friendly (replace the loose `any` flat keys). */
272
+ type TextStyleProps = {
273
+ fontFamily?: FontFamilyInput;
274
+ fontWeight?: FontWeightInput;
275
+ fontSize?: SizeInput;
276
+ lineHeight?: SizeInput;
277
+ /** Letter spacing — a CSS string ("0.5px", "-0.01em") or a number (px). */
278
+ letterSpacing?: SizeInput;
279
+ color?: string;
280
+ };
281
+ /** Image `src` accepts a plain URL string or the value object (loosened sizing). */
282
+ type ImageSrcInput = string | {
283
+ url: string;
284
+ width?: SizeInput;
285
+ height?: number;
286
+ autoWidth?: boolean;
287
+ maxWidth?: SizeInput;
288
+ [key: string]: unknown;
289
+ };
260
290
  /** Button component props */
261
- type ButtonProps = ItemProps<ButtonValues>;
291
+ type ButtonProps = Omit<ItemProps<ButtonValues>, keyof TextStyleProps | "width"> & TextStyleProps & {
292
+ /** Display width — a number/px pins the button; "100%" makes it full-width. */
293
+ width?: SizeInput;
294
+ };
262
295
  /** Heading component props */
263
- type HeadingProps = ItemProps<HeadingValues>;
296
+ type HeadingProps = Omit<ItemProps<HeadingValues>, keyof TextStyleProps | "headingType"> & TextStyleProps & {
297
+ /** Heading level h1–h6. */
298
+ headingType?: HeadingLevel;
299
+ /** Alias for `headingType`. */
300
+ level?: HeadingLevel;
301
+ /** Heading text (or use children). */
302
+ text?: string;
303
+ };
264
304
  /** Divider component props */
265
305
  type DividerProps = ItemProps<DividerValues>;
266
306
  /** HTML component props */
267
307
  type HtmlProps = ItemProps<HtmlValues>;
268
308
  /** Paragraph component props */
269
- type ParagraphProps = ItemProps<ParagraphValues>;
309
+ type ParagraphProps = Omit<ItemProps<ParagraphValues>, keyof TextStyleProps> & TextStyleProps & {
310
+ /** Plain-text content (or use `html` for inline formatting, or children). */
311
+ text?: string;
312
+ };
270
313
  /** Image component props — supports `alt` shorthand for `altText`. */
271
- type ImageProps = ItemProps<ImageValues> & {
314
+ type ImageProps = Omit<ItemProps<ImageValues>, "src" | "width" | "maxWidth"> & {
272
315
  /** Alt text (alias for altText) */
273
316
  alt?: string;
317
+ /** Image URL string, or the value object `{ url, width?, maxWidth?, ... }`. */
318
+ src?: ImageSrcInput;
319
+ /** Display width — number/px pins the image; "50%" sets a percentage width. */
320
+ width?: SizeInput;
321
+ /** Display width as a CSS value ("50%", "300px"). */
322
+ maxWidth?: SizeInput;
274
323
  };
275
324
  /** Social component props — supports `icons` shorthand array. */
276
325
  type SocialProps = ItemProps<SocialValues> & {
@@ -338,6 +387,14 @@ type ItemComponentProps<TSemanticProps> = BaseItemComponentProps & TSemanticProp
338
387
  */
339
388
  type SemanticProps<T> = SemanticProps$1<T, React.ReactNode>;
340
389
 
390
+ /**
391
+ * Button semantic props — agent-friendly text/style types (replacing the loose
392
+ * `any` flat props) plus a CSS-style `width` (number/px pins; "100%" full-width).
393
+ */
394
+ type ButtonSemanticProps = Omit<SemanticProps<ButtonValues>, keyof TextStyleProps | "width"> & TextStyleProps & {
395
+ /** Display width — a number/px pins the button; "100%" makes it full-width. */
396
+ width?: SizeInput;
397
+ };
341
398
  /**
342
399
  * Button - Universal SSR/Client Component with Automatic Semantic Props
343
400
  *
@@ -375,7 +432,7 @@ type SemanticProps<T> = SemanticProps$1<T, React.ReactNode>;
375
432
  * </Button>
376
433
  * ```
377
434
  */
378
- declare const Button: React$1.FC<ItemComponentProps<SemanticProps<ButtonValues>>>;
435
+ declare const Button: React$1.FC<ItemComponentProps<ButtonSemanticProps>>;
379
436
 
380
437
  /**
381
438
  * Divider - Universal SSR/Client Component with Automatic Semantic Props
@@ -395,6 +452,18 @@ declare const Button: React$1.FC<ItemComponentProps<SemanticProps<ButtonValues>>
395
452
  */
396
453
  declare const Divider: React$1.FC<ItemComponentProps<SemanticProps<DividerValues>>>;
397
454
 
455
+ /**
456
+ * Heading semantic props — agent-friendly text/style types (replacing the loose
457
+ * `any` flat props) plus the `level` alias and h1–h6 levels.
458
+ */
459
+ type HeadingSemanticProps = Omit<SemanticProps<HeadingValues>, keyof TextStyleProps | "headingType"> & TextStyleProps & {
460
+ /** Heading level h1–h6. */
461
+ headingType?: HeadingLevel;
462
+ /** Alias for `headingType`. */
463
+ level?: HeadingLevel;
464
+ /** Heading text (or use children). */
465
+ text?: string;
466
+ };
398
467
  /**
399
468
  * Heading - Universal SSR/Client Component with Semantic Props API
400
469
  *
@@ -415,7 +484,7 @@ declare const Divider: React$1.FC<ItemComponentProps<SemanticProps<DividerValues
415
484
  * <Heading values={{ headingType: "h1", color: "#222" }}>Welcome</Heading>
416
485
  * ```
417
486
  */
418
- declare const Heading: React$1.FC<ItemComponentProps<SemanticProps<HeadingValues>>>;
487
+ declare const Heading: React$1.FC<ItemComponentProps<HeadingSemanticProps>>;
419
488
 
420
489
  /**
421
490
  * Html - Universal SSR/Client Component for custom HTML with Automatic Semantic Props
@@ -432,9 +501,20 @@ declare const Heading: React$1.FC<ItemComponentProps<SemanticProps<HeadingValues
432
501
  */
433
502
  declare const Html: React$1.FC<ItemComponentProps<SemanticProps<HtmlValues>>>;
434
503
 
435
- type ImageSemanticProps = SemanticProps<ImageValues> & {
504
+ /**
505
+ * Image semantic props — agent-friendly `src` (plain URL string or value object)
506
+ * and CSS-style sizing (number/px pins, "50%" sets a percentage), replacing the
507
+ * loose `any` flat props.
508
+ */
509
+ type ImageSemanticProps = Omit<SemanticProps<ImageValues>, "src" | "width" | "maxWidth"> & {
436
510
  /** Alt text (alias for altText) */
437
511
  alt?: string;
512
+ /** Image URL string, or the value object `{ url, width?, maxWidth?, ... }`. */
513
+ src?: ImageSrcInput;
514
+ /** Display width — number/px pins the image; "50%" sets a percentage width. */
515
+ width?: SizeInput;
516
+ /** Display width as a CSS value ("50%", "300px"). */
517
+ maxWidth?: SizeInput;
438
518
  };
439
519
  /**
440
520
  * Image - Renders an image element.
@@ -479,6 +559,14 @@ type MenuSemanticProps = SemanticProps<MenuValues> & {
479
559
  */
480
560
  declare const Menu: React$1.FC<ItemComponentProps<MenuSemanticProps>>;
481
561
 
562
+ /**
563
+ * Paragraph semantic props — agent-friendly text/style types (replacing the
564
+ * loose `any` flat props) plus the `text` shorthand (converted to textJson).
565
+ */
566
+ type ParagraphSemanticProps = Omit<SemanticProps<ParagraphValues>, keyof TextStyleProps> & TextStyleProps & {
567
+ /** Plain-text content (or use `html` for inline formatting, or children). */
568
+ text?: string;
569
+ };
482
570
  /**
483
571
  * Paragraph - Universal SSR/Client Component with Semantic Props API
484
572
  *
@@ -499,7 +587,7 @@ declare const Menu: React$1.FC<ItemComponentProps<MenuSemanticProps>>;
499
587
  * <Paragraph values={{ textJson: "...", color: "#555" }} />
500
588
  * ```
501
589
  */
502
- declare const Paragraph: React$1.FC<ItemComponentProps<SemanticProps<ParagraphValues>>>;
590
+ declare const Paragraph: React$1.FC<ItemComponentProps<ParagraphSemanticProps>>;
503
591
 
504
592
  type SocialSemanticProps = SemanticProps<SocialValues> & {
505
593
  /** Social icons shorthand (array of {name, url}) */
@@ -578,7 +666,7 @@ type VideoSemanticProps = SemanticProps<VideoValues> & {
578
666
  */
579
667
  declare const Video: React$1.FC<ItemComponentProps<VideoSemanticProps>>;
580
668
 
581
- interface RowProps extends SemanticProps<RowValues> {
669
+ type RowProps = Omit<SemanticProps<RowValues>, "padding"> & {
582
670
  children?: React__default.ReactNode;
583
671
  layout?: ColumnLayout;
584
672
  cells?: number[];
@@ -588,12 +676,14 @@ interface RowProps extends SemanticProps<RowValues> {
588
676
  index?: number;
589
677
  bodyValues?: any;
590
678
  collection?: string;
679
+ /** Padding — a CSS string ("0 48px", "20px 40px") or a number (px). */
680
+ padding?: SizeInput;
591
681
  /** @internal - Unlayer config threaded from UnlayerProvider via Body */
592
682
  _config?: UnlayerConfig;
593
- }
683
+ };
594
684
  declare const Row: React__default.FC<RowProps>;
595
685
 
596
- interface ColumnProps extends SemanticProps<ColumnValues> {
686
+ type ColumnProps = Omit<SemanticProps<ColumnValues>, "padding"> & {
597
687
  children?: React__default.ReactNode;
598
688
  index?: number;
599
689
  cells?: number[];
@@ -602,12 +692,14 @@ interface ColumnProps extends SemanticProps<ColumnValues> {
602
692
  mode?: RenderMode;
603
693
  className?: string;
604
694
  style?: React__default.CSSProperties;
695
+ /** Padding — a CSS string ("0 24px", "10px") or a number (px). */
696
+ padding?: SizeInput;
605
697
  /** @internal - Unlayer config threaded from UnlayerProvider via Body/Row */
606
698
  _config?: UnlayerConfig;
607
- }
699
+ };
608
700
  declare const Column: React__default.FC<ColumnProps>;
609
701
 
610
- interface BodyProps extends SemanticProps<BodyValues> {
702
+ type BodyProps = Omit<SemanticProps<BodyValues>, "padding"> & {
611
703
  children?: React__default.ReactNode;
612
704
  mode?: RenderMode;
613
705
  className?: string;
@@ -617,7 +709,9 @@ interface BodyProps extends SemanticProps<BodyValues> {
617
709
  config?: Partial<UnlayerConfig>;
618
710
  /** Preview text shown in email client inboxes (email mode only) */
619
711
  previewText?: string;
620
- }
712
+ /** Padding — a CSS string ("0 48px", "20px") or a number (px). */
713
+ padding?: SizeInput;
714
+ };
621
715
  /**
622
716
  * Body - Universal Server/Client Component
623
717
  *
package/dist/index.d.ts CHANGED
@@ -257,20 +257,69 @@ type ItemProps<TValues> = SemanticProps$1<TValues, React.ReactNode> & {
257
257
  style?: React.CSSProperties;
258
258
  mode?: "web" | "email" | "document";
259
259
  };
260
+ /** fontFamily accepts a ready stack object or a bare family-name string. */
261
+ type FontFamilyInput = {
262
+ label: string;
263
+ value: string;
264
+ } | string;
265
+ /** fontWeight accepts a number, a numeric string, or a CSS keyword. */
266
+ type FontWeightInput = number | `${number}` | "normal" | "bold" | "lighter" | "bolder";
267
+ /** A CSS size: a number (treated as px) or a string ("24px", "50%", "1.5em"). */
268
+ type SizeInput = number | (string & {});
269
+ /** Heading levels (h1–h6). */
270
+ type HeadingLevel = "h1" | "h2" | "h3" | "h4" | "h5" | "h6";
271
+ /** Shared text/style props, agent-friendly (replace the loose `any` flat keys). */
272
+ type TextStyleProps = {
273
+ fontFamily?: FontFamilyInput;
274
+ fontWeight?: FontWeightInput;
275
+ fontSize?: SizeInput;
276
+ lineHeight?: SizeInput;
277
+ /** Letter spacing — a CSS string ("0.5px", "-0.01em") or a number (px). */
278
+ letterSpacing?: SizeInput;
279
+ color?: string;
280
+ };
281
+ /** Image `src` accepts a plain URL string or the value object (loosened sizing). */
282
+ type ImageSrcInput = string | {
283
+ url: string;
284
+ width?: SizeInput;
285
+ height?: number;
286
+ autoWidth?: boolean;
287
+ maxWidth?: SizeInput;
288
+ [key: string]: unknown;
289
+ };
260
290
  /** Button component props */
261
- type ButtonProps = ItemProps<ButtonValues>;
291
+ type ButtonProps = Omit<ItemProps<ButtonValues>, keyof TextStyleProps | "width"> & TextStyleProps & {
292
+ /** Display width — a number/px pins the button; "100%" makes it full-width. */
293
+ width?: SizeInput;
294
+ };
262
295
  /** Heading component props */
263
- type HeadingProps = ItemProps<HeadingValues>;
296
+ type HeadingProps = Omit<ItemProps<HeadingValues>, keyof TextStyleProps | "headingType"> & TextStyleProps & {
297
+ /** Heading level h1–h6. */
298
+ headingType?: HeadingLevel;
299
+ /** Alias for `headingType`. */
300
+ level?: HeadingLevel;
301
+ /** Heading text (or use children). */
302
+ text?: string;
303
+ };
264
304
  /** Divider component props */
265
305
  type DividerProps = ItemProps<DividerValues>;
266
306
  /** HTML component props */
267
307
  type HtmlProps = ItemProps<HtmlValues>;
268
308
  /** Paragraph component props */
269
- type ParagraphProps = ItemProps<ParagraphValues>;
309
+ type ParagraphProps = Omit<ItemProps<ParagraphValues>, keyof TextStyleProps> & TextStyleProps & {
310
+ /** Plain-text content (or use `html` for inline formatting, or children). */
311
+ text?: string;
312
+ };
270
313
  /** Image component props — supports `alt` shorthand for `altText`. */
271
- type ImageProps = ItemProps<ImageValues> & {
314
+ type ImageProps = Omit<ItemProps<ImageValues>, "src" | "width" | "maxWidth"> & {
272
315
  /** Alt text (alias for altText) */
273
316
  alt?: string;
317
+ /** Image URL string, or the value object `{ url, width?, maxWidth?, ... }`. */
318
+ src?: ImageSrcInput;
319
+ /** Display width — number/px pins the image; "50%" sets a percentage width. */
320
+ width?: SizeInput;
321
+ /** Display width as a CSS value ("50%", "300px"). */
322
+ maxWidth?: SizeInput;
274
323
  };
275
324
  /** Social component props — supports `icons` shorthand array. */
276
325
  type SocialProps = ItemProps<SocialValues> & {
@@ -338,6 +387,14 @@ type ItemComponentProps<TSemanticProps> = BaseItemComponentProps & TSemanticProp
338
387
  */
339
388
  type SemanticProps<T> = SemanticProps$1<T, React.ReactNode>;
340
389
 
390
+ /**
391
+ * Button semantic props — agent-friendly text/style types (replacing the loose
392
+ * `any` flat props) plus a CSS-style `width` (number/px pins; "100%" full-width).
393
+ */
394
+ type ButtonSemanticProps = Omit<SemanticProps<ButtonValues>, keyof TextStyleProps | "width"> & TextStyleProps & {
395
+ /** Display width — a number/px pins the button; "100%" makes it full-width. */
396
+ width?: SizeInput;
397
+ };
341
398
  /**
342
399
  * Button - Universal SSR/Client Component with Automatic Semantic Props
343
400
  *
@@ -375,7 +432,7 @@ type SemanticProps<T> = SemanticProps$1<T, React.ReactNode>;
375
432
  * </Button>
376
433
  * ```
377
434
  */
378
- declare const Button: React$1.FC<ItemComponentProps<SemanticProps<ButtonValues>>>;
435
+ declare const Button: React$1.FC<ItemComponentProps<ButtonSemanticProps>>;
379
436
 
380
437
  /**
381
438
  * Divider - Universal SSR/Client Component with Automatic Semantic Props
@@ -395,6 +452,18 @@ declare const Button: React$1.FC<ItemComponentProps<SemanticProps<ButtonValues>>
395
452
  */
396
453
  declare const Divider: React$1.FC<ItemComponentProps<SemanticProps<DividerValues>>>;
397
454
 
455
+ /**
456
+ * Heading semantic props — agent-friendly text/style types (replacing the loose
457
+ * `any` flat props) plus the `level` alias and h1–h6 levels.
458
+ */
459
+ type HeadingSemanticProps = Omit<SemanticProps<HeadingValues>, keyof TextStyleProps | "headingType"> & TextStyleProps & {
460
+ /** Heading level h1–h6. */
461
+ headingType?: HeadingLevel;
462
+ /** Alias for `headingType`. */
463
+ level?: HeadingLevel;
464
+ /** Heading text (or use children). */
465
+ text?: string;
466
+ };
398
467
  /**
399
468
  * Heading - Universal SSR/Client Component with Semantic Props API
400
469
  *
@@ -415,7 +484,7 @@ declare const Divider: React$1.FC<ItemComponentProps<SemanticProps<DividerValues
415
484
  * <Heading values={{ headingType: "h1", color: "#222" }}>Welcome</Heading>
416
485
  * ```
417
486
  */
418
- declare const Heading: React$1.FC<ItemComponentProps<SemanticProps<HeadingValues>>>;
487
+ declare const Heading: React$1.FC<ItemComponentProps<HeadingSemanticProps>>;
419
488
 
420
489
  /**
421
490
  * Html - Universal SSR/Client Component for custom HTML with Automatic Semantic Props
@@ -432,9 +501,20 @@ declare const Heading: React$1.FC<ItemComponentProps<SemanticProps<HeadingValues
432
501
  */
433
502
  declare const Html: React$1.FC<ItemComponentProps<SemanticProps<HtmlValues>>>;
434
503
 
435
- type ImageSemanticProps = SemanticProps<ImageValues> & {
504
+ /**
505
+ * Image semantic props — agent-friendly `src` (plain URL string or value object)
506
+ * and CSS-style sizing (number/px pins, "50%" sets a percentage), replacing the
507
+ * loose `any` flat props.
508
+ */
509
+ type ImageSemanticProps = Omit<SemanticProps<ImageValues>, "src" | "width" | "maxWidth"> & {
436
510
  /** Alt text (alias for altText) */
437
511
  alt?: string;
512
+ /** Image URL string, or the value object `{ url, width?, maxWidth?, ... }`. */
513
+ src?: ImageSrcInput;
514
+ /** Display width — number/px pins the image; "50%" sets a percentage width. */
515
+ width?: SizeInput;
516
+ /** Display width as a CSS value ("50%", "300px"). */
517
+ maxWidth?: SizeInput;
438
518
  };
439
519
  /**
440
520
  * Image - Renders an image element.
@@ -479,6 +559,14 @@ type MenuSemanticProps = SemanticProps<MenuValues> & {
479
559
  */
480
560
  declare const Menu: React$1.FC<ItemComponentProps<MenuSemanticProps>>;
481
561
 
562
+ /**
563
+ * Paragraph semantic props — agent-friendly text/style types (replacing the
564
+ * loose `any` flat props) plus the `text` shorthand (converted to textJson).
565
+ */
566
+ type ParagraphSemanticProps = Omit<SemanticProps<ParagraphValues>, keyof TextStyleProps> & TextStyleProps & {
567
+ /** Plain-text content (or use `html` for inline formatting, or children). */
568
+ text?: string;
569
+ };
482
570
  /**
483
571
  * Paragraph - Universal SSR/Client Component with Semantic Props API
484
572
  *
@@ -499,7 +587,7 @@ declare const Menu: React$1.FC<ItemComponentProps<MenuSemanticProps>>;
499
587
  * <Paragraph values={{ textJson: "...", color: "#555" }} />
500
588
  * ```
501
589
  */
502
- declare const Paragraph: React$1.FC<ItemComponentProps<SemanticProps<ParagraphValues>>>;
590
+ declare const Paragraph: React$1.FC<ItemComponentProps<ParagraphSemanticProps>>;
503
591
 
504
592
  type SocialSemanticProps = SemanticProps<SocialValues> & {
505
593
  /** Social icons shorthand (array of {name, url}) */
@@ -578,7 +666,7 @@ type VideoSemanticProps = SemanticProps<VideoValues> & {
578
666
  */
579
667
  declare const Video: React$1.FC<ItemComponentProps<VideoSemanticProps>>;
580
668
 
581
- interface RowProps extends SemanticProps<RowValues> {
669
+ type RowProps = Omit<SemanticProps<RowValues>, "padding"> & {
582
670
  children?: React__default.ReactNode;
583
671
  layout?: ColumnLayout;
584
672
  cells?: number[];
@@ -588,12 +676,14 @@ interface RowProps extends SemanticProps<RowValues> {
588
676
  index?: number;
589
677
  bodyValues?: any;
590
678
  collection?: string;
679
+ /** Padding — a CSS string ("0 48px", "20px 40px") or a number (px). */
680
+ padding?: SizeInput;
591
681
  /** @internal - Unlayer config threaded from UnlayerProvider via Body */
592
682
  _config?: UnlayerConfig;
593
- }
683
+ };
594
684
  declare const Row: React__default.FC<RowProps>;
595
685
 
596
- interface ColumnProps extends SemanticProps<ColumnValues> {
686
+ type ColumnProps = Omit<SemanticProps<ColumnValues>, "padding"> & {
597
687
  children?: React__default.ReactNode;
598
688
  index?: number;
599
689
  cells?: number[];
@@ -602,12 +692,14 @@ interface ColumnProps extends SemanticProps<ColumnValues> {
602
692
  mode?: RenderMode;
603
693
  className?: string;
604
694
  style?: React__default.CSSProperties;
695
+ /** Padding — a CSS string ("0 24px", "10px") or a number (px). */
696
+ padding?: SizeInput;
605
697
  /** @internal - Unlayer config threaded from UnlayerProvider via Body/Row */
606
698
  _config?: UnlayerConfig;
607
- }
699
+ };
608
700
  declare const Column: React__default.FC<ColumnProps>;
609
701
 
610
- interface BodyProps extends SemanticProps<BodyValues> {
702
+ type BodyProps = Omit<SemanticProps<BodyValues>, "padding"> & {
611
703
  children?: React__default.ReactNode;
612
704
  mode?: RenderMode;
613
705
  className?: string;
@@ -617,7 +709,9 @@ interface BodyProps extends SemanticProps<BodyValues> {
617
709
  config?: Partial<UnlayerConfig>;
618
710
  /** Preview text shown in email client inboxes (email mode only) */
619
711
  previewText?: string;
620
- }
712
+ /** Padding — a CSS string ("0 48px", "20px") or a number (px). */
713
+ padding?: SizeInput;
714
+ };
621
715
  /**
622
716
  * Body - Universal Server/Client Component
623
717
  *
package/dist/index.js CHANGED
@@ -201,16 +201,53 @@ function analyzeNestedStructure(defaultValues) {
201
201
  nestedStructureCache.set(defaultValues, nestedGroups);
202
202
  return nestedGroups;
203
203
  }
204
+ var PX_SIZE_KEYS = [
205
+ "fontSize",
206
+ "padding",
207
+ "containerPadding",
208
+ "borderRadius",
209
+ "letterSpacing"
210
+ ];
211
+ function normalizeCssProps(props) {
212
+ if (typeof props.fontFamily === "string") {
213
+ const v = props.fontFamily;
214
+ props.fontFamily = { label: v, value: v };
215
+ }
216
+ if (typeof props.fontWeight === "string" && /^\d+$/.test(props.fontWeight.trim())) {
217
+ props.fontWeight = Number(props.fontWeight.trim());
218
+ }
219
+ if (typeof props.lineHeight === "number") {
220
+ props.lineHeight = String(props.lineHeight);
221
+ }
222
+ for (const key of PX_SIZE_KEYS) {
223
+ const v = props[key];
224
+ if (typeof v === "number") {
225
+ props[key] = `${v}px`;
226
+ } else if (typeof v === "string" && /^\d+$/.test(v.trim())) {
227
+ props[key] = `${v.trim()}px`;
228
+ }
229
+ }
230
+ }
231
+ function flattenChildrenText(node) {
232
+ if (node == null || typeof node === "boolean") return "";
233
+ if (typeof node === "string") return node;
234
+ if (typeof node === "number") return String(node);
235
+ if (Array.isArray(node)) return node.map(flattenChildrenText).join("");
236
+ if (typeof node === "object" && "props" in node) {
237
+ return flattenChildrenText(node.props?.children);
238
+ }
239
+ return "";
240
+ }
204
241
  function mapSemanticProps(props, defaultValues, componentType) {
205
242
  const { children, values, ...restProps } = props;
206
243
  const userProps = { ...restProps };
207
244
  const result = values ? { ...values } : {};
208
245
  if (children !== void 0 && !result.text && !result.textJson) {
246
+ const textContent = typeof children === "string" ? children : flattenChildrenText(children);
209
247
  if (componentType === "Paragraph") {
210
- const textContent = typeof children === "string" ? children : String(children);
211
248
  result.textJson = textToTextJson(textContent);
212
249
  } else {
213
- result.text = children;
250
+ result.text = textContent;
214
251
  }
215
252
  }
216
253
  const textFromEscapeHatch = result.text;
@@ -236,6 +273,7 @@ function mapSemanticProps(props, defaultValues, componentType) {
236
273
  };
237
274
  }
238
275
  }
276
+ normalizeCssProps(userProps);
239
277
  const nestedGroups = analyzeNestedStructure(defaultValues);
240
278
  const nested = {};
241
279
  const flat = {};
@@ -270,6 +308,19 @@ function mapSemanticProps(props, defaultValues, componentType) {
270
308
  };
271
309
  }
272
310
  }
311
+ if (defaultValues && typeof defaultValues === "object" && "border" in defaultValues) {
312
+ const borderSideRe = /^border(Top|Right|Bottom|Left)(Width|Style|Color)$/;
313
+ const collected = {};
314
+ for (const key of Object.keys(final)) {
315
+ if (borderSideRe.test(key)) {
316
+ collected[key] = final[key];
317
+ delete final[key];
318
+ }
319
+ }
320
+ if (Object.keys(collected).length > 0) {
321
+ final.border = { ...final.border || {}, ...collected };
322
+ }
323
+ }
273
324
  return final;
274
325
  }
275
326
  function normalizeLinkValue(value) {
@@ -538,7 +589,26 @@ var DEFAULT_VALUES = {
538
589
  var Button = createItemComponent({
539
590
  name: "Button",
540
591
  defaultValues: DEFAULT_VALUES,
541
- propMapper: (props) => mapSemanticProps(props, DEFAULT_VALUES, "Button"),
592
+ propMapper: (props) => {
593
+ const mapped = mapSemanticProps(
594
+ props,
595
+ DEFAULT_VALUES,
596
+ "Button"
597
+ );
598
+ const size = mapped.size;
599
+ if (size && typeof size === "object" && !Array.isArray(size)) {
600
+ const s = size;
601
+ if (typeof s.width === "number") {
602
+ s.width = `${s.width}px`;
603
+ } else if (typeof s.width === "string" && /^\d+(?:\.\d+)?$/.test(s.width.trim())) {
604
+ s.width = `${s.width.trim()}px`;
605
+ }
606
+ if (s.width !== void 0 && s.autoWidth === void 0) {
607
+ s.autoWidth = false;
608
+ }
609
+ }
610
+ return mapped;
611
+ },
542
612
  displayName: "Button",
543
613
  exporters: ButtonExporters
544
614
  });
@@ -603,18 +673,46 @@ var Image = createItemComponent({
603
673
  defaultValues: DEFAULT_VALUES5,
604
674
  propMapper: (props) => {
605
675
  const { alt, src, ...rest } = props;
676
+ const restValues = rest.values;
677
+ const normalizedRest = restValues && typeof restValues.src === "string" ? { ...rest, values: { ...restValues, src: { url: restValues.src } } } : rest;
606
678
  const base = mapSemanticProps(
607
- rest,
679
+ normalizedRest,
608
680
  DEFAULT_VALUES5,
609
681
  "Image"
610
682
  );
611
683
  if (alt !== void 0) {
612
684
  base.altText = alt;
613
685
  }
614
- if (typeof src === "string") {
615
- base.src = { url: src, autoWidth: true, maxWidth: "100%" };
616
- } else if (src !== void 0) {
617
- base.src = { ...DEFAULT_VALUES5.src, ...src };
686
+ const baseSrc = base.src;
687
+ const fromValues = baseSrc && typeof baseSrc === "object" && !Array.isArray(baseSrc) ? baseSrc : typeof baseSrc === "string" ? { url: baseSrc } : {};
688
+ const fromProp = typeof src === "string" ? { url: src } : src ?? {};
689
+ const userSrc = { ...fromValues, ...fromProp };
690
+ if (src !== void 0 || baseSrc !== void 0) {
691
+ const isStringUrl = typeof src === "string" || src === void 0 && typeof baseSrc === "string";
692
+ const start = isStringUrl ? { autoWidth: true, maxWidth: "100%" } : { ...DEFAULT_VALUES5.src };
693
+ const merged = { ...start, ...userSrc };
694
+ const pctRe = /^\d+(?:\.\d+)?%$/;
695
+ if (typeof merged.width === "string") {
696
+ const t = merged.width.trim();
697
+ if (pctRe.test(t)) {
698
+ if (userSrc.maxWidth === void 0) merged.maxWidth = t;
699
+ delete merged.width;
700
+ } else {
701
+ const px = /^(\d+(?:\.\d+)?)(?:px)?$/.exec(t);
702
+ if (px) merged.width = parseFloat(px[1]);
703
+ }
704
+ }
705
+ const displayPct = typeof merged.maxWidth === "string" && pctRe.test(merged.maxWidth.trim()) ? merged.maxWidth.trim() : void 0;
706
+ if (userSrc.autoWidth === void 0) {
707
+ if (displayPct && displayPct !== "100%") {
708
+ merged.autoWidth = false;
709
+ merged.maxWidth = displayPct;
710
+ } else {
711
+ merged.autoWidth = true;
712
+ merged.maxWidth = "100%";
713
+ }
714
+ }
715
+ base.src = merged;
618
716
  }
619
717
  return base;
620
718
  },
@@ -725,25 +823,37 @@ var Table = createItemComponent({
725
823
  name: "Table",
726
824
  defaultValues: DEFAULT_VALUES9,
727
825
  propMapper: (props) => {
728
- const { headers, data, ...rest } = props;
729
- if (headers || data) {
826
+ const { headers, data, columns, rows, ...rest } = props;
827
+ if (headers || data || typeof columns === "number" || typeof rows === "number") {
730
828
  const base = mapSemanticProps(
731
829
  rest,
732
830
  DEFAULT_VALUES9,
733
831
  "Table"
734
832
  );
833
+ const colCount = headers ? headers.length : typeof columns === "number" ? columns : data?.[0]?.length ?? 0;
834
+ const blankCells = (n) => Array.from({ length: n }, () => ({ text: "", width: 0 }));
735
835
  const tableHeaders = headers ? [{ cells: headers.map((text) => ({ text, width: 0 })), height: 0 }] : [];
736
836
  const tableRows = data ? data.map((row) => ({
737
837
  cells: row.map((text) => ({ text, width: 0 })),
738
838
  height: 0
739
- })) : [];
839
+ })) : typeof rows === "number" ? (
840
+ // No data: build an empty grid sized by `columns` × `rows`.
841
+ Array.from({ length: rows }, () => ({
842
+ cells: blankCells(colCount),
843
+ height: 0
844
+ }))
845
+ ) : [];
740
846
  base.table = { headers: tableHeaders, rows: tableRows, footers: [] };
847
+ if (headers || typeof columns === "number") {
848
+ base.columns = colCount;
849
+ }
741
850
  if (headers) {
742
- base.columns = headers.length;
743
851
  base.enableHeader = true;
744
852
  }
745
853
  if (data) {
746
854
  base.rows = data.length;
855
+ } else if (typeof rows === "number") {
856
+ base.rows = rows;
747
857
  }
748
858
  return base;
749
859
  }
@@ -1612,6 +1722,10 @@ function processBody(element, counters) {
1612
1722
  const semanticProps = extractSemanticProps2(element.props);
1613
1723
  const mapped = mapSemanticProps(semanticProps, BODY_DEFAULTS, "Body");
1614
1724
  const values = mergeValues(BODY_DEFAULTS, mapped);
1725
+ const previewText = element.props.previewText;
1726
+ if (previewText !== void 0) {
1727
+ values.preheaderText = previewText;
1728
+ }
1615
1729
  const valuesWithMeta = {
1616
1730
  ...values,
1617
1731
  _meta: {