@dotcms/react
Advanced tools
@@ -119,2 +119,3 @@ import { jsx, jsxs } from 'react/jsx-runtime'; | ||
| content: (_node$content = node.content) != null ? _node$content : [], | ||
| attrs: node.attrs, | ||
| blockEditorItem: BlockEditorBlock | ||
@@ -121,0 +122,0 @@ }, key); |
| import { jsxs, jsx } from 'react/jsx-runtime'; | ||
| /** | ||
| * Renders a table component for the Block Editor. | ||
| * Renders a table block for the Block Editor. | ||
| * | ||
| * @param content - The content of the table. | ||
| * @param blockEditorItem - The Block Editor item component. | ||
| * **Cell-type-aware**: each cell is emitted as `<th>` or `<td>` based on the node's | ||
| * `type` (`tableHeader` vs `tableCell`) rather than its row position — so column-header | ||
| * cells in any row (the result of "Toggle column header" in the editor) keep their | ||
| * semantic `<th>` wrapper and the `scope` attribute reaches headless consumers. | ||
| * | ||
| * @param content - The table's child rows. | ||
| * @param attrs - Optional table-level attributes (`caption`, `ariaLabel`, `ariaLabelledby`). | ||
| * @param blockEditorItem - The Block Editor item component for nested content. | ||
| */ | ||
| const TableRenderer = ({ | ||
| content, | ||
| attrs, | ||
| blockEditorItem | ||
| }) => { | ||
| const BlockEditorItemComponent = blockEditorItem; | ||
| const renderTableContent = node => { | ||
| const renderCellContent = node => { | ||
| var _node$content; | ||
@@ -20,5 +27,12 @@ return jsx(BlockEditorItemComponent, { | ||
| }; | ||
| const caption = (attrs == null ? void 0 : attrs.caption) || undefined; | ||
| const ariaLabel = (attrs == null ? void 0 : attrs.ariaLabel) || undefined; | ||
| const ariaLabelledBy = (attrs == null ? void 0 : attrs.ariaLabelledby) || undefined; | ||
| return jsxs("table", { | ||
| children: [jsx("thead", { | ||
| children: content.slice(0, 1).map((rowNode, rowIndex) => { | ||
| "aria-label": ariaLabel, | ||
| "aria-labelledby": ariaLabelledBy, | ||
| children: [caption ? jsx("caption", { | ||
| children: caption | ||
| }) : null, jsx("tbody", { | ||
| children: content.map((rowNode, rowIndex) => { | ||
| var _rowNode$content; | ||
@@ -28,23 +42,22 @@ return jsx("tr", { | ||
| var _cellNode$attrs, _cellNode$attrs2; | ||
| return jsx("th", { | ||
| colSpan: Number(((_cellNode$attrs = cellNode.attrs) == null ? void 0 : _cellNode$attrs.colspan) || 1), | ||
| rowSpan: Number(((_cellNode$attrs2 = cellNode.attrs) == null ? void 0 : _cellNode$attrs2.rowspan) || 1), | ||
| children: renderTableContent(cellNode) | ||
| }, `${cellNode.type}-${cellIndex}`); | ||
| }) | ||
| }, `${rowNode.type}-${rowIndex}`); | ||
| }) | ||
| }), jsx("tbody", { | ||
| children: content.slice(1).map((rowNode, rowIndex) => { | ||
| var _rowNode$content2; | ||
| return jsx("tr", { | ||
| children: (_rowNode$content2 = rowNode.content) == null ? void 0 : _rowNode$content2.map((cellNode, cellIndex) => { | ||
| var _cellNode$attrs3, _cellNode$attrs4; | ||
| const colSpan = Number(((_cellNode$attrs = cellNode.attrs) == null ? void 0 : _cellNode$attrs.colspan) || 1); | ||
| const rowSpan = Number(((_cellNode$attrs2 = cellNode.attrs) == null ? void 0 : _cellNode$attrs2.rowspan) || 1); | ||
| // Cell type — not row index — decides th vs td. Matches the | ||
| // VTL renderer (storyblock/render.vtl). | ||
| if (cellNode.type === 'tableHeader') { | ||
| var _cellNode$attrs3; | ||
| return jsx("th", { | ||
| colSpan: colSpan, | ||
| rowSpan: rowSpan, | ||
| scope: ((_cellNode$attrs3 = cellNode.attrs) == null ? void 0 : _cellNode$attrs3.scope) || undefined, | ||
| children: renderCellContent(cellNode) | ||
| }, `cell-${cellIndex}`); | ||
| } | ||
| return jsx("td", { | ||
| colSpan: Number(((_cellNode$attrs3 = cellNode.attrs) == null ? void 0 : _cellNode$attrs3.colspan) || 1), | ||
| rowSpan: Number(((_cellNode$attrs4 = cellNode.attrs) == null ? void 0 : _cellNode$attrs4.rowspan) || 1), | ||
| children: renderTableContent(cellNode) | ||
| }, `${cellNode.type}-${cellIndex}`); | ||
| colSpan: colSpan, | ||
| rowSpan: rowSpan, | ||
| children: renderCellContent(cellNode) | ||
| }, `cell-${cellIndex}`); | ||
| }) | ||
| }, `${rowNode.type}-${rowIndex}`); | ||
| }, `row-${rowIndex}`); | ||
| }) | ||
@@ -51,0 +64,0 @@ })] |
+1
-1
| { | ||
| "name": "@dotcms/react", | ||
| "version": "1.5.4", | ||
| "version": "1.5.6-next.35", | ||
| "peerDependencies": { | ||
@@ -5,0 +5,0 @@ "react": ">=18", |
@@ -5,2 +5,7 @@ import React from 'react'; | ||
| content: BlockEditorNode[]; | ||
| /** | ||
| * Table-node attributes (`caption`, `ariaLabel`, `ariaLabelledby`). Optional for | ||
| * back-compat with older payloads that don't carry these. | ||
| */ | ||
| attrs?: BlockEditorNode['attrs']; | ||
| blockEditorItem: React.FC<{ | ||
@@ -11,8 +16,14 @@ content: BlockEditorNode[]; | ||
| /** | ||
| * Renders a table component for the Block Editor. | ||
| * Renders a table block for the Block Editor. | ||
| * | ||
| * @param content - The content of the table. | ||
| * @param blockEditorItem - The Block Editor item component. | ||
| * **Cell-type-aware**: each cell is emitted as `<th>` or `<td>` based on the node's | ||
| * `type` (`tableHeader` vs `tableCell`) rather than its row position — so column-header | ||
| * cells in any row (the result of "Toggle column header" in the editor) keep their | ||
| * semantic `<th>` wrapper and the `scope` attribute reaches headless consumers. | ||
| * | ||
| * @param content - The table's child rows. | ||
| * @param attrs - Optional table-level attributes (`caption`, `ariaLabel`, `ariaLabelledby`). | ||
| * @param blockEditorItem - The Block Editor item component for nested content. | ||
| */ | ||
| export declare const TableRenderer: React.FC<TableRendererProps>; | ||
| export {}; |
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
131749
1.03%2815
0.9%2
100%