import { isFilled, type TableField, type TableFieldHead, type TableFieldHeadRow, type TableFieldBody, type TableFieldBodyRow, type TableFieldHeaderCell, type TableFieldDataCell, } from "@prismicio/client" import type { ComponentType, FC, ReactNode } from "react" import { type JSXMapSerializer, PrismicRichText } from "./PrismicRichText.js" type TableComponents = { table?: ComponentType<{ table: TableField<"filled">; children: ReactNode }> thead?: ComponentType<{ head: TableFieldHead; children: ReactNode }> tbody?: ComponentType<{ body: TableFieldBody; children: ReactNode }> tr?: ComponentType<{ row: TableFieldHeadRow | TableFieldBodyRow children: ReactNode }> th?: ComponentType<{ cell: TableFieldHeaderCell; children: ReactNode }> td?: ComponentType<{ cell: TableFieldDataCell; children: ReactNode }> } const defaultComponents: Required = { table: ({ children }) => {children}
, thead: ({ children }) => {children}, tbody: ({ children }) => {children}, tr: ({ children }) => {children}, th: ({ children }) => {children}, td: ({ children }) => {children}, } /** Props for ``. */ export type PrismicTableProps = { /** The Prismic table field to render. */ field: TableField /** * An object that maps a table block to a React component. * * @example * A map serializer. * * ```jsx * { * table: ({children}) => {children}
* thead: ({children}) => {children} * } * ``` */ components?: JSXMapSerializer & TableComponents /** * The value to be rendered when the field is empty. If a fallback is not given, `null` will be * rendered. */ fallback?: ReactNode } /** * Renders content from a Prismic table field as React components. * * @example * ;```tsx * ; * ``` * * @see Learn how to style tables and customize table element components: {@link https://prismic.io/docs/fields/table} */ export const PrismicTable: FC = (props) => { const { field, components, fallback = null } = props if (!isFilled.table(field)) { return fallback } const { table: Table, thead: Thead, tbody: Tbody } = { ...defaultComponents, ...components } return ( {field.head && ( {field.head.rows.map((row) => ( ))} )} {field.body.rows.map((row) => ( ))}
) } type TableRowProps = { row: TableFieldHeadRow | TableFieldBodyRow components?: JSXMapSerializer & TableComponents } function TableRow(props: TableRowProps) { const { row, components } = props const { tr: Tr, th: Th, td: Td } = { ...defaultComponents, ...components } return ( {row.cells.map((cell) => cell.type === "header" ? ( ) : ( ), )} ) }