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