import { useState, useRef, useEffect, useCallback } from "react"; import Markdown from "react-markdown"; import { cn } from "../lib/utils"; import { Button } from "@/components/ui/button"; import { MarkdownEditor } from "./MarkdownEditor"; interface InlineEditorProps { value: string; onSave: (value: string) => void; as?: "h1" | "h2" | "p" | "span"; className?: string; placeholder?: string; multiline?: boolean; imageUploadHandler?: (file: File) => Promise; } /** Shared padding so display and edit modes occupy the exact same box. */ const pad = "px-1 -mx-1"; export function InlineEditor({ value, onSave, as: Tag = "span", className, placeholder = "Click to edit...", multiline = false, imageUploadHandler, }: InlineEditorProps) { const [editing, setEditing] = useState(false); const [draft, setDraft] = useState(value); const inputRef = useRef(null); useEffect(() => { setDraft(value); }, [value]); const autoSize = useCallback((el: HTMLTextAreaElement | null) => { if (!el) return; el.style.height = "auto"; el.style.height = `${el.scrollHeight}px`; }, []); useEffect(() => { if (editing && inputRef.current) { inputRef.current.focus(); inputRef.current.select(); if (multiline && inputRef.current instanceof HTMLTextAreaElement) { autoSize(inputRef.current); } } }, [editing, multiline, autoSize]); function commit() { const trimmed = draft.trim(); if (trimmed && trimmed !== value) { onSave(trimmed); } else { setDraft(value); } setEditing(false); } function handleKeyDown(e: React.KeyboardEvent) { if (e.key === "Enter" && !multiline) { e.preventDefault(); commit(); } if (e.key === "Escape") { setDraft(value); setEditing(false); } } if (editing) { if (multiline) { return (
); } const sharedProps = { ref: inputRef as any, value: draft, onChange: (e: React.ChangeEvent) => { setDraft(e.target.value); if (multiline && e.target instanceof HTMLTextAreaElement) { autoSize(e.target); } }, onBlur: commit, onKeyDown: handleKeyDown, }; return ( ); } return ( setEditing(true)} > {value && multiline ? (
{value}
) : ( value || placeholder )}
); }