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