'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;
}