@unlayer/react-elements 0.1.11 → 0.1.13

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 CHANGED
@@ -473,6 +473,12 @@ var ErrorFallback = ({
473
473
  ]
474
474
  }
475
475
  ) });
476
+ function nextHtmlId(config, prefix) {
477
+ if (!config) return `${prefix}_1`;
478
+ const ids = config.__ids ?? (config.__ids = {});
479
+ ids[prefix] = (ids[prefix] || 0) + 1;
480
+ return `${prefix}_${ids[prefix]}`;
481
+ }
476
482
  function ensureMeta(values, type, index = 0) {
477
483
  return {
478
484
  ...values,
@@ -484,7 +490,7 @@ function ensureMeta(values, type, index = 0) {
484
490
  };
485
491
  }
486
492
  function renderComponent(config) {
487
- const { type, values, className, style, args = [], innerHTML, _config, exporter } = config;
493
+ const { type, values, className, style, args = [], innerHTML, _config, exporter, metaContext } = config;
488
494
  try {
489
495
  const cfg = _config ?? DEFAULT_CONFIG;
490
496
  const exporterConfig = {
@@ -499,7 +505,8 @@ function renderComponent(config) {
499
505
  } else {
500
506
  const meta = {
501
507
  exporterConfig,
502
- mergeTagState: cfg.mergeTagState
508
+ mergeTagState: cfg.mergeTagState,
509
+ ...metaContext ?? {}
503
510
  };
504
511
  html = exporter(values, ...args, void 0, meta);
505
512
  }
@@ -538,6 +545,7 @@ function createItemComponent(config) {
538
545
  cells = [],
539
546
  bodyValues = {},
540
547
  rowValues = {},
548
+ columnValues = {},
541
549
  _config,
542
550
  // Children
543
551
  children,
@@ -556,7 +564,7 @@ function createItemComponent(config) {
556
564
  index
557
565
  );
558
566
  const safeBodyValues = {
559
- contentWidth: 600,
567
+ contentWidth: "500px",
560
568
  ...bodyValues
561
569
  };
562
570
  const valuesForExporter = normalizeValuesForExporter(
@@ -570,6 +578,15 @@ function createItemComponent(config) {
570
578
  className,
571
579
  style,
572
580
  args: [index, colIndex, cells, safeBodyValues, rowValues],
581
+ // The 8th arg the exporters actually read: column/body context for
582
+ // width-aware rendering (Image's available-width calc), mirroring the editor.
583
+ metaContext: {
584
+ columnIndex: colIndex,
585
+ columnValues,
586
+ rowCells: cells,
587
+ rowValues,
588
+ bodyValues: safeBodyValues
589
+ },
573
590
  _config,
574
591
  exporter
575
592
  });
@@ -1105,7 +1122,7 @@ var Row = (props) => {
1105
1122
  ...values,
1106
1123
  cells,
1107
1124
  _meta: {
1108
- htmlID: `u_row_${index + 1}`,
1125
+ htmlID: nextHtmlId(_config, "u_row"),
1109
1126
  htmlClassNames: "u_row",
1110
1127
  ...values._meta || {}
1111
1128
  }
@@ -1167,7 +1184,7 @@ var Column = (props) => {
1167
1184
  const valuesWithMeta = {
1168
1185
  ...values,
1169
1186
  _meta: {
1170
- htmlID: `u_column_${index + 1}`,
1187
+ htmlID: nextHtmlId(_config, "u_column"),
1171
1188
  htmlClassNames: "u_column",
1172
1189
  ...values._meta || {}
1173
1190
  }
@@ -1183,17 +1200,26 @@ var Column = (props) => {
1183
1200
  if (typeof child.type === "function") {
1184
1201
  const ComponentType = child.type;
1185
1202
  const renderFn = ComponentType[UNLAYER_RENDER_KEY] || ComponentType;
1186
- const rendered = renderFn({ ...child.props, _config });
1203
+ const rendered = renderFn({
1204
+ ...child.props,
1205
+ _config,
1206
+ colIndex: index,
1207
+ cells,
1208
+ bodyValues,
1209
+ rowValues,
1210
+ columnValues: valuesWithMeta
1211
+ });
1187
1212
  if (rendered && typeof rendered === "object" && rendered.props && rendered.props.dangerouslySetInnerHTML) {
1188
1213
  const componentHTML = rendered.props.dangerouslySetInnerHTML.__html;
1189
1214
  const componentType = child.type;
1190
1215
  const componentName = (componentType?.displayName || componentType?.name || "component").toLowerCase();
1191
1216
  const childProps = child.props;
1192
- const containerPadding = childProps.containerPadding ?? childProps.values?.containerPadding ?? DEFAULT_CONTAINER_PADDING;
1217
+ const rawContainerPadding = childProps.containerPadding ?? childProps.values?.containerPadding ?? DEFAULT_CONTAINER_PADDING;
1218
+ const containerPadding = typeof rawContainerPadding === "number" ? `${rawContainerPadding}px` : rawContainerPadding;
1193
1219
  const contentValues = {
1194
1220
  containerPadding,
1195
1221
  _meta: {
1196
- htmlID: `u_content_${componentName}_${childIndex + 1}`,
1222
+ htmlID: nextHtmlId(_config, `u_content_${componentName}`),
1197
1223
  htmlClassNames: `u_content_${componentName}`
1198
1224
  }
1199
1225
  };
@@ -1278,6 +1304,7 @@ var Body = (props) => {
1278
1304
  const resolvedConfig = { ...DEFAULT_CONFIG, ...configProp };
1279
1305
  const mode = modeProp ?? resolvedConfig.mode ?? "web";
1280
1306
  const _config = { ...resolvedConfig, mode };
1307
+ _config.__ids = {};
1281
1308
  const values = mergeValues(
1282
1309
  DEFAULT_VALUES13,
1283
1310
  mapSemanticProps(semanticProps, DEFAULT_VALUES13, "Body")
@@ -1285,7 +1312,7 @@ var Body = (props) => {
1285
1312
  const valuesWithMeta = {
1286
1313
  ...values,
1287
1314
  _meta: {
1288
- htmlID: `u_body_${index + 1}`,
1315
+ htmlID: nextHtmlId(_config, "u_body"),
1289
1316
  htmlClassNames: "u_body",
1290
1317
  ...values._meta || {}
1291
1318
  }
@@ -1553,6 +1580,29 @@ function getDisplayName2(element) {
1553
1580
  const type = element.type;
1554
1581
  return type?.displayName || type?.name;
1555
1582
  }
1583
+ var VALID_ROOTS = /* @__PURE__ */ new Set(["Body", "Email", "Page", "Document"]);
1584
+ function unwrapRoot(element) {
1585
+ let current = element;
1586
+ for (let depth = 0; depth < 10; depth++) {
1587
+ const name = getDisplayName2(current);
1588
+ if (name && VALID_ROOTS.has(name)) break;
1589
+ const type = current.type;
1590
+ const isPlainFunctionComponent = typeof type === "function" && !type.prototype?.isReactComponent;
1591
+ if (!isPlainFunctionComponent) break;
1592
+ let produced;
1593
+ try {
1594
+ produced = type({ ...current.props });
1595
+ } catch (cause) {
1596
+ const detail = cause instanceof Error ? cause.message : String(cause);
1597
+ throw new Error(
1598
+ `[Unlayer] renderToJson: could not unwrap <${name || "wrapper"}>. A wrapper must be a plain component that synchronously returns a root (<Email>, <Page>, <Document>, or <Body>) and uses no React hooks. Pass the root element directly \u2014 e.g. renderToJson(<Email>\u2026</Email>). (${detail})`
1599
+ );
1600
+ }
1601
+ if (!React__default.default.isValidElement(produced)) break;
1602
+ current = produced;
1603
+ }
1604
+ return current;
1605
+ }
1556
1606
  function collectChildren2(node) {
1557
1607
  const result = [];
1558
1608
  React__default.default.Children.forEach(node, (child) => {
@@ -1769,9 +1819,9 @@ function renderRowToJson(element) {
1769
1819
  return processRow(element, counters);
1770
1820
  }
1771
1821
  function renderToJson(element) {
1822
+ element = unwrapRoot(element);
1772
1823
  const displayName = getDisplayName2(element);
1773
- const validRoots = /* @__PURE__ */ new Set(["Body", "Email", "Page", "Document"]);
1774
- if (!displayName || !validRoots.has(displayName)) {
1824
+ if (!displayName || !VALID_ROOTS.has(displayName)) {
1775
1825
  throw new Error(
1776
1826
  `[Unlayer] renderToJson: Root element must be <Body>, <Email>, <Page>, or <Document>, but got <${displayName || "unknown"}>. Wrap your content: <Body><Row><Column>...</Column></Row></Body>`
1777
1827
  );