@bettercms-ai/ui 0.18.0 → 0.20.0
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/blocks.js +222 -12
- package/dist/blocks.js.map +1 -1
- package/dist/index.js +222 -12
- package/dist/index.js.map +1 -1
- package/dist/registry.js +222 -12
- package/dist/registry.js.map +1 -1
- package/dist/renderer.js +222 -12
- package/dist/renderer.js.map +1 -1
- package/package.json +3 -3
package/dist/blocks.js
CHANGED
|
@@ -585,6 +585,7 @@ function BlocksRenderer({
|
|
|
585
585
|
}
|
|
586
586
|
|
|
587
587
|
// ../richtext/src/types.ts
|
|
588
|
+
var PT_TABLE_COLUMN_TYPES = ["text", "number", "money", "boolean", "rating", "link"];
|
|
588
589
|
function pullQuoteHref(link) {
|
|
589
590
|
if (typeof link === "string") return link.trim();
|
|
590
591
|
if (link && typeof link === "object" && typeof link.href === "string") {
|
|
@@ -817,7 +818,12 @@ function normalizeCell(raw, at, mint, read) {
|
|
|
817
818
|
...rowSpan === void 0 ? {} : { rowSpan },
|
|
818
819
|
...typeof raw.group === "string" ? { group: raw.group } : {},
|
|
819
820
|
...raw.highlight === true ? { highlight: true } : {},
|
|
820
|
-
...raw.sortable === true ? { sortable: true } : {}
|
|
821
|
+
...raw.sortable === true ? { sortable: true } : {},
|
|
822
|
+
// The V2 table's typed cells: the column (first-row cell), the per-cell type, the typed value.
|
|
823
|
+
...columnOf(raw.column) ? { column: columnOf(raw.column) } : {},
|
|
824
|
+
...isColumnType(raw.type) ? { type: raw.type } : {},
|
|
825
|
+
...typeof raw.value === "boolean" || typeof raw.value === "number" && Number.isFinite(raw.value) ? { value: raw.value } : {},
|
|
826
|
+
...typeof raw.note === "string" && raw.note ? { note: raw.note } : {}
|
|
821
827
|
};
|
|
822
828
|
}
|
|
823
829
|
function normalizeRow(raw, at, mint, read) {
|
|
@@ -829,7 +835,8 @@ function normalizeRow(raw, at, mint, read) {
|
|
|
829
835
|
...isRecord(raw) && typeof raw.group === "string" ? { group: raw.group } : {},
|
|
830
836
|
// The V2 table's two row flags ("Totals row", "Highlight this row"); see `PortableTextTableRow`.
|
|
831
837
|
...isRecord(raw) && raw.footer === true ? { footer: true } : {},
|
|
832
|
-
...isRecord(raw) && raw.highlight === true ? { highlight: true } : {}
|
|
838
|
+
...isRecord(raw) && raw.highlight === true ? { highlight: true } : {},
|
|
839
|
+
...isRecord(raw) && isColumnType(raw.type) ? { type: raw.type } : {}
|
|
833
840
|
};
|
|
834
841
|
}
|
|
835
842
|
function builtInTableToTable(node, key = randomKey) {
|
|
@@ -889,9 +896,18 @@ function tableExtras(node) {
|
|
|
889
896
|
...columnGroups ? { columnGroups } : {},
|
|
890
897
|
...node.filterable === true ? { filterable: true } : {},
|
|
891
898
|
...jsonLdOf(node.jsonLd) ? { jsonLd: jsonLdOf(node.jsonLd) } : {},
|
|
892
|
-
...designOf(node.design) ? { design: designOf(node.design) } : {}
|
|
899
|
+
...designOf(node.design) ? { design: designOf(node.design) } : {},
|
|
900
|
+
...footnotesOf(node.footnotes) ? { footnotes: footnotesOf(node.footnotes) } : {}
|
|
893
901
|
};
|
|
894
902
|
}
|
|
903
|
+
function footnotesOf(v) {
|
|
904
|
+
if (!Array.isArray(v)) return void 0;
|
|
905
|
+
const out = v.filter((f) => isRecord(f) && typeof f._key === "string" && f._key !== "").map((f) => ({ _key: f._key, text: typeof f.text === "string" ? f.text : "" }));
|
|
906
|
+
return out.length ? out : void 0;
|
|
907
|
+
}
|
|
908
|
+
function footnoteNumbers(table) {
|
|
909
|
+
return new Map((footnotesOf(table.footnotes) ?? []).map((f, i) => [f._key, i + 1]));
|
|
910
|
+
}
|
|
895
911
|
function designOf(v) {
|
|
896
912
|
if (!isRecord(v)) return void 0;
|
|
897
913
|
const d = {
|
|
@@ -964,6 +980,133 @@ function tableGroupLayout(table) {
|
|
|
964
980
|
width
|
|
965
981
|
};
|
|
966
982
|
}
|
|
983
|
+
var NUMERIC_TYPES = /* @__PURE__ */ new Set(["number", "money", "rating"]);
|
|
984
|
+
var isColumnType = (v) => PT_TABLE_COLUMN_TYPES.includes(v);
|
|
985
|
+
function columnOf(v) {
|
|
986
|
+
if (!isRecord(v)) return void 0;
|
|
987
|
+
const str = (x) => typeof x === "string" && x !== "" ? x : void 0;
|
|
988
|
+
const int = (x, lo, hi) => Number.isInteger(x) && x >= lo && x <= hi ? x : void 0;
|
|
989
|
+
const c = {
|
|
990
|
+
...isColumnType(v.type) ? { type: v.type } : {},
|
|
991
|
+
...str(v.description) ? { description: str(v.description) } : {},
|
|
992
|
+
...str(v.unit) ? { unit: str(v.unit) } : {},
|
|
993
|
+
...typeof v.currency === "string" && /^[A-Z]{3}$/.test(v.currency) ? { currency: v.currency } : {},
|
|
994
|
+
...int(v.decimals, 0, 10) !== void 0 ? { decimals: int(v.decimals, 0, 10) } : {},
|
|
995
|
+
...v.align === "start" || v.align === "center" || v.align === "end" ? { align: v.align } : {},
|
|
996
|
+
...str(v.trueLabel) ? { trueLabel: str(v.trueLabel) } : {},
|
|
997
|
+
...str(v.falseLabel) ? { falseLabel: str(v.falseLabel) } : {},
|
|
998
|
+
...int(v.max, 1, 10) !== void 0 ? { max: int(v.max, 1, 10) } : {}
|
|
999
|
+
};
|
|
1000
|
+
return Object.keys(c).length ? c : void 0;
|
|
1001
|
+
}
|
|
1002
|
+
function tableColumns(table) {
|
|
1003
|
+
const out = [];
|
|
1004
|
+
const first = Array.isArray(table.rows) ? table.rows[0] : void 0;
|
|
1005
|
+
for (const cell of isRecord(first) && Array.isArray(first.cells) ? first.cells : []) {
|
|
1006
|
+
const w = isRecord(cell) && typeof cell.span === "number" && Number.isInteger(cell.span) && cell.span > 1 ? cell.span : 1;
|
|
1007
|
+
const col = isRecord(cell) ? columnOf(cell.column) : void 0;
|
|
1008
|
+
for (let i = 0; i < w; i += 1) out.push(col);
|
|
1009
|
+
}
|
|
1010
|
+
return out;
|
|
1011
|
+
}
|
|
1012
|
+
function isTypedTable(table) {
|
|
1013
|
+
if (tableColumns(table).some(Boolean)) return true;
|
|
1014
|
+
return (Array.isArray(table.rows) ? table.rows : []).some(
|
|
1015
|
+
(r) => isRecord(r) && (r.type !== void 0 || Array.isArray(r.cells) && r.cells.some((c) => isRecord(c) && (c.type !== void 0 || c.value !== void 0)))
|
|
1016
|
+
);
|
|
1017
|
+
}
|
|
1018
|
+
var cellTypeOf = (col, row, cell) => (isRecord(cell) && isColumnType(cell.type) ? cell.type : void 0) ?? (isRecord(row) && isColumnType(row.type) ? row.type : void 0) ?? col?.type ?? "text";
|
|
1019
|
+
var columnAlign = (col, type) => col?.align ?? (NUMERIC_TYPES.has(type) ? "end" : "start");
|
|
1020
|
+
var TRUE_WORDS = /* @__PURE__ */ new Set(["\u2713", "\u2714", "\u2714\uFE0F", "\u2611", "\u2705", "yes", "y", "true", "included", "available", "supported", "x \u2713", "check", "\u25CF"]);
|
|
1021
|
+
var FALSE_WORDS = /* @__PURE__ */ new Set(["\u2717", "\u2715", "\u2716", "\u274C", "\xD7", "x", "no", "n", "false", "not included", "unavailable", "not available", "unsupported", "\u2014", "\u2013", "-", "\u25CB"]);
|
|
1022
|
+
function toBool(v) {
|
|
1023
|
+
if (typeof v === "boolean") return v;
|
|
1024
|
+
if (typeof v !== "string") return null;
|
|
1025
|
+
const s = v.trim().toLowerCase();
|
|
1026
|
+
return TRUE_WORDS.has(s) ? true : FALSE_WORDS.has(s) ? false : null;
|
|
1027
|
+
}
|
|
1028
|
+
function toNumber(v) {
|
|
1029
|
+
if (typeof v === "number") return Number.isFinite(v) ? v : null;
|
|
1030
|
+
if (typeof v !== "string") return null;
|
|
1031
|
+
const s = v.replace(/[,\s]/g, "").replace(/[^\d.+-]/g, "");
|
|
1032
|
+
if (!s || !/^[+-]?\d*\.?\d+$/.test(s)) return null;
|
|
1033
|
+
return Number(s);
|
|
1034
|
+
}
|
|
1035
|
+
var formatNumber = (n, decimals) => new Intl.NumberFormat("en-US", decimals != null ? { minimumFractionDigits: decimals, maximumFractionDigits: decimals } : { maximumFractionDigits: 6 }).format(n);
|
|
1036
|
+
function formatMoney(n, currency = "USD", decimals) {
|
|
1037
|
+
try {
|
|
1038
|
+
const whole = Number.isInteger(n) && decimals == null;
|
|
1039
|
+
return new Intl.NumberFormat("en-US", { style: "currency", currency, minimumFractionDigits: whole ? 0 : decimals ?? 2, maximumFractionDigits: whole ? 0 : decimals ?? 2 }).format(n);
|
|
1040
|
+
} catch {
|
|
1041
|
+
return `${formatNumber(n, decimals)} ${currency}`;
|
|
1042
|
+
}
|
|
1043
|
+
}
|
|
1044
|
+
var boolLabels = (col) => ({ yes: col?.trueLabel || "Included", no: col?.falseLabel || "Not included" });
|
|
1045
|
+
function typedCellText(col, type, v) {
|
|
1046
|
+
if (v == null || v === "") return "";
|
|
1047
|
+
const words = String(v).replace(/\s+/g, " ").trim();
|
|
1048
|
+
switch (type) {
|
|
1049
|
+
case "boolean": {
|
|
1050
|
+
const b = toBool(v);
|
|
1051
|
+
return b == null ? words : b ? boolLabels(col).yes : boolLabels(col).no;
|
|
1052
|
+
}
|
|
1053
|
+
case "number": {
|
|
1054
|
+
const n = toNumber(v);
|
|
1055
|
+
return n == null ? words : `${formatNumber(n, col?.decimals)}${col?.unit ? /^[%°]/.test(col.unit) ? col.unit : ` ${col.unit}` : ""}`;
|
|
1056
|
+
}
|
|
1057
|
+
case "money": {
|
|
1058
|
+
const n = toNumber(v);
|
|
1059
|
+
return n == null ? words : formatMoney(n, col?.currency || "USD", col?.decimals);
|
|
1060
|
+
}
|
|
1061
|
+
case "rating": {
|
|
1062
|
+
const n = toNumber(v);
|
|
1063
|
+
return n == null ? words : `${formatNumber(n, 1).replace(/\.0$/, "")} out of ${col?.max ?? 5}`;
|
|
1064
|
+
}
|
|
1065
|
+
default:
|
|
1066
|
+
return words;
|
|
1067
|
+
}
|
|
1068
|
+
}
|
|
1069
|
+
var escHtml = (s) => s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
1070
|
+
function typedCellView(column, row, cell, inHead) {
|
|
1071
|
+
if (inHead) {
|
|
1072
|
+
const align2 = columnAlign(column, column?.type ?? "text");
|
|
1073
|
+
return { lead: align2 !== "start" ? [["data-align", align2]] : [], tail: column?.description ? [["title", column.description]] : [] };
|
|
1074
|
+
}
|
|
1075
|
+
const type = cellTypeOf(column, row, cell);
|
|
1076
|
+
const words = portableTextWords(cell.content);
|
|
1077
|
+
const v = typeof cell.value === "number" || typeof cell.value === "boolean" ? cell.value : words;
|
|
1078
|
+
const tail = isColumnType(cell.type) ? [["data-type", cell.type]] : [];
|
|
1079
|
+
let inner;
|
|
1080
|
+
if (v === "") {
|
|
1081
|
+
inner = cell.header === true ? "" : '<span aria-hidden="true" class="bt-dash">\u2014</span><span class="bt-sr">No value</span>';
|
|
1082
|
+
tail.push(["data-empty", ""]);
|
|
1083
|
+
} else if (type === "boolean") {
|
|
1084
|
+
const b = toBool(v);
|
|
1085
|
+
if (b == null) inner = escHtml(words);
|
|
1086
|
+
else {
|
|
1087
|
+
const { yes, no } = boolLabels(column);
|
|
1088
|
+
inner = `<span aria-hidden="true" class="bt-bool" data-bool="${b}">${b ? "\u2713" : "\u2013"}</span><span class="bt-sr">${escHtml(b ? yes : no)}</span>`;
|
|
1089
|
+
tail.push(["data-value", String(b)]);
|
|
1090
|
+
}
|
|
1091
|
+
} else if (type === "rating") {
|
|
1092
|
+
const n = toNumber(v);
|
|
1093
|
+
if (n == null) inner = escHtml(words);
|
|
1094
|
+
else {
|
|
1095
|
+
inner = `<span aria-hidden="true" class="bt-star">\u2605</span> ${escHtml(formatNumber(n, 1).replace(/\.0$/, ""))}<span class="bt-dim"> / ${column?.max ?? 5}</span>`;
|
|
1096
|
+
tail.push(["data-value", String(n)]);
|
|
1097
|
+
}
|
|
1098
|
+
} else if (type === "number" || type === "money") {
|
|
1099
|
+
const n = toNumber(v);
|
|
1100
|
+
inner = escHtml(typedCellText(column, type, v));
|
|
1101
|
+
if (n != null) tail.push(["data-value", String(n)]);
|
|
1102
|
+
}
|
|
1103
|
+
const align = columnAlign(column, type);
|
|
1104
|
+
if (align !== "start") tail.push(["data-align", align]);
|
|
1105
|
+
return { lead: [], tail, ...inner === void 0 ? {} : { inner } };
|
|
1106
|
+
}
|
|
1107
|
+
function portableTextWords(content) {
|
|
1108
|
+
return (Array.isArray(content) ? content : []).map((b) => isRecord(b) && Array.isArray(b.children) ? b.children.map((c) => isRecord(c) && typeof c.text === "string" ? c.text : "").join("") : "").join(" ").replace(/\s+/g, " ").trim();
|
|
1109
|
+
}
|
|
967
1110
|
|
|
968
1111
|
// ../richtext/src/key-takeaways.ts
|
|
969
1112
|
var isRecord2 = (v) => !!v && typeof v === "object" && !Array.isArray(v);
|
|
@@ -1047,9 +1190,12 @@ var tableLines = (table) => {
|
|
|
1047
1190
|
layout.columns.map((r) => one(r.label)).filter(Boolean).join(" "),
|
|
1048
1191
|
...head.map(rowLine),
|
|
1049
1192
|
...layout.rows.flatMap((run) => [...run.label === void 0 ? [] : [one(run.label)], ...run.rows.map(rowLine)]),
|
|
1050
|
-
one(table.notes)
|
|
1193
|
+
one(table.notes),
|
|
1194
|
+
// footnotes, numbered as the html numbers them (V2 tableSearchText reads them too)
|
|
1195
|
+
...(Array.isArray(table.footnotes) ? table.footnotes : []).map((f, i) => one(`[${i + 1}] ${typeof f?.text === "string" ? f.text : ""}`))
|
|
1051
1196
|
];
|
|
1052
|
-
const
|
|
1197
|
+
const fnCount = Array.isArray(table.footnotes) ? table.footnotes.length : 0;
|
|
1198
|
+
const extras = /* @__PURE__ */ new Set([0, 1, lines.length - 1 - fnCount]);
|
|
1053
1199
|
return lines.filter((l, i) => l !== "" || !extras.has(i));
|
|
1054
1200
|
};
|
|
1055
1201
|
var pullQuoteLines = (v) => {
|
|
@@ -1134,6 +1280,13 @@ function Table({ value }) {
|
|
|
1134
1280
|
at += w;
|
|
1135
1281
|
}
|
|
1136
1282
|
}
|
|
1283
|
+
const columns = tableColumns(value);
|
|
1284
|
+
const typed = isTypedTable(value);
|
|
1285
|
+
const headSet = new Set(tableSections(value).head);
|
|
1286
|
+
const props = (list) => Object.fromEntries(list);
|
|
1287
|
+
const fnNumber = footnoteNumbers(value);
|
|
1288
|
+
const footnotes = footnotesOf(value.footnotes) ?? [];
|
|
1289
|
+
const tableId = typeof value._key === "string" && value._key ? value._key : "tbl";
|
|
1137
1290
|
const cells = (row) => {
|
|
1138
1291
|
let col = 0;
|
|
1139
1292
|
return (Array.isArray(row?.cells) ? row.cells : []).map((cell) => {
|
|
@@ -1142,19 +1295,27 @@ function Table({ value }) {
|
|
|
1142
1295
|
const at = col;
|
|
1143
1296
|
col += span2 ?? 1;
|
|
1144
1297
|
const rowSpan = typeof cell?.rowSpan === "number" && cell.rowSpan > 1 ? cell.rowSpan : void 0;
|
|
1298
|
+
const n = typeof cell?.note === "string" ? fnNumber.get(cell.note) : void 0;
|
|
1145
1299
|
const content = Array.isArray(cell?.content) ? cell.content : [];
|
|
1146
1300
|
const lone = content.length === 1 && content[0]._type === "block" && content[0].style === "normal" && !content[0].listItem;
|
|
1147
|
-
|
|
1301
|
+
const view = typed ? typedCellView(columns[at], row, cell ?? {}, headSet.has(row)) : void 0;
|
|
1302
|
+
const noteAttr = n ? [["data-note", cell.note]] : [];
|
|
1303
|
+
const tail = [...(view?.tail ?? []).filter(([k]) => k !== "data-align"), ...noteAttr, ...(view?.tail ?? []).filter(([k]) => k === "data-align")];
|
|
1304
|
+
const supHtml = n ? `<sup><a href="#${tableId}-fn-${n}" aria-label="Note ${n}">${n}</a></sup>` : "";
|
|
1305
|
+
return /* @__PURE__ */ jsx14(Tag, { ...Tag === "td" ? role("cell") : {}, ...span2 ? { colSpan: span2 } : {}, ...rowSpan ? { rowSpan } : {}, ...props(view?.lead ?? []), ...stacked && Tag === "td" ? { "data-label": labels[at] || `Column ${at + 1}` } : {}, ...marked.has(at) ? { "data-highlight": "true" } : {}, ...props(tail), ...view?.inner !== void 0 ? { dangerouslySetInnerHTML: { __html: view.inner + supHtml } } : {}, children: view?.inner !== void 0 ? void 0 : /* @__PURE__ */ jsxs11(Fragment2, { children: [
|
|
1306
|
+
/* @__PURE__ */ jsx14(PT, { value: content, components: lone ? inline : components }),
|
|
1307
|
+
n ? /* @__PURE__ */ jsx14("sup", { children: /* @__PURE__ */ jsx14("a", { href: `#${tableId}-fn-${n}`, "aria-label": `Note ${n}`, children: n }) }) : null
|
|
1308
|
+
] }) }, cell?._key);
|
|
1148
1309
|
});
|
|
1149
1310
|
};
|
|
1150
|
-
const rowEl = (row) => /* @__PURE__ */ jsx14("tr", { ...role("row"), ...row?.highlight === true ? { "data-highlight": "true" } : {}, children: cells(row) }, row?._key);
|
|
1311
|
+
const rowEl = (row) => /* @__PURE__ */ jsx14("tr", { ...role("row"), ...typeof row?.type === "string" ? { "data-type": row.type } : {}, ...row?.highlight === true ? { "data-highlight": "true" } : {}, children: cells(row) }, row?._key);
|
|
1151
1312
|
const sections = tableSections(value);
|
|
1152
1313
|
const head = sections.head.length;
|
|
1153
1314
|
const foot = sections.foot;
|
|
1154
1315
|
const layout = tableGroupLayout(value);
|
|
1155
1316
|
const caption = typeof value.caption === "string" ? value.caption.trim() : "";
|
|
1156
1317
|
const notes = typeof value.notes === "string" ? value.notes.trim() : "";
|
|
1157
|
-
const notesId = notes && typeof value._key === "string" && value._key ? `${value._key}-notes` : void 0;
|
|
1318
|
+
const notesId = (notes || footnotes.length) && typeof value._key === "string" && value._key ? `${value._key}-notes` : void 0;
|
|
1158
1319
|
const span = (n) => n > 1 ? n : void 0;
|
|
1159
1320
|
const groupRow = layout.columns.length ? /* @__PURE__ */ jsx14("tr", { ...role("row"), children: layout.columns.flatMap(
|
|
1160
1321
|
(run, i) => run.label === void 0 ? Array.from({ length: run.width }, (_, k) => /* @__PURE__ */ jsx14("td", { ...role("cell") }, `${i}-${k}`)) : [/* @__PURE__ */ jsx14("th", { ...role("columnheader"), scope: "colgroup", colSpan: span(run.width), "data-group": run.key, children: run.label }, i)]
|
|
@@ -1163,11 +1324,26 @@ function Table({ value }) {
|
|
|
1163
1324
|
run.label !== void 0 && /* @__PURE__ */ jsx14("tr", { ...role("row"), children: /* @__PURE__ */ jsx14("th", { ...role("rowheader"), scope: "rowgroup", colSpan: span(layout.width), children: run.label }) }),
|
|
1164
1325
|
run.rows.map(rowEl)
|
|
1165
1326
|
] }, i)) : sections.body.length > 0 && /* @__PURE__ */ jsx14("tbody", { ...role("rowgroup"), children: sections.body.map(rowEl) });
|
|
1327
|
+
const colProps = (i) => {
|
|
1328
|
+
const c = columns[i];
|
|
1329
|
+
return {
|
|
1330
|
+
...c ? { "data-type": c.type ?? "text" } : {},
|
|
1331
|
+
...c?.unit ? { "data-unit": c.unit } : {},
|
|
1332
|
+
...c?.currency ? { "data-currency": c.currency } : {},
|
|
1333
|
+
...c?.decimals != null ? { "data-decimals": String(c.decimals) } : {},
|
|
1334
|
+
...c?.align ? { "data-align": c.align } : {},
|
|
1335
|
+
...sortable.has(i) ? { "data-sortable": "true" } : {},
|
|
1336
|
+
...c?.trueLabel ? { "data-true": c.trueLabel } : {},
|
|
1337
|
+
...c?.falseLabel ? { "data-false": c.falseLabel } : {},
|
|
1338
|
+
...c?.max != null ? { "data-max": String(c.max) } : {},
|
|
1339
|
+
...c?.description ? { "data-description": c.description } : {}
|
|
1340
|
+
};
|
|
1341
|
+
};
|
|
1166
1342
|
const table = /* @__PURE__ */ jsxs11("table", { ...role("table"), ...value.legacy === true ? { className: "bcms-table" } : {}, ...notesId ? { "aria-describedby": notesId } : {}, children: [
|
|
1167
1343
|
caption && /* @__PURE__ */ jsx14("caption", { children: caption }),
|
|
1168
|
-
sortable.size ? (layout.columns.length ? layout.columns.map((run) => run.width) : [layout.width]).map((w, i, all) => {
|
|
1344
|
+
sortable.size || columns.some(Boolean) ? (layout.columns.length ? layout.columns.map((run) => run.width) : [layout.width]).map((w, i, all) => {
|
|
1169
1345
|
const from = all.slice(0, i).reduce((n, x) => n + x, 0);
|
|
1170
|
-
return /* @__PURE__ */ jsx14("colgroup", { children: Array.from({ length: w }, (_, k) => /* @__PURE__ */ jsx14("col", { ...
|
|
1346
|
+
return /* @__PURE__ */ jsx14("colgroup", { children: Array.from({ length: w }, (_, k) => /* @__PURE__ */ jsx14("col", { ...colProps(from + k) }, k)) }, i);
|
|
1171
1347
|
}) : layout.columns.map((run, i) => /* @__PURE__ */ jsx14("colgroup", { span: span(run.width) }, i)),
|
|
1172
1348
|
(groupRow || head > 0) && /* @__PURE__ */ jsxs11("thead", { ...role("rowgroup"), children: [
|
|
1173
1349
|
groupRow,
|
|
@@ -1180,9 +1356,12 @@ function Table({ value }) {
|
|
|
1180
1356
|
const ld = jsonLdOf(value.jsonLd);
|
|
1181
1357
|
const ldAttrs = ld ? { "data-jsonld": ld.type, ...ld.axis ? { "data-jsonld-axis": ld.axis } : {}, ...ld.priceRow ? { "data-jsonld-price": ld.priceRow } : {} } : {};
|
|
1182
1358
|
const designAttrs = design ? { ...design.responsive ? { "data-responsive": design.responsive } : {}, ...design.sticky ? { "data-sticky": "true" } : {} } : {};
|
|
1183
|
-
return notes || filter || ld || design ? /* @__PURE__ */ jsxs11("figure", { "data-rt": "table", ...designAttrs, ...filter ? { "data-filter": "true" } : {}, ...ldAttrs, children: [
|
|
1359
|
+
return notes || filter || ld || design || footnotes.length ? /* @__PURE__ */ jsxs11("figure", { "data-rt": "table", ...designAttrs, ...filter ? { "data-filter": "true" } : {}, ...ldAttrs, children: [
|
|
1184
1360
|
table,
|
|
1185
|
-
|
|
1361
|
+
footnotes.length ? /* @__PURE__ */ jsxs11("div", { className: "bt-notes", id: `${tableId}-notes`, children: [
|
|
1362
|
+
notes ? /* @__PURE__ */ jsx14("p", { "data-notes": "", children: notes }) : null,
|
|
1363
|
+
/* @__PURE__ */ jsx14("ol", { "data-footnotes": "", children: footnotes.map((f, i) => /* @__PURE__ */ jsx14("li", { id: `${tableId}-fn-${i + 1}`, "data-key": f._key, children: f.text }, f._key)) })
|
|
1364
|
+
] }) : notes ? /* @__PURE__ */ jsx14("p", { "data-notes": "", id: notesId, children: notes }) : null
|
|
1186
1365
|
] }) : table;
|
|
1187
1366
|
}
|
|
1188
1367
|
function buildComponents(renderBlock) {
|
|
@@ -1205,6 +1384,8 @@ function buildComponents(renderBlock) {
|
|
|
1205
1384
|
[PT_TYPES.block]: ({ value }) => {
|
|
1206
1385
|
const rendered = renderBlock?.(value);
|
|
1207
1386
|
if (rendered !== void 0) return /* @__PURE__ */ jsx14(Fragment2, { children: rendered });
|
|
1387
|
+
const builtIn = calloutOrToggle(value);
|
|
1388
|
+
if (builtIn) return builtIn;
|
|
1208
1389
|
const copy = detachedComponentCopy(value);
|
|
1209
1390
|
if (copy) {
|
|
1210
1391
|
return /* @__PURE__ */ jsx14("div", { className: "bcms-block bcms-block--component", "data-bcms-component-copy": copy.componentId, "data-bcms-instance": copy.id, children: /* @__PURE__ */ jsx14(BlocksRenderer, { blocks: copy.blocks }) });
|
|
@@ -1321,6 +1502,35 @@ function runsOf(blocks) {
|
|
|
1321
1502
|
}
|
|
1322
1503
|
return runs;
|
|
1323
1504
|
}
|
|
1505
|
+
function paragraphs(text) {
|
|
1506
|
+
return text.split(/\n\s*\n/).map((p) => p.trim()).filter(Boolean).map((p, i) => /* @__PURE__ */ jsx14("p", { children: p.split("\n").map((line, j) => j === 0 ? line : [/* @__PURE__ */ jsx14("br", {}, j), line]) }, i));
|
|
1507
|
+
}
|
|
1508
|
+
var CALLOUT_TONES = /* @__PURE__ */ new Set(["info", "tip", "warning"]);
|
|
1509
|
+
function calloutOrToggle(value) {
|
|
1510
|
+
const v = value ?? {};
|
|
1511
|
+
const f = v.fields && typeof v.fields === "object" ? v.fields : {};
|
|
1512
|
+
const text = (x) => typeof x === "string" ? x.trim() : "";
|
|
1513
|
+
if (v.schemaKey === "builtin:callout") {
|
|
1514
|
+
const tone = CALLOUT_TONES.has(text(f.tone)) ? text(f.tone) : "info";
|
|
1515
|
+
const title = text(f.title);
|
|
1516
|
+
const body = paragraphs(typeof f.message === "string" ? f.message : "");
|
|
1517
|
+
if (!title && !body.length) return /* @__PURE__ */ jsx14(Fragment2, {});
|
|
1518
|
+
return /* @__PURE__ */ jsxs11("div", { className: `bcms-callout bcms-callout--${tone}`, "data-rt": "callout", "data-callout": tone, role: "note", children: [
|
|
1519
|
+
title ? /* @__PURE__ */ jsx14("p", { className: "bcms-callout__title", "data-title": "", children: title }) : null,
|
|
1520
|
+
/* @__PURE__ */ jsx14("div", { className: "bcms-callout__body", "data-body": "", children: body })
|
|
1521
|
+
] });
|
|
1522
|
+
}
|
|
1523
|
+
if (v.schemaKey === "builtin:toggle") {
|
|
1524
|
+
const title = text(f.title);
|
|
1525
|
+
const body = paragraphs(typeof f.body === "string" ? f.body : "");
|
|
1526
|
+
if (!title && !body.length) return /* @__PURE__ */ jsx14(Fragment2, {});
|
|
1527
|
+
return /* @__PURE__ */ jsxs11("details", { className: "bcms-toggle", "data-rt": "toggle", children: [
|
|
1528
|
+
/* @__PURE__ */ jsx14("summary", { className: "bcms-toggle__title", children: title }),
|
|
1529
|
+
/* @__PURE__ */ jsx14("div", { className: "bcms-toggle__body", "data-body": "", children: body })
|
|
1530
|
+
] });
|
|
1531
|
+
}
|
|
1532
|
+
return null;
|
|
1533
|
+
}
|
|
1324
1534
|
function PortableText({ value, bindingBase, renderBlock }) {
|
|
1325
1535
|
const blocks = React6.useMemo(() => normalizePortableText(readValue(value)), [value]);
|
|
1326
1536
|
const components = React6.useMemo(() => buildComponents(renderBlock), [renderBlock]);
|