@unlayer/react-elements 0.1.21 → 0.1.22

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/README.md CHANGED
@@ -120,6 +120,7 @@ These props have non-obvious shapes that **must** be followed exactly:
120
120
  | `<Social>` | Social media icons with `icons` shorthand array |
121
121
  | `<Menu>` | Navigation menu with `items` shorthand array |
122
122
  | `<Table>` | Data table with `headers` / `data` shorthands |
123
+ | `<PageBreak>` | Force subsequent document content onto a new PDF page |
123
124
  | `<Video>` | Video embed with `videoUrl` shorthand |
124
125
  | `<Html>` | Custom HTML passthrough |
125
126
 
@@ -139,7 +140,9 @@ Root wrapper for email-safe HTML. Same props as Body (without `mode`).
139
140
  Root wrapper for responsive web display. Same props as Email.
140
141
 
141
142
  ### Document
142
- Root wrapper for print/PDF rendering. Same props as Email.
143
+ Root wrapper for print/PDF rendering. It accepts the shared Body props plus:
144
+ - `documentSize?: "A3" | "A4" | "A5" | "Legal" | "Letter" | "Tabloid"` — `"A4"`
145
+ - `documentOrientation?: "portrait" | "landscape"` — `"portrait"`
143
146
 
144
147
  ### Row
145
148
  Layout container. Must be child of Email/Page/Document/Body.
@@ -221,6 +224,24 @@ Use `html` for formatted text, children for plain text.
221
224
  - `columns?: number` — `3`
222
225
  - `rows?: number` — `3`
223
226
  - `enableHeader?: boolean` — `true`
227
+ - `repeatHeaderOnEachPage?: boolean` — `true`
228
+ - `enableFooter?: boolean` — `false`
229
+ - `repeatFooterOnEachPage?: boolean` — `true`
230
+
231
+ ### PageBreak
232
+ Forces the next block onto a new page in document output. It is inert in email and web output.
233
+
234
+ ```tsx
235
+ <Document>
236
+ <Row>
237
+ <Column>
238
+ <Paragraph>Page one</Paragraph>
239
+ <PageBreak />
240
+ <Paragraph>Page two</Paragraph>
241
+ </Column>
242
+ </Row>
243
+ </Document>
244
+ ```
224
245
 
225
246
  ### Social
226
247
  - `icons?: { name: string, url: string }[]` — shorthand
package/dist/index.cjs CHANGED
@@ -803,7 +803,8 @@ function createItemComponent(config) {
803
803
  contentType: config.contentType,
804
804
  slug: config.slug,
805
805
  metaName: config.metaName,
806
- head: config.head
806
+ head: config.head,
807
+ omitEmptyOutput: config.omitEmptyOutput
807
808
  };
808
809
  return ItemComponent;
809
810
  }
@@ -1015,13 +1016,45 @@ var Paragraph = createItemComponent({
1015
1016
  exporters: exporters.ParagraphExporters
1016
1017
  });
1017
1018
  var Paragraph_default = Paragraph;
1018
- var DEFAULT_ICONS = exporters.SocialDefaults.icons ?? { iconType: "circle", icons: [] };
1019
+
1020
+ // src/components/PageBreak.tsx
1019
1021
  var DEFAULT_VALUES8 = {
1022
+ color: "#6b7280"
1023
+ };
1024
+ var pageBreakExporters = {
1025
+ // Page breaks are a document-only concept. Keep the unsupported renderers
1026
+ // inert so a component rendered outside <Document> does not throw.
1027
+ web: () => "",
1028
+ email: () => "",
1029
+ document: () => '<div class="u-content-page-break" aria-hidden="true"></div>'
1030
+ };
1031
+ var pageBreakHead = {
1032
+ css: (_values, _bodyValues, meta) => meta.displayMode === "document" ? `
1033
+ .u-content-page-break {
1034
+ break-after: page;
1035
+ page-break-after: always;
1036
+ }
1037
+ ` : void 0
1038
+ };
1039
+ var PageBreak = createItemComponent({
1040
+ name: "PageBreak",
1041
+ contentType: "page_break",
1042
+ metaName: "page_break",
1043
+ defaultValues: DEFAULT_VALUES8,
1044
+ propMapper: (props) => mapSemanticProps(props, DEFAULT_VALUES8, "PageBreak"),
1045
+ displayName: "PageBreak",
1046
+ exporters: pageBreakExporters,
1047
+ head: pageBreakHead,
1048
+ omitEmptyOutput: true
1049
+ });
1050
+ var PageBreak_default = PageBreak;
1051
+ var DEFAULT_ICONS = exporters.SocialDefaults.icons ?? { iconType: "circle", icons: [] };
1052
+ var DEFAULT_VALUES9 = {
1020
1053
  ...exporters.SocialDefaults
1021
1054
  };
1022
1055
  var Social = createItemComponent({
1023
1056
  name: "Social",
1024
- defaultValues: DEFAULT_VALUES8,
1057
+ defaultValues: DEFAULT_VALUES9,
1025
1058
  propMapper: (props) => {
1026
1059
  const { icons, iconType, ...rest } = props;
1027
1060
  const coerceSizes = (base) => {
@@ -1042,7 +1075,7 @@ var Social = createItemComponent({
1042
1075
  }));
1043
1076
  const base = mapSemanticProps(
1044
1077
  rest,
1045
- DEFAULT_VALUES8,
1078
+ DEFAULT_VALUES9,
1046
1079
  "Social"
1047
1080
  );
1048
1081
  base.icons = {
@@ -1054,14 +1087,14 @@ var Social = createItemComponent({
1054
1087
  if (iconType !== void 0) {
1055
1088
  const base = mapSemanticProps(
1056
1089
  rest,
1057
- DEFAULT_VALUES8,
1090
+ DEFAULT_VALUES9,
1058
1091
  "Social"
1059
1092
  );
1060
1093
  base.icons = { ...DEFAULT_ICONS, ...base.icons, iconType };
1061
1094
  return coerceSizes(base);
1062
1095
  }
1063
1096
  return coerceSizes(
1064
- mapSemanticProps(props, DEFAULT_VALUES8, "Social")
1097
+ mapSemanticProps(props, DEFAULT_VALUES9, "Social")
1065
1098
  );
1066
1099
  },
1067
1100
  displayName: "Social",
@@ -1069,20 +1102,20 @@ var Social = createItemComponent({
1069
1102
  });
1070
1103
  var Social_default = Social;
1071
1104
  var DEFAULT_TABLE = { headers: [], rows: [], footers: [] };
1072
- var DEFAULT_VALUES9 = {
1105
+ var DEFAULT_VALUES10 = {
1073
1106
  ...exporters.TableDefaults,
1074
1107
  table: DEFAULT_TABLE
1075
1108
  // Schema doesn't include table data structure
1076
1109
  };
1077
1110
  var Table = createItemComponent({
1078
1111
  name: "Table",
1079
- defaultValues: DEFAULT_VALUES9,
1112
+ defaultValues: DEFAULT_VALUES10,
1080
1113
  propMapper: (props) => {
1081
1114
  const { headers, data, columns, rows, ...rest } = props;
1082
1115
  if (headers || data || typeof columns === "number" || typeof rows === "number") {
1083
1116
  const base = mapSemanticProps(
1084
1117
  rest,
1085
- DEFAULT_VALUES9,
1118
+ DEFAULT_VALUES10,
1086
1119
  "Table"
1087
1120
  );
1088
1121
  const colCount = headers ? headers.length : typeof columns === "number" ? columns : data?.[0]?.length ?? 0;
@@ -1114,7 +1147,7 @@ var Table = createItemComponent({
1114
1147
  }
1115
1148
  return mapSemanticProps(
1116
1149
  props,
1117
- DEFAULT_VALUES9,
1150
+ DEFAULT_VALUES10,
1118
1151
  "Table"
1119
1152
  );
1120
1153
  },
@@ -1129,7 +1162,7 @@ var DEFAULT_VIDEO = {
1129
1162
  loading: false,
1130
1163
  ...exporters.VideoDefaults.video
1131
1164
  };
1132
- var DEFAULT_VALUES10 = {
1165
+ var DEFAULT_VALUES11 = {
1133
1166
  ...exporters.VideoDefaults,
1134
1167
  video: DEFAULT_VIDEO
1135
1168
  };
@@ -1157,14 +1190,14 @@ function parseVideoUrl(url) {
1157
1190
  }
1158
1191
  var Video = createItemComponent({
1159
1192
  name: "Video",
1160
- defaultValues: DEFAULT_VALUES10,
1193
+ defaultValues: DEFAULT_VALUES11,
1161
1194
  propMapper: (props) => {
1162
1195
  const { videoUrl, ...rest } = props;
1163
1196
  if (typeof videoUrl === "string") {
1164
1197
  const parsed = parseVideoUrl(videoUrl);
1165
1198
  const base = mapSemanticProps(
1166
1199
  rest,
1167
- DEFAULT_VALUES10,
1200
+ DEFAULT_VALUES11,
1168
1201
  "Video"
1169
1202
  );
1170
1203
  if (parsed) {
@@ -1174,7 +1207,7 @@ var Video = createItemComponent({
1174
1207
  }
1175
1208
  return mapSemanticProps(
1176
1209
  props,
1177
- DEFAULT_VALUES10,
1210
+ DEFAULT_VALUES11,
1178
1211
  "Video"
1179
1212
  );
1180
1213
  },
@@ -1202,7 +1235,7 @@ var {
1202
1235
  var BODY_DEFAULTS = bodyRest;
1203
1236
  var ROW_DEFAULTS = { ...exporters.RowDefaults };
1204
1237
  var COLUMN_DEFAULTS = { ...exporters.ColumnDefaults };
1205
- var DEFAULT_VALUES11 = ROW_DEFAULTS;
1238
+ var DEFAULT_VALUES12 = ROW_DEFAULTS;
1206
1239
  var DEFAULT_BODY_VALUES = BODY_DEFAULTS;
1207
1240
  function getWidthPercentages(cells) {
1208
1241
  if (cells.length === 0) return [];
@@ -1340,7 +1373,7 @@ var Row = (props) => {
1340
1373
  const safeBodyValues = { ...DEFAULT_BODY_VALUES, ...bodyValues };
1341
1374
  const values = mapSemanticProps(
1342
1375
  semanticProps,
1343
- DEFAULT_VALUES11,
1376
+ DEFAULT_VALUES12,
1344
1377
  "Row"
1345
1378
  );
1346
1379
  const valuesWithMeta = {
@@ -1378,7 +1411,7 @@ var Row = (props) => {
1378
1411
  Row.displayName = "Row";
1379
1412
  var Row_default = Row;
1380
1413
  var DEFAULT_CONTAINER_PADDING2 = "10px";
1381
- var DEFAULT_VALUES12 = COLUMN_DEFAULTS;
1414
+ var DEFAULT_VALUES13 = COLUMN_DEFAULTS;
1382
1415
  function renderColumnToHtml(innerHTML, values, index, cells, bodyValues, rowValues, mode) {
1383
1416
  const columnExporter = exporters.ColumnExporters[mode] || exporters.ColumnExporters.web;
1384
1417
  return columnExporter(innerHTML, values, index, cells, bodyValues, rowValues);
@@ -1403,7 +1436,7 @@ var Column = (props) => {
1403
1436
  const mode = modeProp ?? _config?.mode ?? "web";
1404
1437
  const values = mapSemanticProps(
1405
1438
  semanticProps,
1406
- DEFAULT_VALUES12,
1439
+ DEFAULT_VALUES13,
1407
1440
  "Column"
1408
1441
  );
1409
1442
  const valuesWithMeta = {
@@ -1439,6 +1472,7 @@ var Column = (props) => {
1439
1472
  });
1440
1473
  if (rendered && typeof rendered === "object" && rendered.props && rendered.props.dangerouslySetInnerHTML) {
1441
1474
  const componentHTML = rendered.props.dangerouslySetInnerHTML.__html;
1475
+ if (!componentHTML && ComponentType?.[UNLAYER_CONFIG_KEY]?.omitEmptyOutput) return;
1442
1476
  const childProps = child.props;
1443
1477
  const rawContainerPadding = childProps.containerPadding ?? childProps.values?.containerPadding ?? DEFAULT_CONTAINER_PADDING2;
1444
1478
  const containerPadding = typeof rawContainerPadding === "number" ? `${rawContainerPadding}px` : rawContainerPadding;
@@ -1486,7 +1520,7 @@ var Column = (props) => {
1486
1520
  };
1487
1521
  Column.displayName = "Column";
1488
1522
  var Column_default = Column;
1489
- var DEFAULT_VALUES13 = BODY_DEFAULTS;
1523
+ var DEFAULT_VALUES14 = BODY_DEFAULTS;
1490
1524
  var MAX_PREVIEW_LENGTH = 150;
1491
1525
  var PADDING_CHARS = [
1492
1526
  "\xA0",
@@ -1532,8 +1566,8 @@ var Body = (props) => {
1532
1566
  const _config = { ...resolvedConfig, mode };
1533
1567
  _config.__ids = {};
1534
1568
  const values = mergeValues(
1535
- DEFAULT_VALUES13,
1536
- mapSemanticProps(semanticProps, DEFAULT_VALUES13, "Body")
1569
+ DEFAULT_VALUES14,
1570
+ mapSemanticProps(semanticProps, DEFAULT_VALUES14, "Body")
1537
1571
  );
1538
1572
  const valuesWithMeta = {
1539
1573
  ...values,
@@ -2292,6 +2326,7 @@ exports.Html = Html_default;
2292
2326
  exports.Image = Image_default;
2293
2327
  exports.Menu = Menu_default;
2294
2328
  exports.Page = Page;
2329
+ exports.PageBreak = PageBreak_default;
2295
2330
  exports.Paragraph = Paragraph_default;
2296
2331
  exports.Row = Row_default;
2297
2332
  exports.Social = Social_default;