fix(chart): use direct TipTap node creation via transaction

Instead of relying on HTML parsing which can be inconsistent,
create the chartBlock node directly using TipTap's schema and transaction API.
This ensures the custom node is properly created and rendered as a visual chart.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Antigravity
2026-05-23 10:05:07 +00:00
parent d1395d9b81
commit 468a2bffc8

View File

@@ -295,31 +295,38 @@ export const RichTextEditor = forwardRef<RichTextEditorHandle, RichTextEditorPro
if (!editor || !editor.isEditable) return if (!editor || !editor.isEditable) return
try { try {
// chartContent is now raw content without markdown ticks console.log('[handleSelectChart] Inserting chart type:', chartContent.split('\n')[0])
// Example: "bar\nTitle\nlabel: value"
const htmlContent = `<pre><code class="language-chart">${chartContent}</code></pre>`
// Insert the chart HTML at current position const { from, to } = editor.state.selection
const { from } = editor.state.selection const { tr } = editor.state
const { schema } = editor.state
// Check if we're in the middle of text, if so create a new paragraph // Create the chartBlock node directly
const $pos = editor.state.doc.resolve(from) const chartNode = schema.nodes.chartBlock.create({
const isInTextNode = $pos.parent.type.name === 'paragraph' code: chartContent,
language: 'chart'
})
if (isInTextNode && $pos.parentOffset > 0) { if (!chartNode) {
// Create a new paragraph after current one console.error('[handleSelectChart] Failed to create chartBlock node')
const afterPos = $pos.after() toast.error('Chart extension not available')
// Ensure we don't exceed document bounds return
if (afterPos < editor.state.doc.content.size) {
editor.chain().focus().selectParentNode().insertContentAt(afterPos, '<p></p>').run()
}
} }
// Insert the chart as HTML // Replace selection with the chart node
editor.chain().focus().insertContent(htmlContent).run() const transaction = tr.replaceWith(from, to, chartNode)
// Add a paragraph after for continued typing
const paragraph = schema.nodes.paragraph.create()
transaction.insert(transaction.mapping.map(to).map(to), paragraph)
editor.view.dispatch(transaction)
editor.chain().focus().run()
console.log('[handleSelectChart] Chart inserted')
} catch (error) { } catch (error) {
console.error('[handleSelectChart] Failed to insert chart:', error) console.error('[handleSelectChart] Failed:', error)
toast.error('Failed to insert chart. Please try again.') toast.error('Failed to insert chart: ' + (error as Error).message)
} }
}, [editor]) }, [editor])