import { z } from "zod"; import type { BlockMdxConfig } from "../types.js"; /** * Pure (React-free) part of the standard `table` block: its data schema and MDX * round-trip config. Shared by the server MDX adapter (the plan * `plan-block-registry.ts` → `plan-mdx.ts`) and the client spec * (`table.tsx`). Keeping it React-free means a server module that imports it * never pulls React into the Nitro/SSR bundle. * * The schema MUST stay data-compatible with the legacy `table` branch of the * plan `planBlockSchema` (`{ columns: string[]; rows: string[][] }`), and the * MDX `tag` + attribute shape MUST match the legacy self-closing * `` encoding (`plan-mdx.ts` * `serializeBlock`/`parseBlock`) so stored `.mdx` round-trips byte-compatibly. */ export interface TableData { columns: string[]; rows: string[][]; density?: TableDensity; } export const TABLE_DENSITIES = ["compact", "normal", "relaxed"] as const; export type TableDensity = (typeof TABLE_DENSITIES)[number]; export const tableSchema = z.object({ columns: z.array(z.string()), rows: z.array(z.array(z.string())), density: z.enum(TABLE_DENSITIES).optional(), }) as unknown as z.ZodType; /** * MDX config: `columns` and `rows` are JSON attributes (no children) — exactly * the legacy self-closing `
` * form. The legacy serializer emits `columns` before `rows`; `toAttrs` returns * the keys in that exact insertion order because `serializeSpecBlock` preserves * `Object.entries` order. `fromAttrs` mirrors the legacy parser's `?? []` * defaults so partial/older nodes stay tolerant. */ export const tableMdx: BlockMdxConfig = { tag: "Table", toAttrs: (data) => ({ columns: data.columns, rows: data.rows, density: data.density && data.density !== "normal" ? data.density : undefined, }), fromAttrs: (attrs) => ({ columns: attrs.array("columns") ?? [], rows: attrs.array("rows") ?? [], density: parseDensity(attrs.string("density")), }), }; function parseDensity(value: string | undefined): TableDensity | undefined { return value && TABLE_DENSITIES.includes(value as TableDensity) ? (value as TableDensity) : undefined; }