@bettercms-ai/ui 0.17.1 → 0.19.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 +355 -28
- package/dist/blocks.js.map +1 -1
- package/dist/index.js +355 -28
- package/dist/index.js.map +1 -1
- package/dist/registry.js +355 -28
- package/dist/registry.js.map +1 -1
- package/dist/renderer.js +355 -28
- package/dist/renderer.js.map +1 -1
- package/package.json +3 -3
package/dist/index.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") {
|
|
@@ -592,6 +593,8 @@ function pullQuoteHref(link) {
|
|
|
592
593
|
}
|
|
593
594
|
return "";
|
|
594
595
|
}
|
|
596
|
+
var isPortableTextBlock = (n) => !!n && typeof n === "object" && n._type === "block";
|
|
597
|
+
var isPortableTextSpan = (n) => !!n && typeof n === "object" && n._type === "span";
|
|
595
598
|
var PT_TYPES = {
|
|
596
599
|
/** A generic embedded block: `{schemaKey, schemaLabel, fields}`, the successor to Lexical's BlockNode. */
|
|
597
600
|
block: "bcmsBlock",
|
|
@@ -813,7 +816,14 @@ function normalizeCell(raw, at, mint, read) {
|
|
|
813
816
|
...raw.header === true ? { header: true } : {},
|
|
814
817
|
...span === void 0 ? {} : { span },
|
|
815
818
|
...rowSpan === void 0 ? {} : { rowSpan },
|
|
816
|
-
...typeof raw.group === "string" ? { group: raw.group } : {}
|
|
819
|
+
...typeof raw.group === "string" ? { group: raw.group } : {},
|
|
820
|
+
...raw.highlight === true ? { highlight: 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 } : {}
|
|
817
827
|
};
|
|
818
828
|
}
|
|
819
829
|
function normalizeRow(raw, at, mint, read) {
|
|
@@ -822,7 +832,11 @@ function normalizeRow(raw, at, mint, read) {
|
|
|
822
832
|
_key: isRecord(raw) && isValidKey(raw._key) ? raw._key : mint("r", at),
|
|
823
833
|
cells: cells.map((c, col) => normalizeCell(c, [at, col], mint, read)),
|
|
824
834
|
...isRecord(raw) && raw.head === true ? { head: true } : {},
|
|
825
|
-
...isRecord(raw) && typeof raw.group === "string" ? { group: raw.group } : {}
|
|
835
|
+
...isRecord(raw) && typeof raw.group === "string" ? { group: raw.group } : {},
|
|
836
|
+
// The V2 table's two row flags ("Totals row", "Highlight this row"); see `PortableTextTableRow`.
|
|
837
|
+
...isRecord(raw) && raw.footer === true ? { footer: true } : {},
|
|
838
|
+
...isRecord(raw) && raw.highlight === true ? { highlight: true } : {},
|
|
839
|
+
...isRecord(raw) && isColumnType(raw.type) ? { type: raw.type } : {}
|
|
826
840
|
};
|
|
827
841
|
}
|
|
828
842
|
function builtInTableToTable(node, key = randomKey) {
|
|
@@ -879,9 +893,62 @@ function tableExtras(node) {
|
|
|
879
893
|
...typeof node.caption === "string" ? { caption: node.caption } : {},
|
|
880
894
|
...typeof node.notes === "string" ? { notes: node.notes } : {},
|
|
881
895
|
...rowGroups ? { rowGroups } : {},
|
|
882
|
-
...columnGroups ? { columnGroups } : {}
|
|
896
|
+
...columnGroups ? { columnGroups } : {},
|
|
897
|
+
...node.filterable === true ? { filterable: true } : {},
|
|
898
|
+
...jsonLdOf(node.jsonLd) ? { jsonLd: jsonLdOf(node.jsonLd) } : {},
|
|
899
|
+
...designOf(node.design) ? { design: designOf(node.design) } : {},
|
|
900
|
+
...footnotesOf(node.footnotes) ? { footnotes: footnotesOf(node.footnotes) } : {}
|
|
883
901
|
};
|
|
884
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
|
+
}
|
|
911
|
+
function designOf(v) {
|
|
912
|
+
if (!isRecord(v)) return void 0;
|
|
913
|
+
const d = {
|
|
914
|
+
...v.responsive === "stack" || v.responsive === "cards" ? { responsive: v.responsive } : {},
|
|
915
|
+
...v.sticky === true ? { sticky: true } : {}
|
|
916
|
+
};
|
|
917
|
+
return Object.keys(d).length ? d : void 0;
|
|
918
|
+
}
|
|
919
|
+
var JSONLD_TYPES = ["ItemList", "Dataset", "Offers"];
|
|
920
|
+
function jsonLdOf(v) {
|
|
921
|
+
if (!isRecord(v) || !JSONLD_TYPES.includes(v.type)) return void 0;
|
|
922
|
+
return {
|
|
923
|
+
type: v.type,
|
|
924
|
+
...v.axis === "rows" || v.axis === "columns" ? { axis: v.axis } : {},
|
|
925
|
+
...typeof v.priceRow === "string" && v.priceRow ? { priceRow: v.priceRow } : {}
|
|
926
|
+
};
|
|
927
|
+
}
|
|
928
|
+
function tableSections(table) {
|
|
929
|
+
const rows = Array.isArray(table.rows) ? table.rows : [];
|
|
930
|
+
const headCount = rows.findIndex((r) => !isRecord(r) || r.head !== true);
|
|
931
|
+
const head = rows.slice(0, headCount === -1 ? rows.length : headCount);
|
|
932
|
+
let footFrom = rows.length;
|
|
933
|
+
while (footFrom > head.length && isRecord(rows[footFrom - 1]) && rows[footFrom - 1].footer === true) footFrom -= 1;
|
|
934
|
+
return { head, body: rows.slice(head.length, footFrom), foot: rows.slice(footFrom) };
|
|
935
|
+
}
|
|
936
|
+
function highlightedColumns(table) {
|
|
937
|
+
return markedColumns(table, "highlight");
|
|
938
|
+
}
|
|
939
|
+
function sortableColumns(table) {
|
|
940
|
+
return markedColumns(table, "sortable");
|
|
941
|
+
}
|
|
942
|
+
function markedColumns(table, flag) {
|
|
943
|
+
const out = /* @__PURE__ */ new Set();
|
|
944
|
+
const first = Array.isArray(table.rows) ? table.rows[0] : void 0;
|
|
945
|
+
let at = 0;
|
|
946
|
+
for (const cell of isRecord(first) && Array.isArray(first.cells) ? first.cells : []) {
|
|
947
|
+
if (isRecord(cell) && cell[flag] === true) out.add(at);
|
|
948
|
+
at += isRecord(cell) && typeof cell.span === "number" && Number.isInteger(cell.span) && cell.span > 1 ? cell.span : 1;
|
|
949
|
+
}
|
|
950
|
+
return out;
|
|
951
|
+
}
|
|
885
952
|
function tableGroupLayout(table) {
|
|
886
953
|
const rows = Array.isArray(table.rows) ? table.rows : [];
|
|
887
954
|
const labels = (list) => new Map(
|
|
@@ -899,8 +966,7 @@ function tableGroupLayout(table) {
|
|
|
899
966
|
else columns.push({ width: spanOf2(cell), ...key === void 0 ? {} : { key, label: colLabels.get(key) } });
|
|
900
967
|
}
|
|
901
968
|
const rowLabels = labels(table.rowGroups);
|
|
902
|
-
const
|
|
903
|
-
const body = headCount === -1 ? [] : rows.slice(headCount);
|
|
969
|
+
const { body } = tableSections(table);
|
|
904
970
|
const runs = [];
|
|
905
971
|
for (const row of body) {
|
|
906
972
|
const key = isRecord(row) && typeof row.group === "string" && rowLabels.has(row.group) ? row.group : void 0;
|
|
@@ -914,6 +980,133 @@ function tableGroupLayout(table) {
|
|
|
914
980
|
width
|
|
915
981
|
};
|
|
916
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
|
+
}
|
|
917
1110
|
|
|
918
1111
|
// ../richtext/src/key-takeaways.ts
|
|
919
1112
|
var isRecord2 = (v) => !!v && typeof v === "object" && !Array.isArray(v);
|
|
@@ -939,6 +1132,77 @@ function detachedComponentCopy(value) {
|
|
|
939
1132
|
...typeof f.variant === "string" ? { variant: f.variant } : {}
|
|
940
1133
|
};
|
|
941
1134
|
}
|
|
1135
|
+
function componentCopyLines(copy) {
|
|
1136
|
+
const line = (v) => {
|
|
1137
|
+
if (typeof v === "number" && Number.isFinite(v)) return String(v);
|
|
1138
|
+
if (typeof v === "string") {
|
|
1139
|
+
const t = v.replace(/<[^>]+>/g, " ").replace(/ /g, " ").replace(/\s+/g, " ").trim();
|
|
1140
|
+
return t || null;
|
|
1141
|
+
}
|
|
1142
|
+
if (isRecord3(v)) return line(v.label ?? v.text ?? v.title);
|
|
1143
|
+
return null;
|
|
1144
|
+
};
|
|
1145
|
+
return Object.values(copy.props).map(line).filter((s) => !!s);
|
|
1146
|
+
}
|
|
1147
|
+
|
|
1148
|
+
// ../richtext/src/plain.ts
|
|
1149
|
+
function portableTextToPlainText(value) {
|
|
1150
|
+
if (!Array.isArray(value)) return "";
|
|
1151
|
+
const lines = [];
|
|
1152
|
+
for (const node of value) {
|
|
1153
|
+
if (isPortableTextBlock(node)) {
|
|
1154
|
+
lines.push(node.children.map((c) => isPortableTextSpan(c) ? c.text : "").join(""));
|
|
1155
|
+
continue;
|
|
1156
|
+
}
|
|
1157
|
+
if (node._type === PT_TYPES.code && typeof node.code === "string") {
|
|
1158
|
+
lines.push(node.code);
|
|
1159
|
+
}
|
|
1160
|
+
if (node._type === PT_TYPES.pullQuote) {
|
|
1161
|
+
lines.push(...pullQuoteLines(node));
|
|
1162
|
+
continue;
|
|
1163
|
+
}
|
|
1164
|
+
if (node._type === PT_TYPES.keyTakeaways) {
|
|
1165
|
+
const { title, points } = keyTakeawaysView(node);
|
|
1166
|
+
lines.push(...title ? [title] : [], ...points);
|
|
1167
|
+
continue;
|
|
1168
|
+
}
|
|
1169
|
+
const table = migrateTable(node);
|
|
1170
|
+
if (table) {
|
|
1171
|
+
lines.push(...tableLines(table));
|
|
1172
|
+
continue;
|
|
1173
|
+
}
|
|
1174
|
+
const copy = detachedComponentCopy(node);
|
|
1175
|
+
if (copy) {
|
|
1176
|
+
lines.push(...componentCopyLines(copy));
|
|
1177
|
+
continue;
|
|
1178
|
+
}
|
|
1179
|
+
}
|
|
1180
|
+
return lines.join("\n");
|
|
1181
|
+
}
|
|
1182
|
+
var tableLines = (table) => {
|
|
1183
|
+
const rows = Array.isArray(table.rows) ? table.rows : [];
|
|
1184
|
+
const rowLine = (row) => (Array.isArray(row?.cells) ? row.cells : []).map((cell) => portableTextToPlainText(cell?.content).replace(/\s+/g, " ").trim()).join(" ").trim();
|
|
1185
|
+
const layout = tableGroupLayout(table);
|
|
1186
|
+
const one = (s) => typeof s === "string" ? s.replace(/\s+/g, " ").trim() : "";
|
|
1187
|
+
const head = layout.rows.length ? rows.slice(0, rows.length - layout.rows.reduce((n, r) => n + r.rows.length, 0)) : rows;
|
|
1188
|
+
const lines = [
|
|
1189
|
+
one(table.caption),
|
|
1190
|
+
layout.columns.map((r) => one(r.label)).filter(Boolean).join(" "),
|
|
1191
|
+
...head.map(rowLine),
|
|
1192
|
+
...layout.rows.flatMap((run) => [...run.label === void 0 ? [] : [one(run.label)], ...run.rows.map(rowLine)]),
|
|
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 : ""}`))
|
|
1196
|
+
];
|
|
1197
|
+
const fnCount = Array.isArray(table.footnotes) ? table.footnotes.length : 0;
|
|
1198
|
+
const extras = /* @__PURE__ */ new Set([0, 1, lines.length - 1 - fnCount]);
|
|
1199
|
+
return lines.filter((l, i) => l !== "" || !extras.has(i));
|
|
1200
|
+
};
|
|
1201
|
+
var pullQuoteLines = (v) => {
|
|
1202
|
+
const text = (x) => typeof x === "string" ? x.trim() : "";
|
|
1203
|
+
const by = [text(v.name), text(v.role)].filter(Boolean).join(", ");
|
|
1204
|
+
return [text(v.quote), ...by ? [`\u2014 ${by}`] : []].filter(Boolean);
|
|
1205
|
+
};
|
|
942
1206
|
|
|
943
1207
|
// ../richtext/src/read.ts
|
|
944
1208
|
var isRecord4 = (v) => !!v && typeof v === "object" && !Array.isArray(v);
|
|
@@ -1000,41 +1264,104 @@ function Table({ value }) {
|
|
|
1000
1264
|
);
|
|
1001
1265
|
const rows = Array.isArray(value?.rows) ? value.rows : [];
|
|
1002
1266
|
if (rows.length === 0) return null;
|
|
1003
|
-
const
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1267
|
+
const marked = highlightedColumns(value);
|
|
1268
|
+
const sortable = sortableColumns(value);
|
|
1269
|
+
const design = designOf(value.design);
|
|
1270
|
+
const stacked = design?.responsive === "stack" || design?.responsive === "cards";
|
|
1271
|
+
const role = (r) => stacked ? { role: r } : {};
|
|
1272
|
+
const labels = [];
|
|
1273
|
+
if (stacked) {
|
|
1274
|
+
const headRows = tableSections(value).head;
|
|
1275
|
+
let at = 0;
|
|
1276
|
+
for (const c of Array.isArray(headRows[headRows.length - 1]?.cells) ? headRows[headRows.length - 1].cells : []) {
|
|
1277
|
+
const text = portableTextToPlainText(Array.isArray(c?.content) ? c.content : []).replace(/\s+/g, " ").trim();
|
|
1278
|
+
const w = typeof c?.span === "number" && c.span > 1 ? c.span : 1;
|
|
1279
|
+
for (let i = 0; i < w; i += 1) labels[at + i] = text;
|
|
1280
|
+
at += w;
|
|
1281
|
+
}
|
|
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";
|
|
1290
|
+
const cells = (row) => {
|
|
1291
|
+
let col = 0;
|
|
1292
|
+
return (Array.isArray(row?.cells) ? row.cells : []).map((cell) => {
|
|
1293
|
+
const Tag = cell?.header === true ? "th" : "td";
|
|
1294
|
+
const span2 = typeof cell?.span === "number" && cell.span > 1 ? cell.span : void 0;
|
|
1295
|
+
const at = col;
|
|
1296
|
+
col += span2 ?? 1;
|
|
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;
|
|
1299
|
+
const content = Array.isArray(cell?.content) ? cell.content : [];
|
|
1300
|
+
const lone = content.length === 1 && content[0]._type === "block" && content[0].style === "normal" && !content[0].listItem;
|
|
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);
|
|
1309
|
+
});
|
|
1310
|
+
};
|
|
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);
|
|
1312
|
+
const sections = tableSections(value);
|
|
1313
|
+
const head = sections.head.length;
|
|
1314
|
+
const foot = sections.foot;
|
|
1014
1315
|
const layout = tableGroupLayout(value);
|
|
1015
1316
|
const caption = typeof value.caption === "string" ? value.caption.trim() : "";
|
|
1016
1317
|
const notes = typeof value.notes === "string" ? value.notes.trim() : "";
|
|
1017
|
-
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;
|
|
1018
1319
|
const span = (n) => n > 1 ? n : void 0;
|
|
1019
|
-
const groupRow = layout.columns.length ? /* @__PURE__ */ jsx14("tr", { children: layout.columns.flatMap(
|
|
1020
|
-
(run, i) => run.label === void 0 ? Array.from({ length: run.width }, (_, k) => /* @__PURE__ */ jsx14("td", {}, `${i}-${k}`)) : [/* @__PURE__ */ jsx14("th", { scope: "colgroup", colSpan: span(run.width), "data-group": run.key, children: run.label }, i)]
|
|
1320
|
+
const groupRow = layout.columns.length ? /* @__PURE__ */ jsx14("tr", { ...role("row"), children: layout.columns.flatMap(
|
|
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)]
|
|
1021
1322
|
) }) : null;
|
|
1022
|
-
const bodies = layout.rows.length ? layout.rows.map((run, i) => /* @__PURE__ */ jsxs11("tbody", { "data-key": run.key, children: [
|
|
1023
|
-
run.label !== void 0 && /* @__PURE__ */ jsx14("tr", { children: /* @__PURE__ */ jsx14("th", { scope: "rowgroup", colSpan: span(layout.width), children: run.label }) }),
|
|
1323
|
+
const bodies = layout.rows.length ? layout.rows.map((run, i) => /* @__PURE__ */ jsxs11("tbody", { ...role("rowgroup"), "data-key": run.key, children: [
|
|
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 }) }),
|
|
1024
1325
|
run.rows.map(rowEl)
|
|
1025
|
-
] }, i)) :
|
|
1026
|
-
const
|
|
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
|
+
};
|
|
1342
|
+
const table = /* @__PURE__ */ jsxs11("table", { ...role("table"), ...value.legacy === true ? { className: "bcms-table" } : {}, ...notesId ? { "aria-describedby": notesId } : {}, children: [
|
|
1027
1343
|
caption && /* @__PURE__ */ jsx14("caption", { children: caption }),
|
|
1028
|
-
layout.columns.map((run
|
|
1029
|
-
|
|
1344
|
+
sortable.size || columns.some(Boolean) ? (layout.columns.length ? layout.columns.map((run) => run.width) : [layout.width]).map((w, i, all) => {
|
|
1345
|
+
const from = all.slice(0, i).reduce((n, x) => n + x, 0);
|
|
1346
|
+
return /* @__PURE__ */ jsx14("colgroup", { children: Array.from({ length: w }, (_, k) => /* @__PURE__ */ jsx14("col", { ...colProps(from + k) }, k)) }, i);
|
|
1347
|
+
}) : layout.columns.map((run, i) => /* @__PURE__ */ jsx14("colgroup", { span: span(run.width) }, i)),
|
|
1348
|
+
(groupRow || head > 0) && /* @__PURE__ */ jsxs11("thead", { ...role("rowgroup"), children: [
|
|
1030
1349
|
groupRow,
|
|
1031
1350
|
rows.slice(0, head).map(rowEl)
|
|
1032
1351
|
] }),
|
|
1033
|
-
bodies
|
|
1352
|
+
bodies,
|
|
1353
|
+
foot.length > 0 && /* @__PURE__ */ jsx14("tfoot", { ...role("rowgroup"), children: foot.map(rowEl) })
|
|
1034
1354
|
] });
|
|
1035
|
-
|
|
1355
|
+
const filter = value.filterable === true;
|
|
1356
|
+
const ld = jsonLdOf(value.jsonLd);
|
|
1357
|
+
const ldAttrs = ld ? { "data-jsonld": ld.type, ...ld.axis ? { "data-jsonld-axis": ld.axis } : {}, ...ld.priceRow ? { "data-jsonld-price": ld.priceRow } : {} } : {};
|
|
1358
|
+
const designAttrs = design ? { ...design.responsive ? { "data-responsive": design.responsive } : {}, ...design.sticky ? { "data-sticky": "true" } : {} } : {};
|
|
1359
|
+
return notes || filter || ld || design || footnotes.length ? /* @__PURE__ */ jsxs11("figure", { "data-rt": "table", ...designAttrs, ...filter ? { "data-filter": "true" } : {}, ...ldAttrs, children: [
|
|
1036
1360
|
table,
|
|
1037
|
-
/* @__PURE__ */
|
|
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
|
|
1038
1365
|
] }) : table;
|
|
1039
1366
|
}
|
|
1040
1367
|
function buildComponents(renderBlock) {
|