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
|
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])
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user