import type { BlockConfig } from '@knapsack/types'; import type { JSONContent } from '@knapsack/tiptap-utils'; export type TiptapContentField = { fieldPath: string; content: JSONContent | null | undefined; setContent: (content: JSONContent | null | undefined) => void; }; /** * Every JSONContent-bearing field on a block - the single source of truth * for both detection (reads `content`) and stripping (calls `setContent`), * so a block type gaining a new tiptap field only needs updating here once, * not in two independently-maintained switches that could silently drift. */ export function getTiptapContentFields( block: BlockConfig, ): TiptapContentField[] { switch (block.blockType) { case 'text-editor': case 'callout': case 'code-snippet': case 'table': return [ { fieldPath: 'content', content: block.data.content, setContent: (content) => { block.data.content = content; }, }, ]; case 'guidelines': return (block.data.guidelines || []).map((guideline, index) => ({ fieldPath: `guidelines[${index}].content`, content: guideline.content, setContent: (content) => { const target = block.data.guidelines?.[index]; if (target) target.content = content; }, })); case 'design-src-tiles': // Not rendered through TextEditor anywhere today - included here for // detection completeness, but the live-editor safety net doesn't // reach it. Flagged as informational in the Doctor listing. return (block.data.items || []).map((item, index) => ({ fieldPath: `items[${index}].description`, content: item.description, setContent: (content) => { const target = block.data.items?.[index]; if (target) target.description = content; }, })); default: return []; } }