import { useState, useRef, useEffect, useCallback } from "react"; import { cn } from "../lib/utils"; import { Button } from "@/components/ui/button"; import { MarkdownBody } from "./MarkdownBody"; import { MarkdownEditor, type MentionOption } 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; mentions?: MentionOption[]; } /** 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, mentions, }: 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 (inputRef.current instanceof HTMLTextAreaElement) { autoSize(inputRef.current); } } }, [editing, 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 (
); } return (