'use client'; /** * Editor enriquecido ligero para notas de Seguimiento * (barra tipo Google Docs: negrita, color, resaltado, listas, enlaces). */ import React, { useCallback, useEffect, useRef } from 'react'; import { Bold, Italic, Underline, List, ListOrdered, Link as LinkIcon, Highlighter, Type, RemoveFormatting, AlignLeft, AlignCenter, AlignRight, } from 'lucide-react'; type Props = { value: string; onChange: (html: string) => void; placeholder?: string; className?: string; minHeight?: string; }; function run(cmd: string, value?: string) { try { document.execCommand(cmd, false, value); } catch { /* ignore */ } } function ToolbarBtn({ title, active, onClick, children, }: { title: string; active?: boolean; onClick: () => void; children: React.ReactNode; }) { return ( ); } const TEXT_COLORS = [ { label: 'Negro', value: '#111827' }, { label: 'Rojo', value: '#DC2626' }, { label: 'Naranja', value: '#EA580C' }, { label: 'Ámbar', value: '#D97706' }, { label: 'Verde', value: '#059669' }, { label: 'Azul', value: '#2563EB' }, { label: 'Violeta', value: '#7C3AED' }, ]; const HIGHLIGHTS = [ { label: 'Ninguno', value: 'transparent' }, { label: 'Amarillo', value: '#FEF08A' }, { label: 'Verde', value: '#BBF7D0' }, { label: 'Azul', value: '#BFDBFE' }, { label: 'Rosa', value: '#FECDD3' }, { label: 'Naranja', value: '#FED7AA' }, ]; export default function NoteRichEditor({ value, onChange, placeholder = 'Escribe la nota…', className = '', minHeight = '140px', }: Props) { const ref = useRef(null); const lastHtml = useRef(value); useEffect(() => { const el = ref.current; if (!el) return; if (value !== lastHtml.current && el.innerHTML !== value) { el.innerHTML = value || ''; lastHtml.current = value; } }, [value]); const emit = useCallback(() => { const el = ref.current; if (!el) return; const html = el.innerHTML; lastHtml.current = html; onChange(html); }, [onChange]); const apply = (fn: () => void) => { ref.current?.focus(); fn(); emit(); }; const addLink = () => { const url = window.prompt('URL del enlace', 'https://'); if (!url) return; apply(() => run('createLink', url)); }; return (
apply(() => run('bold'))}> apply(() => run('italic'))}> apply(() => run('underline'))} > apply(() => run('insertUnorderedList'))} > apply(() => run('insertOrderedList'))} > apply(() => run('justifyLeft'))} > apply(() => run('justifyCenter'))} > apply(() => run('justifyRight'))} > apply(() => run('removeFormat'))} >
); } /** True if HTML has visible text. */ export function richTextHasContent(html: string): boolean { const text = html .replace(//gi, '') .replace(/ /gi, ' ') .replace(/<[^>]+>/g, '') .trim(); return text.length > 0; }