@unlayer/react-elements 0.1.20 → 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 +22 -1
- package/dist/index.cjs +109 -22
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +24 -3
- package/dist/index.d.ts +24 -3
- package/dist/index.js +109 -23
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
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.
|
|
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
|
@@ -512,6 +512,7 @@ function normalizeValuesForExporter(values, componentName) {
|
|
|
512
512
|
return out;
|
|
513
513
|
}
|
|
514
514
|
var HTML_ENTITIES = {
|
|
515
|
+
// Core markup + whitespace
|
|
515
516
|
"&": "&",
|
|
516
517
|
"<": "<",
|
|
517
518
|
">": ">",
|
|
@@ -519,16 +520,67 @@ var HTML_ENTITIES = {
|
|
|
519
520
|
"'": "'",
|
|
520
521
|
"'": "'",
|
|
521
522
|
" ": " ",
|
|
523
|
+
// Dashes, quotes, and typographic punctuation
|
|
522
524
|
"—": "\u2014",
|
|
523
525
|
"–": "\u2013",
|
|
524
526
|
"«": "\xAB",
|
|
525
527
|
"»": "\xBB",
|
|
528
|
+
"‘": "\u2018",
|
|
529
|
+
"’": "\u2019",
|
|
530
|
+
"“": "\u201C",
|
|
531
|
+
"”": "\u201D",
|
|
526
532
|
"•": "\u2022",
|
|
527
533
|
"·": "\xB7",
|
|
528
534
|
"…": "\u2026",
|
|
535
|
+
// Currency
|
|
536
|
+
"¢": "\xA2",
|
|
537
|
+
"£": "\xA3",
|
|
538
|
+
"¥": "\xA5",
|
|
539
|
+
"€": "\u20AC",
|
|
540
|
+
// Legal / trademark
|
|
529
541
|
"©": "\xA9",
|
|
530
542
|
"®": "\xAE",
|
|
531
|
-
"™": "\u2122"
|
|
543
|
+
"™": "\u2122",
|
|
544
|
+
"§": "\xA7",
|
|
545
|
+
"¶": "\xB6",
|
|
546
|
+
// Math and misc symbols
|
|
547
|
+
"°": "\xB0",
|
|
548
|
+
"±": "\xB1",
|
|
549
|
+
"×": "\xD7",
|
|
550
|
+
"÷": "\xF7",
|
|
551
|
+
"µ": "\xB5",
|
|
552
|
+
"¼": "\xBC",
|
|
553
|
+
"½": "\xBD",
|
|
554
|
+
"¾": "\xBE",
|
|
555
|
+
// Latin-1 accented letters (common in European names/words)
|
|
556
|
+
"ß": "\xDF",
|
|
557
|
+
"à": "\xE0",
|
|
558
|
+
"á": "\xE1",
|
|
559
|
+
"â": "\xE2",
|
|
560
|
+
"ã": "\xE3",
|
|
561
|
+
"ä": "\xE4",
|
|
562
|
+
"å": "\xE5",
|
|
563
|
+
"æ": "\xE6",
|
|
564
|
+
"ç": "\xE7",
|
|
565
|
+
"è": "\xE8",
|
|
566
|
+
"é": "\xE9",
|
|
567
|
+
"ê": "\xEA",
|
|
568
|
+
"ë": "\xEB",
|
|
569
|
+
"ì": "\xEC",
|
|
570
|
+
"í": "\xED",
|
|
571
|
+
"î": "\xEE",
|
|
572
|
+
"ï": "\xEF",
|
|
573
|
+
"ñ": "\xF1",
|
|
574
|
+
"ò": "\xF2",
|
|
575
|
+
"ó": "\xF3",
|
|
576
|
+
"ô": "\xF4",
|
|
577
|
+
"õ": "\xF5",
|
|
578
|
+
"ö": "\xF6",
|
|
579
|
+
"ø": "\xF8",
|
|
580
|
+
"ù": "\xF9",
|
|
581
|
+
"ú": "\xFA",
|
|
582
|
+
"û": "\xFB",
|
|
583
|
+
"ü": "\xFC"
|
|
532
584
|
};
|
|
533
585
|
function decodeEntities(text) {
|
|
534
586
|
let result = text.replace(/&\w+;/g, (match) => HTML_ENTITIES[match] ?? match);
|
|
@@ -751,7 +803,8 @@ function createItemComponent(config) {
|
|
|
751
803
|
contentType: config.contentType,
|
|
752
804
|
slug: config.slug,
|
|
753
805
|
metaName: config.metaName,
|
|
754
|
-
head: config.head
|
|
806
|
+
head: config.head,
|
|
807
|
+
omitEmptyOutput: config.omitEmptyOutput
|
|
755
808
|
};
|
|
756
809
|
return ItemComponent;
|
|
757
810
|
}
|
|
@@ -963,13 +1016,45 @@ var Paragraph = createItemComponent({
|
|
|
963
1016
|
exporters: exporters.ParagraphExporters
|
|
964
1017
|
});
|
|
965
1018
|
var Paragraph_default = Paragraph;
|
|
966
|
-
|
|
1019
|
+
|
|
1020
|
+
// src/components/PageBreak.tsx
|
|
967
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 = {
|
|
968
1053
|
...exporters.SocialDefaults
|
|
969
1054
|
};
|
|
970
1055
|
var Social = createItemComponent({
|
|
971
1056
|
name: "Social",
|
|
972
|
-
defaultValues:
|
|
1057
|
+
defaultValues: DEFAULT_VALUES9,
|
|
973
1058
|
propMapper: (props) => {
|
|
974
1059
|
const { icons, iconType, ...rest } = props;
|
|
975
1060
|
const coerceSizes = (base) => {
|
|
@@ -990,7 +1075,7 @@ var Social = createItemComponent({
|
|
|
990
1075
|
}));
|
|
991
1076
|
const base = mapSemanticProps(
|
|
992
1077
|
rest,
|
|
993
|
-
|
|
1078
|
+
DEFAULT_VALUES9,
|
|
994
1079
|
"Social"
|
|
995
1080
|
);
|
|
996
1081
|
base.icons = {
|
|
@@ -1002,14 +1087,14 @@ var Social = createItemComponent({
|
|
|
1002
1087
|
if (iconType !== void 0) {
|
|
1003
1088
|
const base = mapSemanticProps(
|
|
1004
1089
|
rest,
|
|
1005
|
-
|
|
1090
|
+
DEFAULT_VALUES9,
|
|
1006
1091
|
"Social"
|
|
1007
1092
|
);
|
|
1008
1093
|
base.icons = { ...DEFAULT_ICONS, ...base.icons, iconType };
|
|
1009
1094
|
return coerceSizes(base);
|
|
1010
1095
|
}
|
|
1011
1096
|
return coerceSizes(
|
|
1012
|
-
mapSemanticProps(props,
|
|
1097
|
+
mapSemanticProps(props, DEFAULT_VALUES9, "Social")
|
|
1013
1098
|
);
|
|
1014
1099
|
},
|
|
1015
1100
|
displayName: "Social",
|
|
@@ -1017,20 +1102,20 @@ var Social = createItemComponent({
|
|
|
1017
1102
|
});
|
|
1018
1103
|
var Social_default = Social;
|
|
1019
1104
|
var DEFAULT_TABLE = { headers: [], rows: [], footers: [] };
|
|
1020
|
-
var
|
|
1105
|
+
var DEFAULT_VALUES10 = {
|
|
1021
1106
|
...exporters.TableDefaults,
|
|
1022
1107
|
table: DEFAULT_TABLE
|
|
1023
1108
|
// Schema doesn't include table data structure
|
|
1024
1109
|
};
|
|
1025
1110
|
var Table = createItemComponent({
|
|
1026
1111
|
name: "Table",
|
|
1027
|
-
defaultValues:
|
|
1112
|
+
defaultValues: DEFAULT_VALUES10,
|
|
1028
1113
|
propMapper: (props) => {
|
|
1029
1114
|
const { headers, data, columns, rows, ...rest } = props;
|
|
1030
1115
|
if (headers || data || typeof columns === "number" || typeof rows === "number") {
|
|
1031
1116
|
const base = mapSemanticProps(
|
|
1032
1117
|
rest,
|
|
1033
|
-
|
|
1118
|
+
DEFAULT_VALUES10,
|
|
1034
1119
|
"Table"
|
|
1035
1120
|
);
|
|
1036
1121
|
const colCount = headers ? headers.length : typeof columns === "number" ? columns : data?.[0]?.length ?? 0;
|
|
@@ -1062,7 +1147,7 @@ var Table = createItemComponent({
|
|
|
1062
1147
|
}
|
|
1063
1148
|
return mapSemanticProps(
|
|
1064
1149
|
props,
|
|
1065
|
-
|
|
1150
|
+
DEFAULT_VALUES10,
|
|
1066
1151
|
"Table"
|
|
1067
1152
|
);
|
|
1068
1153
|
},
|
|
@@ -1077,7 +1162,7 @@ var DEFAULT_VIDEO = {
|
|
|
1077
1162
|
loading: false,
|
|
1078
1163
|
...exporters.VideoDefaults.video
|
|
1079
1164
|
};
|
|
1080
|
-
var
|
|
1165
|
+
var DEFAULT_VALUES11 = {
|
|
1081
1166
|
...exporters.VideoDefaults,
|
|
1082
1167
|
video: DEFAULT_VIDEO
|
|
1083
1168
|
};
|
|
@@ -1105,14 +1190,14 @@ function parseVideoUrl(url) {
|
|
|
1105
1190
|
}
|
|
1106
1191
|
var Video = createItemComponent({
|
|
1107
1192
|
name: "Video",
|
|
1108
|
-
defaultValues:
|
|
1193
|
+
defaultValues: DEFAULT_VALUES11,
|
|
1109
1194
|
propMapper: (props) => {
|
|
1110
1195
|
const { videoUrl, ...rest } = props;
|
|
1111
1196
|
if (typeof videoUrl === "string") {
|
|
1112
1197
|
const parsed = parseVideoUrl(videoUrl);
|
|
1113
1198
|
const base = mapSemanticProps(
|
|
1114
1199
|
rest,
|
|
1115
|
-
|
|
1200
|
+
DEFAULT_VALUES11,
|
|
1116
1201
|
"Video"
|
|
1117
1202
|
);
|
|
1118
1203
|
if (parsed) {
|
|
@@ -1122,7 +1207,7 @@ var Video = createItemComponent({
|
|
|
1122
1207
|
}
|
|
1123
1208
|
return mapSemanticProps(
|
|
1124
1209
|
props,
|
|
1125
|
-
|
|
1210
|
+
DEFAULT_VALUES11,
|
|
1126
1211
|
"Video"
|
|
1127
1212
|
);
|
|
1128
1213
|
},
|
|
@@ -1150,7 +1235,7 @@ var {
|
|
|
1150
1235
|
var BODY_DEFAULTS = bodyRest;
|
|
1151
1236
|
var ROW_DEFAULTS = { ...exporters.RowDefaults };
|
|
1152
1237
|
var COLUMN_DEFAULTS = { ...exporters.ColumnDefaults };
|
|
1153
|
-
var
|
|
1238
|
+
var DEFAULT_VALUES12 = ROW_DEFAULTS;
|
|
1154
1239
|
var DEFAULT_BODY_VALUES = BODY_DEFAULTS;
|
|
1155
1240
|
function getWidthPercentages(cells) {
|
|
1156
1241
|
if (cells.length === 0) return [];
|
|
@@ -1288,7 +1373,7 @@ var Row = (props) => {
|
|
|
1288
1373
|
const safeBodyValues = { ...DEFAULT_BODY_VALUES, ...bodyValues };
|
|
1289
1374
|
const values = mapSemanticProps(
|
|
1290
1375
|
semanticProps,
|
|
1291
|
-
|
|
1376
|
+
DEFAULT_VALUES12,
|
|
1292
1377
|
"Row"
|
|
1293
1378
|
);
|
|
1294
1379
|
const valuesWithMeta = {
|
|
@@ -1326,7 +1411,7 @@ var Row = (props) => {
|
|
|
1326
1411
|
Row.displayName = "Row";
|
|
1327
1412
|
var Row_default = Row;
|
|
1328
1413
|
var DEFAULT_CONTAINER_PADDING2 = "10px";
|
|
1329
|
-
var
|
|
1414
|
+
var DEFAULT_VALUES13 = COLUMN_DEFAULTS;
|
|
1330
1415
|
function renderColumnToHtml(innerHTML, values, index, cells, bodyValues, rowValues, mode) {
|
|
1331
1416
|
const columnExporter = exporters.ColumnExporters[mode] || exporters.ColumnExporters.web;
|
|
1332
1417
|
return columnExporter(innerHTML, values, index, cells, bodyValues, rowValues);
|
|
@@ -1351,7 +1436,7 @@ var Column = (props) => {
|
|
|
1351
1436
|
const mode = modeProp ?? _config?.mode ?? "web";
|
|
1352
1437
|
const values = mapSemanticProps(
|
|
1353
1438
|
semanticProps,
|
|
1354
|
-
|
|
1439
|
+
DEFAULT_VALUES13,
|
|
1355
1440
|
"Column"
|
|
1356
1441
|
);
|
|
1357
1442
|
const valuesWithMeta = {
|
|
@@ -1387,6 +1472,7 @@ var Column = (props) => {
|
|
|
1387
1472
|
});
|
|
1388
1473
|
if (rendered && typeof rendered === "object" && rendered.props && rendered.props.dangerouslySetInnerHTML) {
|
|
1389
1474
|
const componentHTML = rendered.props.dangerouslySetInnerHTML.__html;
|
|
1475
|
+
if (!componentHTML && ComponentType?.[UNLAYER_CONFIG_KEY]?.omitEmptyOutput) return;
|
|
1390
1476
|
const childProps = child.props;
|
|
1391
1477
|
const rawContainerPadding = childProps.containerPadding ?? childProps.values?.containerPadding ?? DEFAULT_CONTAINER_PADDING2;
|
|
1392
1478
|
const containerPadding = typeof rawContainerPadding === "number" ? `${rawContainerPadding}px` : rawContainerPadding;
|
|
@@ -1434,7 +1520,7 @@ var Column = (props) => {
|
|
|
1434
1520
|
};
|
|
1435
1521
|
Column.displayName = "Column";
|
|
1436
1522
|
var Column_default = Column;
|
|
1437
|
-
var
|
|
1523
|
+
var DEFAULT_VALUES14 = BODY_DEFAULTS;
|
|
1438
1524
|
var MAX_PREVIEW_LENGTH = 150;
|
|
1439
1525
|
var PADDING_CHARS = [
|
|
1440
1526
|
"\xA0",
|
|
@@ -1480,8 +1566,8 @@ var Body = (props) => {
|
|
|
1480
1566
|
const _config = { ...resolvedConfig, mode };
|
|
1481
1567
|
_config.__ids = {};
|
|
1482
1568
|
const values = mergeValues(
|
|
1483
|
-
|
|
1484
|
-
mapSemanticProps(semanticProps,
|
|
1569
|
+
DEFAULT_VALUES14,
|
|
1570
|
+
mapSemanticProps(semanticProps, DEFAULT_VALUES14, "Body")
|
|
1485
1571
|
);
|
|
1486
1572
|
const valuesWithMeta = {
|
|
1487
1573
|
...values,
|
|
@@ -2240,6 +2326,7 @@ exports.Html = Html_default;
|
|
|
2240
2326
|
exports.Image = Image_default;
|
|
2241
2327
|
exports.Menu = Menu_default;
|
|
2242
2328
|
exports.Page = Page;
|
|
2329
|
+
exports.PageBreak = PageBreak_default;
|
|
2243
2330
|
exports.Paragraph = Paragraph_default;
|
|
2244
2331
|
exports.Row = Row_default;
|
|
2245
2332
|
exports.Social = Social_default;
|