/** * @usevyre/react — RichTextEditor * * AI CONTEXT: * ┌─────────────────────────────────────────────────────────────────┐ * │ Component: RichTextEditor (WYSIWYG, contentEditable) │ * │ Import: import { RichTextEditor } from "@usevyre/react" │ * │ │ * │ CONTROLLED. value is an HTML string; onChange gives next HTML. │ * │ Zero dependencies — native contentEditable + execCommand. │ * │ │ * │ Props: │ * │ value = string (HTML, controlled) │ * │ onChange = (html: string) => void │ * │ placeholder?= string (shown when empty) │ * │ disabled? = boolean (not editable, dimmed) │ * │ readOnly? = boolean (not editable, no toolbar) │ * │ toolbar? = RichTextTool[] (which buttons; default = all) │ * │ minHeight? = string (CSS, default "10rem") │ * │ sanitize? = (html: string) => string │ * │ │ * │ RichTextTool = "bold"|"italic"|"underline"|"strike"| │ * │ "h1"|"h2"|"h3"|"ul"|"ol"|"quote"|"code"|"link"|"clear" │ * │ │ * │ Controlled: store value in state and set it in onChange. │ * │ SECURITY: value is rendered as raw HTML. Sanitize untrusted │ * │ HTML before passing it in — e.g. sanitize={DOMPurify.sanitize}. │ * │ sanitize runs on render-in AND emit-out. The link tool blocks │ * │ javascript:/data:/vbscript: URLs regardless. │ * └─────────────────────────────────────────────────────────────────┘ * * @example * const [html, setHtml] = useState("
Hello world
"); *