'use client'; import { useEffect, type ReactNode } from 'react'; import { EditorContent, useEditor, type Editor } from '@tiptap/react'; import StarterKit from '@tiptap/starter-kit'; import Placeholder from '@tiptap/extension-placeholder'; import { Bold, Italic, List, ListOrdered, Quote } from 'lucide-react'; import { cn } from '@/lib/utils'; interface RichTextEditorProps { value?: string; onChange?: (value: string) => void; placeholder?: string; /** Extra content voor in de toolbar (bijv. mic button) */ toolbarExtra?: ReactNode; /** Callback met editor instance voor externe controle */ onEditorReady?: (editor: Editor) => void; /** Highlight border tijdens streaming */ isStreaming?: boolean; /** Min height voor editor */ minHeight?: string; } export function RichTextEditor({ value, onChange, placeholder, toolbarExtra, onEditorReady, isStreaming = false, minHeight = '160px', }: RichTextEditorProps) { const editor = useEditor({ extensions: [ StarterKit.configure({ heading: false, bulletList: { keepMarks: true }, orderedList: { keepMarks: true }, }), Placeholder.configure({ placeholder: placeholder || 'Schrijf iets...', includeChildren: true }), ], content: value || '', editorProps: { attributes: { class: `prose prose-sm max-w-none focus:outline-none px-3 py-2 text-slate-800 bg-white`, style: `min-height: ${minHeight}`, }, }, onUpdate({ editor: e }) { onChange?.(e.getHTML()); }, immediatelyRender: false, }); useEffect(() => { if (!editor) return; const html = value || ''; if (html !== editor.getHTML()) { editor.commands.setContent(html); } }, [value, editor]); // Notify parent when editor is ready useEffect(() => { if (editor && onEditorReady) { onEditorReady(editor); } }, [editor, onEditorReady]); if (!editor) { return
; } const toggle = (command: () => void) => { editor.chain().focus(); command(); }; return (