From 468a2bffc85f8fcbdde03580bec9a234cfd1abe7 Mon Sep 17 00:00:00 2001 From: Antigravity Date: Sat, 23 May 2026 10:05:07 +0000 Subject: [PATCH] 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) --- memento-note/components/rich-text-editor.tsx | 45 +++++++++++--------- 1 file changed, 26 insertions(+), 19 deletions(-) diff --git a/memento-note/components/rich-text-editor.tsx b/memento-note/components/rich-text-editor.tsx index 8589651..024f5bf 100644 --- a/memento-note/components/rich-text-editor.tsx +++ b/memento-note/components/rich-text-editor.tsx @@ -295,31 +295,38 @@ export const RichTextEditor = forwardRef${chartContent}` + 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, '

').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])