@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.cjs
CHANGED
|
@@ -12,6 +12,81 @@ var ReactDOMServer__default = /*#__PURE__*/_interopDefault(ReactDOMServer);
|
|
|
12
12
|
|
|
13
13
|
// src/components/Button.tsx
|
|
14
14
|
|
|
15
|
+
// src/utils/image-sizing.ts
|
|
16
|
+
function toPx(value) {
|
|
17
|
+
if (typeof value === "number") return Number.isFinite(value) ? value : void 0;
|
|
18
|
+
if (typeof value !== "string") return void 0;
|
|
19
|
+
const m = /^(\d+(?:\.\d+)?)(?:px)?$/.exec(value.trim());
|
|
20
|
+
return m ? parseFloat(m[1]) : void 0;
|
|
21
|
+
}
|
|
22
|
+
function edges(value) {
|
|
23
|
+
if (value == null) return { left: 0, right: 0 };
|
|
24
|
+
if (typeof value === "number") return { left: value, right: value };
|
|
25
|
+
const parts = String(value).trim().split(/\s+/).map((p) => parseFloat(p) || 0);
|
|
26
|
+
if (parts.length === 1) return { left: parts[0], right: parts[0] };
|
|
27
|
+
if (parts.length === 2 || parts.length === 3)
|
|
28
|
+
return { left: parts[1], right: parts[1] };
|
|
29
|
+
return { left: parts[3] || 0, right: parts[1] || 0 };
|
|
30
|
+
}
|
|
31
|
+
function borderEdges(border) {
|
|
32
|
+
if (!border || typeof border !== "object") return { left: 0, right: 0 };
|
|
33
|
+
const b = border;
|
|
34
|
+
const width = (v) => parseFloat(`${v ?? ""}`) || 0;
|
|
35
|
+
return {
|
|
36
|
+
left: width(b.borderLeftWidth),
|
|
37
|
+
right: width(b.borderRightWidth)
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
function fixedContentWidth(contentWidth) {
|
|
41
|
+
if (typeof contentWidth === "number")
|
|
42
|
+
return Number.isFinite(contentWidth) ? contentWidth : void 0;
|
|
43
|
+
if (typeof contentWidth === "string") {
|
|
44
|
+
const m = /^(\d+(?:\.\d+)?)(?:px)?$/.exec(contentWidth.trim());
|
|
45
|
+
if (m) return parseFloat(m[1]);
|
|
46
|
+
}
|
|
47
|
+
return void 0;
|
|
48
|
+
}
|
|
49
|
+
var FALLBACK_BODY_CONTENT_WIDTH = 500;
|
|
50
|
+
var DEFAULT_CONTAINER_PADDING = "10px";
|
|
51
|
+
function bodyContentWidthPx(contentWidth, fallback = FALLBACK_BODY_CONTENT_WIDTH) {
|
|
52
|
+
return fixedContentWidth(contentWidth) ?? fallback;
|
|
53
|
+
}
|
|
54
|
+
function contentSlotWidth(ctx) {
|
|
55
|
+
const { bodyValues = {}, rowValues = {}, columnValues = {} } = ctx;
|
|
56
|
+
const rowCells = ctx.rowCells && ctx.rowCells.length ? ctx.rowCells : [1];
|
|
57
|
+
const columnIndex = ctx.columnIndex ?? 0;
|
|
58
|
+
const bodyWidth = bodyContentWidthPx(bodyValues.contentWidth);
|
|
59
|
+
const bp = edges(bodyValues.padding);
|
|
60
|
+
const bb = borderEdges(bodyValues.border);
|
|
61
|
+
const bodyAvail = bodyWidth - bp.left - bp.right - bb.left - bb.right;
|
|
62
|
+
const rp = edges(rowValues.padding);
|
|
63
|
+
const rb = borderEdges(rowValues.border);
|
|
64
|
+
const rowAvail = bodyAvail - rp.left - rp.right - rb.left - rb.right;
|
|
65
|
+
const rowSpan = rowCells.reduce((a, b) => a + b, 0) || 1;
|
|
66
|
+
const colSpan = rowCells[columnIndex] || 1;
|
|
67
|
+
const colWidth = colSpan / rowSpan * rowAvail;
|
|
68
|
+
const cp = edges(columnValues.padding);
|
|
69
|
+
const cb = borderEdges(columnValues.border);
|
|
70
|
+
const colAvail = colWidth - cp.left - cp.right - cb.left - cb.right;
|
|
71
|
+
const ip = edges(ctx.containerPadding ?? DEFAULT_CONTAINER_PADDING);
|
|
72
|
+
return colAvail - ip.left - ip.right;
|
|
73
|
+
}
|
|
74
|
+
var PERCENT = /^\d+(?:\.\d+)?%$/;
|
|
75
|
+
function round2(n) {
|
|
76
|
+
return Math.round(n * 100) / 100;
|
|
77
|
+
}
|
|
78
|
+
function pinImageSrc(src, availableWidth) {
|
|
79
|
+
if (!src || typeof src !== "object") return src;
|
|
80
|
+
if (src.autoWidth !== false) return src;
|
|
81
|
+
const maxWidth = src.maxWidth;
|
|
82
|
+
if (typeof maxWidth === "string" && PERCENT.test(maxWidth.trim())) return src;
|
|
83
|
+
const pinPx = toPx(maxWidth);
|
|
84
|
+
if (pinPx == null) return src;
|
|
85
|
+
const avail = availableWidth && availableWidth > 0 ? availableWidth : void 0;
|
|
86
|
+
const pct = avail ? pinPx >= avail ? 100 : round2(pinPx / avail * 100) : 100;
|
|
87
|
+
return { ...src, autoWidth: false, maxWidth: `${pct}%` };
|
|
88
|
+
}
|
|
89
|
+
|
|
15
90
|
// ../shared/dist/index.js
|
|
16
91
|
var DEFAULT_CONFIG = {
|
|
17
92
|
cdnBaseUrl: "https://cdn.tools.unlayer.com",
|
|
@@ -571,6 +646,18 @@ function createItemComponent(config) {
|
|
|
571
646
|
valuesWithMeta,
|
|
572
647
|
config.name
|
|
573
648
|
);
|
|
649
|
+
const exportSrc = valuesForExporter.src;
|
|
650
|
+
if (exportSrc && typeof exportSrc === "object" && exportSrc.autoWidth === false) {
|
|
651
|
+
const availableWidth = contentSlotWidth({
|
|
652
|
+
bodyValues: safeBodyValues,
|
|
653
|
+
rowValues,
|
|
654
|
+
rowCells: cells,
|
|
655
|
+
columnIndex: colIndex,
|
|
656
|
+
columnValues,
|
|
657
|
+
containerPadding: props.containerPadding ?? props.values?.containerPadding
|
|
658
|
+
});
|
|
659
|
+
valuesForExporter.src = pinImageSrc(exportSrc, availableWidth);
|
|
660
|
+
}
|
|
574
661
|
const exporter = config.exporters[mode] || config.exporters.web;
|
|
575
662
|
return renderComponent({
|
|
576
663
|
type: config.name,
|
|
@@ -696,7 +783,7 @@ var Image = createItemComponent({
|
|
|
696
783
|
name: "Image",
|
|
697
784
|
defaultValues: DEFAULT_VALUES5,
|
|
698
785
|
propMapper: (props) => {
|
|
699
|
-
const { alt, src, ...rest } = props;
|
|
786
|
+
const { alt, src, width: widthProp, maxWidth: maxWidthProp, ...rest } = props;
|
|
700
787
|
const restValues = rest.values;
|
|
701
788
|
const normalizedRest = restValues && typeof restValues.src === "string" ? { ...rest, values: { ...restValues, src: { url: restValues.src } } } : rest;
|
|
702
789
|
const base = mapSemanticProps(
|
|
@@ -716,21 +803,39 @@ var Image = createItemComponent({
|
|
|
716
803
|
const start = isStringUrl ? { autoWidth: true, maxWidth: "100%" } : { ...DEFAULT_VALUES5.src };
|
|
717
804
|
const merged = { ...start, ...userSrc };
|
|
718
805
|
const pctRe = /^\d+(?:\.\d+)?%$/;
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
if (
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
const
|
|
726
|
-
if (
|
|
806
|
+
const asPercent = (v) => typeof v === "string" && pctRe.test(v.trim()) ? v.trim() : void 0;
|
|
807
|
+
const asPx = (v) => {
|
|
808
|
+
if (typeof v === "number" && Number.isFinite(v)) return v;
|
|
809
|
+
if (typeof v === "string") {
|
|
810
|
+
const t = v.trim();
|
|
811
|
+
if (pctRe.test(t)) return void 0;
|
|
812
|
+
const m = /^(\d+(?:\.\d+)?)(?:px)?$/.exec(t);
|
|
813
|
+
if (m) return parseFloat(m[1]);
|
|
814
|
+
}
|
|
815
|
+
return void 0;
|
|
816
|
+
};
|
|
817
|
+
let displayPct;
|
|
818
|
+
let displayPx;
|
|
819
|
+
for (const candidate of [widthProp, maxWidthProp, userSrc.maxWidth]) {
|
|
820
|
+
if (candidate === void 0) continue;
|
|
821
|
+
const pct = asPercent(candidate);
|
|
822
|
+
if (pct) {
|
|
823
|
+
displayPct = pct;
|
|
824
|
+
break;
|
|
825
|
+
}
|
|
826
|
+
const px = asPx(candidate);
|
|
827
|
+
if (px != null) {
|
|
828
|
+
displayPx = px;
|
|
829
|
+
break;
|
|
727
830
|
}
|
|
728
831
|
}
|
|
729
|
-
const displayPct = typeof merged.maxWidth === "string" && pctRe.test(merged.maxWidth.trim()) ? merged.maxWidth.trim() : void 0;
|
|
730
832
|
if (userSrc.autoWidth === void 0) {
|
|
731
833
|
if (displayPct && displayPct !== "100%") {
|
|
732
834
|
merged.autoWidth = false;
|
|
733
835
|
merged.maxWidth = displayPct;
|
|
836
|
+
} else if (displayPx != null) {
|
|
837
|
+
merged.autoWidth = false;
|
|
838
|
+
merged.maxWidth = displayPx;
|
|
734
839
|
} else {
|
|
735
840
|
merged.autoWidth = true;
|
|
736
841
|
merged.maxWidth = "100%";
|
|
@@ -1039,13 +1144,7 @@ ${widths.map(({ value, className }) => ` .no-stack .u-col-${className} { width:
|
|
|
1039
1144
|
return baseCSS + "\n" + columnCSS + "\n" + responsiveCSS;
|
|
1040
1145
|
}
|
|
1041
1146
|
function toContentWidthPx(bodyValues, fallback = 500) {
|
|
1042
|
-
|
|
1043
|
-
if (typeof raw === "number" && Number.isFinite(raw)) return raw;
|
|
1044
|
-
if (typeof raw === "string") {
|
|
1045
|
-
const n = parseInt(raw, 10);
|
|
1046
|
-
if (Number.isFinite(n)) return n;
|
|
1047
|
-
}
|
|
1048
|
-
return fallback;
|
|
1147
|
+
return bodyContentWidthPx(bodyValues?.contentWidth, fallback);
|
|
1049
1148
|
}
|
|
1050
1149
|
function renderRowToHtml(innerHTML, values, bodyValues, mode, cells, collection = "rows") {
|
|
1051
1150
|
const rowExporter = exporters.RowExporters[mode] || exporters.RowExporters.web;
|
|
@@ -1152,7 +1251,7 @@ var Row = (props) => {
|
|
|
1152
1251
|
};
|
|
1153
1252
|
Row.displayName = "Row";
|
|
1154
1253
|
var Row_default = Row;
|
|
1155
|
-
var
|
|
1254
|
+
var DEFAULT_CONTAINER_PADDING2 = "10px";
|
|
1156
1255
|
var DEFAULT_VALUES12 = COLUMN_DEFAULTS;
|
|
1157
1256
|
function renderColumnToHtml(innerHTML, values, index, cells, bodyValues, rowValues, mode) {
|
|
1158
1257
|
const columnExporter = exporters.ColumnExporters[mode] || exporters.ColumnExporters.web;
|
|
@@ -1214,7 +1313,7 @@ var Column = (props) => {
|
|
|
1214
1313
|
const componentType = child.type;
|
|
1215
1314
|
const componentName = (componentType?.displayName || componentType?.name || "component").toLowerCase();
|
|
1216
1315
|
const childProps = child.props;
|
|
1217
|
-
const rawContainerPadding = childProps.containerPadding ?? childProps.values?.containerPadding ??
|
|
1316
|
+
const rawContainerPadding = childProps.containerPadding ?? childProps.values?.containerPadding ?? DEFAULT_CONTAINER_PADDING2;
|
|
1218
1317
|
const containerPadding = typeof rawContainerPadding === "number" ? `${rawContainerPadding}px` : rawContainerPadding;
|
|
1219
1318
|
const contentValues = {
|
|
1220
1319
|
containerPadding,
|
|
@@ -1669,7 +1768,7 @@ function extractTextFromTextJson(textJson) {
|
|
|
1669
1768
|
return "";
|
|
1670
1769
|
}
|
|
1671
1770
|
}
|
|
1672
|
-
function processItem(element, counters) {
|
|
1771
|
+
function processItem(element, counters, layout = {}) {
|
|
1673
1772
|
const componentType = element.type;
|
|
1674
1773
|
const config = componentType[UNLAYER_CONFIG_KEY];
|
|
1675
1774
|
if (!config) {
|
|
@@ -1703,9 +1802,17 @@ function processItem(element, counters) {
|
|
|
1703
1802
|
deletable: true,
|
|
1704
1803
|
hideable: true
|
|
1705
1804
|
};
|
|
1805
|
+
const itemSrc = values.src;
|
|
1806
|
+
if (itemSrc && typeof itemSrc === "object" && itemSrc.autoWidth === false) {
|
|
1807
|
+
const availableWidth = contentSlotWidth({
|
|
1808
|
+
...layout,
|
|
1809
|
+
containerPadding: values.containerPadding
|
|
1810
|
+
});
|
|
1811
|
+
values.src = pinImageSrc(itemSrc, availableWidth);
|
|
1812
|
+
}
|
|
1706
1813
|
return { type: contentType, values };
|
|
1707
1814
|
}
|
|
1708
|
-
function processColumn(element, counters) {
|
|
1815
|
+
function processColumn(element, counters, layout = {}) {
|
|
1709
1816
|
const count = nextCounter2(counters, "u_column");
|
|
1710
1817
|
const id = makeId("u_column", count);
|
|
1711
1818
|
const semanticProps = extractSemanticProps2(element.props);
|
|
@@ -1721,12 +1828,13 @@ function processColumn(element, counters) {
|
|
|
1721
1828
|
};
|
|
1722
1829
|
const contents = [];
|
|
1723
1830
|
const children = collectChildren2(element.props.children);
|
|
1831
|
+
const itemLayout = { ...layout, columnValues: valuesWithMeta };
|
|
1724
1832
|
for (const child of children) {
|
|
1725
|
-
contents.push(processItem(child, counters));
|
|
1833
|
+
contents.push(processItem(child, counters, itemLayout));
|
|
1726
1834
|
}
|
|
1727
1835
|
return { contents, values: valuesWithMeta };
|
|
1728
1836
|
}
|
|
1729
|
-
function processRow(element, counters) {
|
|
1837
|
+
function processRow(element, counters, parentLayout = {}) {
|
|
1730
1838
|
const count = nextCounter2(counters, "u_row");
|
|
1731
1839
|
const id = makeId("u_row", count);
|
|
1732
1840
|
const { layout, cells: propsCells } = element.props;
|
|
@@ -1738,7 +1846,9 @@ function processRow(element, counters) {
|
|
|
1738
1846
|
} else {
|
|
1739
1847
|
const columnCount = Math.max(
|
|
1740
1848
|
1,
|
|
1741
|
-
collectChildren2(element.props.children).
|
|
1849
|
+
collectChildren2(element.props.children).filter(
|
|
1850
|
+
(child) => getDisplayName2(child) === "Column"
|
|
1851
|
+
).length
|
|
1742
1852
|
);
|
|
1743
1853
|
cells = Array(columnCount).fill(1);
|
|
1744
1854
|
}
|
|
@@ -1762,10 +1872,19 @@ function processRow(element, counters) {
|
|
|
1762
1872
|
};
|
|
1763
1873
|
const columns = [];
|
|
1764
1874
|
const children = collectChildren2(element.props.children);
|
|
1875
|
+
const columnLayout = {
|
|
1876
|
+
bodyValues: parentLayout.bodyValues,
|
|
1877
|
+
rowValues: valuesWithMeta,
|
|
1878
|
+
rowCells: cells
|
|
1879
|
+
};
|
|
1880
|
+
let columnIndex = 0;
|
|
1765
1881
|
for (const child of children) {
|
|
1766
1882
|
const name = getDisplayName2(child);
|
|
1767
1883
|
if (name === "Column") {
|
|
1768
|
-
columns.push(
|
|
1884
|
+
columns.push(
|
|
1885
|
+
processColumn(child, counters, { ...columnLayout, columnIndex })
|
|
1886
|
+
);
|
|
1887
|
+
columnIndex += 1;
|
|
1769
1888
|
} else {
|
|
1770
1889
|
console.warn(
|
|
1771
1890
|
`[Unlayer] renderToJson: <${name}> is not a valid Row child. Only <Column> is allowed.`
|
|
@@ -1796,7 +1915,7 @@ function processBody(element, counters) {
|
|
|
1796
1915
|
for (const child of children) {
|
|
1797
1916
|
const name = getDisplayName2(child);
|
|
1798
1917
|
if (name === "Row") {
|
|
1799
|
-
rows.push(processRow(child, counters));
|
|
1918
|
+
rows.push(processRow(child, counters, { bodyValues: valuesWithMeta }));
|
|
1800
1919
|
} else {
|
|
1801
1920
|
console.warn(
|
|
1802
1921
|
`[Unlayer] renderToJson: <${name}> is not a valid Body child. Only <Row> is allowed.`
|