@unlayer/react-elements 0.1.13 → 0.1.14
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.cjs +145 -26
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +145 -26
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -5,6 +5,81 @@ import ReactDOMServer, { renderToStaticMarkup } from 'react-dom/server';
|
|
|
5
5
|
|
|
6
6
|
// src/components/Button.tsx
|
|
7
7
|
|
|
8
|
+
// src/utils/image-sizing.ts
|
|
9
|
+
function toPx(value) {
|
|
10
|
+
if (typeof value === "number") return Number.isFinite(value) ? value : void 0;
|
|
11
|
+
if (typeof value !== "string") return void 0;
|
|
12
|
+
const m = /^(\d+(?:\.\d+)?)(?:px)?$/.exec(value.trim());
|
|
13
|
+
return m ? parseFloat(m[1]) : void 0;
|
|
14
|
+
}
|
|
15
|
+
function edges(value) {
|
|
16
|
+
if (value == null) return { left: 0, right: 0 };
|
|
17
|
+
if (typeof value === "number") return { left: value, right: value };
|
|
18
|
+
const parts = String(value).trim().split(/\s+/).map((p) => parseFloat(p) || 0);
|
|
19
|
+
if (parts.length === 1) return { left: parts[0], right: parts[0] };
|
|
20
|
+
if (parts.length === 2 || parts.length === 3)
|
|
21
|
+
return { left: parts[1], right: parts[1] };
|
|
22
|
+
return { left: parts[3] || 0, right: parts[1] || 0 };
|
|
23
|
+
}
|
|
24
|
+
function borderEdges(border) {
|
|
25
|
+
if (!border || typeof border !== "object") return { left: 0, right: 0 };
|
|
26
|
+
const b = border;
|
|
27
|
+
const width = (v) => parseFloat(`${v ?? ""}`) || 0;
|
|
28
|
+
return {
|
|
29
|
+
left: width(b.borderLeftWidth),
|
|
30
|
+
right: width(b.borderRightWidth)
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
function fixedContentWidth(contentWidth) {
|
|
34
|
+
if (typeof contentWidth === "number")
|
|
35
|
+
return Number.isFinite(contentWidth) ? contentWidth : void 0;
|
|
36
|
+
if (typeof contentWidth === "string") {
|
|
37
|
+
const m = /^(\d+(?:\.\d+)?)(?:px)?$/.exec(contentWidth.trim());
|
|
38
|
+
if (m) return parseFloat(m[1]);
|
|
39
|
+
}
|
|
40
|
+
return void 0;
|
|
41
|
+
}
|
|
42
|
+
var FALLBACK_BODY_CONTENT_WIDTH = 500;
|
|
43
|
+
var DEFAULT_CONTAINER_PADDING = "10px";
|
|
44
|
+
function bodyContentWidthPx(contentWidth, fallback = FALLBACK_BODY_CONTENT_WIDTH) {
|
|
45
|
+
return fixedContentWidth(contentWidth) ?? fallback;
|
|
46
|
+
}
|
|
47
|
+
function contentSlotWidth(ctx) {
|
|
48
|
+
const { bodyValues = {}, rowValues = {}, columnValues = {} } = ctx;
|
|
49
|
+
const rowCells = ctx.rowCells && ctx.rowCells.length ? ctx.rowCells : [1];
|
|
50
|
+
const columnIndex = ctx.columnIndex ?? 0;
|
|
51
|
+
const bodyWidth = bodyContentWidthPx(bodyValues.contentWidth);
|
|
52
|
+
const bp = edges(bodyValues.padding);
|
|
53
|
+
const bb = borderEdges(bodyValues.border);
|
|
54
|
+
const bodyAvail = bodyWidth - bp.left - bp.right - bb.left - bb.right;
|
|
55
|
+
const rp = edges(rowValues.padding);
|
|
56
|
+
const rb = borderEdges(rowValues.border);
|
|
57
|
+
const rowAvail = bodyAvail - rp.left - rp.right - rb.left - rb.right;
|
|
58
|
+
const rowSpan = rowCells.reduce((a, b) => a + b, 0) || 1;
|
|
59
|
+
const colSpan = rowCells[columnIndex] || 1;
|
|
60
|
+
const colWidth = colSpan / rowSpan * rowAvail;
|
|
61
|
+
const cp = edges(columnValues.padding);
|
|
62
|
+
const cb = borderEdges(columnValues.border);
|
|
63
|
+
const colAvail = colWidth - cp.left - cp.right - cb.left - cb.right;
|
|
64
|
+
const ip = edges(ctx.containerPadding ?? DEFAULT_CONTAINER_PADDING);
|
|
65
|
+
return colAvail - ip.left - ip.right;
|
|
66
|
+
}
|
|
67
|
+
var PERCENT = /^\d+(?:\.\d+)?%$/;
|
|
68
|
+
function round2(n) {
|
|
69
|
+
return Math.round(n * 100) / 100;
|
|
70
|
+
}
|
|
71
|
+
function pinImageSrc(src, availableWidth) {
|
|
72
|
+
if (!src || typeof src !== "object") return src;
|
|
73
|
+
if (src.autoWidth !== false) return src;
|
|
74
|
+
const maxWidth = src.maxWidth;
|
|
75
|
+
if (typeof maxWidth === "string" && PERCENT.test(maxWidth.trim())) return src;
|
|
76
|
+
const pinPx = toPx(maxWidth);
|
|
77
|
+
if (pinPx == null) return src;
|
|
78
|
+
const avail = availableWidth && availableWidth > 0 ? availableWidth : void 0;
|
|
79
|
+
const pct = avail ? pinPx >= avail ? 100 : round2(pinPx / avail * 100) : 100;
|
|
80
|
+
return { ...src, autoWidth: false, maxWidth: `${pct}%` };
|
|
81
|
+
}
|
|
82
|
+
|
|
8
83
|
// ../shared/dist/index.js
|
|
9
84
|
var DEFAULT_CONFIG = {
|
|
10
85
|
cdnBaseUrl: "https://cdn.tools.unlayer.com",
|
|
@@ -564,6 +639,18 @@ function createItemComponent(config) {
|
|
|
564
639
|
valuesWithMeta,
|
|
565
640
|
config.name
|
|
566
641
|
);
|
|
642
|
+
const exportSrc = valuesForExporter.src;
|
|
643
|
+
if (exportSrc && typeof exportSrc === "object" && exportSrc.autoWidth === false) {
|
|
644
|
+
const availableWidth = contentSlotWidth({
|
|
645
|
+
bodyValues: safeBodyValues,
|
|
646
|
+
rowValues,
|
|
647
|
+
rowCells: cells,
|
|
648
|
+
columnIndex: colIndex,
|
|
649
|
+
columnValues,
|
|
650
|
+
containerPadding: props.containerPadding ?? props.values?.containerPadding
|
|
651
|
+
});
|
|
652
|
+
valuesForExporter.src = pinImageSrc(exportSrc, availableWidth);
|
|
653
|
+
}
|
|
567
654
|
const exporter = config.exporters[mode] || config.exporters.web;
|
|
568
655
|
return renderComponent({
|
|
569
656
|
type: config.name,
|
|
@@ -689,7 +776,7 @@ var Image = createItemComponent({
|
|
|
689
776
|
name: "Image",
|
|
690
777
|
defaultValues: DEFAULT_VALUES5,
|
|
691
778
|
propMapper: (props) => {
|
|
692
|
-
const { alt, src, ...rest } = props;
|
|
779
|
+
const { alt, src, width: widthProp, maxWidth: maxWidthProp, ...rest } = props;
|
|
693
780
|
const restValues = rest.values;
|
|
694
781
|
const normalizedRest = restValues && typeof restValues.src === "string" ? { ...rest, values: { ...restValues, src: { url: restValues.src } } } : rest;
|
|
695
782
|
const base = mapSemanticProps(
|
|
@@ -709,21 +796,39 @@ var Image = createItemComponent({
|
|
|
709
796
|
const start = isStringUrl ? { autoWidth: true, maxWidth: "100%" } : { ...DEFAULT_VALUES5.src };
|
|
710
797
|
const merged = { ...start, ...userSrc };
|
|
711
798
|
const pctRe = /^\d+(?:\.\d+)?%$/;
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
if (
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
const
|
|
719
|
-
if (
|
|
799
|
+
const asPercent = (v) => typeof v === "string" && pctRe.test(v.trim()) ? v.trim() : void 0;
|
|
800
|
+
const asPx = (v) => {
|
|
801
|
+
if (typeof v === "number" && Number.isFinite(v)) return v;
|
|
802
|
+
if (typeof v === "string") {
|
|
803
|
+
const t = v.trim();
|
|
804
|
+
if (pctRe.test(t)) return void 0;
|
|
805
|
+
const m = /^(\d+(?:\.\d+)?)(?:px)?$/.exec(t);
|
|
806
|
+
if (m) return parseFloat(m[1]);
|
|
807
|
+
}
|
|
808
|
+
return void 0;
|
|
809
|
+
};
|
|
810
|
+
let displayPct;
|
|
811
|
+
let displayPx;
|
|
812
|
+
for (const candidate of [widthProp, maxWidthProp, userSrc.maxWidth]) {
|
|
813
|
+
if (candidate === void 0) continue;
|
|
814
|
+
const pct = asPercent(candidate);
|
|
815
|
+
if (pct) {
|
|
816
|
+
displayPct = pct;
|
|
817
|
+
break;
|
|
818
|
+
}
|
|
819
|
+
const px = asPx(candidate);
|
|
820
|
+
if (px != null) {
|
|
821
|
+
displayPx = px;
|
|
822
|
+
break;
|
|
720
823
|
}
|
|
721
824
|
}
|
|
722
|
-
const displayPct = typeof merged.maxWidth === "string" && pctRe.test(merged.maxWidth.trim()) ? merged.maxWidth.trim() : void 0;
|
|
723
825
|
if (userSrc.autoWidth === void 0) {
|
|
724
826
|
if (displayPct && displayPct !== "100%") {
|
|
725
827
|
merged.autoWidth = false;
|
|
726
828
|
merged.maxWidth = displayPct;
|
|
829
|
+
} else if (displayPx != null) {
|
|
830
|
+
merged.autoWidth = false;
|
|
831
|
+
merged.maxWidth = displayPx;
|
|
727
832
|
} else {
|
|
728
833
|
merged.autoWidth = true;
|
|
729
834
|
merged.maxWidth = "100%";
|
|
@@ -1032,13 +1137,7 @@ ${widths.map(({ value, className }) => ` .no-stack .u-col-${className} { width:
|
|
|
1032
1137
|
return baseCSS + "\n" + columnCSS + "\n" + responsiveCSS;
|
|
1033
1138
|
}
|
|
1034
1139
|
function toContentWidthPx(bodyValues, fallback = 500) {
|
|
1035
|
-
|
|
1036
|
-
if (typeof raw === "number" && Number.isFinite(raw)) return raw;
|
|
1037
|
-
if (typeof raw === "string") {
|
|
1038
|
-
const n = parseInt(raw, 10);
|
|
1039
|
-
if (Number.isFinite(n)) return n;
|
|
1040
|
-
}
|
|
1041
|
-
return fallback;
|
|
1140
|
+
return bodyContentWidthPx(bodyValues?.contentWidth, fallback);
|
|
1042
1141
|
}
|
|
1043
1142
|
function renderRowToHtml(innerHTML, values, bodyValues, mode, cells, collection = "rows") {
|
|
1044
1143
|
const rowExporter = RowExporters[mode] || RowExporters.web;
|
|
@@ -1145,7 +1244,7 @@ var Row = (props) => {
|
|
|
1145
1244
|
};
|
|
1146
1245
|
Row.displayName = "Row";
|
|
1147
1246
|
var Row_default = Row;
|
|
1148
|
-
var
|
|
1247
|
+
var DEFAULT_CONTAINER_PADDING2 = "10px";
|
|
1149
1248
|
var DEFAULT_VALUES12 = COLUMN_DEFAULTS;
|
|
1150
1249
|
function renderColumnToHtml(innerHTML, values, index, cells, bodyValues, rowValues, mode) {
|
|
1151
1250
|
const columnExporter = ColumnExporters[mode] || ColumnExporters.web;
|
|
@@ -1207,7 +1306,7 @@ var Column = (props) => {
|
|
|
1207
1306
|
const componentType = child.type;
|
|
1208
1307
|
const componentName = (componentType?.displayName || componentType?.name || "component").toLowerCase();
|
|
1209
1308
|
const childProps = child.props;
|
|
1210
|
-
const rawContainerPadding = childProps.containerPadding ?? childProps.values?.containerPadding ??
|
|
1309
|
+
const rawContainerPadding = childProps.containerPadding ?? childProps.values?.containerPadding ?? DEFAULT_CONTAINER_PADDING2;
|
|
1211
1310
|
const containerPadding = typeof rawContainerPadding === "number" ? `${rawContainerPadding}px` : rawContainerPadding;
|
|
1212
1311
|
const contentValues = {
|
|
1213
1312
|
containerPadding,
|
|
@@ -1662,7 +1761,7 @@ function extractTextFromTextJson(textJson) {
|
|
|
1662
1761
|
return "";
|
|
1663
1762
|
}
|
|
1664
1763
|
}
|
|
1665
|
-
function processItem(element, counters) {
|
|
1764
|
+
function processItem(element, counters, layout = {}) {
|
|
1666
1765
|
const componentType = element.type;
|
|
1667
1766
|
const config = componentType[UNLAYER_CONFIG_KEY];
|
|
1668
1767
|
if (!config) {
|
|
@@ -1696,9 +1795,17 @@ function processItem(element, counters) {
|
|
|
1696
1795
|
deletable: true,
|
|
1697
1796
|
hideable: true
|
|
1698
1797
|
};
|
|
1798
|
+
const itemSrc = values.src;
|
|
1799
|
+
if (itemSrc && typeof itemSrc === "object" && itemSrc.autoWidth === false) {
|
|
1800
|
+
const availableWidth = contentSlotWidth({
|
|
1801
|
+
...layout,
|
|
1802
|
+
containerPadding: values.containerPadding
|
|
1803
|
+
});
|
|
1804
|
+
values.src = pinImageSrc(itemSrc, availableWidth);
|
|
1805
|
+
}
|
|
1699
1806
|
return { type: contentType, values };
|
|
1700
1807
|
}
|
|
1701
|
-
function processColumn(element, counters) {
|
|
1808
|
+
function processColumn(element, counters, layout = {}) {
|
|
1702
1809
|
const count = nextCounter2(counters, "u_column");
|
|
1703
1810
|
const id = makeId("u_column", count);
|
|
1704
1811
|
const semanticProps = extractSemanticProps2(element.props);
|
|
@@ -1714,12 +1821,13 @@ function processColumn(element, counters) {
|
|
|
1714
1821
|
};
|
|
1715
1822
|
const contents = [];
|
|
1716
1823
|
const children = collectChildren2(element.props.children);
|
|
1824
|
+
const itemLayout = { ...layout, columnValues: valuesWithMeta };
|
|
1717
1825
|
for (const child of children) {
|
|
1718
|
-
contents.push(processItem(child, counters));
|
|
1826
|
+
contents.push(processItem(child, counters, itemLayout));
|
|
1719
1827
|
}
|
|
1720
1828
|
return { contents, values: valuesWithMeta };
|
|
1721
1829
|
}
|
|
1722
|
-
function processRow(element, counters) {
|
|
1830
|
+
function processRow(element, counters, parentLayout = {}) {
|
|
1723
1831
|
const count = nextCounter2(counters, "u_row");
|
|
1724
1832
|
const id = makeId("u_row", count);
|
|
1725
1833
|
const { layout, cells: propsCells } = element.props;
|
|
@@ -1731,7 +1839,9 @@ function processRow(element, counters) {
|
|
|
1731
1839
|
} else {
|
|
1732
1840
|
const columnCount = Math.max(
|
|
1733
1841
|
1,
|
|
1734
|
-
collectChildren2(element.props.children).
|
|
1842
|
+
collectChildren2(element.props.children).filter(
|
|
1843
|
+
(child) => getDisplayName2(child) === "Column"
|
|
1844
|
+
).length
|
|
1735
1845
|
);
|
|
1736
1846
|
cells = Array(columnCount).fill(1);
|
|
1737
1847
|
}
|
|
@@ -1755,10 +1865,19 @@ function processRow(element, counters) {
|
|
|
1755
1865
|
};
|
|
1756
1866
|
const columns = [];
|
|
1757
1867
|
const children = collectChildren2(element.props.children);
|
|
1868
|
+
const columnLayout = {
|
|
1869
|
+
bodyValues: parentLayout.bodyValues,
|
|
1870
|
+
rowValues: valuesWithMeta,
|
|
1871
|
+
rowCells: cells
|
|
1872
|
+
};
|
|
1873
|
+
let columnIndex = 0;
|
|
1758
1874
|
for (const child of children) {
|
|
1759
1875
|
const name = getDisplayName2(child);
|
|
1760
1876
|
if (name === "Column") {
|
|
1761
|
-
columns.push(
|
|
1877
|
+
columns.push(
|
|
1878
|
+
processColumn(child, counters, { ...columnLayout, columnIndex })
|
|
1879
|
+
);
|
|
1880
|
+
columnIndex += 1;
|
|
1762
1881
|
} else {
|
|
1763
1882
|
console.warn(
|
|
1764
1883
|
`[Unlayer] renderToJson: <${name}> is not a valid Row child. Only <Column> is allowed.`
|
|
@@ -1789,7 +1908,7 @@ function processBody(element, counters) {
|
|
|
1789
1908
|
for (const child of children) {
|
|
1790
1909
|
const name = getDisplayName2(child);
|
|
1791
1910
|
if (name === "Row") {
|
|
1792
|
-
rows.push(processRow(child, counters));
|
|
1911
|
+
rows.push(processRow(child, counters, { bodyValues: valuesWithMeta }));
|
|
1793
1912
|
} else {
|
|
1794
1913
|
console.warn(
|
|
1795
1914
|
`[Unlayer] renderToJson: <${name}> is not a valid Body child. Only <Row> is allowed.`
|