import React, { useRef, useEffect, useState, useCallback } from 'react' function exec(cmd, value = null) { try { return document.execCommand(cmd, false, value) } catch (_) { return false } } /** Browser: formatBlock erwartet oft Tag in Großschreibung. */ function formatBlock(tag) { const t = String(tag).toUpperCase() if (!exec('formatBlock', t)) { exec('formatBlock', tag.toLowerCase()) } } function normalText() { exec('removeFormat') formatBlock('p') } /** * Leichter WYSIWYG (contenteditable). Wert kommt von außen zuverlässig ins DOM (Edit-Modus). */ export default function RichTextEditor({ value, onChange, placeholder, minHeight = '140px' }) { const ref = useRef(null) const [focused, setFocused] = useState(false) useEffect(() => { const el = ref.current if (!el || focused) return const next = value ?? '' if (el.innerHTML !== next) { el.innerHTML = next } }, [value, focused]) const sync = useCallback(() => { if (!ref.current) return onChange(ref.current.innerHTML) }, [onChange]) const run = (fn) => (e) => { e.preventDefault() ref.current?.focus() fn() sync() } const onLink = (e) => { e.preventDefault() ref.current?.focus() const url = window.prompt('Link-URL (https://…)') if (url) { exec('createLink', url) sync() } } return (
setFocused(true)} onBlur={() => { setFocused(false) sync() }} onInput={sync} />
) }