'use client'; import { useEffect, useMemo, useRef, useState } from 'react'; import { renderLatexSource, type LatexEditorResult } from './latex-editor'; import type { LatexEditorLabels } from '../types'; const DEFAULT_LABELS: LatexEditorLabels = { toolbar: 'Formula toolbar', insertFormula: 'Insert formula', editFormula: 'Edit formula', bringToFront: 'Bring to front', sendToBack: 'Send to back', delete: 'Delete', dialog: 'Formula editor', source: 'LaTeX source', preview: 'Preview', symbols: 'Symbols', presets: 'Presets', cancel: 'Cancel', confirm: 'Confirm', invalidSource: 'The LaTeX source is invalid.', }; export interface LatexEditorDialogProps { readonly initialLatex?: string; readonly labels?: Partial; readonly onConfirm: (result: LatexEditorResult) => void; readonly onClose: () => void; } export function LatexEditorDialog({ initialLatex = '', labels: providedLabels, onConfirm, onClose, }: LatexEditorDialogProps) { const labels = { ...DEFAULT_LABELS, ...providedLabels }; const [latex, setLatex] = useState(initialLatex); const sourceRef = useRef(null); const previewRef = useRef(null); const rendered = useMemo(() => renderLatexSource(latex), [latex]); const canConfirm = latex.trim().length > 0 && !('error' in rendered); useEffect(() => { sourceRef.current?.focus(); }, []); useEffect(() => { const closeOnEscape = (event: KeyboardEvent) => { if (event.key === 'Escape') onClose(); }; document.addEventListener('keydown', closeOnEscape); return () => document.removeEventListener('keydown', closeOnEscape); }, [onClose]); const confirm = () => { if (!canConfirm || 'error' in rendered) return; const preview = previewRef.current; onConfirm({ latex, html: rendered.html, width: Math.max(120, Math.ceil(preview?.scrollWidth ?? 0) + 32), height: Math.max(48, Math.ceil(preview?.scrollHeight ?? 0) + 32), }); }; return (
event.stopPropagation()} >