"use client"; import { type ReactNode, useEffect, useRef, useState } from "react"; import aiStyles from "@/styles/ai.module.css"; import styles from "./RichTextArea.module.css"; const FONT_SIZES = [ { value: "2", label: "S" }, { value: "3", label: "M" }, { value: "4", label: "L" }, { value: "5", label: "XL" }, ] as const; function escapeAttr(value: string) { return value .replace(/&/g, "&") .replace(/"/g, """) .replace(/ void; disabled?: boolean; minHeight?: number; toolbarEnd?: ReactNode; aiWorking?: boolean; onUploadImage?: (file: File) => Promise; }) { const ref = useRef(null); const imageInputRef = useRef(null); const [direction, setDirection] = useState<"ltr" | "rtl">("ltr"); const [fontSize, setFontSize] = useState("3"); const [uploadingImage, setUploadingImage] = useState(false); const [imageError, setImageError] = useState(""); useEffect(() => { const node = ref.current; if (!node) return; if (node.innerHTML !== value) { node.innerHTML = value || ""; } }, [value]); function emit() { onChange(ref.current?.innerHTML ?? ""); } function exec(command: string, commandValue?: string) { if (disabled) return; ref.current?.focus(); document.execCommand(command, false, commandValue); emit(); } function applyFontSize(size: string) { setFontSize(size); exec("fontSize", size); } function applyDirection(next: "ltr" | "rtl") { setDirection(next); const node = ref.current; if (!node || disabled) return; node.setAttribute("dir", next); node.focus(); emit(); } async function insertImage(file: File) { if (!onUploadImage || disabled) return; setUploadingImage(true); setImageError(""); try { const url = await onUploadImage(file); if ( !url.startsWith("/") && !url.startsWith("http://") && !url.startsWith("https://") ) { throw new Error("Could not add image."); } ref.current?.focus(); document.execCommand( "insertHTML", false, ``, ); emit(); } catch (err) { setImageError( err instanceof Error ? err.message : "Could not add image.", ); } finally { setUploadingImage(false); } } return (
{label ? {label} : null}
{onUploadImage ? ( ) : null} {toolbarEnd ? (
{toolbarEnd}
) : null}
{imageError ?

{imageError}

: null}
{onUploadImage ? ( { const file = event.target.files?.[0]; event.target.value = ""; if (file) void insertImage(file); }} /> ) : null}
); }