'use client'; import React, { useState, useEffect, useRef, forwardRef, useImperativeHandle } from 'react'; import { detectTextDirection } from '@/lib/utils/text-direction'; import { sanitizeHtml } from '@/lib/utils/dom-sanitizer'; interface RichTextEditorProps { /** Initial HTML content */ initialContent?: string; /** Callback when content changes */ onChange?: (html: string) => void; /** Additional CSS class names */ className?: string; /** Editor placeholder text */ placeholder?: string; /** Whether the editor is read-only */ readOnly?: boolean; /** Minimum height of the editor */ minHeight?: string; /** Initial text direction */ initialDirection?: 'ltr' | 'rtl'; } /** * Unified rich text editor component with proper RTL support * Handles email composition with appropriate text direction detection */ const RichTextEditor = forwardRef(({ initialContent = '', onChange, className = '', placeholder = 'Write your message...', readOnly = false, minHeight = '200px', initialDirection }, ref) => { const internalEditorRef = useRef(null); const [direction, setDirection] = useState<'ltr' | 'rtl'>( initialDirection || detectTextDirection(initialContent) ); // Forward the ref to parent components useImperativeHandle(ref, () => internalEditorRef.current as HTMLDivElement); // Initialize editor with clean content useEffect(() => { if (internalEditorRef.current) { // Clean the initial content const cleanContent = sanitizeHtml(initialContent); internalEditorRef.current.innerHTML = cleanContent; // Set initial direction internalEditorRef.current.setAttribute('dir', direction); // Focus editor if not read-only if (!readOnly) { setTimeout(() => { internalEditorRef.current?.focus(); }, 100); } } }, [initialContent, direction, readOnly]); // Handle content changes and detect direction changes const handleInput = (e: React.FormEvent) => { if (onChange && e.currentTarget.innerHTML !== initialContent) { onChange(e.currentTarget.innerHTML); } // Re-detect direction on significant content changes // Only do this when the content length has changed significantly const newContent = e.currentTarget.innerText; if (newContent.length > 5 && newContent.length % 10 === 0) { const newDirection = detectTextDirection(newContent); if (newDirection !== direction) { setDirection(newDirection); e.currentTarget.setAttribute('dir', newDirection); } } }; // Toggle direction manually const toggleDirection = () => { const newDirection = direction === 'ltr' ? 'rtl' : 'ltr'; setDirection(newDirection); if (internalEditorRef.current) { internalEditorRef.current.setAttribute('dir', newDirection); } }; return (
{!readOnly && (
)}
); }); RichTextEditor.displayName = 'RichTextEditor'; export default RichTextEditor;