import type { RichTextContent, TableContent } from "@prismicio/types-internal/lib/content" import { type Table, TableCell as TableCellModel } from "@prismicio/types-internal/lib/customtypes" import type { RenderContext, Renderer } from "../../models" import type { SimpleField } from "../../models/fetch" import StructuredTextRenderer from "./StructuredTextContent" type TableRow = TableContent["content"][number] type TableCell = TableRow["content"][number] const TableRenderer: (ctx: RenderContext) => Renderer = (ctx) => ({ renderV1(_content: TableContent, _fetch: SimpleField | undefined): unknown { // V1 is not supported for Table return null }, renderV2(_def: Table, content: TableContent, fetch: SimpleField | undefined): unknown { const renderStructuredText = (cellContent: RichTextContent) => StructuredTextRenderer(ctx).renderV2(TableCellModel, cellContent, fetch) return renderTable(content, renderStructuredText) }, renderDefault(_def: Table): unknown { return renderDefaultTable() }, renderMocks(def: Table, content: TableContent): unknown { return this.renderV2(def, content) }, }) function renderTable(table: TableContent, renderStructuredText: (cellContent: RichTextContent) => unknown) { const firstRow = table.content[0] if (!firstRow) return renderDefaultTable() const isFirstRowHeader = firstRow.content.every((cell) => cell.type === "tableHeader") const headRow = isFirstRowHeader ? firstRow : undefined const bodyRows = isFirstRowHeader ? table.content.slice(1) : table.content return { ...(headRow ? { head: renderHead(headRow, renderStructuredText) } : {}), body: renderBody(bodyRows, renderStructuredText), } } function renderHead(row: TableRow | undefined, renderStructuredText: (cellContent: RichTextContent) => unknown) { if (!row) { return undefined } return { rows: [renderRow(row, renderStructuredText)], } } function renderBody(rows: TableRow[], renderStructuredText: (cellContent: RichTextContent) => unknown) { return { rows: rows.map((row) => { return renderRow(row, renderStructuredText) }), } } function renderRow(row: TableRow, renderStructuredText: (cellContent: RichTextContent) => unknown) { return { key: row.key, cells: row.content.map((cell) => { return renderCell(cell, renderStructuredText) }), } } function renderCell(cell: TableCell, renderStructuredText: (cellContent: RichTextContent) => unknown) { return { key: cell.key, type: CELL_TYPE_MAP[cell.type], content: renderStructuredText(cell.content), } } const CELL_TYPE_MAP = { tableHeader: "header", tableCell: "data", } as const function renderDefaultTable() { return null } export default TableRenderer